From 7f0dd9d318402dd909a194b6a9a52c94e031ae18 Mon Sep 17 00:00:00 2001 From: kogisin Date: Wed, 6 Oct 2021 20:26:03 +0900 Subject: [PATCH 1/8] chore: remove unused tx file and update comments --- x/budget/client/cli/flags.go | 1 + x/budget/client/cli/query.go | 1 + x/budget/client/cli/tx.go | 25 ------------------------- x/budget/module.go | 3 +-- 4 files changed, 3 insertions(+), 27 deletions(-) delete mode 100644 x/budget/client/cli/tx.go diff --git a/x/budget/client/cli/flags.go b/x/budget/client/cli/flags.go index 0465869..39d1d3e 100644 --- a/x/budget/client/cli/flags.go +++ b/x/budget/client/cli/flags.go @@ -10,6 +10,7 @@ const ( FlagCollectionAddress = "collection-address" ) +// flagSetBudgets returns the FlagSet used for budgets. func flagSetBudgets() *flag.FlagSet { fs := flag.NewFlagSet("", flag.ContinueOnError) diff --git a/x/budget/client/cli/query.go b/x/budget/client/cli/query.go index cd3bb84..fcdb1d9 100644 --- a/x/budget/client/cli/query.go +++ b/x/budget/client/cli/query.go @@ -71,6 +71,7 @@ $ %s query %s params return cmd } +// GetCmdQueryBudgets implements the query budgets command. func GetCmdQueryBudgets() *cobra.Command { cmd := &cobra.Command{ Use: "budgets", diff --git a/x/budget/client/cli/tx.go b/x/budget/client/cli/tx.go deleted file mode 100644 index 8052f62..0000000 --- a/x/budget/client/cli/tx.go +++ /dev/null @@ -1,25 +0,0 @@ -package cli - -// Modification of Budgets of Params proceeds to governance proposition, not to Tx. -//import ( -// "github.com/cosmos/cosmos-sdk/client" -// "github.com/spf13/cobra" -// -// "github.com/tendermint/budget/x/budget/types" -//) -// -//// GetTxCmd returns a root CLI command handler for all x/budget transaction commands. -//func GetTxCmd() *cobra.Command { -// budgetTxCmd := &cobra.Command{ -// Use: types.ModuleName, -// Short: "Budget transaction subcommands", -// DisableFlagParsing: true, -// SuggestionsMinimumDistance: 2, -// RunE: client.ValidateCmd, -// } -// -// budgetTxCmd.AddCommand( -// ) -// -// return budgetTxCmd -//} diff --git a/x/budget/module.go b/x/budget/module.go index 9348f32..f3c4231 100644 --- a/x/budget/module.go +++ b/x/budget/module.go @@ -72,10 +72,9 @@ func (AppModuleBasic) RegisterGRPCGatewayRoutes(clientCtx sdkclient.Context, mux } // GetTxCmd returns the root tx command for the budget module. +// Modifying parameters of a budget can be done through governance process, not through transaction level. func (AppModuleBasic) GetTxCmd() *cobra.Command { - // Modification of Budgets of Params proceeds to governance proposition, not to Tx. return nil - } // GetQueryCmd returns the root query command for the budget module. From e5c272dd02b023243fb1a71510bb3c072bd9a4d9 Mon Sep 17 00:00:00 2001 From: kogisin Date: Fri, 8 Oct 2021 14:35:24 +0900 Subject: [PATCH 2/8] docs: update comments on proto files --- client/docs/statik/statik.go | 2 +- client/docs/swagger-ui/swagger.yaml | 67 +++++++++---------- proto/tendermint/budget/v1beta1/budget.proto | 15 +++-- proto/tendermint/budget/v1beta1/genesis.proto | 6 +- 4 files changed, 42 insertions(+), 48 deletions(-) diff --git a/client/docs/statik/statik.go b/client/docs/statik/statik.go index 1295436..1f2072c 100644 --- a/client/docs/statik/statik.go +++ b/client/docs/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\x0c\x00 \x00swagger.yamlUT\x05\x00\x01\x80Cm8\xec]_s\xdc8r\x7f\xd7\xa7\xe8\xe8\xe1$\xe7d\xca\xf6^\xe5A\x89\xae\xe2x\xed=_\xf6\x8fN\x96\x9f\xb6\xb6$\x0c\xd9\x9cA\xcc\x01h\x00\x94|\xfb\xdf\xf0_E\xb2F\x05?\xf0\xa4\xc8\x10\x9e\xc3\xed\xdb\x0fw@X\x02\xeb\xdb\x9b7\xf0\x1dQ\xf8Dv\x90\xf0X\x9e\x00$(cAsE9\xbb\x82\xb3\xd7v2e\nEJb\x84\x94\x0b\x90\x8a(\x84\xcf\x05\n\x8a\xf2\x02\x94 L\x92X?!\xcfN\x00\x1eQH\xf3\xf4\x8b\xe8e\xf4\xe2$'j#5c\x97\xb1a\xe9re\xd8\xb9||\xb9BE^\x96\xffif\x00\xacQ\xd9\xbf\x00\xc8b\xbb%bwU\xb2/A\xa0*\x04\x93@\xb2\x0c\xca\x87\xa2r.\xcfQ\x10\xcd\xc0\xfbd?\xbf\xfcI\xa0\xcc9\x93(+\xba\x00g\xaf^\xbc8;\xfcgk\xcf\xafA\x16q\x8cR\xa6E\xb6\x7f:\xaa\xcd\x96\xf1\x06\xb7\xa4\xfe<\x80\xda\xe5x\x05|\xf5?\x18\xab\xc6\x0f\xb9\xd0\xbc)Z_\xdf\x8e\xc6\xbe\xeb\xc3\xd2\"B\x90]\xe77\xaap\xebx$\xc0\x80\x1d~6\xec\xb0\xcc\xb8\x7f\xeb%\x0e\x03\x16\xd0\x83\x91-\xfa\x7f\xad\x96\x91JP\xb6\x0eM\xb3\n\xae\xa9A\x82)e(Am\xd0\xfe\x03O\xcd\xdf\xed~\xbcD\x04Q3r\xf2\xe7\xe7\x819v1\x909\xc64\xa5%\xab \xd5\xb4W\x85\xa2l\x0dd\xcb\x0b\xa6`\xb5\x03\xa3\xc3\xc0\xd3 9\xc5\x15\xa9\x0e\x00H^\x88\x18\xbd\xf3\xed\xac{;\xeb\x9e$\x89@\x19xA3o\xdc\xb9z\xe3\x95\xad0\xde|\xf3\xea9\xb2\x98'\x98\x04\x89U\x8f\xab\x0d\xa9\xb6=\xf0e\xc7<\xcb\xd0\x98\xa7\x7f\xba\x04\xbaKO\xdd~c\xcb\x90s\x9e\x81\xe2\x07}\xf2\xab\x82TD\xa8{Eg9\x82)\x17[\xa2\xae !\n\x9fk\x9a\xfd\x92:\xac\xdf:\x0b\xe6\x070?\x0c{\x9f\xc8\x92\xdfp\x1f\xd5\xea\xad] K\x86\xef\xa1\xe1oJ\xef\xdc\xd0\x8b\xf2p+Q\xc4*r\x121V\xe0\xbe\xd4/L\xeecN\x99W\xafC\x1e\xc5\x0e\xaf_\xb1c\x80\x03\x18\xe6\x02\xf4\xde\x19\xdf\x86&\x0c~y\xd6n\xce@\xaa\xf1:\x82'\xfa\x0d\xa7l\xff\xa6\x08(\xfe \x19\x17T`\xa2\xdd\xd3\x9a\xafy.\xb8\xe2M\x95\x0c\x8b\xefo\x05\x8a]\x19\x92\xdd\x96\xd1\x94\xde\x82\xd6\xf3*\xba2\xaf\xc9\x84\x96\xfa_\xcd\x13\x97\xcd(\xae\x1a:`\xb5\xfc\x1fxH0%E\xa6\xfc\x01\x1d\x83\x82\xe1\x97\xdc\x1c\x14@!\xb8\xd8\xaf\\{f\xa6\xb0\xce\xd0\xf7\x05uNE\xd4\xc6\xdf\xf7\x80\x0e\xbc\xd7(:\xbfV\x86\x8b2\xf5\xcd\xab\xd6\xaf[\x94\x92\xac\xbd$\x9d<$\xa8\x08\xcd~'\xc1\xa8~\xfc\xbe\x10Y\xd8\x9c\x05\x0f\xf5\xd0#\xfd\x1a>\xde~\x7f)\xb0\x0c(L\x08i\"\x8c\x82\xd1\xcf\x05f;\xa0 2u\xb0\xf3FS\x03\x11\x9a\xf1h((\xc9\xe8\xdf1p\xc8\xcc9\x8a\xb9\x0e\xe4\xd2\x14E\xf5\xd2\"\xb8\xdbPY\xee\x0d\xb6\x85T\x10s\xa6\x08e@\xfc\x967C\"\x95\x7f-\xce\x10N/O!\xde\x10Ab\x85\"2F%#R\x81\xc4\xb56\x1d\x95\xdb\xfax\xfb\xfd\x99\x04}e\xf3R3L \xcc\x05Jd\x81U5\xb9\xb4\xc8\xb2\x1d|.H\xa6%\x984Bt#\xc9s\"\x812?\x91\x07\xcd\xca\xe5\x9a\xf3u\x86\x91\x91\xd9\xaaH\xa3o\x0b{\xdb{xfwb\xc8\xca\x0d/\xb2\x04V\xa8 \xfa\xe8\x11\x88 \xe3\x8c\xc6$3g\xc8\xbf\xf29F\xeb\xe8B\x8b6\xd1\xaf\xe24:\xd5V\x8bq\x05$\x8e1W\x98<\x0bY\xef\xf7\x0cr-l\x1a\xe3\x05($[ \x85,\x88\x16G.0\xe6\xdb\x9cf\x9aS\xc5\xad\xc7\xa7\x8c\x08\x9fs\x06s\xe5\xd5\xf2*\xc3_\xb5\xc1\x9d\x7fik\xea\x80*\x1d\x19\x16\xda\xda2\xb3\x86V$\xfcb^\xf5k\xb6\x8b\xe0/\xfc \x1fQ\\hAx\x89}\xbc\xfd^\x96~F\x93\xd2\x0e\xc6;\xd7XP\x84\x87\x8dR\xf9\xc3\x85\xfdS>\\\x00\x17\xc0x\xf9\xeb\x85\xd1\xc6\x980\xe0\xe6tj\x89\xf8 \xa2\x82\"\xd7\x8ev\x97\x87\xd6E\xf1\x88\xc2\x8afKriU\xcbp\xaexu\xb2\xac\xdb\xa6&K\x01\xa4\xedW\x0e#\xe5Y\xc6\x9f\xe4U\xe0\xdd\xfe+\xbcO\x0f;\xd2j\x91\x0b\xfeH\x13L\xf6\x9b6NZ\xcab\x8bI\x14\"\xf4\x9a\xc1_\xee\xeen\xe0\xbb\xb7w\xc0Yu\x04\xed\x19\xdb\x19oO\xbcO\xff\xdc>\x16w\xbb\x1c\x7f\xf9\xf9\x17\xef\x03\x00\x8f$+\x8c>X}+\xdd\x88yC\xb9\xe0I\x11\xa3\x0e-\x8c\x0bs\x87\x9d`\xb9\xce\xf3\x8c\xc6\xa4\x94\xa5@\xad\x9f\xfc \x13-\xee\x98\xc4\xda\xb6p\xfe\xa9\xc8\xb5\x9b-2%aEd\xe0~c7\x1e`\xfb\xe3\xed\xf7\x86\xc7\x0dy4*\xb8\xad\x9d\xa1\xc4\x1e\"RmI\xff\xfd\x91S\x1d~\xf9\x15\x0bJ\x06\x8d\xf9\x10\x98r\x81\x17\x15\x01M\x97(\xba\xa2\x19U;`\x88\x89Q\xa3\x15\x821y\xe21xS\xe3L\x9bY\xb6F\xf3\x909\xb3\x11\x9c\x7f\x94X\xa5\xc5\xb4\x94\xb4zj\x9be\xf5\x930\xb2\x0e\xed~%\x90|\xd26\xa8$\x1c=\xf3k\xd4\x8f\\\xe1\x15(\xedC\xd2\x82\xc5\xf6\x84\xe9}\x94\xb6+.\x84@\xa6\xb2\x1d\x90GB3\xb2\xca\x82\xe6R\xeb#OS\x1aS\x92\xf5\xf8\xb2U\x91\x82@\xed\x89\xf0\xc2\x84\xbfTU\x8b\x16\x12\x13\x1b\xddU\xe7\xd2Kj\x85k\xca\x98\xde\xac\x8e\xaa\x03\xcee\x97cd\xf5\x9f\xe4TF1\xdf\x86\xac\xf1\x07sR%p\xb5\xb1\x86\x82\xb5\xad\x14\x9c\x97\xd1'ns\xb5+\x8f\xf63\xbf\x13\xa4\xeb\x8d\x82U\xc0(\x99M\x9b\xab\xc1>>\xb7W\x83\xf2\xde\x18\x83\xc4-a\x8a\xc6\xd2}\xd4\xccY\x9d\x10\x02U!\xe2j\xe7\xcd\n\x0c\x8d\x92~\xd0\xe6h\x85@4S4\xa9\x058\x9d8\xa6t\xeed\xc5\x1f\x03\xb9\x88\xf2\xeal\x8f\x82k\xfbC8{x\xcdv\x0fUxd\xeeDD\xac\xa8\x12\xfa\x10\xfb9t\x92\xaa|\x04\xc9x\xa9z@\xdc\xafV[g\xe3h,\x87\xabfX\xd8\n\xff\xf6Q\x9dG5o\xaa\x83\x93\xd1\x95a\xbb\xf4#\x12d\x91\xe7\\\x18\x0f\x9e\x93\xf8\xd3e\xc1\xf4\x1f\xdao[\xbdp\x9f\xa0\xd2\xd1\xfb\x03\x1b\x9eB\xa1\xaca\xab\xcc\x83\xd4\x86\x95$ \xb5\xb6\x02\xd6\xc8P\x10e\x98\xd7\xf7\xac*\xe5\xe4\xa4\xa7\xf9\xb1\xaf\xd0\xbd\xde\xdb/D+?\xbc\xbc\x82\x1b\xcd\xbf\xb6\x0b\xe5V\xc8^\xe8\x94\xc1\x9b?\xfe1\xe0&\xdfq\x0e)\xe7p\x0dQ\x14\xfd\xbbw\x9af\x86\xb0\x9d\x7f\x02a\xbbH\xb3\xf1N\xf0\xedy\xca\xf93\xff\xd4(\xf2\xfb?\x9a\xc2\xb9&\xf5\xd1l\xe4\x8e\x9f\xffA\xd3z\x06\xff\x08\xd8\xf0\x10\xbd\xafa\xd9\xbd\xea\x91\xdd_\xc9#\x99MxpmbC\xbd\xca\x0c\x12\xa2\xf2\xfc\x1d\xe7Q\x9c\x11){\x04dY\xd4\x0f\xd9=\xd6\x1e\xf4\xf3\xe0\x91\xdc^t\xdf\xf4\x88\xeef\xa76\x9c\x05\x84g\xb9z\xc7\xf9y\x14E~o\xb0\x17\xdcyp\x8eQ>#\xd6\xb1R\xd5D\xde[\xa1~\xfb\xf6\xc3\x9b\xdb\xf77w?\xdd>\x0b\xa5\xc0\x0e\x8a\x1a^\xd8.\x1d\x16\xe7\x9fz\xc4\xf9\x1d\x0f$\x95\xb4(\xaf\xae\xe1\x0f\xf9*z\xc7\xf9?\xa2(\xfa\xea\x9fL\xd8\xeeB\x87\xa1\xfa\x89\xdc\x06Q?\x10!7$\xd3B\x0eo$$\xc26\x17\x01\x16h\xdab\xe0#\xdb\x1eX0\x0c\x9a\x03bf\xfd\xcb50\x9a\x05\x15<\xcc\x97G\x93\xf5\xe5\xd6\xc8\xb9\xb2\xc5\xd5E\x03V\xbbC\xd8Uy\x8f'\x9ae\xb0rG\xbde\x92L\x87%\xee\xa5\xce\x1c!\xd5\xa5\xbe\xbfG\xe6\x07\x1d\xae\x9e\x01\xa9y;\xed \xb5&\xf8|\x83\xd5\x10\xf7b{\xd7\xc2\xb2]u\xaf\xec$\x0b\xf6a2\x90T\x99\xb0\xcd\xbd\x90\xc9c\x9c]\x9e\xb9\x97*}b\xc5\xb2\xb9\xed\x02\x96\x1a}\x9ar\x1e\xad\x880\x9b\xfdr\xb9\x8b\xfe~j\xa5h\xee^Nz\xfe\xab\xa8a\xf5T\xd3\xd0\xee\xd09\xe5\xaf\x1f~\xfa\xd1\xfd\xcb\xf5\xf5\xf5\xb5_\x07\xf4s\x87\x9c\x8b\x8d#\xb96\x07e\x10d\xefu\x85\xc4*\xaf\xba.2\"\xdc\xf4\xbad\xcc\x17I<\x84-\x17\x80\xdb\x15&\xc9!\x80\xb9\xb0\xe1\xb8\x8b\x1c\xf1doj!\x85M[?\xfc\xa7\x16\xddC\x99L\xd8\x87m\xf5\x97\xe3> \xa5\xf9\xb9\n\\@H\xfcI\xdb\xa0\xc3\x858\xa5\x19\xfa\xfdFe\xb3nPH\xce\x82\xc7\xb6\xcc\xc4\xa5THuo\xde\xf05\xbc\xf4S\xde?\xa0\x95\xb2\x9a\xff\xeax\x0f\x06\x10\xe4\xea\xd4\xc8\xf2\xf4\nN]\xa7\xb6)\x86\xc8\xee\xf2\xf4\"D\xcf\xec\xefG\xb2\xd54\xff\xc3n\xe1\xcf\xc1\x07\xf4\xfeZ\xf3\x8f\xdd\xe4\xfb\xb4\xbcp5u\xcdj\x03\x95\xf0\x84Y\xf6\xfc\x13\xe3O\xf6s\xca\x86H \xe57\x8c#\x0fWS\xe5/l\x00\xdf:\x07\xd6x\xd6\xd8\xd1\n\xec\xb9\\\x11\xab\xd2\xee\xc5\x1e\xcca\xac\xf4|\xc3\xb3\xc4*y\xf9\xf5\xc5\x1ce\xca\xf6\xe7\x03l\x06\xd0M\xca\x1e\x19\xf7:\x86\x85h\xef\x9c\xcf\xb5]\xabD\xd8I\x0dU\x19\xd3_~\xfe\xe5Y\xe0 \xcd\xa1s\xcd\x05\xc3jgD\xa5I\xbe\x8c^\xbd|%O\x03*d\xff\xcc\x89 [T(j\x9f\x0e\x9e\xdb\xc2\x12\xf3\xbf5\x02\x94]\x99\x1a\xa5\xba?\xac\xbef]AJ\xb2\xc6\xd7\x1f\xe7\x85\xba\xa2\xec,d\xf8u\x96\xeaV\x0c\xcc\xb9\x8e\"\xeb\x86\xe0\xfeV\x12\xf3\x94f\x19i\x07*\xb3n\xcc\xef\xfb\xc2\xac\xc3\xcbi\x95)lM\xe5Y\xa0X\xcb\x12:\xa9v\xf4;\xad\xd8\xaa\x8b\xa3>\xbc\xa4\xa0\xf7c\x17\xe6<\xde\xdc\xaf2\x1e\x7f\n|\x0c\xf3\x7f\x07\x84\xe6\xb7\xc0\x7f\xfb\x93\x9bFO\xb1\x8a\x0e1\nF\x1fQH\x92Y\x9e C\xb6V\x1bm\xa9X\xb1]\xd9\xcc\x8e\xe5\xf3\x02\xde>\xa2\xf7cE.\xb8~\x15&\xcc*_\x7f\xa5\xd3l\xad\xcd:~\xc1\xb8PUrLm\xa8\xf4\xd9\xa3\xbap \xd5\x8a\x8e,v\xad\xeb-\xa5\x83\x01\xc5\x0f\xc1\xd2\x87\xe0\xab\xb5\xa3\xefk&,\x95oK\xe5\xdb\x1c\xa5_K\xe5\x9bZ*\xdf~\xc3}\xfcN*\xdf\x86|\x1a\x80}\xd1\xf8>&1\xdf\x9cW\xa8\xd5I\xdfp\x13\xccP\xe9\xbf\xe8\xab\xc5\x96'&\xe5\xe0s\x02\x1b\xc1\x8b\xf5\x06\xd6\xfc1\xba\xa9\xe8\xbd1\x1f\xe3n\x04\xcf\xb9$\x99\xa5cR\x0b$\xde@^\x88\x9cK\xbc\xf0y6s\x1f(?\x13\x96 \n\xfcB\xa51\x8a\xa5\x082*U\xad\xa6\x81\xe4y\xe6\xe7P/.\xd1!\xb0\x86\xb0\xcap\xad.o\x89\xa6\x1e\xc0F6\xfb\n,g\xd8\xe6 \xe8.\xf6\xb2\xcb\x1cS\xebU2v{\xf3\xa6Eo)\xf5ZJ\xbd\xfa\xac\xd90{\xb0\x94z-\xa5^\xbe\x99K\xa9\x97\x19K\xa9Ww,\xa5^K\xa9\x97o,\xa5^K\xa9\x97\x19K\xa9\xd7R\xea\xb5\x94z-\xa5^v,\xa5^K\xa9\xd7R\xea\xb5\x94z\xf9\xc6R\xea\xb5\x94z-\xa5^K\xa9Wm\xccQv\xb3\x94z\x99\xb1\x94z\xfd\x7f)\xf5r\xd7*\xd5R{\xfaG[\xb7\x14\xad\x88\xc4\xa8\xacZ\x8a\xdep\xca\xec\x83\x9d\x8f\x13\xdd\xcf\x11\xadv\x14\x8e\xcbv\xbb\xcdDgJ\xe3\x02\xfb\xbf\xd5\x05\xf6\xc8V\x11\x87\x86\x10\xf6\xf1Q\xbd\x1fZ\x1d\x1e,\xa5!\xcd\x1c*1\x9a\xef~{A\xdao\xa8\x83E\xd9,rq\xa6-\x8e.`i\x96\xab\x84h\x1e_k\x12\xa8'\xe9\xa9\x1e \xf1\xd1\xc8`\x1c[\x07\xe2\xaa\xf5\xa8\x91sI(T\xe31\x98\xcf\xa3\xaa5\xdc\x15\x195j\xde\xda\x0cW%\x86\x93G\x7fu\xc2\xc4\x9a\x8an\x05\xc5\xb8\xf5\x8f\xaf\x858\xba\xf2!t&\xab\x8f\xeb\x83\xcf\xe6\xaav\x94\x9d\x8f\xb8\x1f\x03g\xed\x9a7#y\xf4\xf1\x06gEZ\x1f\xfdN\x92p\xe2\xd9oQ\xeb\x1c\xbb\x01\xb5dG\xb3<\xc928\x19\xf6\n\xb8\xaf\n\xech\xde\xa7X\x0b\xa7\x18\xc2\xd5\\\xbe\xfa-/\xdf\xe1\xda\xa6\x89\x16\x04\xbcuX\xd3\xf89\xde\xa2\xc0\x18\xabbV\x0c\xf7\x0eS\x8e:\x90N\xfd\x87\xd3\x80\xf8\xeb=\x9c]\xbf\xbc\x02sw\xf6\xf2Lw\x87_vL\x0c\xc2\xec\x98/\x14\xb3c|@vS+@\x1f`\xf4\xdd\xc5\xe5\xcaYm\xe4.\"wY\x80Q\xc5\xe2\xf5\xb2\xf0\x1a\xadR=\x8f)\x10\x0f\x16\x85[z\xbf\xb2.\xbb\x8a\xb9\xbd\xaa<\xd2)\xba\x0b\xb5\xfbWq|?\x9b\xd79:\xdc\xe3 \x079\x92\xf99\xddd\xaf\xa3\xecw\x95#w1\xa3\xc3\x1c\xe62CE\xcf\x81\x1d\xf4\x15\x05\xcf\xe0:\xfdE\xcc\xd3\xf9\x1a\xe7BG:\xd1\xd0\x87\xebQ\xc5\xc7U\x99q\x8d\xce\xb4\x82c5\xb6\xc8\xb8YN\xbe \n\x1a\xec\xe2\xdb\x90k\xa7\xda\xb9\xd5\xcd\x0f\xadv\xdf\x80!\x08\xa5\xf6Y\xd99o\xc30\xeeF\x0c}\xb7b\xf0A\xa4}\xa7\xdey\xe6\x97\x90g y\x96\x90g y\x8e\xe1\xf37\ny\xc2\xee~\xae\xdb9L\xbe\xa1\x03\xccvK\x87\xf9n\xea-B\x931\xbd\xb5\x00\xa1]:\xf2\x9a\xed\x06\x87\x02\xaa\x03\x15u\xea\xa9\xff\xdd\x8f\x05\x80\xb6\xec\x82\x1b\xf29\x06\xe4\xd9\x05s\x8e\x82o\x06`\x9aj\x1c0s$\x14\xb3\x0e\xb9\xacQkc\x14\x8e\x86[\x8e\x02X\xb6\x80\x94M\xa14 \x95c@\x94-\xb0d\x93z\x9d\xf8X\xa0\xa4\x1f\x109\x06\x02\xe9\x86:N\x007\x0e\x823\x0e\x83-\x8e\x04*\x8e\x85&\xba \x88\xb3\x80\x0e\xe7\x83\x19\xce\x02,\x0cC \xc7\x81\x07\xcd[v\x81\x04\x8f\x87\x05\x06\xe0\x7f\xaa\x0f\xf07\x16\xe2\xe7\x84\xf2\x8d\x00\xef\xb5\xe0zN7\xe4\x84\xe4\xf9}\xd3H\xd8\xdd\x01^\xd7\x96\xdf\x89\x7f\xbdq`:\x07p\xae\xa4\xb7\x87\xcfM\x04\xccM\x80\xc8\xb9\xe0p\x13\x00p\x0e\xb0\xdbXx\x9b\x17\x93\xe5\x80\xb0\x05AkML\xc90`Z\xf3\x99\xaf\xed\xbd\x1c\x0d7\xeb\xdbL\x08R\xe6\xe6?\x08\x1b\x1b\x08\x14;\xd4\x9cO\x00\x83y\xe1_n\xc0\x97\x0f\xe2\xd5\xd9\xe5\x10\x18W\x08\xb8U\x87j\x8d\x04g\xf5\xc0\xb1\x8e\x03`\xb5\xa0M!\x90\xd5\x0c\xb0\xaa\xd6j\xfb7=\n,\xe5\x02FM\x81B\xb5`Oc\x81N\x1dP\xd3\x04\x18S#Xt\x82\x94\xea\xc8\x89:\x10i:\xf4h<\xd8\xa8\x06,\x1a\x05%r\xc2\x86\xfa\x81BAhPyc\x0b\x81\x81\xca)^\xf8O\x03\x0b\xd3\xa4>\x14`\xe1\x07\xf5\x0c\x80\xf1\xf4\x00w\xf6\xecM\x00\xe74\xd4i\x02\xf4\xa6\x0d\xb3\x19\x07\xaci\x83h\xe6\x81\xcd\x8c{sAhL\x08\x0c\xa3M\xe8Z\xe4q\xb4\xb6\xff\xbf\xec\x91(\x98\xa2[\x8c\xde\x1e\xba\x8d\x0d\xc8\x96\xb4z\x939b\xd4f/2\xe5\xfc&\xe2\xea=\xd6\xe99\xe6\xa0\xdd\xe91\xa6~\x85\xca\x0c\xe5\xe9\x1d\xe6\x8c\xc7\xed\xe8\xfb\x0e8S\x8a\xc8\x8ePo\xb0y\xd2Ev\x8cO\x1auH\x05z}\x8dL%\xd91:\xa1\xd4\xa1\xd4\xd7\xd3\xeb\xe8\xe4\x92\x1d\x13SL\x0eiy{wML7u\xe8y{uML=u\xe8\xf9zs\xcd\x97\x90\xb2cBZ\xaa\"0[r\xca\x8e\x91)\xaa=7\xb3%\xaa\xec\x98%]e\xc7|I+;fI]\xd91\xa4\x17\xd6\xf84V\xd7\x8az{_MInu\x88\xb9{]9b \x97\x95\x9a\x96\xf8\xea\x90s\xf5\xb4\x1a\x91\x0e\xb3\xc3\xd9\xc3*\xe0\x8a\x03=\xab\xfa\xbc\xf4\xc8dY\xd7py{S\x858\x98#}\xd6 \xe8\xeaA51\x95f\xc7\xf4\x84Z\x83\\\xd7\xe1NL\xb15h)Go\xa9\xb1I7;z\xda!y{H\x0d\xe8\x1d\xe5j\xf02,%\xe7\x7f\xfe\xab{\xefG'\xe9\xec\x18\xb6\xf9\xfe\x1eP\xa1\x9d\x0e\xe8\xf940\x85gG\xbby\xc4\x84t\x9e\x1d==\x9dB\xbd\x9c\xc2=\x9c,-\"\x04\xd9u~\xa3\n\xb7\x8e)\x01\x06\xec\xf0\xb3a\x87e\xc6\xfd[/q\x18\xb0\x80\x1e\x8cl\xd1\xffk\xb5\x8cT\x82\xb2u\xe81\xab\xe0\x9a\x1a$\x98R\x86\x12\xd4\x06\xed?\xf0\xd4\xfc\xdd\xee\xc7KD\x105#'\x7f~\x1ex\xc6.\x062\xc7\x98\xa6\xb4d5\xa1\x9a\xf6\xaaP\x94\xad\x81ly\xc1\x14\xacv`t\x18x\x1a$\xa7\xb8\"\xd5\x01\x00\xc9\x0b\x11\xa3\xf7y\xfb\xd4\xbd}\xea\x9e$\x89@\x19xA3o\xdc\xb9z\xe3\x95\xad0\xde|\xf5\xea9\xb2\x98'\x98\x04\x89U\xd3\xd5\x86T\xdb\x1e\xf8\xb2c\x9eeh\xcc\xd3\xaf.\x81\xee\xd2S\xb7\xdf\xd82\xe4\x9cg\xa0\xf8A\x9f\xfc\xaa \x15\x11\xea^\xd1Y\x8e`\xca\xc5\x96\xa8+H\x88\xc2\xe7\x9af\xbf\xa4\x0e\xeb\xb7\xce\x82\xf9\x01\xcc\x0f\xc3\xde'\xb2\xe47\xdcG\xb5zk\x17\xc8\x92\xe1{h\xf8\x9b\xd2;WzA\xaawk\xcdm\xe4$al\xc0}\xa9]\x98\xdc\xc7\x9c2\xafV\x87\xfc\x89\x1d^\xafb\xc7\x00\xf3?\xcc\x01\xe8\x9d3\xbe\x0d=0\xf8\xd5Y\xab9\x03\xa9\xc6\xcb\x08\x9e\xe77\x9c\xb2\xda{R\xfc\x132x\xa2j\x03\xc4n\x8c2\x13\x84\x98\xd8\x8a\xb0^\xe6\xa3\x93\x93\xc03\xdf\xffp\xf7\xf6\n\xee6X9\x88\x94b\x96\x00\x95@\x18\xbcg\n\x9e64\xde\x00\xdd\xe6\x19n\x91)\xa3\x87\x01zq!\x15\xdf\xc2\x16\xd5\x86'\xa1\x85%]3\xa2\n\x81:\xe4\xfa\xb9\xa0\x02\x13\xed\x9c\xd6|\xcds\xc1\x15o\xaadX|\x7f/P\xec\xca\x80\xec\xb6\x8c\xa5\xf4\x16\xf4\x11\xa9b+\xf3\x9aL`\xa9\xff\xd5\xcc\xb8l\xc6p\xd5\xd0\xe1\xaa\xe5\xff\xc0C\x82))2\xe5\x0f\xe7\x18\x14\x0c?\xe7\xe6\xa0\x00\n\xc1\xc5~\xe5\xda\x9c\x99\x82:C\xdf\x17\xd29\x15Q\x9b~\xdf\x04\x1dv\xafQt~\xad\xcc\x16e\xea\xabW\xad_\xb7(%Y{I:yHP\x11\x9a\xfdNBQ=\xfd\xbe\x10Y\xd8\x9c\x05\x0f\xf5\xd0#\xfd\x1a>\xde~{)\xb0\x0c'L\x00i\xe2\x8b\x82\xd1\x9f\x0b\xccv@\x13d\xea`\xe5\x8d\xa6\x06\xe23\xe3\xcfPP\x92\xd1\x7f`\xe0\x90\x99s\x14s\x1d\xc6\xa5)\x8a\xea\xa5Ep\xb7\xa1\xb2\xdc\x1bl\x0b\xa9 \xe6L\x11\xca\x80\xf8-o\x86D*\xffZ\x9c!\x9c^\x9eB\xbc!\x82\xc4\nEd\x8cJF\xa4\x02\x89km:*\xa7\xf5\xf1\xf6\xdb3 \xfa\xc2\xe6\xa5f\x98\x12\x98\x0b\x94\xc8\x02\xabjri\x91e;\xf8\xb9 \x99\x96`\xd2\x08\xd0\x8d$\xcf\x89\x04\xca\xfcD\x1e4+\x97k\xce\xd7\x19FFf\xab\"\x8d\xbe.\xec]\xef\xe1\x99\xdd\x89!+7\xbc\xc8\x12X\xa1&\xe8\xa3G &\x8c3\x1a\x93\xcc\x9c!\xff\xca\xe7\x18\xad\xa3\x0b-\xdaD\xbf\x8a\xd3\xe8T[-\xc6\x15\x908\xc6\\a\xf2,d\xbd\xdf3\xc8\xb5\xb0i\x8c\x17\xa0\x90l%\x14\xb2 Z\x1c\xb9\xc0\x98os\x9aiN\x15\xb7\xc1\x02eD\xf8\x9c3\x98\x0b\xaf\x96W\x19\xfc\xaa\x0d\xee\xfcK[S\x07T\xe9\xb8\xb0\xd0\xd6\x96\x995\xb4\"\xe1g\xf3\xaa_\xb3]\x04\x7f\xe5O\xf8\x88\xe2B\x0b\xc2K\xec\xe3\xed\xb7\xb2\xf43\x9a\x94v0\xdeg\x8d\x05Ex\xd8(\x95?\\\xd8?\xe5\xc3\x05p\x01\x8c\x97\xbf^\x18m\x8c \x03nN\xa7\x96\x88\x9f *(r\xedhwyh]\x14\x8f(\xach\xb6$\x97V\xb5\x0c\xe7\x8aW'\xcb\xbamjr\x14@\xda~\xe50R\x9ee\xfcI^\x05\xde\xed\xbf\xc3\xfb\xf4\xb0#\xad\x16\xb9\xe0\x8f4\xc1d\xbfi\xe3\xa4\xa5,\xb6\x98D!B\xaf\x19\xfc\xf5\xee\xee\x06\xbey{\x07\x9cUG\xd0\x9e\xb1\x9d\xf1\xf6\xc4;\xfb\xc7\xf6\xb1\xb8\xdb\xe5\xf8\xd3\x8f?y'\x00<\x92\xac0\xfa`\xf5\xadt#\xe6\x0d\xe5\x82'E\x8c:\xb40.\xcc\x1dv\x82\xe5:\xcf3\x1a\x93R\x96\x02\xb5~\xf2'L\xb4\xb8c\x12k\xdb\xc2\xf9\xa7\"\xd7n\xb6\xc8\x94\x84\x15\x91\x81\xdb\x8d\xddx\x80\xed\x8f\xb7\xdf\x1a\x1e7\xe4\xd1\xa8\xe0\xb6v\x86\x12{\x88H\xb5%\xfd\xf7GNu\xf8\xe5W,(\x194\xe6C`\xca\x05^T\x044]\xa2\xe8\x8afT\xed\x80!&F\x8dV\x08\xc6\xe4\x89\xc7\xe0=\x8d3mf\xd9\x1a\xcd$sf#8\xff(\xb1J\x8ai)i\xf5\xd46\xcb\xea'ad\x1d\xda\xfdJ \xf9\xa4mPI8z\xe6\xd7\xa8\xef\xb9\xc2+P\xda\x87\xa4\x05\x8b\xed \xd3\xfb(mW\\\x08\x81Le; \x8f\x84fd\x95\x05\xcd\xa5\xd6G\x9e\xa64\xa6$\xeb\xf1e\xab\"\x05\x81\xda\x13\xe1\x85 \x7f\xa9\xaa\x16-$&6\xba\xab\xce\xa5\x97\xd4\n\xd7\x941\xbdY\x1dU\x07\x9c\xcb.\xc7\xc8\xea?\xc9\xa9\x8cb\xbe\x0dY\xe3\x0f\xe6\xa4J\xe0jc\x0d\x05k[)8/\xa3O\xdc\xe6jW\x1e\xedg~'H\xd7\x1b\x05\xab\x80Q2\x9b6W\x83}|n\xaf\x06\xe5\xad1\x06\x89[\xc2\x14\x8d\xa5\xfb\xa8\x99\xb3:!\x04\xaaB\xc4\xd5\xce\x9b\x13\x18\x1a%}\xa7\xcd\xd1\n\x81h\xa6hR\x0bp:qL\xe9\xdc\xc9\x8a?\x062\x11\xe5\xc5\xd9\x1e\x05\xd7\xf6\x87p\xf6\xf0\x9a\xed\x1e\xaa\xf0\xc8\xdc\x89\x88XQ%\xf4!\xf6s\xe8$U\xf9\x08\x92\xf1R\xf5\x80\xb8_\xad\xb6\xce\xc6\xd1X\x0eW\xcd\xb0\xb0\x15\xfe\xed\xa3:\x8fj\xdeT\x07'\xa3+\xc3v\xe9G$\xc8\"\xcf\xb90\x1e<'\xf1\xa7\xcb\x82\xe9?\xb4\xdf\xb6z\xe1>A\xa5\xa3\xf7\x076<\x85BY\xc3V\x99\x07\xa9\x0d+I\x12jm\x05\xac\x91\xa1 \xca0\xaf\xefYU\xc2\xc9IO\xf3c_\xa1{\xbd\xb7\x9f\x89V~xy\x057\x9a\x7fm\x17\xca\xad\x90\xbd\xd0)\x837\x7f\xfcc\xc0M\xbe\xe3\x1cR\xce\xe1\x1a\xa2(\xfaO\xefc\x9a\x19\xc2v\xfe\x07\x08\xdbE\x9a\x8dw\x82o\xcfS\xce\x9f\xf9\x1f\x8d\"\xbf\xff\xa3)\x9ckR\x1f\xcdF\xee\xf8\xf9\x1f4\xadg\xf0\xcf\x80\x0d\x0f\xd1\xfb\x12\x96\xdd\xab\x1e\xd9\xfd\x8d<\x92\xd9\x84\x07\xd7&6\xd4\xab\xcc !*\xcf\xdfq\x1e\xc5\x19\x91\xb2G@\x96E=\xc9\xee\xb16\xd1\xcf\x83Gr{\xd1}\xd5#\xba\x9b\x9d\xdap\x16\x10\x9e\xe5\xea\x1d\xe7\xe7Q\x14\xf9\xbd\xc1^p\xe7\xc1g\x8c\xf2\x19\xb1\x8e\x95\xaa&\xf2\xde\n\xf5\xeb\xb7\x1f\xde\xdc\xbe\xbf\xb9\xfb\xe1\xf6Y(\x05vP\xd4\xf0\xc2v\xe9\xb08\xff\xd4#\xceox \xa9\xa4Eyu\x0d\x7f\xc8W\xd1;\xce\xff\x19E\xd1\x17\xff\xc3\x84\xed.t\x18\xaag\xe46\x88\xfa\x8e\x08\xb9!\x99\x16rx#!\x11\xb6\xb9\x08\xb0@\xd3\x16\x03\x1f\xd9\xf6\xc0\x82a\xd0\x1c\x10\xf3\xd4\xbf]\x03\xa3YP\xc1\xc3|y4Y_n\x8d\x9c+[\\]4`\xb5;\x84]\x95\xf7x\xa2Y\x06+w\xd4[&\xc9tX\xe2^\xea\xcc\x11R]\xea\xfb{d~\xd0\xe1\xea\x19\x90\x9a\xb7\xd3\x9ePk\x82\xcf7X\x0dq/\xb6w-,\xdbU\xf7\xcaN\xb2`\x1f&\x03I\x95 \xdb\xdc\x0b\x99<\xc6\xd9\xe5\x99{\xa9\xd2'V,\x9b\xdb.`\xa9\xd1\xa7)\xe7\xd1\x8a\x08\xb3\xd9\xcf\x97\xbb\xe8\x1f\xa7V\x8a\xe6\xee\xe5\xa4\xe7\xbf\x8a\x1aVO5\x0d\xed\x0e\x9d\x8f\xfc\xed\xc3\x0f\xdf\xbb\x7f\xb9\xbe\xbe\xbe\xf6\xeb\x80\x9ew\xc8\xb9\xd88\x92ksP\x06A\xf6^WH\xac\xf2\xaa\xeb\"#\xc2M\xafK\xc6|\x8f\xc4C\xd8r\x01\xb8]a\x92\x1c\x02\x98\x0b\x1b\x8e\xbb\xc8\x11O\xf6\xa6\x16R\xd8\xb4\xf5\xc3\x7fk\xd1=\x94\xc9\x84}\xd8V\x7f9\xee\x03R\x9a\x9f\xab\xc0\x05\x84\xc4\x9f\xb4\x0d:\\\x88S\x9a\xa1\xdfoT6\xeb\x06\x85\xe4,xl\xcbL\\J\x85T\xf7\xe6\x0d_\xc3K?\xe5\xfd\x04\xad\x94\xd5\xf3\xaf\x8e\xf7`\x00A\xaeN\x8d,O\xaf\xe0\xd4uj\x9bb\x88\xec.O/B\xf4\xcc\xfe\xbe'[M\xf3\xbf\xec\x16\xfe\x1c\x9c\xa0\xf7\xd7z\xfe\xd8M\xbeO\xcb\x0bWS\xd7\xac6P O\x98e\xcf?1\xfed?\xa7l\x88\x04R~\xc38\xf2p5U\xfe\xc2\x06\xf0\xads`\x8dg\x8d\x1d\xad\xc0\x9e\xcb\x15\xb1*\xed^\xec\xc1\x1c\xc6J\xcf7\xc0f\x00\xdd\xa4\xec\x91q\xafcX\x88\xf6\xce\xf9\\\xdb\xb5J\x84\x9d\xd4P\x951\xfd\xe9\xc7\x9f\x9e\x05\x0e\xd2\x1c:\xd7\\0\xacvFT\x9a\xe4\xcb\xe8\xd5\xcbW\xf24\xa0B\xf6\xcf\x9c\x08\xb2E\x85\xa2\xf6\xe9\xe0\xb9-+1\xff[#@\xd9\x95\xa9P\xaa\xfb\xc3\xeak\xd6\x15\xa4$k|\xfdq^\xa8+\xca\xce2\x86_f\xa9n\xbd\xc0\x9c\xeb(\xb2n\x08\xee\xef%1Oa\x96\x91v\xa0.\xeb\xc6\xfc\xbe/\xcb:\xbc\x9cV\x91\xc2\xd6\xd4\x9d\x05J\xb5,\xa1\x93jG\xbf\xd3z\xad\xba8\xea\xc3K\nz?va\xce\xe3\xcd\xfd*\xe3\xf1\xa7\xc0\xc70\xffw@h~\x0b\xfc\x8f?\xb9i\xf4\x94\xaa\xe8\x10\xa3`\xf4\x11\x85$\x99\xe5 2dk\xb5\xd1\x96\x8a\x15\xdb\x95\xcd\xecX>}\xe6\xe3uMy\xcd\xd3e\xd5\x1e\x95\x80\x9f1.T\x95\x103\xe9\xc9\xfa\xce=\x04\xf7\xfa\xe4\xf8\xdd[;\x07\x03\xea\x1d\x82\xd5\x0e\xc1\xb7iG\xdf\x07LXJ\xdd\x96R\xb79j\xbd\x96R7\xb5\x94\xba\xfd\x86\xfb\xf8}\x94\xba\xf5h_U\x1d\xbew\x17\xe6\xf3\xf2\n\xb5\x1a\xe9\xcb\xec\x96'&\xa1`?K%\x98\xa1\xf2\xea\x9f\xda\x08^\xac7\xe0\xf3q\xb55\xcc\xc78X\xf3G\x14\x8c\xb0\x18\x8dW\xe0\x92d\x9d\xa9\x0d \x941S\xfdd\xd4\xe2\xa6\xaa\x06\xca\x1989\xa8\xb9\xcb\xad\xec\x1a\xc7T[\x95\\\xdd\xde\xbci\xd1[\x8a\xad\x96b\xab>\xe32\xe4c\x1d,\xc5VK\xb1\x95\xf7\xc9\xa5\xd8\xca\x8c\xa5\xd8\xaa;\x96b\xab\xa5\xd8\xca7\x96b\xab\xa5\xd8\xca\x8c\xa5\xd8j)\xb6Z\x8a\xad\x96b+;\x96b\xab\xa5\xd8j)\xb6Z\x8a\xad|c)\xb6Z\x8a\xad\x96b\xab\xa5\xd8\xaa6\xe6(|Y\x8a\xad\xccX\x8a\xad\xfeU\x8a\xad\xdc\xd5B\xb5\xd4\x9e\xfe\xd1V\x0eE+\"1*\xeb\x86\xa27\x9c2;\xb1\xf3q\xa2\xfb9\xa2\xd5\x10\xc2q\xd9n7z\xe8<\xd2\xb8\xc0\xfe_u\x81=\xb2Y\xc3\xa1%\x83\x9d>\xaa\xfbB\xab\xc7\x82\xa54\xa4\x9dB%F\xf3\xddo/\xc8\xbf\xd4\x9a2\x0d\x10e\xb3\xe6\xc4\x99\xb68\xba\x9e\xa4Y=\x12\xa2y|\xe9G\xa0\xbc\xa3\xa7\x98#\xc4G#\x83qlY\x86\xab\xf4\xa2F\xce%\xa1P\xc9\xc5`>\x8f*\x9ep\x17H\xd4\xa8yK%\\\x85\x11N\x1e\xfd\xc5\x02\x13K\x1c\xba\x05\x0d\xe3\xd6?\xbe4\xe1\xc8B\x84\xd0\x89\xac>\xad\x0f>\x99\xab\xdaAvNqO\x03g!\x997\x1fy\xf4\xe1\x06gyX\x1f\xfdN\x8ap\xe2\xc9oQ\xeb\x1c\xba\x01\x85]G\xb3<\xc9.8\x19\xf6\n\xb8\xaf$\xebh\xde\xa7\xd8\n\xa7\x18\xc2\xa5U\xbeb*/\xdf\xe1B\xa3\x89\xf6\x03\xbcEQ\xd3\xf89\xde\x9e\xc0\xf16\xc5\xac\x17\xee\xdc\xa5\x1c5 \x9d\xda\x0f\xa7\xf9\xf0\xd7z8{ny\xc5\xe5\xee\xab\xe5y\xdc\x1dz\xd911\x00\xb3c\xbe0\xcc\x8e\xf1\xc1\xd8M\xad\xfc{\x80\xc9w\x97v+g\xa5\x91\xbb\x84\xbb\xd4\xcc\x86T\x8f,\xd5>L\x1c_\x9d\xdd\xa9\xc3.\xa7\xfe\xb2:\xeb\xaa\x9f\xf6\xaa\xecH\xd7\xe7\xae\x8d\xee_\xc5\xf1\x8dl^\x17\xe8p\x82\x83\xdc\xe0H\xe6\xe7t\x86\xbd\xee\xb0\xdf!\x8e\xdc\xc5\x8cnq\x98c\x0c\xd5\x19\x07v\xd0W\x87;\x83\x83\xf4\xd7\x0dO\xe7k\x9c\xa3\x1c\xe5*\xdd&pT\xbd\xef\xa1\xb2\xf7@hp1\xef\x1c\x05\xbcn\x9f\xe2\xea\x8e8\xd8\xc3\xfc*v\xb8}s \x12 \x11\x82\x00(&\xa0\x950\xde\xb8C\x00\xfc2lEO1\xc4Xc\xef$Vj\x8a\x07\xdc2\xc8\xe8\xc3\xd4\x0d\x8du\x00Nb\xc3A+\xfd\x8e\x00\xa6\xeelV\xa7\x00\x83\x1d\x03\xf4\x82Pzv\xd5g\x8ca.G\x01= \x93\xf9\xf8\x1c\xeb8`\xac\xf30k\x0f\xe9\x93\xec\xb2\x9bvx\xaa\xee\x03\xe6\xaf\xaf\xe2>\xd0\xff\xb8G\xd4\xa1~\xc7\xc1\xa9\xfd\xf5]\xa3oj\x0eZS.l\x0er\xfen\xc5Cnr\xbe\xcdO\xecJ\\\x03\xca\x1c\x002\x01\x0f\xdf\x04\xe4\x0cv\xf0m\xc0\xb1S\xed\xdc\xea\xe6\x07\x16\xbbo\xa0\x10\x04\x12\xfbl\xec\x91\xb7\xd1\xd6\xec\xf1W\xd2\x16!\x17P\xb8\x13\x1cA\xe0\xa0;\x8f\xf9\x12\xe3,1\xce\x12\xe3,1\xce1|\xfe61\x8e\xe3\x92\x0cs^\x94\xe1\x98\xcb2\xcctanQ\x99\x0cl\xady\xeav\xfd\xc4k\xb6\x1b\xec\x93U\x07/\xe9\xd4\x1e\x7f\xcc5\x16\x05\xd9:\xadn\xdc\xe3\x18\xa4c\x17\xd18\n\xc3\x18\xc0*\xaaq\xe8\xc4\x91x\xc4:\xee\xb0F\xad]\xa8\x7f4\xe6p\x14\xca\xb0\x85&l\n\xa5\x81+\x1c\x83$l!\x06\x9b\xd4\xeb\xc4\xc7\xa2\x05\xfd\xa8\xc018@7\xdeo\x02\xc2o\x10\xa6o\x18vo$Zo,>\xcf\x85\xc3\x9b\x05y7\x1f\xd6n\x16t]\x18O7\x0eAg\xde\xb2\x0b)w<6.\x80\x81S}\xa8\xb7\xb187'\x9em\x04\x82\xad\x85Ys\xba!'.\xcd\xef\x9bFb\xcf\x0e\x18\xb3\xb6\xfcN\xfc\xeb\x8dC\x949\xd0c%\xbd=\x86l\"jl\x02N\xcc\x85 \x9b\x80\x02s \xbe\xc6b\xbc\xbc\xc0$\x07\x8e+\x88\xdcj\x02+\x86\xa1\xb3\x9as\xbe\xb4\xf7r4\xe6\xaao3!\\\x95\x9b\xff vj Z\xeaPx=\x01\x11\xe5\xc5@\xb9QO>\x9cSg\x97C\xb0L!\xf4R\x1d\xaf4\x12\xa1\xd4\x83I:\x0e\x85\xd4\xc2\xf7\x84\x90F3`\x8bZ\xab\xed\xdf\xf4(\xc4\x90\x0b\x1d4\x05\x0f\xd4\xc2\xfe\x8cE\xfbt\x90=\x13\xb0<\x8d`\xd1\x89\xd4\xa9\xc3\x07\xeah\x9c\xe9\xf8\x9b\xf1\x88\x9b\x1a\xbaf\x14\x9e\xc6\x89\x9d\xe9G\xcb\x04\xf11\xe5\x8d-\x84\x88)\x1f\xf1b`\x1a\x80\x90&\xf5\xa1(\x03?\xb2e\x00\x96\xa5\x07\xbd\xb2go\x02B\xa5\xa1N\x13\xf0'm\xac\xc98tI\x1bI2\x0fvd\xdc\x9b\x0b\xe2CB\x88\x10mB\xd7\"\x8f\xa3\xb5\xfd?\x07\x8fD\xc1\x14\xddb\xf4\xf6\xd0rk@\xb6\xa4\xd5\xa0\xcb\x11\xa36\x1br)\xe7\xc7 W\x03\xaeN\xe3-\x07\xedN\xa3-\xf5\x0b\x14H(O\x03-g- - The universal epoch length in number of blocks, Every - process for budget collecting is executed with this + The universal epoch length in number of blocks - epoch_blocks frequency + A collection of budgets is executed with this epoch_blocks + parameter budgets: type: array items: @@ -326,14 +326,13 @@ paths: type: string format: date-time title: end_time specifies the end time of the budget - description: Budget defines the budget struct. - description: >- - Budgets parameter can be added, deleted, and modified - through gov.ParameterChangeProposal, and for each purpose, - - the changes in the existing budget list should be applied - and set. - description: Params defines the set of params for the budget module. + description: Budget defines a budget object. + title: >- + Budgets parameter can be added, modified, and deleted + through + + parameter change governance proposal + description: Params defines the parameters for the budget module. description: >- QueryParamsResponse is the response type for the Query/Params RPC method. @@ -568,7 +567,7 @@ definitions: type: string format: date-time title: end_time specifies the end time of the budget - description: Budget defines the budget struct. + description: Budget defines a budget object. cosmos.budget.v1beta1.BudgetResponse: type: object properties: @@ -601,7 +600,7 @@ definitions: type: string format: date-time title: end_time specifies the end time of the budget - description: Budget defines the budget struct. + description: Budget defines a budget object. total_collected_coins: type: array items: @@ -622,11 +621,9 @@ definitions: epoch_blocks: type: integer format: int64 - title: >- - The universal epoch length in number of blocks, Every process for - budget collecting is executed with this - - epoch_blocks frequency + title: |- + The universal epoch length in number of blocks + A collection of budgets is executed with this epoch_blocks parameter budgets: type: array items: @@ -658,13 +655,11 @@ definitions: type: string format: date-time title: end_time specifies the end time of the budget - description: Budget defines the budget struct. - description: >- - Budgets parameter can be added, deleted, and modified through - gov.ParameterChangeProposal, and for each purpose, - - the changes in the existing budget list should be applied and set. - description: Params defines the set of params for the budget module. + description: Budget defines a budget object. + title: |- + Budgets parameter can be added, modified, and deleted through + parameter change governance proposal + description: Params defines the parameters for the budget module. cosmos.budget.v1beta1.QueryBudgetsResponse: type: object properties: @@ -702,7 +697,7 @@ definitions: type: string format: date-time title: end_time specifies the end time of the budget - description: Budget defines the budget struct. + description: Budget defines a budget object. total_collected_coins: type: array items: @@ -733,10 +728,10 @@ definitions: type: integer format: int64 title: >- - The universal epoch length in number of blocks, Every process for - budget collecting is executed with this + The universal epoch length in number of blocks - epoch_blocks frequency + A collection of budgets is executed with this epoch_blocks + parameter budgets: type: array items: @@ -768,13 +763,11 @@ definitions: type: string format: date-time title: end_time specifies the end time of the budget - description: Budget defines the budget struct. - description: >- - Budgets parameter can be added, deleted, and modified through - gov.ParameterChangeProposal, and for each purpose, - - the changes in the existing budget list should be applied and set. - description: Params defines the set of params for the budget module. + description: Budget defines a budget object. + title: |- + Budgets parameter can be added, modified, and deleted through + parameter change governance proposal + description: Params defines the parameters for the budget module. description: QueryParamsResponse is the response type for the Query/Params RPC method. google.protobuf.Any: type: object diff --git a/proto/tendermint/budget/v1beta1/budget.proto b/proto/tendermint/budget/v1beta1/budget.proto index 7d7f871..169a9a9 100644 --- a/proto/tendermint/budget/v1beta1/budget.proto +++ b/proto/tendermint/budget/v1beta1/budget.proto @@ -10,19 +10,19 @@ import "cosmos/base/v1beta1/coin.proto"; option go_package = "github.com/tendermint/budget/x/budget/types"; -// Params defines the set of params for the budget module. +// Params defines the parameters for the budget module. message Params { option (gogoproto.goproto_stringer) = false; - // The universal epoch length in number of blocks, Every process for budget collecting is executed with this - // epoch_blocks frequency + // The universal epoch length in number of blocks + // A collection of budgets is executed with this epoch_blocks parameter uint32 epoch_blocks = 1 [(gogoproto.moretags) = "yaml:\"epoch_blocks\""]; - // Budgets parameter can be added, deleted, and modified through gov.ParameterChangeProposal, and for each purpose, - // the changes in the existing budget list should be applied and set. + // Budgets parameter can be added, modified, and deleted through + // parameter change governance proposal repeated Budget budgets = 2 [(gogoproto.moretags) = "yaml:\"budgets\"", (gogoproto.nullable) = false]; } -// Budget defines the budget struct. +// Budget defines a budget object. message Budget { option (gogoproto.goproto_getters) = false; option (gogoproto.goproto_stringer) = false; @@ -52,10 +52,11 @@ message Budget { [(gogoproto.stdtime) = true, (gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"end_time\""]; } -// The cumulative coins collected in the budget since the bucket was created. +// TotalCollectedCoins defines total collected coins with relevant metadata. message TotalCollectedCoins { option (gogoproto.goproto_getters) = false; + // total_collected_coins specifis the total collected coins in a budget ever since the budget is created repeated cosmos.base.v1beta1.Coin total_collected_coins = 1 [ (gogoproto.moretags) = "yaml:\"total_collected_coins\"", (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins", diff --git a/proto/tendermint/budget/v1beta1/genesis.proto b/proto/tendermint/budget/v1beta1/genesis.proto index 871e441..562d75a 100644 --- a/proto/tendermint/budget/v1beta1/genesis.proto +++ b/proto/tendermint/budget/v1beta1/genesis.proto @@ -25,12 +25,12 @@ message GenesisState { [(gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"budget_records\""]; } -// records the state of each budget after genesis export or import. +// BudgetRecord records the state of each budget after genesis import or export. message BudgetRecord { - // the name of the budget + // name defines the name of the budget string name = 1 [(gogoproto.moretags) = "yaml:\"name\""]; - // the cumulative coins collected in the budget since the bucket was created. + // total_collected_coins specifis the total collected coins in a budget ever since the budget is created repeated cosmos.base.v1beta1.Coin total_collected_coins = 2 [ (gogoproto.moretags) = "yaml:\"total_collected_coins\"", (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins", From 6840d8539fe923358603fe3d4a1b4e320ae14c3f Mon Sep 17 00:00:00 2001 From: kogisin Date: Fri, 8 Oct 2021 15:05:23 +0900 Subject: [PATCH 3/8] chore: update comments in types package and handle TODO comments --- x/budget/types/budget.go | 27 ++++++++++++--------------- x/budget/types/codec.go | 2 +- x/budget/types/errors.go | 6 +++--- x/budget/types/expected_keepers.go | 2 -- x/budget/types/genesis.go | 2 +- x/budget/types/keys.go | 3 +++ x/budget/types/params.go | 8 ++++++-- 7 files changed, 26 insertions(+), 24 deletions(-) diff --git a/x/budget/types/budget.go b/x/budget/types/budget.go index e6c364b..939f93e 100644 --- a/x/budget/types/budget.go +++ b/x/budget/types/budget.go @@ -16,6 +16,7 @@ var ( reBudgetName = regexp.MustCompile(fmt.Sprintf(`^%s$`, reBudgetNameString)) ) +// String returns a human-readable string representation of the budget. func (budget Budget) String() string { out, _ := budget.MarshalYAML() return out.(string) @@ -30,28 +31,20 @@ func (budget Budget) MarshalYAML() (interface{}, error) { return string(bz), err } +// Validate validates the budget. func (budget Budget) Validate() error { - //Name only allowed letters(`A-Z, a-z`), digits(`0-9`), and `-` without spaces and the maximum length is 50. - err := ValidateName(budget.Name) - if err != nil { + if err := ValidateName(budget.Name); err != nil { return err } - // Check that the CollectionAddress is a valid address. - _, err = ValidityAddr(budget.CollectionAddress) - if err != nil { - // TODO: return error with Wrapping + if _, err := ValidityAddr(budget.CollectionAddress); err != nil { return err } - // Check that the BudgetSourceAddress is a valid address. - _, err = ValidityAddr(budget.BudgetSourceAddress) - if err != nil { - // TODO: return error with Wrapping + if _, err := ValidityAddr(budget.BudgetSourceAddress); err != nil { return err } - // EndTime should not be earlier than StartTime. if budget.EndTime.Before(budget.StartTime) { return ErrInvalidStartEndTime } @@ -62,19 +55,23 @@ func (budget Budget) Validate() error { return nil } +// Expired validates the budget's end time expiration. func (budget Budget) Expired(blockTime time.Time) bool { return !budget.EndTime.After(blockTime) } +// ValidityAddr validates the bech32 address format. func ValidityAddr(bech32 string) (sdk.AccAddress, error) { acc, err := sdk.AccAddressFromBech32(bech32) if err != nil { - return nil, err + return nil, sdkerrors.Wrap(sdkerrors.ErrInvalidAddress, acc.String()) } return acc, nil } // ValidateName is the default validation function for Budget.Name. +// A budget name only allows alphabet letters(`A-Z, a-z`), digit numbers(`0-9`), and `-`. +// It doesn't allow spaces and the maximum length is 50 characters. func ValidateName(name string) error { if !reBudgetName.MatchString(name) { return sdkerrors.Wrap(ErrInvalidBudgetName, name) @@ -82,6 +79,7 @@ func ValidateName(name string) error { return nil } +// BudgetsBySource defines the total rate of budget lists. type BudgetsBySource struct { Budgets []Budget TotalRate sdk.Dec @@ -89,8 +87,7 @@ type BudgetsBySource struct { type BudgetsBySourceMap map[string]BudgetsBySource -// GetBudgetsBySourceMap returns a map by BudgetSourceAddress to handle the budgets for the same BudgetSourceAddress together based on the -// same balance when calculating rates for the same BudgetSourceAddress. +// GetBudgetsBySourceMap returns BudgetsBySourceMap that has a list of budgets with the same BudgetSourceAddress and its total rate. func GetBudgetsBySourceMap(budgets []Budget) BudgetsBySourceMap { budgetsMap := make(BudgetsBySourceMap) for _, budget := range budgets { diff --git a/x/budget/types/codec.go b/x/budget/types/codec.go index f75915e..df0bf8a 100644 --- a/x/budget/types/codec.go +++ b/x/budget/types/codec.go @@ -10,7 +10,7 @@ import ( func RegisterLegacyAminoCodec(cdc *codec.LegacyAmino) { } -// RegisterInterfaces registers the x/budget interfaces types with the interface registry +// RegisterInterfaces registers the x/budget interfaces types with the interface registry. func RegisterInterfaces(registry types.InterfaceRegistry) { } diff --git a/x/budget/types/errors.go b/x/budget/types/errors.go index d413784..8c84432 100644 --- a/x/budget/types/errors.go +++ b/x/budget/types/errors.go @@ -4,13 +4,13 @@ import ( sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" ) -// budget module sentinel errors +// Sentinel errors for the budget module. var ( ErrInvalidBudgetEndTime = sdkerrors.Register(ModuleName, 2, "invalid Budget end time") - ErrInvalidBudgetName = sdkerrors.Register(ModuleName, 3, "budget name only allowed letters, digits, and dash without spaces and the maximum length is 50") + ErrInvalidBudgetName = sdkerrors.Register(ModuleName, 3, "budget name only allows letters, digits, and dash(-) without spaces and the maximum length is 50") ErrInvalidNameOfAddr = sdkerrors.Register(ModuleName, 4, "address must be generated in accordance with Rule adr-028 using the name and matched") ErrInvalidStartEndTime = sdkerrors.Register(ModuleName, 5, "budget endtime should not be earlier than budget starttime") ErrZeroBudgetRate = sdkerrors.Register(ModuleName, 6, "budget rate can't be zero") ErrOverflowedBudgetRate = sdkerrors.Register(ModuleName, 7, "the total rate of budgets with the same budget source address value should not exceed 1") - ErrDuplicatedBudgetName = sdkerrors.Register(ModuleName, 8, "budget name can be duplicated") + ErrDuplicatedBudgetName = sdkerrors.Register(ModuleName, 8, "budget name cannot be duplicated") ) diff --git a/x/budget/types/expected_keepers.go b/x/budget/types/expected_keepers.go index 3c4d5c8..246f0ee 100644 --- a/x/budget/types/expected_keepers.go +++ b/x/budget/types/expected_keepers.go @@ -17,8 +17,6 @@ type BankKeeper interface { GetSupply(ctx sdk.Context, denom string) sdk.Coin 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 - //MintCoins(ctx sdk.Context, name string, amt sdk.Coins) error } // AccountKeeper defines the expected account keeper diff --git a/x/budget/types/genesis.go b/x/budget/types/genesis.go index ce5c886..1a6b239 100644 --- a/x/budget/types/genesis.go +++ b/x/budget/types/genesis.go @@ -1,6 +1,6 @@ package types -// NewGenesisState returns new GenesisState. +// NewGenesisState returns new GenesisState instance. func NewGenesisState(params Params, records []BudgetRecord) *GenesisState { return &GenesisState{ Params: params, diff --git a/x/budget/types/keys.go b/x/budget/types/keys.go index 7ae793d..1df59e9 100644 --- a/x/budget/types/keys.go +++ b/x/budget/types/keys.go @@ -19,13 +19,16 @@ const ( ) var ( + // Keys for store prefixes TotalCollectedCoinsKeyPrefix = []byte{0x11} ) +// GetTotalCollectedCoinsKey creates the key for the total collected coins for a budget. func GetTotalCollectedCoinsKey(budgetName string) []byte { return append(TotalCollectedCoinsKeyPrefix, []byte(budgetName)...) } +// ParseTotalCollectedCoinsKey parses the total collected coins key and returns the budget name. func ParseTotalCollectedCoinsKey(key []byte) (budgetName string) { if !bytes.HasPrefix(key, TotalCollectedCoinsKeyPrefix) { panic("key does not have proper prefix") diff --git a/x/budget/types/params.go b/x/budget/types/params.go index 2b17732..a72e380 100644 --- a/x/budget/types/params.go +++ b/x/budget/types/params.go @@ -12,8 +12,9 @@ import ( const ( // MaxBudgetNameLength is the maximum length of the name of each budget. - MaxBudgetNameLength int = 50 - DefaultEpochBlocks uint32 = 1 + MaxBudgetNameLength int = 50 + // DefaultEpochBlocks is the default epoch blocks. + DefaultEpochBlocks uint32 = 1 ) // Parameter store keys @@ -66,6 +67,8 @@ func (p Params) Validate() error { return nil } +// ValidateBudgets validates budget name and total rate. +// The total rate of budgets with the same budget source address must not exceed 1. func ValidateBudgets(i interface{}) error { budgets, ok := i.([]Budget) if !ok { @@ -92,6 +95,7 @@ func ValidateBudgets(i interface{}) error { return nil } +// ValidateEpochBlocks validates epoch blocks. func ValidateEpochBlocks(i interface{}) error { _, ok := i.(uint32) if !ok { From cb44a64fd1979fdcab3a50197337359c67ff5737 Mon Sep 17 00:00:00 2001 From: kogisin Date: Fri, 8 Oct 2021 15:15:40 +0900 Subject: [PATCH 4/8] fix: broken test --- x/budget/types/budget.go | 2 +- x/budget/types/genesis_test.go | 5 ++--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/x/budget/types/budget.go b/x/budget/types/budget.go index 939f93e..7fe0e68 100644 --- a/x/budget/types/budget.go +++ b/x/budget/types/budget.go @@ -64,7 +64,7 @@ func (budget Budget) Expired(blockTime time.Time) bool { func ValidityAddr(bech32 string) (sdk.AccAddress, error) { acc, err := sdk.AccAddressFromBech32(bech32) if err != nil { - return nil, sdkerrors.Wrap(sdkerrors.ErrInvalidAddress, acc.String()) + return nil, err } return acc, nil } diff --git a/x/budget/types/genesis_test.go b/x/budget/types/genesis_test.go index 7862176..420bd4c 100644 --- a/x/budget/types/genesis_test.go +++ b/x/budget/types/genesis_test.go @@ -11,7 +11,6 @@ import ( "github.com/tendermint/budget/x/budget/types" ) -// TODO: not implemented func TestValidateGenesis(t *testing.T) { startTime, _ := time.Parse(time.RFC3339, "0000-01-01T00:00:00Z") endTime, _ := time.Parse(time.RFC3339, "9999-12-31T00:00:00Z") @@ -84,7 +83,7 @@ func TestValidateGenesis(t *testing.T) { }, } }, - "budget1: budget name can be duplicated", + "budget1: budget name cannot be duplicated", }, { "invalid budget name case", @@ -97,7 +96,7 @@ func TestValidateGenesis(t *testing.T) { }, } }, - "invalid name: budget name only allowed letters, digits, and dash without spaces and the maximum length is 50", + "invalid name: budget name only allows letters, digits, and dash(-) without spaces and the maximum length is 50", }, { "invalid total_collected_coin case", From 7857677d2e607a49f20fc173f274f4e3da62827d Mon Sep 17 00:00:00 2001 From: kogisin Date: Fri, 8 Oct 2021 16:19:44 +0900 Subject: [PATCH 5/8] docs: update comments --- x/budget/keeper/budget.go | 9 ++++++--- x/budget/keeper/grpc_query.go | 2 ++ x/budget/types/budget.go | 4 +++- 3 files changed, 11 insertions(+), 4 deletions(-) diff --git a/x/budget/keeper/budget.go b/x/budget/keeper/budget.go index 324c785..2e5f83d 100644 --- a/x/budget/keeper/budget.go +++ b/x/budget/keeper/budget.go @@ -7,8 +7,9 @@ import ( "github.com/tendermint/budget/x/budget/types" ) +// BudgetCollection collets all the valid budgets registered in params.Budgets and +// distributes the total collected coins to collection address. func (k Keeper) BudgetCollection(ctx sdk.Context) error { - // Get all the Budgets registered in params.Budgets and select only the valid budgets. If there is no valid budget, exit. budgets := k.CollectibleBudgets(ctx) if len(budgets) == 0 { return nil @@ -22,8 +23,9 @@ func (k Keeper) BudgetCollection(ctx sdk.Context) error { outputs = append(outputs, banktypes.NewOutput(to, coins)) } } - // Create a map by BudgetSourceAddress to handle the budgets for the same BudgetSourceAddress together based on the - // same balance when calculating rates for the same BudgetSourceAddress. + + // Get a map GetBudgetsBySourceMap that has a list of budgets and their total rate, which + // contain the same BudgetSourceAddress budgetsBySourceMap := types.GetBudgetsBySourceMap(budgets) for budgetSource, budgetsBySource := range budgetsBySourceMap { budgetSourceAcc, err := sdk.AccAddressFromBech32(budgetSource) @@ -53,6 +55,7 @@ func (k Keeper) BudgetCollection(ctx sdk.Context) error { collectionCoins, changeCoins := budgetSourceBalances.MulDecTruncate(budget.Rate).TruncateDecimal() totalCollectionCoins = totalCollectionCoins.Add(collectionCoins...) totalChangeCoins = totalChangeCoins.Add(changeCoins...) + // TODO: sendcoins after validation sendCoins(budgetSourceAcc, collectionAcc, collectionCoins) k.AddTotalCollectedCoins(ctx, budget.Name, collectionCoins) diff --git a/x/budget/keeper/grpc_query.go b/x/budget/keeper/grpc_query.go index b799047..1d0eae4 100644 --- a/x/budget/keeper/grpc_query.go +++ b/x/budget/keeper/grpc_query.go @@ -18,6 +18,7 @@ type Querier struct { var _ types.QueryServer = Querier{} +// Params queries the parameters of the budget module. func (k Querier) Params(c context.Context, _ *types.QueryParamsRequest) (*types.QueryParamsResponse, error) { ctx := sdk.UnwrapSDKContext(c) var params types.Params @@ -25,6 +26,7 @@ func (k Querier) Params(c context.Context, _ *types.QueryParamsRequest) (*types. return &types.QueryParamsResponse{Params: params}, nil } +// Budgets queries all budgets. func (k Querier) Budgets(c context.Context, req *types.QueryBudgetsRequest) (*types.QueryBudgetsResponse, error) { if req == nil { return nil, status.Error(codes.InvalidArgument, "invalid request") diff --git a/x/budget/types/budget.go b/x/budget/types/budget.go index 7fe0e68..dbbddb2 100644 --- a/x/budget/types/budget.go +++ b/x/budget/types/budget.go @@ -87,7 +87,9 @@ type BudgetsBySource struct { type BudgetsBySourceMap map[string]BudgetsBySource -// GetBudgetsBySourceMap returns BudgetsBySourceMap that has a list of budgets with the same BudgetSourceAddress and its total rate. +// GetBudgetsBySourceMap returns BudgetsBySourceMap that has a list of budgets and their total rate +// which contain the same BudgetSourceAddress. It can be used to track of what budgets are avilable with BudgetSourceAddress +// and validate their total rate. func GetBudgetsBySourceMap(budgets []Budget) BudgetsBySourceMap { budgetsMap := make(BudgetsBySourceMap) for _, budget := range budgets { From 7096d236d6ee672736184aacbd3f0f6cb18989a0 Mon Sep 17 00:00:00 2001 From: kogisin Date: Thu, 14 Oct 2021 17:15:29 +0900 Subject: [PATCH 6/8] chore: rename BudgetCollection to CollectBudgets and update relevant docs --- x/budget/abci.go | 4 ++-- x/budget/keeper/budget.go | 4 ++-- x/budget/keeper/budget_test.go | 6 +++--- x/budget/keeper/genesis_test.go | 2 +- x/budget/keeper/grpc_query_test.go | 2 +- x/budget/spec/03_state_transitions.md | 6 +++--- 6 files changed, 12 insertions(+), 12 deletions(-) diff --git a/x/budget/abci.go b/x/budget/abci.go index 2b8a3de..8f4a506 100644 --- a/x/budget/abci.go +++ b/x/budget/abci.go @@ -12,10 +12,10 @@ import ( "github.com/tendermint/budget/x/budget/types" ) -// BeginBlocker collect budgets for the current block +// BeginBlocker collects budgets for the current block func BeginBlocker(ctx sdk.Context, req abci.RequestBeginBlock, k keeper.Keeper) { defer telemetry.ModuleMeasureSince(types.ModuleName, time.Now(), telemetry.MetricKeyBeginBlocker) - err := k.BudgetCollection(ctx) + err := k.CollectBudgets(ctx) if err != nil { panic(err) } diff --git a/x/budget/keeper/budget.go b/x/budget/keeper/budget.go index 2e5f83d..300e4be 100644 --- a/x/budget/keeper/budget.go +++ b/x/budget/keeper/budget.go @@ -7,9 +7,9 @@ import ( "github.com/tendermint/budget/x/budget/types" ) -// BudgetCollection collets all the valid budgets registered in params.Budgets and +// CollectBudgets collects all the valid budgets registered in params.Budgets and // distributes the total collected coins to collection address. -func (k Keeper) BudgetCollection(ctx sdk.Context) error { +func (k Keeper) CollectBudgets(ctx sdk.Context) error { budgets := k.CollectibleBudgets(ctx) if len(budgets) == 0 { return nil diff --git a/x/budget/keeper/budget_test.go b/x/budget/keeper/budget_test.go index 6be6ac3..2642694 100644 --- a/x/budget/keeper/budget_test.go +++ b/x/budget/keeper/budget_test.go @@ -6,7 +6,7 @@ import ( "github.com/tendermint/budget/x/budget/types" ) -func (suite *KeeperTestSuite) TestBudgetCollection() { +func (suite *KeeperTestSuite) TestCollectBudgets() { for _, tc := range []struct { name string budgets []types.Budget @@ -155,7 +155,7 @@ func (suite *KeeperTestSuite) TestBudgetCollection() { params.EpochBlocks = tc.epochBlocks suite.keeper.SetParams(suite.ctx, params) - err := suite.keeper.BudgetCollection(suite.ctx) + err := suite.keeper.CollectBudgets(suite.ctx) if tc.expectErr { suite.Error(err) } else { @@ -211,7 +211,7 @@ func (suite *KeeperTestSuite) TestTotalCollectedCoins() { suite.Require().Equal(sdk.Coins(nil), collectedCoins) suite.ctx = suite.ctx.WithBlockTime(mustParseRFC3339("2021-08-31T00:00:00Z")) - err := suite.keeper.BudgetCollection(suite.ctx) + err := suite.keeper.CollectBudgets(suite.ctx) suite.Require().NoError(err) collectedCoins = suite.keeper.GetTotalCollectedCoins(suite.ctx, "budget1") diff --git a/x/budget/keeper/genesis_test.go b/x/budget/keeper/genesis_test.go index 34fda1e..4965834 100644 --- a/x/budget/keeper/genesis_test.go +++ b/x/budget/keeper/genesis_test.go @@ -16,7 +16,7 @@ func (suite *KeeperTestSuite) TestInitGenesis() { suite.Require().Equal(emptyGenState, suite.keeper.ExportGenesis(suite.ctx)) suite.Require().Nil(emptyGenState.BudgetRecords) - err := suite.keeper.BudgetCollection(suite.ctx) + err := suite.keeper.CollectBudgets(suite.ctx) suite.Require().NoError(err) var genState *types.GenesisState suite.Require().NotPanics(func() { diff --git a/x/budget/keeper/grpc_query_test.go b/x/budget/keeper/grpc_query_test.go index 0a2d1ae..68c2cc3 100644 --- a/x/budget/keeper/grpc_query_test.go +++ b/x/budget/keeper/grpc_query_test.go @@ -58,7 +58,7 @@ func (suite *KeeperTestSuite) TestGRPCBudgets() { expectedCoins, _ := sdk.NewDecCoinsFromCoins(balance...).MulDec(sdk.NewDecWithPrec(5, 2)).TruncateDecimal() suite.ctx = suite.ctx.WithBlockTime(mustParseRFC3339("2021-08-31T00:00:00Z")) - err := suite.keeper.BudgetCollection(suite.ctx) + err := suite.keeper.CollectBudgets(suite.ctx) suite.Require().NoError(err) for _, tc := range []struct { diff --git a/x/budget/spec/03_state_transitions.md b/x/budget/spec/03_state_transitions.md index 3065a5c..0bdac6f 100644 --- a/x/budget/spec/03_state_transitions.md +++ b/x/budget/spec/03_state_transitions.md @@ -4,9 +4,9 @@ This document describes the state transaction operations pertaining to the budget module. -- BudgetCollection +- CollectBudgets - TotalCollectedCoins -## BudgetCollection +## CollectBudgets Get all budgets registered in `params.Budgets` and select the valid budgets to collect budgets for the block by its respective plan. This state transition occurs at each `BeginBlock`. You can read more about it in [04_begin_block.md](04_begin_block.md). @@ -14,4 +14,4 @@ This state transition occurs at each `BeginBlock`. You can read more about it in ## TotalCollectedCoins `TotalCollectedCoins` are accumulated coins in a budget since the creation of the budget. -This state transition occurs at each `BeginBlock` with `BudgetCollection`. You can read more about it in [04_begin_block.md](04_begin_block.md). +This state transition occurs at each `BeginBlock` with `CollectBudgets`. You can read more about it in [04_begin_block.md](04_begin_block.md). From 54c31537ac75f822214b56b6a74c8596e1780f74 Mon Sep 17 00:00:00 2001 From: kogisin Date: Thu, 14 Oct 2021 18:00:55 +0900 Subject: [PATCH 7/8] refactor: apply suggestion --- x/budget/types/budget.go | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/x/budget/types/budget.go b/x/budget/types/budget.go index dbbddb2..7c54083 100644 --- a/x/budget/types/budget.go +++ b/x/budget/types/budget.go @@ -37,11 +37,11 @@ func (budget Budget) Validate() error { return err } - if _, err := ValidityAddr(budget.CollectionAddress); err != nil { + if _, err := sdk.AccAddressFromBech32(budget.CollectionAddress); err != nil { return err } - if _, err := ValidityAddr(budget.BudgetSourceAddress); err != nil { + if _, err := sdk.AccAddressFromBech32(budget.BudgetSourceAddress); err != nil { return err } @@ -60,15 +60,6 @@ func (budget Budget) Expired(blockTime time.Time) bool { return !budget.EndTime.After(blockTime) } -// ValidityAddr validates the bech32 address format. -func ValidityAddr(bech32 string) (sdk.AccAddress, error) { - acc, err := sdk.AccAddressFromBech32(bech32) - if err != nil { - return nil, err - } - return acc, nil -} - // ValidateName is the default validation function for Budget.Name. // A budget name only allows alphabet letters(`A-Z, a-z`), digit numbers(`0-9`), and `-`. // It doesn't allow spaces and the maximum length is 50 characters. From d0139a1d13fbd30ba4106ca868219eefd81f746c Mon Sep 17 00:00:00 2001 From: dongsam Date: Fri, 15 Oct 2021 13:46:36 +0900 Subject: [PATCH 8/8] docs: make proto-all --- client/docs/statik/statik.go | 2 +- client/docs/swagger-ui/swagger.yaml | 6 +++--- proto/tendermint/budget/v1beta1/budget.proto | 2 +- x/budget/types/budget.pb.go | 15 ++++++++------- x/budget/types/genesis.pb.go | 6 +++--- 5 files changed, 16 insertions(+), 15 deletions(-) diff --git a/client/docs/statik/statik.go b/client/docs/statik/statik.go index 1f2072c..d6bb837 100644 --- a/client/docs/statik/statik.go +++ b/client/docs/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\x0c\x00 \x00swagger.yamlUT\x05\x00\x01\x80Cm8\xec]\xdds\xdc\xb8\x91\x7f\xd7_\xd1\xa7\x87H\xbe\xc8\x94\xedM\xdd\x83\xee\x94:\xc7ko\x9c\xdb\x0fE\x96\x9f\xb6\xb6$\x0c\xd9\x9c\xc1\x99\x03p\x01P\xf2$\xe7\xff\xfd\n\x009\xc3\x0f\x00\xe4\x90\xdc\x8fJ\x11\x0f\xb1\xd7C4\x1a\xcdFw\xa3\xd9\xbf\x8e|\"\xeb5\x8a+8{\x15\xbd8;\xa1,\xe5W'\x00\x8a\xaa\x0c\xaf\xe0\x0d\x97[.\xe1\xc3\xd7\xff\x03\x7f)\x925*\xf8\x8e'E\x86\xf0\x1cn\xdf~\xb8\x03\xc2\x12X\xdf\xde\xbc\x81o\x88\xc2'\xb2\x83\x84\xc7\xf2\x04 A\x19\x0b\x9a+\xca\xd9\x15\x9c\xbd\xb6\x0fS\xa6P\xa4$FH\xb9\x00\xa9\x88B\xf8\xb9@AQ^\x80\x12\x84I\x12\xeb\x19\xf2\xec\x04\xe0\x11\x854\xb3_D/\xa3\x17'9Q\x1b\xa9\x19\xbb\x8c\x0dK\x97+\xc3\xce\xe5\xe3\xcb\x15*\xf2\xb2\xfcO\xf3\x04\xc0\x1a\x95\xfd\x0b\x80,\xb6[\"vW%\xfb\x12\x04\xaaB0 $\xcb\xa0\x9c\x14\x95\xcf\xf2\x1c\x05\xd1\x0c\xbcO\xf6\xcf\x97? \x949g\x12eE\x17\xe0\xec\xd5\x8b\x17g\x87\xffl\xed\xf95\xc8\"\x8eQ\xca\xb4\xc8\xf6\xb3\xa3\xda\xd32\xde\xe0\x96\xd4\xe7\x03\xa8]\x8eW\xc0W\xff\x8b\xb1j\xfc\x90\x0b\xcd\x9b\xa2\xf5\xf5\xedh\xec\xbb>,-\"\x04\xd9u~\xa3\n\xb7\x8e)\x01\x06\xec\xf0\xb3a\x87e\xc6\xfd[/q\x18\xb0\x80\x1e\x8cl\xd1\xffk\xb5\x8cT\x82\xb2u\xe81\xab\xe0\x9a\x1a$\x98R\x86\x12\xd4\x06\xed?\xf0\xd4\xfc\xdd\xee\xc7KD\x105#'\x7f~\x1ex\xc6.\x062\xc7\x98\xa6\xb4d5\xa1\x9a\xf6\xaaP\x94\xad\x81ly\xc1\x14\xacv`t\x18x\x1a$\xa7\xb8\"\xd5\x01\x00\xc9\x0b\x11\xa3\xf7y\xfb\xd4\xbd}\xea\x9e$\x89@\x19xA3o\xdc\xb9z\xe3\x95\xad0\xde|\xf5\xea9\xb2\x98'\x98\x04\x89U\xd3\xd5\x86T\xdb\x1e\xf8\xb2c\x9eeh\xcc\xd3\xaf.\x81\xee\xd2S\xb7\xdf\xd82\xe4\x9cg\xa0\xf8A\x9f\xfc\xaa \x15\x11\xea^\xd1Y\x8e`\xca\xc5\x96\xa8+H\x88\xc2\xe7\x9af\xbf\xa4\x0e\xeb\xb7\xce\x82\xf9\x01\xcc\x0f\xc3\xde'\xb2\xe47\xdcG\xb5zk\x17\xc8\x92\xe1{h\xf8\x9b\xd2;WzA\xaawk\xcdm\xe4$al\xc0}\xa9]\x98\xdc\xc7\x9c2\xafV\x87\xfc\x89\x1d^\xafb\xc7\x00\xf3?\xcc\x01\xe8\x9d3\xbe\x0d=0\xf8\xd5Y\xab9\x03\xa9\xc6\xcb\x08\x9e\xe77\x9c\xb2\xda{R\xfc\x132x\xa2j\x03\xc4n\x8c2\x13\x84\x98\xd8\x8a\xb0^\xe6\xa3\x93\x93\xc03\xdf\xffp\xf7\xf6\n\xee6X9\x88\x94b\x96\x00\x95@\x18\xbcg\n\x9e64\xde\x00\xdd\xe6\x19n\x91)\xa3\x87\x01zq!\x15\xdf\xc2\x16\xd5\x86'\xa1\x85%]3\xa2\n\x81:\xe4\xfa\xb9\xa0\x02\x13\xed\x9c\xd6|\xcds\xc1\x15o\xaadX|\x7f/P\xec\xca\x80\xec\xb6\x8c\xa5\xf4\x16\xf4\x11\xa9b+\xf3\x9aL`\xa9\xff\xd5\xcc\xb8l\xc6p\xd5\xd0\xe1\xaa\xe5\xff\xc0C\x82))2\xe5\x0f\xe7\x18\x14\x0c?\xe7\xe6\xa0\x00\n\xc1\xc5~\xe5\xda\x9c\x99\x82:C\xdf\x17\xd29\x15Q\x9b~\xdf\x04\x1dv\xafQt~\xad\xcc\x16e\xea\xabW\xad_\xb7(%Y{I:yHP\x11\x9a\xfdNBQ=\xfd\xbe\x10Y\xd8\x9c\x05\x0f\xf5\xd0#\xfd\x1a>\xde~{)\xb0\x0c'L\x00i\xe2\x8b\x82\xd1\x9f\x0b\xccv@\x13d\xea`\xe5\x8d\xa6\x06\xe23\xe3\xcfPP\x92\xd1\x7f`\xe0\x90\x99s\x14s\x1d\xc6\xa5)\x8a\xea\xa5Ep\xb7\xa1\xb2\xdc\x1bl\x0b\xa9 \xe6L\x11\xca\x80\xf8-o\x86D*\xffZ\x9c!\x9c^\x9eB\xbc!\x82\xc4\nEd\x8cJF\xa4\x02\x89km:*\xa7\xf5\xf1\xf6\xdb3 \xfa\xc2\xe6\xa5f\x98\x12\x98\x0b\x94\xc8\x02\xabjri\x91e;\xf8\xb9 \x99\x96`\xd2\x08\xd0\x8d$\xcf\x89\x04\xca\xfcD\x1e4+\x97k\xce\xd7\x19FFf\xab\"\x8d\xbe.\xec]\xef\xe1\x99\xdd\x89!+7\xbc\xc8\x12X\xa1&\xe8\xa3G &\x8c3\x1a\x93\xcc\x9c!\xff\xca\xe7\x18\xad\xa3\x0b-\xdaD\xbf\x8a\xd3\xe8T[-\xc6\x15\x908\xc6\\a\xf2,d\xbd\xdf3\xc8\xb5\xb0i\x8c\x17\xa0\x90l%\x14\xb2 Z\x1c\xb9\xc0\x98os\x9aiN\x15\xb7\xc1\x02eD\xf8\x9c3\x98\x0b\xaf\x96W\x19\xfc\xaa\x0d\xee\xfcK[S\x07T\xe9\xb8\xb0\xd0\xd6\x96\x995\xb4\"\xe1g\xf3\xaa_\xb3]\x04\x7f\xe5O\xf8\x88\xe2B\x0b\xc2K\xec\xe3\xed\xb7\xb2\xf43\x9a\x94v0\xdeg\x8d\x05Ex\xd8(\x95?\\\xd8?\xe5\xc3\x05p\x01\x8c\x97\xbf^\x18m\x8c \x03nN\xa7\x96\x88\x9f *(r\xedhwyh]\x14\x8f(\xach\xb6$\x97V\xb5\x0c\xe7\x8aW'\xcb\xbamjr\x14@\xda~\xe50R\x9ee\xfcI^\x05\xde\xed\xbf\xc3\xfb\xf4\xb0#\xad\x16\xb9\xe0\x8f4\xc1d\xbfi\xe3\xa4\xa5,\xb6\x98D!B\xaf\x19\xfc\xf5\xee\xee\x06\xbey{\x07\x9cUG\xd0\x9e\xb1\x9d\xf1\xf6\xc4;\xfb\xc7\xf6\xb1\xb8\xdb\xe5\xf8\xd3\x8f?y'\x00<\x92\xac0\xfa`\xf5\xadt#\xe6\x0d\xe5\x82'E\x8c:\xb40.\xcc\x1dv\x82\xe5:\xcf3\x1a\x93R\x96\x02\xb5~\xf2'L\xb4\xb8c\x12k\xdb\xc2\xf9\xa7\"\xd7n\xb6\xc8\x94\x84\x15\x91\x81\xdb\x8d\xddx\x80\xed\x8f\xb7\xdf\x1a\x1e7\xe4\xd1\xa8\xe0\xb6v\x86\x12{\x88H\xb5%\xfd\xf7GNu\xf8\xe5W,(\x194\xe6C`\xca\x05^T\x044]\xa2\xe8\x8afT\xed\x80!&F\x8dV\x08\xc6\xe4\x89\xc7\xe0=\x8d3mf\xd9\x1a\xcd$sf#8\xff(\xb1J\x8ai)i\xf5\xd46\xcb\xea'ad\x1d\xda\xfdJ \xf9\xa4mPI8z\xe6\xd7\xa8\xef\xb9\xc2+P\xda\x87\xa4\x05\x8b\xed \xd3\xfb(mW\\\x08\x81Le; \x8f\x84fd\x95\x05\xcd\xa5\xd6G\x9e\xa64\xa6$\xeb\xf1e\xab\"\x05\x81\xda\x13\xe1\x85 \x7f\xa9\xaa\x16-$&6\xba\xab\xce\xa5\x97\xd4\n\xd7\x941\xbdY\x1dU\x07\x9c\xcb.\xc7\xc8\xea?\xc9\xa9\x8cb\xbe\x0dY\xe3\x0f\xe6\xa4J\xe0jc\x0d\x05k[)8/\xa3O\xdc\xe6jW\x1e\xedg~'H\xd7\x1b\x05\xab\x80Q2\x9b6W\x83}|n\xaf\x06\xe5\xad1\x06\x89[\xc2\x14\x8d\xa5\xfb\xa8\x99\xb3:!\x04\xaaB\xc4\xd5\xce\x9b\x13\x18\x1a%}\xa7\xcd\xd1\n\x81h\xa6hR\x0bp:qL\xe9\xdc\xc9\x8a?\x062\x11\xe5\xc5\xd9\x1e\x05\xd7\xf6\x87p\xf6\xf0\x9a\xed\x1e\xaa\xf0\xc8\xdc\x89\x88XQ%\xf4!\xf6s\xe8$U\xf9\x08\x92\xf1R\xf5\x80\xb8_\xad\xb6\xce\xc6\xd1X\x0eW\xcd\xb0\xb0\x15\xfe\xed\xa3:\x8fj\xdeT\x07'\xa3+\xc3v\xe9G$\xc8\"\xcf\xb90\x1e<'\xf1\xa7\xcb\x82\xe9?\xb4\xdf\xb6z\xe1>A\xa5\xa3\xf7\x076<\x85BY\xc3V\x99\x07\xa9\x0d+I\x12jm\x05\xac\x91\xa1 \xca0\xaf\xefYU\xc2\xc9IO\xf3c_\xa1{\xbd\xb7\x9f\x89V~xy\x057\x9a\x7fm\x17\xca\xad\x90\xbd\xd0)\x837\x7f\xfcc\xc0M\xbe\xe3\x1cR\xce\xe1\x1a\xa2(\xfaO\xefc\x9a\x19\xc2v\xfe\x07\x08\xdbE\x9a\x8dw\x82o\xcfS\xce\x9f\xf9\x1f\x8d\"\xbf\xff\xa3)\x9ckR\x1f\xcdF\xee\xf8\xf9\x1f4\xadg\xf0\xcf\x80\x0d\x0f\xd1\xfb\x12\x96\xdd\xab\x1e\xd9\xfd\x8d<\x92\xd9\x84\x07\xd7&6\xd4\xab\xcc !*\xcf\xdfq\x1e\xc5\x19\x91\xb2G@\x96E=\xc9\xee\xb16\xd1\xcf\x83Gr{\xd1}\xd5#\xba\x9b\x9d\xdap\x16\x10\x9e\xe5\xea\x1d\xe7\xe7Q\x14\xf9\xbd\xc1^p\xe7\xc1g\x8c\xf2\x19\xb1\x8e\x95\xaa&\xf2\xde\n\xf5\xeb\xb7\x1f\xde\xdc\xbe\xbf\xb9\xfb\xe1\xf6Y(\x05vP\xd4\xf0\xc2v\xe9\xb08\xff\xd4#\xceox \xa9\xa4Eyu\x0d\x7f\xc8W\xd1;\xce\xff\x19E\xd1\x17\xff\xc3\x84\xed.t\x18\xaag\xe46\x88\xfa\x8e\x08\xb9!\x99\x16rx#!\x11\xb6\xb9\x08\xb0@\xd3\x16\x03\x1f\xd9\xf6\xc0\x82a\xd0\x1c\x10\xf3\xd4\xbf]\x03\xa3YP\xc1\xc3|y4Y_n\x8d\x9c+[\\]4`\xb5;\x84]\x95\xf7x\xa2Y\x06+w\xd4[&\xc9tX\xe2^\xea\xcc\x11R]\xea\xfb{d~\xd0\xe1\xea\x19\x90\x9a\xb7\xd3\x9ePk\x82\xcf7X\x0dq/\xb6w-,\xdbU\xf7\xcaN\xb2`\x1f&\x03I\x95 \xdb\xdc\x0b\x99<\xc6\xd9\xe5\x99{\xa9\xd2'V,\x9b\xdb.`\xa9\xd1\xa7)\xe7\xd1\x8a\x08\xb3\xd9\xcf\x97\xbb\xe8\x1f\xa7V\x8a\xe6\xee\xe5\xa4\xe7\xbf\x8a\x1aVO5\x0d\xed\x0e\x9d\x8f\xfc\xed\xc3\x0f\xdf\xbb\x7f\xb9\xbe\xbe\xbe\xf6\xeb\x80\x9ew\xc8\xb9\xd88\x92ksP\x06A\xf6^WH\xac\xf2\xaa\xeb\"#\xc2M\xafK\xc6|\x8f\xc4C\xd8r\x01\xb8]a\x92\x1c\x02\x98\x0b\x1b\x8e\xbb\xc8\x11O\xf6\xa6\x16R\xd8\xb4\xf5\xc3\x7fk\xd1=\x94\xc9\x84}\xd8V\x7f9\xee\x03R\x9a\x9f\xab\xc0\x05\x84\xc4\x9f\xb4\x0d:\\\x88S\x9a\xa1\xdfoT6\xeb\x06\x85\xe4,xl\xcbL\\J\x85T\xf7\xe6\x0d_\xc3K?\xe5\xfd\x04\xad\x94\xd5\xf3\xaf\x8e\xf7`\x00A\xaeN\x8d,O\xaf\xe0\xd4uj\x9bb\x88\xec.O/B\xf4\xcc\xfe\xbe'[M\xf3\xbf\xec\x16\xfe\x1c\x9c\xa0\xf7\xd7z\xfe\xd8M\xbeO\xcb\x0bWS\xd7\xac6P O\x98e\xcf?1\xfed?\xa7l\x88\x04R~\xc38\xf2p5U\xfe\xc2\x06\xf0\xads`\x8dg\x8d\x1d\xad\xc0\x9e\xcb\x15\xb1*\xed^\xec\xc1\x1c\xc6J\xcf7\xc0f\x00\xdd\xa4\xec\x91q\xafcX\x88\xf6\xce\xf9\\\xdb\xb5J\x84\x9d\xd4P\x951\xfd\xe9\xc7\x9f\x9e\x05\x0e\xd2\x1c:\xd7\\0\xacvFT\x9a\xe4\xcb\xe8\xd5\xcbW\xf24\xa0B\xf6\xcf\x9c\x08\xb2E\x85\xa2\xf6\xe9\xe0\xb9-+1\xff[#@\xd9\x95\xa9P\xaa\xfb\xc3\xeak\xd6\x15\xa4$k|\xfdq^\xa8+\xca\xce2\x86_f\xa9n\xbd\xc0\x9c\xeb(\xb2n\x08\xee\xef%1Oa\x96\x91v\xa0.\xeb\xc6\xfc\xbe/\xcb:\xbc\x9cV\x91\xc2\xd6\xd4\x9d\x05J\xb5,\xa1\x93jG\xbf\xd3z\xad\xba8\xea\xc3K\nz?va\xce\xe3\xcd\xfd*\xe3\xf1\xa7\xc0\xc70\xffw@h~\x0b\xfc\x8f?\xb9i\xf4\x94\xaa\xe8\x10\xa3`\xf4\x11\x85$\x99\xe5 2dk\xb5\xd1\x96\x8a\x15\xdb\x95\xcd\xecX>}\xe6\xe3uMy\xcd\xd3e\xd5\x1e\x95\x80\x9f1.T\x95\x103\xe9\xc9\xfa\xce=\x04\xf7\xfa\xe4\xf8\xdd[;\x07\x03\xea\x1d\x82\xd5\x0e\xc1\xb7iG\xdf\x07LXJ\xdd\x96R\xb79j\xbd\x96R7\xb5\x94\xba\xfd\x86\xfb\xf8}\x94\xba\xf5h_U\x1d\xbew\x17\xe6\xf3\xf2\n\xb5\x1a\xe9\xcb\xec\x96'&\xa1`?K%\x98\xa1\xf2\xea\x9f\xda\x08^\xac7\xe0\xf3q\xb55\xcc\xc78X\xf3G\x14\x8c\xb0\x18\x8dW\xe0\x92d\x9d\xa9\x0d \x941S\xfdd\xd4\xe2\xa6\xaa\x06\xca\x1989\xa8\xb9\xcb\xad\xec\x1a\xc7T[\x95\\\xdd\xde\xbci\xd1[\x8a\xad\x96b\xab>\xe32\xe4c\x1d,\xc5VK\xb1\x95\xf7\xc9\xa5\xd8\xca\x8c\xa5\xd8\xaa;\x96b\xab\xa5\xd8\xca7\x96b\xab\xa5\xd8\xca\x8c\xa5\xd8j)\xb6Z\x8a\xad\x96b+;\x96b\xab\xa5\xd8j)\xb6Z\x8a\xad|c)\xb6Z\x8a\xad\x96b\xab\xa5\xd8\xaa6\xe6(|Y\x8a\xad\xccX\x8a\xad\xfeU\x8a\xad\xdc\xd5B\xb5\xd4\x9e\xfe\xd1V\x0eE+\"1*\xeb\x86\xa27\x9c2;\xb1\xf3q\xa2\xfb9\xa2\xd5\x10\xc2q\xd9n7z\xe8<\xd2\xb8\xc0\xfe_u\x81=\xb2Y\xc3\xa1%\x83\x9d>\xaa\xfbB\xab\xc7\x82\xa54\xa4\x9dB%F\xf3\xddo/\xc8\xbf\xd4\x9a2\x0d\x10e\xb3\xe6\xc4\x99\xb68\xba\x9e\xa4Y=\x12\xa2y|\xe9G\xa0\xbc\xa3\xa7\x98#\xc4G#\x83qlY\x86\xab\xf4\xa2F\xce%\xa1P\xc9\xc5`>\x8f*\x9ep\x17H\xd4\xa8yK%\\\x85\x11N\x1e\xfd\xc5\x02\x13K\x1c\xba\x05\x0d\xe3\xd6?\xbe4\xe1\xc8B\x84\xd0\x89\xac>\xad\x0f>\x99\xab\xdaAvNqO\x03g!\x997\x1fy\xf4\xe1\x06gyX\x1f\xfdN\x8ap\xe2\xc9oQ\xeb\x1c\xba\x01\x85]G\xb3<\xc9.8\x19\xf6\n\xb8\xaf$\xebh\xde\xa7\xd8\n\xa7\x18\xc2\xa5U\xbeb*/\xdf\xe1B\xa3\x89\xf6\x03\xbcEQ\xd3\xf89\xde\x9e\xc0\xf16\xc5\xac\x17\xee\xdc\xa5\x1c5 \x9d\xda\x0f\xa7\xf9\xf0\xd7z8{ny\xc5\xe5\xee\xab\xe5y\xdc\x1dz\xd911\x00\xb3c\xbe0\xcc\x8e\xf1\xc1\xd8M\xad\xfc{\x80\xc9w\x97v+g\xa5\x91\xbb\x84\xbb\xd4\xcc\x86T\x8f,\xd5>L\x1c_\x9d\xdd\xa9\xc3.\xa7\xfe\xb2:\xeb\xaa\x9f\xf6\xaa\xecH\xd7\xe7\xae\x8d\xee_\xc5\xf1\x8dl^\x17\xe8p\x82\x83\xdc\xe0H\xe6\xe7t\x86\xbd\xee\xb0\xdf!\x8e\xdc\xc5\x8cnq\x98c\x0c\xd5\x19\x07v\xd0W\x87;\x83\x83\xf4\xd7\x0dO\xe7k\x9c\xa3\x1c\xe5*\xdd&pT\xbd\xef\xa1\xb2\xf7@hp1\xef\x1c\x05\xbcn\x9f\xe2\xea\x8e8\xd8\xc3\xfc*v\xb8}s \x12 \x11\x82\x00(&\xa0\x950\xde\xb8C\x00\xfc2lEO1\xc4Xc\xef$Vj\x8a\x07\xdc2\xc8\xe8\xc3\xd4\x0d\x8du\x00Nb\xc3A+\xfd\x8e\x00\xa6\xeelV\xa7\x00\x83\x1d\x03\xf4\x82Pzv\xd5g\x8ca.G\x01= \x93\xf9\xf8\x1c\xeb8`\xac\xf30k\x0f\xe9\x93\xec\xb2\x9bvx\xaa\xee\x03\xe6\xaf\xaf\xe2>\xd0\xff\xb8G\xd4\xa1~\xc7\xc1\xa9\xfd\xf5]\xa3oj\x0eZS.l\x0er\xfen\xc5Cnr\xbe\xcdO\xecJ\\\x03\xca\x1c\x002\x01\x0f\xdf\x04\xe4\x0cv\xf0m\xc0\xb1S\xed\xdc\xea\xe6\x07\x16\xbbo\xa0\x10\x04\x12\xfbl\xec\x91\xb7\xd1\xd6\xec\xf1W\xd2\x16!\x17P\xb8\x13\x1cA\xe0\xa0;\x8f\xf9\x12\xe3,1\xce\x12\xe3,1\xce1|\xfe61\x8e\xe3\x92\x0cs^\x94\xe1\x98\xcb2\xcctanQ\x99\x0cl\xady\xeav\xfd\xc4k\xb6\x1b\xec\x93U\x07/\xe9\xd4\x1e\x7f\xcc5\x16\x05\xd9:\xadn\xdc\xe3\x18\xa4c\x17\xd18\n\xc3\x18\xc0*\xaaq\xe8\xc4\x91x\xc4:\xee\xb0F\xad]\xa8\x7f4\xe6p\x14\xca\xb0\x85&l\n\xa5\x81+\x1c\x83$l!\x06\x9b\xd4\xeb\xc4\xc7\xa2\x05\xfd\xa8\xc018@7\xdeo\x02\xc2o\x10\xa6o\x18vo$Zo,>\xcf\x85\xc3\x9b\x05y7\x1f\xd6n\x16t]\x18O7\x0eAg\xde\xb2\x0b)w<6.\x80\x81S}\xa8\xb7\xb187'\x9em\x04\x82\xad\x85Ys\xba!'.\xcd\xef\x9bFb\xcf\x0e\x18\xb3\xb6\xfcN\xfc\xeb\x8dC\x949\xd0c%\xbd=\x86l\"jl\x02N\xcc\x85 \x9b\x80\x02s \xbe\xc6b\xbc\xbc\xc0$\x07\x8e+\x88\xdcj\x02+\x86\xa1\xb3\x9as\xbe\xb4\xf7r4\xe6\xaao3!\\\x95\x9b\xff vj Z\xeaPx=\x01\x11\xe5\xc5@\xb9QO>\x9cSg\x97C\xb0L!\xf4R\x1d\xaf4\x12\xa1\xd4\x83I:\x0e\x85\xd4\xc2\xf7\x84\x90F3`\x8bZ\xab\xed\xdf\xf4(\xc4\x90\x0b\x1d4\x05\x0f\xd4\xc2\xfe\x8cE\xfbt\x90=\x13\xb0<\x8d`\xd1\x89\xd4\xa9\xc3\x07\xeah\x9c\xe9\xf8\x9b\xf1\x88\x9b\x1a\xbaf\x14\x9e\xc6\x89\x9d\xe9G\xcb\x04\xf11\xe5\x8d-\x84\x88)\x1f\xf1b`\x1a\x80\x90&\xf5\xa1(\x03?\xb2e\x00\x96\xa5\x07\xbd\xb2go\x02B\xa5\xa1N\x13\xf0'm\xac\xc98tI\x1bI2\x0fvd\xdc\x9b\x0b\xe2CB\x88\x10mB\xd7\"\x8f\xa3\xb5\xfd?\x07\x8fD\xc1\x14\xddb\xf4\xf6\xd0rk@\xb6\xa4\xd5\xa0\xcb\x11\xa36\x1br)\xe7\xc7 W\x03\xaeN\xe3-\x07\xedN\xa3-\xf5\x0b\x14H(O\x03-g,-\"\x04\xd9u~\xa3\n\xb7\x8e)\x01\x06\xec\xf0\xb3a\x87e\xc6\xfd[/q\x18\xb0\x80\x1e\x8cl\xd1\xffk\xb5\x8cT\x82\xb2u\xe81\xab\xe0\x9a\x1a$\x98R\x86\x12\xd4\x06\xed?\xf0\xd4\xfc\xdd\xee\xc7KD\x105#'\x7f~\x1ex\xc6.\x062\xc7\x98\xa6\xb4d5\xa1\x9a\xf6\xaaP\x94\xad\x81ly\xc1\x14\xacv`t\x18x\x1a$\xa7\xb8\"\xd5\x01\x00\xc9\x0b\x11\xa3\xf7y\xfb\xd4\xbd}\xea\x9e$\x89@\x19xA3o\xdc\xb9z\xe3\x95\xad0\xde|\xf5\xea9\xb2\x98'\x98\x04\x89U\xd3\xd5\x86T\xdb\x1e\xf8\xb2c\x9eeh\xcc\xd3\xaf.\x81\xee\xd2S\xb7\xdf\xd82\xe4\x9cg\xa0\xf8A\x9f\xfc\xaa \x15\x11\xea^\xd1Y\x8e`\xca\xc5\x96\xa8+H\x88\xc2\xe7\x9af\xbf\xa4\x0e\xeb\xb7\xce\x82\xf9\x01\xcc\x0f\xc3\xde'\xb2\xe47\xdcG\xb5zk\x17\xc8\x92\xe1{h\xf8\x9b\xd2;WzA\xaawk\xcdm\xe4$al\xc0}\xa9]\x98\xdc\xc7\x9c2\xafV\x87\xfc\x89\x1d^\xafb\xc7\x00\xf3?\xcc\x01\xe8\x9d3\xbe\x0d=0\xf8\xd5Y\xab9\x03\xa9\xc6\xcb\x08\x9e\xe77\x9c\xb2\xda{R\xfc\x132x\xa2j\x03\xc4n\x8c2\x13\x84\x98\xd8\x8a\xb0^\xe6\xa3\x93\x93\xc03\xdf\xffp\xf7\xf6\n\xee6X9\x88\x94b\x96\x00\x95@\x18\xbcg\n\x9e64\xde\x00\xdd\xe6\x19n\x91)\xa3\x87\x01zq!\x15\xdf\xc2\x16\xd5\x86'\xa1\x85%]3\xa2\n\x81:\xe4\xfa\xb9\xa0\x02\x13\xed\x9c\xd6|\xcds\xc1\x15o\xaadX|\x7f/P\xec\xca\x80\xec\xb6\x8c\xa5\xf4\x16\xf4\x11\xa9b+\xf3\x9aL`\xa9\xff\xd5\xcc\xb8l\xc6p\xd5\xd0\xe1\xaa\xe5\xff\xc0C\x82))2\xe5\x0f\xe7\x18\x14\x0c?\xe7\xe6\xa0\x00\n\xc1\xc5~\xe5\xda\x9c\x99\x82:C\xdf\x17\xd29\x15Q\x9b~\xdf\x04\x1dv\xafQt~\xad\xcc\x16e\xea\xabW\xad_\xb7(%Y{I:yHP\x11\x9a\xfdNBQ=\xfd\xbe\x10Y\xd8\x9c\x05\x0f\xf5\xd0#\xfd\x1a>\xde~{)\xb0\x0c'L\x00i\xe2\x8b\x82\xd1\x9f\x0b\xccv@\x13d\xea`\xe5\x8d\xa6\x06\xe23\xe3\xcfPP\x92\xd1\x7f`\xe0\x90\x99s\x14s\x1d\xc6\xa5)\x8a\xea\xa5Ep\xb7\xa1\xb2\xdc\x1bl\x0b\xa9 \xe6L\x11\xca\x80\xf8-o\x86D*\xffZ\x9c!\x9c^\x9eB\xbc!\x82\xc4\nEd\x8cJF\xa4\x02\x89km:*\xa7\xf5\xf1\xf6\xdb3 \xfa\xc2\xe6\xa5f\x98\x12\x98\x0b\x94\xc8\x02\xabjri\x91e;\xf8\xb9 \x99\x96`\xd2\x08\xd0\x8d$\xcf\x89\x04\xca\xfcD\x1e4+\x97k\xce\xd7\x19FFf\xab\"\x8d\xbe.\xec]\xef\xe1\x99\xdd\x89!+7\xbc\xc8\x12X\xa1&\xe8\xa3G &\x8c3\x1a\x93\xcc\x9c!\xff\xca\xe7\x18\xad\xa3\x0b-\xdaD\xbf\x8a\xd3\xe8T[-\xc6\x15\x908\xc6\\a\xf2,d\xbd\xdf3\xc8\xb5\xb0i\x8c\x17\xa0\x90l%\x14\xb2 Z\x1c\xb9\xc0\x98os\x9aiN\x15\xb7\xc1\x02eD\xf8\x9c3\x98\x0b\xaf\x96W\x19\xfc\xaa\x0d\xee\xfcK[S\x07T\xe9\xb8\xb0\xd0\xd6\x96\x995\xb4\"\xe1g\xf3\xaa_\xb3]\x04\x7f\xe5O\xf8\x88\xe2B\x0b\xc2K\xec\xe3\xed\xb7\xb2\xf43\x9a\x94v0\xdeg\x8d\x05Ex\xd8(\x95?\\\xd8?\xe5\xc3\x05p\x01\x8c\x97\xbf^\x18m\x8c \x03nN\xa7\x96\x88\x9f *(r\xedhwyh]\x14\x8f(\xach\xb6$\x97V\xb5\x0c\xe7\x8aW'\xcb\xbamjr\x14@\xda~\xe50R\x9ee\xfcI^\x05\xde\xed\xbf\xc3\xfb\xf4\xb0#\xad\x16\xb9\xe0\x8f4\xc1d\xbfi\xe3\xa4\xa5,\xb6\x98D!B\xaf\x19\xfc\xf5\xee\xee\x06\xbey{\x07\x9cUG\xd0\x9e\xb1\x9d\xf1\xf6\xc4;\xfb\xc7\xf6\xb1\xb8\xdb\xe5\xf8\xd3\x8f?y'\x00<\x92\xac0\xfa`\xf5\xadt#\xe6\x0d\xe5\x82'E\x8c:\xb40.\xcc\x1dv\x82\xe5:\xcf3\x1a\x93R\x96\x02\xb5~\xf2'L\xb4\xb8c\x12k\xdb\xc2\xf9\xa7\"\xd7n\xb6\xc8\x94\x84\x15\x91\x81\xdb\x8d\xddx\x80\xed\x8f\xb7\xdf\x1a\x1e7\xe4\xd1\xa8\xe0\xb6v\x86\x12{\x88H\xb5%\xfd\xf7GNu\xf8\xe5W,(\x194\xe6C`\xca\x05^T\x044]\xa2\xe8\x8afT\xed\x80!&F\x8dV\x08\xc6\xe4\x89\xc7\xe0=\x8d3mf\xd9\x1a\xcd$sf#8\xff(\xb1J\x8ai)i\xf5\xd46\xcb\xea'ad\x1d\xda\xfdJ \xf9\xa4mPI8z\xe6\xd7\xa8\xef\xb9\xc2+P\xda\x87\xa4\x05\x8b\xed \xd3\xfb(mW\\\x08\x81Le; \x8f\x84fd\x95\x05\xcd\xa5\xd6G\x9e\xa64\xa6$\xeb\xf1e\xab\"\x05\x81\xda\x13\xe1\x85 \x7f\xa9\xaa\x16-$&6\xba\xab\xce\xa5\x97\xd4\n\xd7\x941\xbdY\x1dU\x07\x9c\xcb.\xc7\xc8\xea?\xc9\xa9\x8cb\xbe\x0dY\xe3\x0f\xe6\xa4J\xe0jc\x0d\x05k[)8/\xa3O\xdc\xe6jW\x1e\xedg~'H\xd7\x1b\x05\xab\x80Q2\x9b6W\x83}|n\xaf\x06\xe5\xad1\x06\x89[\xc2\x14\x8d\xa5\xfb\xa8\x99\xb3:!\x04\xaaB\xc4\xd5\xce\x9b\x13\x18\x1a%}\xa7\xcd\xd1\n\x81h\xa6hR\x0bp:qL\xe9\xdc\xc9\x8a?\x062\x11\xe5\xc5\xd9\x1e\x05\xd7\xf6\x87p\xf6\xf0\x9a\xed\x1e\xaa\xf0\xc8\xdc\x89\x88XQ%\xf4!\xf6s\xe8$U\xf9\x08\x92\xf1R\xf5\x80\xb8_\xad\xb6\xce\xc6\xd1X\x0eW\xcd\xb0\xb0\x15\xfe\xed\xa3:\x8fj\xdeT\x07'\xa3+\xc3v\xe9G$\xc8\"\xcf\xb90\x1e<'\xf1\xa7\xcb\x82\xe9?\xb4\xdf\xb6z\xe1>A\xa5\xa3\xf7\x076<\x85BY\xc3V\x99\x07\xa9\x0d+I\x12jm\x05\xac\x91\xa1 \xca0\xaf\xefYU\xc2\xc9IO\xf3c_\xa1{\xbd\xb7\x9f\x89V~xy\x057\x9a\x7fm\x17\xca\xad\x90\xbd\xd0)\x837\x7f\xfcc\xc0M\xbe\xe3\x1cR\xce\xe1\x1a\xa2(\xfaO\xefc\x9a\x19\xc2v\xfe\x07\x08\xdbE\x9a\x8dw\x82o\xcfS\xce\x9f\xf9\x1f\x8d\"\xbf\xff\xa3)\x9ckR\x1f\xcdF\xee\xf8\xf9\x1f4\xadg\xf0\xcf\x80\x0d\x0f\xd1\xfb\x12\x96\xdd\xab\x1e\xd9\xfd\x8d<\x92\xd9\x84\x07\xd7&6\xd4\xab\xcc !*\xcf\xdfq\x1e\xc5\x19\x91\xb2G@\x96E=\xc9\xee\xb16\xd1\xcf\x83Gr{\xd1}\xd5#\xba\x9b\x9d\xdap\x16\x10\x9e\xe5\xea\x1d\xe7\xe7Q\x14\xf9\xbd\xc1^p\xe7\xc1g\x8c\xf2\x19\xb1\x8e\x95\xaa&\xf2\xde\n\xf5\xeb\xb7\x1f\xde\xdc\xbe\xbf\xb9\xfb\xe1\xf6Y(\x05vP\xd4\xf0\xc2v\xe9\xb08\xff\xd4#\xceox \xa9\xa4Eyu\x0d\x7f\xc8W\xd1;\xce\xff\x19E\xd1\x17\xff\xc3\x84\xed.t\x18\xaag\xe46\x88\xfa\x8e\x08\xb9!\x99\x16rx#!\x11\xb6\xb9\x08\xb0@\xd3\x16\x03\x1f\xd9\xf6\xc0\x82a\xd0\x1c\x10\xf3\xd4\xbf]\x03\xa3YP\xc1\xc3|y4Y_n\x8d\x9c+[\\]4`\xb5;\x84]\x95\xf7x\xa2Y\x06+w\xd4[&\xc9tX\xe2^\xea\xcc\x11R]\xea\xfb{d~\xd0\xe1\xea\x19\x90\x9a\xb7\xd3\x9ePk\x82\xcf7X\x0dq/\xb6w-,\xdbU\xf7\xcaN\xb2`\x1f&\x03I\x95 \xdb\xdc\x0b\x99<\xc6\xd9\xe5\x99{\xa9\xd2'V,\x9b\xdb.`\xa9\xd1\xa7)\xe7\xd1\x8a\x08\xb3\xd9\xcf\x97\xbb\xe8\x1f\xa7V\x8a\xe6\xee\xe5\xa4\xe7\xbf\x8a\x1aVO5\x0d\xed\x0e\x9d\x8f\xfc\xed\xc3\x0f\xdf\xbb\x7f\xb9\xbe\xbe\xbe\xf6\xeb\x80\x9ew\xc8\xb9\xd88\x92ksP\x06A\xf6^WH\xac\xf2\xaa\xeb\"#\xc2M\xafK\xc6|\x8f\xc4C\xd8r\x01\xb8]a\x92\x1c\x02\x98\x0b\x1b\x8e\xbb\xc8\x11O\xf6\xa6\x16R\xd8\xb4\xf5\xc3\x7fk\xd1=\x94\xc9\x84}\xd8V\x7f9\xee\x03R\x9a\x9f\xab\xc0\x05\x84\xc4\x9f\xb4\x0d:\\\x88S\x9a\xa1\xdfoT6\xeb\x06\x85\xe4,xl\xcbL\\J\x85T\xf7\xe6\x0d_\xc3K?\xe5\xfd\x04\xad\x94\xd5\xf3\xaf\x8e\xf7`\x00A\xaeN\x8d,O\xaf\xe0\xd4uj\x9bb\x88\xec.O/B\xf4\xcc\xfe\xbe'[M\xf3\xbf\xec\x16\xfe\x1c\x9c\xa0\xf7\xd7z\xfe\xd8M\xbeO\xcb\x0bWS\xd7\xac6P O\x98e\xcf?1\xfed?\xa7l\x88\x04R~\xc38\xf2p5U\xfe\xc2\x06\xf0\xads`\x8dg\x8d\x1d\xad\xc0\x9e\xcb\x15\xb1*\xed^\xec\xc1\x1c\xc6J\xcf7\xc0f\x00\xdd\xa4\xec\x91q\xafcX\x88\xf6\xce\xf9\\\xdb\xb5J\x84\x9d\xd4P\x951\xfd\xe9\xc7\x9f\x9e\x05\x0e\xd2\x1c:\xd7\\0\xacvFT\x9a\xe4\xcb\xe8\xd5\xcbW\xf24\xa0B\xf6\xcf\x9c\x08\xb2E\x85\xa2\xf6\xe9\xe0\xb9-+1\xff[#@\xd9\x95\xa9P\xaa\xfb\xc3\xeak\xd6\x15\xa4$k|\xfdq^\xa8+\xca\xce2\x86_f\xa9n\xbd\xc0\x9c\xeb(\xb2n\x08\xee\xef%1Oa\x96\x91v\xa0.\xeb\xc6\xfc\xbe/\xcb:\xbc\x9cV\x91\xc2\xd6\xd4\x9d\x05J\xb5,\xa1\x93jG\xbf\xd3z\xad\xba8\xea\xc3K\nz?va\xce\xe3\xcd\xfd*\xe3\xf1\xa7\xc0\xc70\xffw@h~\x0b\xfc\x8f?\xb9i\xf4\x94\xaa\xe8\x10\xa3`\xf4\x11\x85$\x99\xe5 2dk\xb5\xd1\x96\x8a\x15\xdb\x95\xcd\xecX>}\xe6\xe3uMy\xcd\xd3e\xd5\x1e\x95\x80\x9f1.T\x95\x103\xe9\xc9\xfa\xce=\x04\xf7\xfa\xe4\xf8\xdd[;\x07\x03\xea\x1d\x82\xd5\x0e\xc1\xb7iG\xdf\x07LXJ\xdd\x96R\xb79j\xbd\x96R7\xb5\x94\xba\xfd\x86\xfb\xf8}\x94\xba\xf5h_U\x1d\xbew\x17\xe6\xf3\xf2\n\xb5\x1a\xe9\xcb\xec\x96'&\xa1`?K%\x98\xa1\xf2\xea\x9f\xda\x08^\xac\xbd\x1f\x9ejK\x98oq\xb0\xe6\x8f(\x18a1\x1a\xa7\xc0%\xc9:S\x1b\x02(C\xa6\xfa\xc1\xa8\x85MU \x943nrPsW[\xd95\x8e)\xb6*\xb9\xba\xbdy\xd3\xa2\xb7\xd4Z-\xb5V}\xb6e\xc8\xb7:Xj\xad\x96Z+\xef\x93K\xad\x95\x19K\xadUw,\xb5VK\xad\x95o,\xb5VK\xad\x95\x19K\xad\xd5Rk\xb5\xd4Z-\xb5Vv,\xb5VK\xad\xd5Rk\xb5\xd4Z\xf9\xc6Rk\xb5\xd4Z-\xb5VK\xadUm\xccQ\xf7\xb2\xd4Z\x99\xb1\xd4Z\xfd\xab\xd4Z\xb9\x8b\x85j\xa9=\xfd\xa3-\x1c\x8aVDbT\x96\x0dEo8evb\xe7\xe3D\xf7sD\xab\x1f\x84\xe3\xb2\xdd\xee\xf3\xd0y\xa4q\x81\xfd\xbf\xea\x02{d\xaf\x86CG\x06;}T\xf3\x85V\x8b\x05KiH7\x85J\x8c\xe6\xbb\xdf^\x90\x7f\xa9\xf5d\x1a \xcaf\xc9\x893mqt9I\xb3x$D\xf3\xf8\xca\x8f@uGO-G\x88\x8fF\x06\xe3\xd8\xaa\x0cW\xe5E\x8d\x9cKB\xa1\x8a\x8b\xc1|\x1eU;\xe1\xae\x8f\xa8Q\xf3VJ\xb8\xea\"\x9c<\xfak\x05&V8t\xeb\x19\xc6\xad\x7f|e\xc2\x91u\x08\xa1\x13Y}Z\x1f|2W\xb5\x83\xec\x9c\xe2\x9e\x06\xce:2o>\xf2\xe8\xc3\x0d\xce\xea\xb0>\xfa\x9d\x14\xe1\xc4\x93\xdf\xa2\xd69t\x03\xea\xba\x8efy\x92]p2\xec\x15p_E\xd6\xd1\xbcO\xb1\x15N1\x84+\xab|\xb5T^\xbe\xc3uF\x13\xed\x07xk\xa2\xa6\xf1s\xbc=\x81\xe3m\x8aY/\xdc\xb8K9j@:\xb5\x1fN\xf3\xe1\xaf\xf5p\xb6\xdc\xf2\x8a\xcb\xddV\xcb\xf3\xb8;\xf4\xb2cb\x00f\xc7|a\x98\x1d\xe3\x83\xb1\x9bZ\xf5\xf7\x00\x93\xef\xae\xecV\xceJ#w\x05w\xa9\x99\x0d\xa9\x1eY\xa9}\x988\xbe8\xbbS\x86]N\xfdeu\xd6U>\xedU\xd9\x91\xae\xcf]\x1a\xdd\xbf\x8a\xe3\x1b\xd9\xbc.\xd0\xe1\x04\x07\xb9\xc1\x91\xcc\xcf\xe9\x0c{\xdda\xbfC\x1c\xb9\x8b\x19\xdd\xe20\xc7\x18*3\x0e\xec\xa0\xaf\x0cw\x06\x07\xe9/\x1b\x9e\xce\xd78G9\xcaU\xbaM\xe0\xa8r\xdf}a\xef\x81\xce\xe0Z\xde9\xeaw\xdd.\xc5\xd5\x1bq\xb0\x83\xf9U\xccp\xfb\xe2\x12$\x12\"\x04\x01HL@)a\xbcm\x87\x00\xf4e\xd8\x8a\x9eZ\x88\xb1\xb6\xdeI\xac\xd4\x14\x0f\xb4e\x90\xcd\x87\xa9\x1b\x1ak\xff\x9d\xc4\x86CV\xfa\xfd\x00L\xdd\xd9\xac>\x01\x06\xfb\x05\xe8\x85\xa0\xf4\xec\xaa\xcf\x16\xc3\\~\x02z &\xf3\xf19\xd6o\xc0X\xdfa\xd6\x1e\xd2%\xd9e7\xed\xf0\x14\xdd\x07\xcc__\xc1}\xa0\xfbq\x8f\xa8C\xdd\x8e\x83S\xfb\xcb\xbbF_\xd4\x1c\xb4\xa6\xdc\xd7\x1c\xe4\xfc\xbd\x8a\x87\\\xe4|\x9b\x9f\xd8\x93\xb8\x86\x939\xe0c\x02\x1e\xbe\x89\xc7\x19\xec\xe0\xdbpc\xa7\xda\xb9\xd5\xcd\x0f+v_@!\x08#\xf6\xd9\xd8#/\xa3\xad\xd9\xe3o\xa4-B.\x98p'8\x82\xc0Aw\x1e\xf3%\xc6Yb\x9c%\xc6Yb\x9cc\xf8\xfcmb\x1c\xc7\x1d\x19f\xbc'\xc31we\x98\xe9\xbe\xdc\xa22\x19\xd6Zs\xd4\xed\xea\x89\xd7l7\xd8%\xab\x0eZ\xd2\xa9<\xfe\x90k,\x06\xb2uX\xdd\xa8\xc718\xc7.\x9eq\x14\x821\x80TT\xe3\xb0\x89#\xd1\x88u\xd4a\x8dZ\xbbL\xffh\xc4\xe1(\x8ca\x0bK\xd8\x14J\x03U8\x06G\xd8\xc2\x0b6\xa9\xd7\x89\x8f\xc5\n\xfa1\x81cP\x80n\xb4\xdf\x04|\xdf D\xdf0\xe4\xdeH\xac\xdeXt\x9e\x0b\x857\x0b\xeen>\xa4\xdd,\xd8\xba0\x9an\x1c~\xce\xbce\x17N\xeexd\\\x00\x01\xa7\xfa0ocQnN4\xdb\x08\xfcZ\x0b\xb1\xe6tCNT\x9a\xdf7\x8dD\x9e\x1d\x10fm\xf9\x9d\xf8\xd7\x1b\x87's`\xc7Jz{\x04\xd9D\xcc\xd8\x04\x94\x98\x0b\x116\x01\x03\xe6\xc0{\x8dExyaI\x0e\x14W\x10\xb7\xd5\x84U\x0c\xc3f5\xe7|i\xef\xe5h\xc4U\xdffB\xa8*7\xffA\xe4\xd4@\xac\xd4\xa1\xecz\x02\x1e\xca\x8b\x80rc\x9e|(\xa7\xce.\x87 \x99B\xd8\xa5:Zi$>\xa9\x07\x91t\x1c\x06\xa9\x85\xee \xe1\x8cf@\x16\xb5V\xdb\xbf\xe9Qx!\x176h\n\x1a\xa8\x85\xfc\x19\x8b\xf5\xe9\xe0z& y\x1a\xc1\xa2\x13\xa7S\x07\x0f\xd4\xb18\xd3\xd17\xe3\xf165l\xcd(4\x8d\x139\xd3\x8f\x95 \xa2c\xca\x1b[\x08\x0fS>\xe2E\xc04\xe0 M\xeaC1\x06~\\\xcb\x00$K\x0fve\xcf\xde\x04|JC\x9d&\xa0O\xdaH\x93q\xd8\x926\x8ed\x1e\xe4\xc8\xb87\x17D\x87\x84\xf0 \xda\x84\xaeE\x1eGk\xfb\xff\x0c\x1e\x89\x82)\xba\xc5\xe8\xed\xa1\xe1\xd6\x80lI\xab=\x97#Fm\xb6\xe3R\xceo\x13\xae\xf6[\x9d\xb6[\x0e\xda\x9d6[\xea\x17\xa8\x8fP\x9e\xf6Y\xcex\xdc\x8e\xbe\xefq3\xa5\x88\xec\x08\xb5\xc7\x9a']d\xc7\xf8\xa4Q\x87T\xa0\xdd\xd5\xc8T\x92\x1d\xa3\x13J\x1dJ}m\xad\x8eN.\xd911\xc5\xe4\x90\x96\xb7}\xd5\xc4tS\x87\x9e\xb7]\xd5\xc4\xd4S\x87\x9e\xaf=\xd5| );&\xa4\xa5*\x02\xb3%\xa7\xec\x18\x99\xa2\xdas3[\xa2\xca\x8eY\xd2Uv\xcc\x97\xb4\xb2c\x96\xd4\x95\x1dC\xdaA\x8dOcu\xad\xa8\xb7\xfd\xd3\x94\xe4V\x87\x98\xbb\xdd\x93#\x96pY\xa9i\x89\xaf\x0e9W[\xa7\x11\xe90;\x9cm\x9c\x02\xae8\xd0\xb6\xa9\xcfK\x8fL\x96u\x0d\x97\xb7=S\x88\x839\xd2g\x0d\x82\xae6L\x13SivLO\xa85\xc8u\x1d\xee\xc4\x14[\x83\x96r\xb4W\x1a\x9bt\xb3\xa3\xa7#\x90\xb7\x8d\xd2\x80\xf6I\xae\x1e'\xc3Rr\xfe\xf9_\xdc{?:Ig\xc7\xb0\xcd\xf7\xb7A\n\xedt@\xdb\xa3\x81)<;\xda\xfd\x13&\xa4\xf3\xec\xe8ik\x14jg\x14nc\xe4\x91\xca\x90d\x9f\x1d\xfd\xed\x8a\xbam\x8aF\xa6\xff\xec\x18\xd4\x96\xe8\xb8T\xa0\x1d\xcev?\xfd\xed\x87fH\x0e\xda\xe1\\\xbf\xa5I\xb3\xa5\x0b\xed\x981ih\xc7l\xa9C;\xe6J \xda\xe1L#\xda\xd1\xedD\xd2m\xef3=\xb1h\xc7,\xe9E;\xe6K2\xda\xd1\x9fj\xb4c@;\x9e\x01i\xc7\xc6\x83=\xedw\x1c\x1di\\\xab\x0eMj\xf5\xb5\xd9\x19\x90\x94,\x1f\x1c\xd2V\xa7\xc5\xfc\\iJ;fLV\xda1O\xca\xd2\x8ey\x12\x97vLy\xdf\x03Z\xdc\xf4\xb7\xb6\xf9r\xf2\xff\x01\x00\x00\xff\xffPK\x07\x08\x90a\xbb\x86\xec\x10\x00\x00+\x91\x00\x00PK\x01\x02\x14\x03\x14\x00\x08\x00\x08\x00\x00\x00!(\x90a\xbb\x86\xec\x10\x00\x00+\x91\x00\x00\x0c\x00 \x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x00\x00\x00\x00swagger.yamlUT\x05\x00\x01\x80Cm8PK\x05\x06\x00\x00\x00\x00\x01\x00\x01\x00C\x00\x00\x00/\x11\x00\x00\x00\x00" fs.Register(data) } diff --git a/client/docs/swagger-ui/swagger.yaml b/client/docs/swagger-ui/swagger.yaml index 72b623a..846dad1 100644 --- a/client/docs/swagger-ui/swagger.yaml +++ b/client/docs/swagger-ui/swagger.yaml @@ -329,7 +329,7 @@ paths: description: Budget defines a budget object. title: >- Budgets parameter can be added, modified, and deleted - through + through parameter change governance proposal description: Params defines the parameters for the budget module. @@ -657,7 +657,7 @@ definitions: title: end_time specifies the end time of the budget description: Budget defines a budget object. title: |- - Budgets parameter can be added, modified, and deleted through + Budgets parameter can be added, modified, and deleted through parameter change governance proposal description: Params defines the parameters for the budget module. cosmos.budget.v1beta1.QueryBudgetsResponse: @@ -765,7 +765,7 @@ definitions: title: end_time specifies the end time of the budget description: Budget defines a budget object. title: |- - Budgets parameter can be added, modified, and deleted through + Budgets parameter can be added, modified, and deleted through parameter change governance proposal description: Params defines the parameters for the budget module. description: QueryParamsResponse is the response type for the Query/Params RPC method. diff --git a/proto/tendermint/budget/v1beta1/budget.proto b/proto/tendermint/budget/v1beta1/budget.proto index 169a9a9..32c810d 100644 --- a/proto/tendermint/budget/v1beta1/budget.proto +++ b/proto/tendermint/budget/v1beta1/budget.proto @@ -17,7 +17,7 @@ message Params { // A collection of budgets is executed with this epoch_blocks parameter uint32 epoch_blocks = 1 [(gogoproto.moretags) = "yaml:\"epoch_blocks\""]; - // Budgets parameter can be added, modified, and deleted through + // Budgets parameter can be added, modified, and deleted through // parameter change governance proposal repeated Budget budgets = 2 [(gogoproto.moretags) = "yaml:\"budgets\"", (gogoproto.nullable) = false]; } diff --git a/x/budget/types/budget.pb.go b/x/budget/types/budget.pb.go index 7ee355e..a378ee2 100644 --- a/x/budget/types/budget.pb.go +++ b/x/budget/types/budget.pb.go @@ -30,13 +30,13 @@ var _ = time.Kitchen // proto package needs to be updated. const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package -// Params defines the set of params for the budget module. +// Params defines the parameters for the budget module. type Params struct { - // The universal epoch length in number of blocks, Every process for budget collecting is executed with this - // epoch_blocks frequency + // The universal epoch length in number of blocks + // A collection of budgets is executed with this epoch_blocks parameter EpochBlocks uint32 `protobuf:"varint,1,opt,name=epoch_blocks,json=epochBlocks,proto3" json:"epoch_blocks,omitempty" yaml:"epoch_blocks"` - // Budgets parameter can be added, deleted, and modified through gov.ParameterChangeProposal, and for each purpose, - // the changes in the existing budget list should be applied and set. + // Budgets parameter can be added, modified, and deleted through + // parameter change governance proposal Budgets []Budget `protobuf:"bytes,2,rep,name=budgets,proto3" json:"budgets" yaml:"budgets"` } @@ -86,7 +86,7 @@ func (m *Params) GetBudgets() []Budget { return nil } -// Budget defines the budget struct. +// Budget defines a budget object. type Budget struct { // name defines the name of the budget Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty" yaml:"name"` @@ -134,8 +134,9 @@ func (m *Budget) XXX_DiscardUnknown() { var xxx_messageInfo_Budget proto.InternalMessageInfo -// The cumulative coins collected in the budget since the bucket was created. +// TotalCollectedCoins defines total collected coins with relevant metadata. type TotalCollectedCoins struct { + // total_collected_coins specifis the total collected coins in a budget ever since the budget is created TotalCollectedCoins github_com_cosmos_cosmos_sdk_types.Coins `protobuf:"bytes,1,rep,name=total_collected_coins,json=totalCollectedCoins,proto3,castrepeated=github.com/cosmos/cosmos-sdk/types.Coins" json:"total_collected_coins" yaml:"total_collected_coins"` } diff --git a/x/budget/types/genesis.pb.go b/x/budget/types/genesis.pb.go index 346fa0d..abf8fcd 100644 --- a/x/budget/types/genesis.pb.go +++ b/x/budget/types/genesis.pb.go @@ -68,11 +68,11 @@ func (m *GenesisState) XXX_DiscardUnknown() { var xxx_messageInfo_GenesisState proto.InternalMessageInfo -// records the state of each budget after genesis export or import. +// BudgetRecord records the state of each budget after genesis import or export. type BudgetRecord struct { - // the name of the budget + // name defines the name of the budget Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty" yaml:"name"` - // the cumulative coins collected in the budget since the bucket was created. + // total_collected_coins specifis the total collected coins in a budget ever since the budget is created TotalCollectedCoins github_com_cosmos_cosmos_sdk_types.Coins `protobuf:"bytes,2,rep,name=total_collected_coins,json=totalCollectedCoins,proto3,castrepeated=github.com/cosmos/cosmos-sdk/types.Coins" json:"total_collected_coins" yaml:"total_collected_coins"` }