From 0f70ecf2d23eac36ab623246b50e1ee55c70d4b7 Mon Sep 17 00:00:00 2001 From: billy rennekamp Date: Fri, 30 Jul 2021 16:06:43 +0200 Subject: [PATCH 01/22] added upgrade module --- app/app.go | 42 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 41 insertions(+), 1 deletion(-) diff --git a/app/app.go b/app/app.go index fad13f2..29dcbaf 100644 --- a/app/app.go +++ b/app/app.go @@ -16,7 +16,9 @@ import ( "github.com/cosmos/cosmos-sdk/server/config" servertypes "github.com/cosmos/cosmos-sdk/server/types" "github.com/cosmos/cosmos-sdk/simapp" + store "github.com/cosmos/cosmos-sdk/store/types" sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/types/module" "github.com/cosmos/cosmos-sdk/version" "github.com/cosmos/cosmos-sdk/x/auth" @@ -85,6 +87,11 @@ import ( tmos "github.com/tendermint/tendermint/libs/os" tmproto "github.com/tendermint/tendermint/proto/tendermint/types" dbm "github.com/tendermint/tm-db" + + "github.com/cosmos/cosmos-sdk/x/upgrade" + upgradeclient "github.com/cosmos/cosmos-sdk/x/upgrade/client" + upgradekeeper "github.com/cosmos/cosmos-sdk/x/upgrade/keeper" + upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types" ) const Name = "pooltoy" @@ -98,6 +105,8 @@ func getGovProposalHandlers() []govclient.ProposalHandler { govProposalHandlers = append(govProposalHandlers, paramsclient.ProposalHandler, distrclient.ProposalHandler, + upgradeclient.ProposalHandler, + upgradeclient.CancelProposalHandler, // this line is used by starport scaffolding # stargate/app/govProposalHandler ) @@ -124,6 +133,7 @@ var ( crisis.AppModuleBasic{}, slashing.AppModuleBasic{}, ibc.AppModuleBasic{}, + upgrade.AppModuleBasic{}, evidence.AppModuleBasic{}, transfer.AppModuleBasic{}, pooltoy.AppModuleBasic{}, @@ -189,6 +199,7 @@ type App struct { DistrKeeper distrkeeper.Keeper GovKeeper govkeeper.Keeper CrisisKeeper crisiskeeper.Keeper + UpgradeKeeper upgradekeeper.Keeper ParamsKeeper paramskeeper.Keeper IBCKeeper *ibckeeper.Keeper // IBC Keeper must be a pointer in the app, so we can SetRouter on it correctly EvidenceKeeper evidencekeeper.Keeper @@ -229,7 +240,7 @@ func New( keys := sdk.NewKVStoreKeys( authtypes.StoreKey, banktypes.StoreKey, stakingtypes.StoreKey, minttypes.StoreKey, distrtypes.StoreKey, slashingtypes.StoreKey, - govtypes.StoreKey, paramstypes.StoreKey, ibchost.StoreKey, + govtypes.StoreKey, paramstypes.StoreKey, ibchost.StoreKey, upgradetypes.StoreKey, evidencetypes.StoreKey, ibctransfertypes.StoreKey, capabilitytypes.StoreKey, pooltoytypes.StoreKey, faucettypes.StoreKey, @@ -285,6 +296,9 @@ func New( app.CrisisKeeper = crisiskeeper.NewKeeper( app.GetSubspace(crisistypes.ModuleName), invCheckPeriod, app.BankKeeper, authtypes.FeeCollectorName, ) + + app.UpgradeKeeper = upgradekeeper.NewKeeper(skipUpgradeHeights, keys[upgradetypes.StoreKey], appCodec, homePath) + // register the staking hooks // NOTE: stakingKeeper above is passed by reference, so that it will contain these hooks app.StakingKeeper = *stakingKeeper.SetHooks( @@ -303,6 +317,7 @@ func New( govRouter.AddRoute(govtypes.RouterKey, govtypes.ProposalHandler). AddRoute(paramproposal.RouterKey, params.NewParamChangeProposalHandler(app.ParamsKeeper)). AddRoute(distrtypes.RouterKey, distr.NewCommunityPoolSpendProposalHandler(app.DistrKeeper)). + AddRoute(upgradetypes.RouterKey, upgrade.NewSoftwareUpgradeProposalHandler(app.UpgradeKeeper)). AddRoute(ibchost.RouterKey, ibcclient.NewClientUpdateProposalHandler(app.IBCKeeper.ClientKeeper)) // Create Transfer Keepers @@ -371,6 +386,7 @@ func New( slashing.NewAppModule(appCodec, app.SlashingKeeper, app.AccountKeeper, app.BankKeeper, app.StakingKeeper), distr.NewAppModule(appCodec, app.DistrKeeper, app.AccountKeeper, app.BankKeeper, app.StakingKeeper), staking.NewAppModule(appCodec, app.StakingKeeper, app.AccountKeeper, app.BankKeeper), + upgrade.NewAppModule(app.UpgradeKeeper), evidence.NewAppModule(app.EvidenceKeeper), ibc.NewAppModule(app.IBCKeeper), params.NewAppModule(app.ParamsKeeper), @@ -391,6 +407,7 @@ func New( // CanWithdrawInvariant invariant. // NOTE: staking module is required if HistoricalEntries param > 0 app.mm.SetOrderBeginBlockers( + upgradetypes.ModuleName, distrtypes.ModuleName, slashingtypes.ModuleName, evidencetypes.ModuleName, stakingtypes.ModuleName, minttypes.ModuleName, ibchost.ModuleName, ) @@ -457,6 +474,29 @@ func New( ), ) app.SetEndBlocker(app.EndBlocker) + app.UpgradeKeeper.SetUpgradeHandler("pooltoy-upgrade-0", + func(ctx sdk.Context, plan upgradetypes.Plan) { + // a place to run genesis initialization logic for new modules that were just added as part of the upgrade... + + // var genState liquiditytypes.GenesisState + // genState.Params = liquiditytypes.DefaultParams() + // genState.Params.PoolCreationFee = sdk.NewCoins(sdk.NewCoin("uatom", sdk.NewInt(40000000))) + // app.LiquidityKeeper.InitGenesis(ctx, genState) + }) + + upgradeInfo, err := app.UpgradeKeeper.ReadUpgradeInfoFromDisk() + if err != nil { + panic(err) + } + + if upgradeInfo.Name == "pooltoy-upgrade-0" && !app.UpgradeKeeper.IsSkipHeight(upgradeInfo.Height) { + storeUpgrades := store.StoreUpgrades{ + // Added: []string{liquiditytypes.ModuleName}, + } + + // configure store loader that checks if version == upgradeHeight and applies store upgrades + app.SetStoreLoader(upgradetypes.UpgradeStoreLoader(upgradeInfo.Height, &storeUpgrades)) + } if loadLatest { if err := app.LoadLatestVersion(); err != nil { From 41a383ce59613cc465cd9017eb3aa55a69fc36d0 Mon Sep 17 00:00:00 2001 From: yaruwang Date: Thu, 15 Jul 2021 18:57:09 +0200 Subject: [PATCH 02/22] pause --- .idea/.gitignore | 8 + .idea/encodings.xml | 6 + .idea/inspectionProfiles/Project_Default.xml | 7 + .idea/misc.xml | 94 +++++ .idea/modules.xml | 8 + .idea/pooltoy.iml | 10 + .idea/vcs.xml | 6 + app/app.go | 4 +- proto/pooltoy/query.proto | 9 + x/faucet/types/query.pb.gw.go | 7 +- x/pooltoy/client/cli/query.go | 26 ++ x/pooltoy/keeper/keeper.go | 3 +- x/pooltoy/keeper/query_server.go | 38 ++ x/pooltoy/types/query.pb.go | 404 ++++++++++++++++++- x/pooltoy/types/query.pb.gw.go | 7 +- 15 files changed, 612 insertions(+), 25 deletions(-) create mode 100644 .idea/.gitignore create mode 100644 .idea/encodings.xml create mode 100644 .idea/inspectionProfiles/Project_Default.xml create mode 100644 .idea/misc.xml create mode 100644 .idea/modules.xml create mode 100644 .idea/pooltoy.iml create mode 100644 .idea/vcs.xml diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..73f69e0 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,8 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml +# Editor-based HTTP Client requests +/httpRequests/ diff --git a/.idea/encodings.xml b/.idea/encodings.xml new file mode 100644 index 0000000..ada92a5 --- /dev/null +++ b/.idea/encodings.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml new file mode 100644 index 0000000..4aea665 --- /dev/null +++ b/.idea/inspectionProfiles/Project_Default.xml @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..80c5509 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,94 @@ + + + + IDE + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..7a38906 --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/pooltoy.iml b/.idea/pooltoy.iml new file mode 100644 index 0000000..25ed3f6 --- /dev/null +++ b/.idea/pooltoy.iml @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..35eb1dd --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/app/app.go b/app/app.go index 29dcbaf..a87787a 100644 --- a/app/app.go +++ b/app/app.go @@ -194,8 +194,8 @@ type App struct { BankKeeper bankkeeper.Keeper CapabilityKeeper *capabilitykeeper.Keeper StakingKeeper stakingkeeper.Keeper - SlashingKeeper slashingkeeper.Keeper - MintKeeper mintkeeper.Keeper + SlashingKeeper slashingkeeper.Keeper // todo check if needed + MintKeeper mintkeeper.Keeper // todo check if needed DistrKeeper distrkeeper.Keeper GovKeeper govkeeper.Keeper CrisisKeeper crisiskeeper.Keeper diff --git a/proto/pooltoy/query.proto b/proto/pooltoy/query.proto index af3606b..341eafa 100644 --- a/proto/pooltoy/query.proto +++ b/proto/pooltoy/query.proto @@ -14,6 +14,7 @@ service Query { rpc QueryListUsers(QueryListUsersRequest) returns (QueryListUsersResponse) { option (google.api.http).get = "/pooltoy/user"; } + rpc QueryMostEmojiOwner(QueryMostEmojiOwnerRequest) returns (QueryMostEmojiOwnerResponse){} } message QueryListUsersRequest { @@ -22,3 +23,11 @@ message QueryListUsersRequest { message QueryListUsersResponse { repeated User users = 1; } + +message QueryMostEmojiOwnerRequest { +} + +message QueryMostEmojiOwnerResponse { + string address = 1; + int64 total = 2; +} diff --git a/x/faucet/types/query.pb.gw.go b/x/faucet/types/query.pb.gw.go index 039b0ea..a32ff48 100644 --- a/x/faucet/types/query.pb.gw.go +++ b/x/faucet/types/query.pb.gw.go @@ -20,6 +20,7 @@ import ( "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/grpclog" + "google.golang.org/grpc/metadata" "google.golang.org/grpc/status" ) @@ -30,6 +31,7 @@ var _ status.Status var _ = runtime.String var _ = utilities.NewDoubleArray var _ = descriptor.ForMessage +var _ = metadata.Join func request_Query_QueryWhenBrr_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { var protoReq QueryWhenBrrRequest @@ -88,12 +90,14 @@ func local_request_Query_QueryWhenBrr_0(ctx context.Context, marshaler runtime.M // RegisterQueryHandlerServer registers the http handlers for service Query to "mux". // UnaryRPC :call QueryServer directly. // StreamingRPC :currently unsupported pending https://github.com/grpc/grpc-go/issues/906. -// Note that using this registration option will cause many gRPC library features (such as grpc.SendHeader, etc) to stop working. Consider using RegisterQueryHandlerFromEndpoint instead. +// Note that using this registration option will cause many gRPC library features to stop working. Consider using RegisterQueryHandlerFromEndpoint instead. func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, server QueryServer) error { mux.Handle("GET", pattern_Query_QueryWhenBrr_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req) if err != nil { @@ -101,6 +105,7 @@ func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv return } resp, md, err := local_request_Query_QueryWhenBrr_0(rctx, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) ctx = runtime.NewServerMetadataContext(ctx, md) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) diff --git a/x/pooltoy/client/cli/query.go b/x/pooltoy/client/cli/query.go index de5cb29..df2f87f 100644 --- a/x/pooltoy/client/cli/query.go +++ b/x/pooltoy/client/cli/query.go @@ -22,6 +22,7 @@ func GetQueryCmd() *cobra.Command { } pooltoyQueryCmd.AddCommand(queryListUsers()) + pooltoyQueryCmd.AddCommand(queryMostEmojiOwner()) return pooltoyQueryCmd } @@ -50,3 +51,28 @@ func queryListUsers() *cobra.Command { flags.AddQueryFlagsToCmd(cmd) return cmd } + +func queryMostEmojiOwner() *cobra.Command { + cmd := &cobra.Command{ + Use: "mostemoji", + Short: "who has the most emoji", + Args: cobra.NoArgs, + RunE: func(cmd *cobra.Command, args []string) error { + ctx, err := client.GetClientTxContext(cmd) + if err != nil { + return err + } + + queryClient := types.NewQueryClient(ctx) + req := &types.QueryMostEmojiOwnerRequest{} + res, err := queryClient.QueryMostEmojiOwner(context.Background(), req) + if err != nil { + return err + } + + return ctx.PrintProto(res) + }, + } + flags.AddQueryFlagsToCmd(cmd) + return cmd +} diff --git a/x/pooltoy/keeper/keeper.go b/x/pooltoy/keeper/keeper.go index 9187ef4..55fb8e5 100644 --- a/x/pooltoy/keeper/keeper.go +++ b/x/pooltoy/keeper/keeper.go @@ -2,11 +2,11 @@ package keeper import ( "fmt" - "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" authkeeper "github.com/cosmos/cosmos-sdk/x/auth/keeper" authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" + bankkeeper "github.com/cosmos/cosmos-sdk/x/bank/keeper" "github.com/interchainberlin/pooltoy/x/pooltoy/types" "github.com/tendermint/tendermint/libs/log" ) @@ -18,6 +18,7 @@ type Keeper struct { cdc codec.BinaryMarshaler storeKey sdk.StoreKey AccountKeeper authkeeper.AccountKeeper + BankKeeper bankkeeper.BaseKeeper } // NewKeeper creates a pooltoy keeper diff --git a/x/pooltoy/keeper/query_server.go b/x/pooltoy/keeper/query_server.go index 4c45dc8..9127e16 100644 --- a/x/pooltoy/keeper/query_server.go +++ b/x/pooltoy/keeper/query_server.go @@ -2,6 +2,8 @@ package keeper import ( "context" + _ "github.com/cosmos/cosmos-sdk/x/bank/keeper" + banktype "github.com/cosmos/cosmos-sdk/x/bank/types" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/interchainberlin/pooltoy/x/pooltoy/types" @@ -27,3 +29,39 @@ func (k Keeper) QueryListUsers(c context.Context, req *types.QueryListUsersReque Users: users, }, nil } + +func (k Keeper) QueryMostEmojiOwner(c context.Context, req *types.QueryMostEmojiOwnerRequest) (*types.QueryMostEmojiOwnerResponse, error) { + var mostMojiAdrr string + var allBalance int64 + var maxAllBalance = int64(0) + var allBalanceReq *banktype.QueryAllBalancesRequest + //if req != nil { + // return nil, status.Error(codes.InvalidArgument, "non-empty request") + //} + ctx := sdk.UnwrapSDKContext(c) + users := k.ListUsers(ctx) + if len(users) == 0{ + return nil, status.Error(codes.InvalidArgument, "no users") + } + for _, u := range users { + addr, err := sdk.AccAddressFromBech32(u.UserAccount) + if err!= nil{ + return nil, status.Error(codes.InvalidArgument, err.Error()) + } + allBalanceReq = &banktype.QueryAllBalancesRequest{Address:addr.String()} + allBalanceResp, err := k.BankKeeper.AllBalances(c, allBalanceReq) + if allBalanceResp == nil{ + continue + } + for _, emoji := range allBalanceResp.GetBalances(){ + allBalance += emoji.Amount.Int64() + } + + if maxAllBalance < allBalance{ + maxAllBalance = allBalance + mostMojiAdrr = addr.String() + } + } + + return &types.QueryMostEmojiOwnerResponse{Address: mostMojiAdrr, Total: maxAllBalance}, nil +} diff --git a/x/pooltoy/types/query.pb.go b/x/pooltoy/types/query.pb.go index a3b63d3..ef16b19 100644 --- a/x/pooltoy/types/query.pb.go +++ b/x/pooltoy/types/query.pb.go @@ -111,34 +111,128 @@ func (m *QueryListUsersResponse) GetUsers() []*User { return nil } +type QueryMostEmojiOwnerRequest struct { +} + +func (m *QueryMostEmojiOwnerRequest) Reset() { *m = QueryMostEmojiOwnerRequest{} } +func (m *QueryMostEmojiOwnerRequest) String() string { return proto.CompactTextString(m) } +func (*QueryMostEmojiOwnerRequest) ProtoMessage() {} +func (*QueryMostEmojiOwnerRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_ad30f92fb5fc18db, []int{2} +} +func (m *QueryMostEmojiOwnerRequest) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryMostEmojiOwnerRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryMostEmojiOwnerRequest.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 *QueryMostEmojiOwnerRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryMostEmojiOwnerRequest.Merge(m, src) +} +func (m *QueryMostEmojiOwnerRequest) XXX_Size() int { + return m.Size() +} +func (m *QueryMostEmojiOwnerRequest) XXX_DiscardUnknown() { + xxx_messageInfo_QueryMostEmojiOwnerRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryMostEmojiOwnerRequest proto.InternalMessageInfo + +type QueryMostEmojiOwnerResponse struct { + Address string `protobuf:"bytes,1,opt,name=address,proto3" json:"address,omitempty"` + Total int64 `protobuf:"varint,2,opt,name=total,proto3" json:"total,omitempty"` +} + +func (m *QueryMostEmojiOwnerResponse) Reset() { *m = QueryMostEmojiOwnerResponse{} } +func (m *QueryMostEmojiOwnerResponse) String() string { return proto.CompactTextString(m) } +func (*QueryMostEmojiOwnerResponse) ProtoMessage() {} +func (*QueryMostEmojiOwnerResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_ad30f92fb5fc18db, []int{3} +} +func (m *QueryMostEmojiOwnerResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryMostEmojiOwnerResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryMostEmojiOwnerResponse.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 *QueryMostEmojiOwnerResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryMostEmojiOwnerResponse.Merge(m, src) +} +func (m *QueryMostEmojiOwnerResponse) XXX_Size() int { + return m.Size() +} +func (m *QueryMostEmojiOwnerResponse) XXX_DiscardUnknown() { + xxx_messageInfo_QueryMostEmojiOwnerResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryMostEmojiOwnerResponse proto.InternalMessageInfo + +func (m *QueryMostEmojiOwnerResponse) GetAddress() string { + if m != nil { + return m.Address + } + return "" +} + +func (m *QueryMostEmojiOwnerResponse) GetTotal() int64 { + if m != nil { + return m.Total + } + return 0 +} + func init() { proto.RegisterType((*QueryListUsersRequest)(nil), "pooltoy.QueryListUsersRequest") proto.RegisterType((*QueryListUsersResponse)(nil), "pooltoy.QueryListUsersResponse") + proto.RegisterType((*QueryMostEmojiOwnerRequest)(nil), "pooltoy.QueryMostEmojiOwnerRequest") + proto.RegisterType((*QueryMostEmojiOwnerResponse)(nil), "pooltoy.QueryMostEmojiOwnerResponse") } func init() { proto.RegisterFile("pooltoy/query.proto", fileDescriptor_ad30f92fb5fc18db) } var fileDescriptor_ad30f92fb5fc18db = []byte{ - // 291 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x74, 0x50, 0xbd, 0x4a, 0xf4, 0x40, - 0x14, 0x4d, 0xbe, 0x8f, 0x55, 0x18, 0x59, 0x85, 0xd1, 0x55, 0x37, 0xc8, 0x28, 0xb1, 0xb1, 0xca, - 0xc0, 0x6e, 0x6d, 0x63, 0xad, 0x85, 0x0b, 0x36, 0x36, 0x92, 0x84, 0x31, 0x19, 0xc8, 0xce, 0x4d, - 0xe6, 0x4e, 0xc0, 0xb4, 0x3e, 0x81, 0xe0, 0x4b, 0x59, 0x2e, 0xd8, 0x58, 0x4a, 0xe2, 0x83, 0x48, - 0x32, 0xd9, 0xa0, 0xa2, 0xdd, 0xbd, 0xe7, 0xdc, 0xf3, 0x33, 0x43, 0x76, 0x73, 0x80, 0xcc, 0x40, - 0xc5, 0x8b, 0x52, 0xe8, 0x2a, 0xc8, 0x35, 0x18, 0xa0, 0x9b, 0x3d, 0xe8, 0x4d, 0x63, 0xc0, 0x25, - 0xe0, 0x5d, 0x07, 0x73, 0xbb, 0xd8, 0x1b, 0xef, 0x28, 0x01, 0x48, 0x32, 0xc1, 0xc3, 0x5c, 0xf2, - 0x50, 0x29, 0x30, 0xa1, 0x91, 0xa0, 0xd6, 0xec, 0x5e, 0x02, 0x09, 0x58, 0x55, 0x3b, 0xf5, 0xe8, - 0xb4, 0xd7, 0x74, 0x5b, 0x54, 0xde, 0xf3, 0x50, 0xf5, 0x91, 0x1e, 0x5d, 0xf7, 0x28, 0x51, 0x68, - 0x8b, 0xf9, 0x07, 0x64, 0x72, 0xdd, 0xb6, 0xba, 0x94, 0x68, 0x6e, 0x50, 0x68, 0x5c, 0x88, 0xa2, - 0x14, 0x68, 0xfc, 0x73, 0xb2, 0xff, 0x93, 0xc0, 0x1c, 0x14, 0x0a, 0x7a, 0x4a, 0x46, 0xad, 0x01, - 0x1e, 0xba, 0x27, 0xff, 0xcf, 0xb6, 0x66, 0xe3, 0xa0, 0xb7, 0x0d, 0xda, 0xb3, 0x85, 0xe5, 0x66, - 0x05, 0x19, 0x75, 0x72, 0x9a, 0x92, 0xed, 0xef, 0x3e, 0x94, 0x0d, 0x82, 0x5f, 0x93, 0xbd, 0xe3, - 0x3f, 0x79, 0x5b, 0xc0, 0x9f, 0x3c, 0xbe, 0x7e, 0x3c, 0xff, 0xdb, 0xa1, 0x63, 0xfe, 0xf5, 0x41, - 0x17, 0x57, 0x2f, 0x35, 0x73, 0x57, 0x35, 0x73, 0xdf, 0x6b, 0xe6, 0x3e, 0x35, 0xcc, 0x59, 0x35, - 0xcc, 0x79, 0x6b, 0x98, 0x73, 0x3b, 0x4f, 0xa4, 0x49, 0xcb, 0x28, 0x88, 0x61, 0xc9, 0xa5, 0x32, - 0x42, 0xc7, 0x69, 0x28, 0x55, 0x24, 0x74, 0x26, 0xd5, 0xe0, 0xf1, 0x30, 0x4c, 0xa6, 0xca, 0x05, - 0x46, 0x1b, 0xdd, 0x07, 0xcd, 0x3f, 0x03, 0x00, 0x00, 0xff, 0xff, 0x68, 0x49, 0x3e, 0x5e, 0xbe, - 0x01, 0x00, 0x00, + // 368 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x7c, 0x51, 0x41, 0x4b, 0xf3, 0x40, + 0x14, 0x4c, 0x5a, 0xfa, 0x95, 0x6f, 0xa5, 0x0a, 0xdb, 0x56, 0xdb, 0x58, 0x62, 0x49, 0x3d, 0xf4, + 0x94, 0x40, 0x7b, 0xf6, 0x22, 0x78, 0xb3, 0x88, 0x01, 0x2f, 0x5e, 0x24, 0x69, 0xd7, 0x74, 0x25, + 0xdd, 0x97, 0xee, 0x6e, 0xd0, 0x5e, 0xfd, 0x05, 0x82, 0x7f, 0xca, 0x63, 0x41, 0x04, 0x8f, 0xd2, + 0xfa, 0x43, 0x24, 0xc9, 0xa6, 0x58, 0x89, 0xde, 0x76, 0x66, 0xde, 0x9b, 0x99, 0x97, 0xa0, 0x7a, + 0x04, 0x10, 0x4a, 0x58, 0x38, 0xf3, 0x98, 0xf0, 0x85, 0x1d, 0x71, 0x90, 0x80, 0xab, 0x8a, 0x34, + 0xda, 0x63, 0x10, 0x33, 0x10, 0x37, 0x29, 0xed, 0x64, 0x20, 0x9b, 0x31, 0x3a, 0x01, 0x40, 0x10, + 0x12, 0xc7, 0x8b, 0xa8, 0xe3, 0x31, 0x06, 0xd2, 0x93, 0x14, 0x58, 0xae, 0x36, 0x02, 0x08, 0x20, + 0xdb, 0x4a, 0x5e, 0x8a, 0x6d, 0xab, 0x9d, 0x14, 0xf9, 0xf1, 0xad, 0xe3, 0x31, 0x15, 0x69, 0xe0, + 0xbc, 0x47, 0x2c, 0x08, 0xcf, 0x38, 0xeb, 0x00, 0x35, 0x2f, 0x93, 0x56, 0xe7, 0x54, 0xc8, 0x2b, + 0x41, 0xb8, 0x70, 0xc9, 0x3c, 0x26, 0x42, 0x5a, 0x27, 0x68, 0xff, 0xa7, 0x20, 0x22, 0x60, 0x82, + 0xe0, 0x1e, 0xaa, 0x24, 0x06, 0xa2, 0xa5, 0x77, 0xcb, 0xfd, 0x9d, 0x41, 0xcd, 0x56, 0xb6, 0x76, + 0x32, 0xe6, 0x66, 0x9a, 0xd5, 0x41, 0x46, 0xba, 0x3e, 0x02, 0x21, 0xcf, 0x66, 0x70, 0x47, 0x2f, + 0xee, 0x19, 0xe1, 0xb9, 0xf9, 0x08, 0x1d, 0x16, 0xaa, 0x2a, 0xa1, 0x85, 0xaa, 0xde, 0x64, 0xc2, + 0x89, 0x48, 0x32, 0xf4, 0xfe, 0x7f, 0x37, 0x87, 0xb8, 0x81, 0x2a, 0x12, 0xa4, 0x17, 0xb6, 0x4a, + 0x5d, 0xbd, 0x5f, 0x76, 0x33, 0x30, 0x78, 0xd3, 0x51, 0x25, 0xf5, 0xc3, 0x53, 0xb4, 0xbb, 0xdd, + 0x1a, 0x9b, 0x9b, 0x7a, 0x85, 0x77, 0x1a, 0x47, 0xbf, 0xea, 0x59, 0x19, 0xab, 0xf9, 0xf8, 0xfa, + 0xf9, 0x5c, 0xda, 0xc3, 0x35, 0xe7, 0xfb, 0xe7, 0xc3, 0x3e, 0xaa, 0x17, 0x9c, 0x80, 0x7b, 0xdb, + 0x76, 0x85, 0xe7, 0x1b, 0xc7, 0x7f, 0x0f, 0xa9, 0x60, 0xed, 0x74, 0xf4, 0xb2, 0x32, 0xf5, 0xe5, + 0xca, 0xd4, 0x3f, 0x56, 0xa6, 0xfe, 0xb4, 0x36, 0xb5, 0xe5, 0xda, 0xd4, 0xde, 0xd7, 0xa6, 0x76, + 0x3d, 0x0c, 0xa8, 0x9c, 0xc6, 0xbe, 0x3d, 0x86, 0x99, 0x43, 0x99, 0x24, 0x7c, 0x3c, 0xf5, 0x28, + 0xf3, 0x09, 0x0f, 0x29, 0xdb, 0xf4, 0x7c, 0xd8, 0xbc, 0xe4, 0x22, 0x22, 0xc2, 0xff, 0x97, 0xfe, + 0xf2, 0xe1, 0x57, 0x00, 0x00, 0x00, 0xff, 0xff, 0xab, 0xab, 0x32, 0x7e, 0x90, 0x02, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -154,6 +248,7 @@ const _ = grpc.SupportPackageIsVersion4 // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. type QueryClient interface { QueryListUsers(ctx context.Context, in *QueryListUsersRequest, opts ...grpc.CallOption) (*QueryListUsersResponse, error) + QueryMostEmojiOwner(ctx context.Context, in *QueryMostEmojiOwnerRequest, opts ...grpc.CallOption) (*QueryMostEmojiOwnerResponse, error) } type queryClient struct { @@ -173,9 +268,19 @@ func (c *queryClient) QueryListUsers(ctx context.Context, in *QueryListUsersRequ return out, nil } +func (c *queryClient) QueryMostEmojiOwner(ctx context.Context, in *QueryMostEmojiOwnerRequest, opts ...grpc.CallOption) (*QueryMostEmojiOwnerResponse, error) { + out := new(QueryMostEmojiOwnerResponse) + err := c.cc.Invoke(ctx, "/pooltoy.Query/QueryMostEmojiOwner", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + // QueryServer is the server API for Query service. type QueryServer interface { QueryListUsers(context.Context, *QueryListUsersRequest) (*QueryListUsersResponse, error) + QueryMostEmojiOwner(context.Context, *QueryMostEmojiOwnerRequest) (*QueryMostEmojiOwnerResponse, error) } // UnimplementedQueryServer can be embedded to have forward compatible implementations. @@ -185,6 +290,9 @@ type UnimplementedQueryServer struct { func (*UnimplementedQueryServer) QueryListUsers(ctx context.Context, req *QueryListUsersRequest) (*QueryListUsersResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method QueryListUsers not implemented") } +func (*UnimplementedQueryServer) QueryMostEmojiOwner(ctx context.Context, req *QueryMostEmojiOwnerRequest) (*QueryMostEmojiOwnerResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method QueryMostEmojiOwner not implemented") +} func RegisterQueryServer(s grpc1.Server, srv QueryServer) { s.RegisterService(&_Query_serviceDesc, srv) @@ -208,6 +316,24 @@ func _Query_QueryListUsers_Handler(srv interface{}, ctx context.Context, dec fun return interceptor(ctx, in, info, handler) } +func _Query_QueryMostEmojiOwner_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(QueryMostEmojiOwnerRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(QueryServer).QueryMostEmojiOwner(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/pooltoy.Query/QueryMostEmojiOwner", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(QueryServer).QueryMostEmojiOwner(ctx, req.(*QueryMostEmojiOwnerRequest)) + } + return interceptor(ctx, in, info, handler) +} + var _Query_serviceDesc = grpc.ServiceDesc{ ServiceName: "pooltoy.Query", HandlerType: (*QueryServer)(nil), @@ -216,6 +342,10 @@ var _Query_serviceDesc = grpc.ServiceDesc{ MethodName: "QueryListUsers", Handler: _Query_QueryListUsers_Handler, }, + { + MethodName: "QueryMostEmojiOwner", + Handler: _Query_QueryMostEmojiOwner_Handler, + }, }, Streams: []grpc.StreamDesc{}, Metadata: "pooltoy/query.proto", @@ -281,6 +411,64 @@ func (m *QueryListUsersResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) return len(dAtA) - i, nil } +func (m *QueryMostEmojiOwnerRequest) 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 *QueryMostEmojiOwnerRequest) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryMostEmojiOwnerRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + return len(dAtA) - i, nil +} + +func (m *QueryMostEmojiOwnerResponse) 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 *QueryMostEmojiOwnerResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryMostEmojiOwnerResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.Total != 0 { + i = encodeVarintQuery(dAtA, i, uint64(m.Total)) + i-- + dAtA[i] = 0x10 + } + if len(m.Address) > 0 { + i -= len(m.Address) + copy(dAtA[i:], m.Address) + i = encodeVarintQuery(dAtA, i, uint64(len(m.Address))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + func encodeVarintQuery(dAtA []byte, offset int, v uint64) int { offset -= sovQuery(v) base := offset @@ -316,6 +504,31 @@ func (m *QueryListUsersResponse) Size() (n int) { return n } +func (m *QueryMostEmojiOwnerRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + return n +} + +func (m *QueryMostEmojiOwnerResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Address) + if l > 0 { + n += 1 + l + sovQuery(uint64(l)) + } + if m.Total != 0 { + n += 1 + sovQuery(uint64(m.Total)) + } + return n +} + func sovQuery(x uint64) (n int) { return (math_bits.Len64(x|1) + 6) / 7 } @@ -456,6 +669,157 @@ func (m *QueryListUsersResponse) Unmarshal(dAtA []byte) error { } return nil } +func (m *QueryMostEmojiOwnerRequest) 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 ErrIntOverflowQuery + } + 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: QueryMostEmojiOwnerRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryMostEmojiOwnerRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *QueryMostEmojiOwnerResponse) 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 ErrIntOverflowQuery + } + 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: QueryMostEmojiOwnerResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryMostEmojiOwnerResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Address", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + 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 ErrInvalidLengthQuery + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Address = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Total", wireType) + } + m.Total = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Total |= int64(b&0x7F) << shift + if b < 0x80 { + break + } + } + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func skipQuery(dAtA []byte) (n int, err error) { l := len(dAtA) iNdEx := 0 diff --git a/x/pooltoy/types/query.pb.gw.go b/x/pooltoy/types/query.pb.gw.go index b326b80..6bc8446 100644 --- a/x/pooltoy/types/query.pb.gw.go +++ b/x/pooltoy/types/query.pb.gw.go @@ -20,6 +20,7 @@ import ( "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/grpclog" + "google.golang.org/grpc/metadata" "google.golang.org/grpc/status" ) @@ -30,6 +31,7 @@ var _ status.Status var _ = runtime.String var _ = utilities.NewDoubleArray var _ = descriptor.ForMessage +var _ = metadata.Join func request_Query_QueryListUsers_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { var protoReq QueryListUsersRequest @@ -52,12 +54,14 @@ func local_request_Query_QueryListUsers_0(ctx context.Context, marshaler runtime // RegisterQueryHandlerServer registers the http handlers for service Query to "mux". // UnaryRPC :call QueryServer directly. // StreamingRPC :currently unsupported pending https://github.com/grpc/grpc-go/issues/906. -// Note that using this registration option will cause many gRPC library features (such as grpc.SendHeader, etc) to stop working. Consider using RegisterQueryHandlerFromEndpoint instead. +// Note that using this registration option will cause many gRPC library features to stop working. Consider using RegisterQueryHandlerFromEndpoint instead. func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, server QueryServer) error { mux.Handle("GET", pattern_Query_QueryListUsers_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req) if err != nil { @@ -65,6 +69,7 @@ func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv return } resp, md, err := local_request_Query_QueryListUsers_0(rctx, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) ctx = runtime.NewServerMetadataContext(ctx, md) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) From 562c7d3ff51decb71216e0c6ec382772da3b94f2 Mon Sep 17 00:00:00 2001 From: yaruwang Date: Tue, 20 Jul 2021 11:54:36 +0200 Subject: [PATCH 03/22] queryEmoji rank without filter out module accounts --- accounts1.json | 52 ++++ proto/pooltoy/query.proto | 8 - scripts/init.sh | 2 +- x/faucet/keeper/query_server.go | 2 + x/pooltoy/client/cli/query.go | 26 -- x/pooltoy/keeper/query_server.go | 40 +-- x/pooltoy/types/query.pb.go | 404 ++----------------------------- 7 files changed, 79 insertions(+), 455 deletions(-) create mode 100644 accounts1.json diff --git a/accounts1.json b/accounts1.json new file mode 100644 index 0000000..554204f --- /dev/null +++ b/accounts1.json @@ -0,0 +1,52 @@ +{ + "balances": [ + { + "name": "alice", + "address": "cosmos1qd4gsa4mlnpzmv4zsf9ghdrsgkt5avs8zte65u", + "coins": [ + { + "amount": "1000", + "denom": "token" + }, + { + "amount": "100000000", + "denom": "stake" + } + ] + }, + { + "address": "cosmos1pxjvm30nf0n832sd0u02nsk8d0un0czv67t9f6", + "name": "U01JT5U5WK0", + "really": "Sean", + "coins": [ + { + "amount": "1", + "denom": "🍣" + }, + { + "amount": "1", + "denom": "🎻" + }, + { + "amount": "1", + "denom": "🛠️" + } + ] + }, + { + "address": "cosmos1zw9p9sppnxawvjqyngn9ce4hy97mu3fjp3tnm9", + "name": "U01EQ9RH73P", + "really": "Onur", + "coins": [ + { + "amount": "1", + "denom": "🆗" + }, + { + "amount": "2", + "denom": "🍍" + } + ] + } + ] +} diff --git a/proto/pooltoy/query.proto b/proto/pooltoy/query.proto index 341eafa..9bfd689 100644 --- a/proto/pooltoy/query.proto +++ b/proto/pooltoy/query.proto @@ -23,11 +23,3 @@ message QueryListUsersRequest { message QueryListUsersResponse { repeated User users = 1; } - -message QueryMostEmojiOwnerRequest { -} - -message QueryMostEmojiOwnerResponse { - string address = 1; - int64 total = 2; -} diff --git a/scripts/init.sh b/scripts/init.sh index aaf905d..2eb1c44 100755 --- a/scripts/init.sh +++ b/scripts/init.sh @@ -8,7 +8,7 @@ pooltoy config pooltoy init mynode --chain-id pooltoy-5 -jq -c '.balances[]' accounts.json | while read i; do +jq -c '.balances[]' accounts1.json | while read i; do echo "y" | pooltoy keys add $(echo "$i" | jq -r ".name") --keyring-backend test pooltoy add-genesis-account $(pooltoy keys show $(echo "$i" | jq -r ".name") --address) $(echo $i | jq -r '.coins | map(.amount+.denom) | join(",")') --keyring-backend test done diff --git a/x/faucet/keeper/query_server.go b/x/faucet/keeper/query_server.go index 508611c..b7d0ca3 100644 --- a/x/faucet/keeper/query_server.go +++ b/x/faucet/keeper/query_server.go @@ -11,6 +11,8 @@ import ( "github.com/interchainberlin/pooltoy/x/faucet/types" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" + "sort" + "time" ) var _ types.QueryServer = Keeper{} diff --git a/x/pooltoy/client/cli/query.go b/x/pooltoy/client/cli/query.go index df2f87f..de5cb29 100644 --- a/x/pooltoy/client/cli/query.go +++ b/x/pooltoy/client/cli/query.go @@ -22,7 +22,6 @@ func GetQueryCmd() *cobra.Command { } pooltoyQueryCmd.AddCommand(queryListUsers()) - pooltoyQueryCmd.AddCommand(queryMostEmojiOwner()) return pooltoyQueryCmd } @@ -51,28 +50,3 @@ func queryListUsers() *cobra.Command { flags.AddQueryFlagsToCmd(cmd) return cmd } - -func queryMostEmojiOwner() *cobra.Command { - cmd := &cobra.Command{ - Use: "mostemoji", - Short: "who has the most emoji", - Args: cobra.NoArgs, - RunE: func(cmd *cobra.Command, args []string) error { - ctx, err := client.GetClientTxContext(cmd) - if err != nil { - return err - } - - queryClient := types.NewQueryClient(ctx) - req := &types.QueryMostEmojiOwnerRequest{} - res, err := queryClient.QueryMostEmojiOwner(context.Background(), req) - if err != nil { - return err - } - - return ctx.PrintProto(res) - }, - } - flags.AddQueryFlagsToCmd(cmd) - return cmd -} diff --git a/x/pooltoy/keeper/query_server.go b/x/pooltoy/keeper/query_server.go index 9127e16..54d2acb 100644 --- a/x/pooltoy/keeper/query_server.go +++ b/x/pooltoy/keeper/query_server.go @@ -2,8 +2,6 @@ package keeper import ( "context" - _ "github.com/cosmos/cosmos-sdk/x/bank/keeper" - banktype "github.com/cosmos/cosmos-sdk/x/bank/types" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/interchainberlin/pooltoy/x/pooltoy/types" @@ -30,38 +28,8 @@ func (k Keeper) QueryListUsers(c context.Context, req *types.QueryListUsersReque }, nil } -func (k Keeper) QueryMostEmojiOwner(c context.Context, req *types.QueryMostEmojiOwnerRequest) (*types.QueryMostEmojiOwnerResponse, error) { - var mostMojiAdrr string - var allBalance int64 - var maxAllBalance = int64(0) - var allBalanceReq *banktype.QueryAllBalancesRequest - //if req != nil { - // return nil, status.Error(codes.InvalidArgument, "non-empty request") - //} - ctx := sdk.UnwrapSDKContext(c) - users := k.ListUsers(ctx) - if len(users) == 0{ - return nil, status.Error(codes.InvalidArgument, "no users") - } - for _, u := range users { - addr, err := sdk.AccAddressFromBech32(u.UserAccount) - if err!= nil{ - return nil, status.Error(codes.InvalidArgument, err.Error()) - } - allBalanceReq = &banktype.QueryAllBalancesRequest{Address:addr.String()} - allBalanceResp, err := k.BankKeeper.AllBalances(c, allBalanceReq) - if allBalanceResp == nil{ - continue - } - for _, emoji := range allBalanceResp.GetBalances(){ - allBalance += emoji.Amount.Int64() - } - - if maxAllBalance < allBalance{ - maxAllBalance = allBalance - mostMojiAdrr = addr.String() - } - } +//todo change find addr by IterateAccounts in auth +//https://github1s.com/cosmos /cosmos-sdk/blob/HEAD/x/auth/keeper/keeper.go#L35 - return &types.QueryMostEmojiOwnerResponse{Address: mostMojiAdrr, Total: maxAllBalance}, nil -} +// todo move query most emoji to faucet module +// todo return a emoji rank list diff --git a/x/pooltoy/types/query.pb.go b/x/pooltoy/types/query.pb.go index ef16b19..a3b63d3 100644 --- a/x/pooltoy/types/query.pb.go +++ b/x/pooltoy/types/query.pb.go @@ -111,128 +111,34 @@ func (m *QueryListUsersResponse) GetUsers() []*User { return nil } -type QueryMostEmojiOwnerRequest struct { -} - -func (m *QueryMostEmojiOwnerRequest) Reset() { *m = QueryMostEmojiOwnerRequest{} } -func (m *QueryMostEmojiOwnerRequest) String() string { return proto.CompactTextString(m) } -func (*QueryMostEmojiOwnerRequest) ProtoMessage() {} -func (*QueryMostEmojiOwnerRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_ad30f92fb5fc18db, []int{2} -} -func (m *QueryMostEmojiOwnerRequest) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *QueryMostEmojiOwnerRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - if deterministic { - return xxx_messageInfo_QueryMostEmojiOwnerRequest.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 *QueryMostEmojiOwnerRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_QueryMostEmojiOwnerRequest.Merge(m, src) -} -func (m *QueryMostEmojiOwnerRequest) XXX_Size() int { - return m.Size() -} -func (m *QueryMostEmojiOwnerRequest) XXX_DiscardUnknown() { - xxx_messageInfo_QueryMostEmojiOwnerRequest.DiscardUnknown(m) -} - -var xxx_messageInfo_QueryMostEmojiOwnerRequest proto.InternalMessageInfo - -type QueryMostEmojiOwnerResponse struct { - Address string `protobuf:"bytes,1,opt,name=address,proto3" json:"address,omitempty"` - Total int64 `protobuf:"varint,2,opt,name=total,proto3" json:"total,omitempty"` -} - -func (m *QueryMostEmojiOwnerResponse) Reset() { *m = QueryMostEmojiOwnerResponse{} } -func (m *QueryMostEmojiOwnerResponse) String() string { return proto.CompactTextString(m) } -func (*QueryMostEmojiOwnerResponse) ProtoMessage() {} -func (*QueryMostEmojiOwnerResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_ad30f92fb5fc18db, []int{3} -} -func (m *QueryMostEmojiOwnerResponse) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *QueryMostEmojiOwnerResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - if deterministic { - return xxx_messageInfo_QueryMostEmojiOwnerResponse.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 *QueryMostEmojiOwnerResponse) XXX_Merge(src proto.Message) { - xxx_messageInfo_QueryMostEmojiOwnerResponse.Merge(m, src) -} -func (m *QueryMostEmojiOwnerResponse) XXX_Size() int { - return m.Size() -} -func (m *QueryMostEmojiOwnerResponse) XXX_DiscardUnknown() { - xxx_messageInfo_QueryMostEmojiOwnerResponse.DiscardUnknown(m) -} - -var xxx_messageInfo_QueryMostEmojiOwnerResponse proto.InternalMessageInfo - -func (m *QueryMostEmojiOwnerResponse) GetAddress() string { - if m != nil { - return m.Address - } - return "" -} - -func (m *QueryMostEmojiOwnerResponse) GetTotal() int64 { - if m != nil { - return m.Total - } - return 0 -} - func init() { proto.RegisterType((*QueryListUsersRequest)(nil), "pooltoy.QueryListUsersRequest") proto.RegisterType((*QueryListUsersResponse)(nil), "pooltoy.QueryListUsersResponse") - proto.RegisterType((*QueryMostEmojiOwnerRequest)(nil), "pooltoy.QueryMostEmojiOwnerRequest") - proto.RegisterType((*QueryMostEmojiOwnerResponse)(nil), "pooltoy.QueryMostEmojiOwnerResponse") } func init() { proto.RegisterFile("pooltoy/query.proto", fileDescriptor_ad30f92fb5fc18db) } var fileDescriptor_ad30f92fb5fc18db = []byte{ - // 368 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x7c, 0x51, 0x41, 0x4b, 0xf3, 0x40, - 0x14, 0x4c, 0x5a, 0xfa, 0x95, 0x6f, 0xa5, 0x0a, 0xdb, 0x56, 0xdb, 0x58, 0x62, 0x49, 0x3d, 0xf4, - 0x94, 0x40, 0x7b, 0xf6, 0x22, 0x78, 0xb3, 0x88, 0x01, 0x2f, 0x5e, 0x24, 0x69, 0xd7, 0x74, 0x25, - 0xdd, 0x97, 0xee, 0x6e, 0xd0, 0x5e, 0xfd, 0x05, 0x82, 0x7f, 0xca, 0x63, 0x41, 0x04, 0x8f, 0xd2, - 0xfa, 0x43, 0x24, 0xc9, 0xa6, 0x58, 0x89, 0xde, 0x76, 0x66, 0xde, 0x9b, 0x99, 0x97, 0xa0, 0x7a, - 0x04, 0x10, 0x4a, 0x58, 0x38, 0xf3, 0x98, 0xf0, 0x85, 0x1d, 0x71, 0x90, 0x80, 0xab, 0x8a, 0x34, - 0xda, 0x63, 0x10, 0x33, 0x10, 0x37, 0x29, 0xed, 0x64, 0x20, 0x9b, 0x31, 0x3a, 0x01, 0x40, 0x10, - 0x12, 0xc7, 0x8b, 0xa8, 0xe3, 0x31, 0x06, 0xd2, 0x93, 0x14, 0x58, 0xae, 0x36, 0x02, 0x08, 0x20, - 0xdb, 0x4a, 0x5e, 0x8a, 0x6d, 0xab, 0x9d, 0x14, 0xf9, 0xf1, 0xad, 0xe3, 0x31, 0x15, 0x69, 0xe0, - 0xbc, 0x47, 0x2c, 0x08, 0xcf, 0x38, 0xeb, 0x00, 0x35, 0x2f, 0x93, 0x56, 0xe7, 0x54, 0xc8, 0x2b, - 0x41, 0xb8, 0x70, 0xc9, 0x3c, 0x26, 0x42, 0x5a, 0x27, 0x68, 0xff, 0xa7, 0x20, 0x22, 0x60, 0x82, - 0xe0, 0x1e, 0xaa, 0x24, 0x06, 0xa2, 0xa5, 0x77, 0xcb, 0xfd, 0x9d, 0x41, 0xcd, 0x56, 0xb6, 0x76, - 0x32, 0xe6, 0x66, 0x9a, 0xd5, 0x41, 0x46, 0xba, 0x3e, 0x02, 0x21, 0xcf, 0x66, 0x70, 0x47, 0x2f, - 0xee, 0x19, 0xe1, 0xb9, 0xf9, 0x08, 0x1d, 0x16, 0xaa, 0x2a, 0xa1, 0x85, 0xaa, 0xde, 0x64, 0xc2, - 0x89, 0x48, 0x32, 0xf4, 0xfe, 0x7f, 0x37, 0x87, 0xb8, 0x81, 0x2a, 0x12, 0xa4, 0x17, 0xb6, 0x4a, - 0x5d, 0xbd, 0x5f, 0x76, 0x33, 0x30, 0x78, 0xd3, 0x51, 0x25, 0xf5, 0xc3, 0x53, 0xb4, 0xbb, 0xdd, - 0x1a, 0x9b, 0x9b, 0x7a, 0x85, 0x77, 0x1a, 0x47, 0xbf, 0xea, 0x59, 0x19, 0xab, 0xf9, 0xf8, 0xfa, - 0xf9, 0x5c, 0xda, 0xc3, 0x35, 0xe7, 0xfb, 0xe7, 0xc3, 0x3e, 0xaa, 0x17, 0x9c, 0x80, 0x7b, 0xdb, - 0x76, 0x85, 0xe7, 0x1b, 0xc7, 0x7f, 0x0f, 0xa9, 0x60, 0xed, 0x74, 0xf4, 0xb2, 0x32, 0xf5, 0xe5, - 0xca, 0xd4, 0x3f, 0x56, 0xa6, 0xfe, 0xb4, 0x36, 0xb5, 0xe5, 0xda, 0xd4, 0xde, 0xd7, 0xa6, 0x76, - 0x3d, 0x0c, 0xa8, 0x9c, 0xc6, 0xbe, 0x3d, 0x86, 0x99, 0x43, 0x99, 0x24, 0x7c, 0x3c, 0xf5, 0x28, - 0xf3, 0x09, 0x0f, 0x29, 0xdb, 0xf4, 0x7c, 0xd8, 0xbc, 0xe4, 0x22, 0x22, 0xc2, 0xff, 0x97, 0xfe, - 0xf2, 0xe1, 0x57, 0x00, 0x00, 0x00, 0xff, 0xff, 0xab, 0xab, 0x32, 0x7e, 0x90, 0x02, 0x00, 0x00, + // 291 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x74, 0x50, 0xbd, 0x4a, 0xf4, 0x40, + 0x14, 0x4d, 0xbe, 0x8f, 0x55, 0x18, 0x59, 0x85, 0xd1, 0x55, 0x37, 0xc8, 0x28, 0xb1, 0xb1, 0xca, + 0xc0, 0x6e, 0x6d, 0x63, 0xad, 0x85, 0x0b, 0x36, 0x36, 0x92, 0x84, 0x31, 0x19, 0xc8, 0xce, 0x4d, + 0xe6, 0x4e, 0xc0, 0xb4, 0x3e, 0x81, 0xe0, 0x4b, 0x59, 0x2e, 0xd8, 0x58, 0x4a, 0xe2, 0x83, 0x48, + 0x32, 0xd9, 0xa0, 0xa2, 0xdd, 0xbd, 0xe7, 0xdc, 0xf3, 0x33, 0x43, 0x76, 0x73, 0x80, 0xcc, 0x40, + 0xc5, 0x8b, 0x52, 0xe8, 0x2a, 0xc8, 0x35, 0x18, 0xa0, 0x9b, 0x3d, 0xe8, 0x4d, 0x63, 0xc0, 0x25, + 0xe0, 0x5d, 0x07, 0x73, 0xbb, 0xd8, 0x1b, 0xef, 0x28, 0x01, 0x48, 0x32, 0xc1, 0xc3, 0x5c, 0xf2, + 0x50, 0x29, 0x30, 0xa1, 0x91, 0xa0, 0xd6, 0xec, 0x5e, 0x02, 0x09, 0x58, 0x55, 0x3b, 0xf5, 0xe8, + 0xb4, 0xd7, 0x74, 0x5b, 0x54, 0xde, 0xf3, 0x50, 0xf5, 0x91, 0x1e, 0x5d, 0xf7, 0x28, 0x51, 0x68, + 0x8b, 0xf9, 0x07, 0x64, 0x72, 0xdd, 0xb6, 0xba, 0x94, 0x68, 0x6e, 0x50, 0x68, 0x5c, 0x88, 0xa2, + 0x14, 0x68, 0xfc, 0x73, 0xb2, 0xff, 0x93, 0xc0, 0x1c, 0x14, 0x0a, 0x7a, 0x4a, 0x46, 0xad, 0x01, + 0x1e, 0xba, 0x27, 0xff, 0xcf, 0xb6, 0x66, 0xe3, 0xa0, 0xb7, 0x0d, 0xda, 0xb3, 0x85, 0xe5, 0x66, + 0x05, 0x19, 0x75, 0x72, 0x9a, 0x92, 0xed, 0xef, 0x3e, 0x94, 0x0d, 0x82, 0x5f, 0x93, 0xbd, 0xe3, + 0x3f, 0x79, 0x5b, 0xc0, 0x9f, 0x3c, 0xbe, 0x7e, 0x3c, 0xff, 0xdb, 0xa1, 0x63, 0xfe, 0xf5, 0x41, + 0x17, 0x57, 0x2f, 0x35, 0x73, 0x57, 0x35, 0x73, 0xdf, 0x6b, 0xe6, 0x3e, 0x35, 0xcc, 0x59, 0x35, + 0xcc, 0x79, 0x6b, 0x98, 0x73, 0x3b, 0x4f, 0xa4, 0x49, 0xcb, 0x28, 0x88, 0x61, 0xc9, 0xa5, 0x32, + 0x42, 0xc7, 0x69, 0x28, 0x55, 0x24, 0x74, 0x26, 0xd5, 0xe0, 0xf1, 0x30, 0x4c, 0xa6, 0xca, 0x05, + 0x46, 0x1b, 0xdd, 0x07, 0xcd, 0x3f, 0x03, 0x00, 0x00, 0xff, 0xff, 0x68, 0x49, 0x3e, 0x5e, 0xbe, + 0x01, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -248,7 +154,6 @@ const _ = grpc.SupportPackageIsVersion4 // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. type QueryClient interface { QueryListUsers(ctx context.Context, in *QueryListUsersRequest, opts ...grpc.CallOption) (*QueryListUsersResponse, error) - QueryMostEmojiOwner(ctx context.Context, in *QueryMostEmojiOwnerRequest, opts ...grpc.CallOption) (*QueryMostEmojiOwnerResponse, error) } type queryClient struct { @@ -268,19 +173,9 @@ func (c *queryClient) QueryListUsers(ctx context.Context, in *QueryListUsersRequ return out, nil } -func (c *queryClient) QueryMostEmojiOwner(ctx context.Context, in *QueryMostEmojiOwnerRequest, opts ...grpc.CallOption) (*QueryMostEmojiOwnerResponse, error) { - out := new(QueryMostEmojiOwnerResponse) - err := c.cc.Invoke(ctx, "/pooltoy.Query/QueryMostEmojiOwner", in, out, opts...) - if err != nil { - return nil, err - } - return out, nil -} - // QueryServer is the server API for Query service. type QueryServer interface { QueryListUsers(context.Context, *QueryListUsersRequest) (*QueryListUsersResponse, error) - QueryMostEmojiOwner(context.Context, *QueryMostEmojiOwnerRequest) (*QueryMostEmojiOwnerResponse, error) } // UnimplementedQueryServer can be embedded to have forward compatible implementations. @@ -290,9 +185,6 @@ type UnimplementedQueryServer struct { func (*UnimplementedQueryServer) QueryListUsers(ctx context.Context, req *QueryListUsersRequest) (*QueryListUsersResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method QueryListUsers not implemented") } -func (*UnimplementedQueryServer) QueryMostEmojiOwner(ctx context.Context, req *QueryMostEmojiOwnerRequest) (*QueryMostEmojiOwnerResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method QueryMostEmojiOwner not implemented") -} func RegisterQueryServer(s grpc1.Server, srv QueryServer) { s.RegisterService(&_Query_serviceDesc, srv) @@ -316,24 +208,6 @@ func _Query_QueryListUsers_Handler(srv interface{}, ctx context.Context, dec fun return interceptor(ctx, in, info, handler) } -func _Query_QueryMostEmojiOwner_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(QueryMostEmojiOwnerRequest) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(QueryServer).QueryMostEmojiOwner(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/pooltoy.Query/QueryMostEmojiOwner", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(QueryServer).QueryMostEmojiOwner(ctx, req.(*QueryMostEmojiOwnerRequest)) - } - return interceptor(ctx, in, info, handler) -} - var _Query_serviceDesc = grpc.ServiceDesc{ ServiceName: "pooltoy.Query", HandlerType: (*QueryServer)(nil), @@ -342,10 +216,6 @@ var _Query_serviceDesc = grpc.ServiceDesc{ MethodName: "QueryListUsers", Handler: _Query_QueryListUsers_Handler, }, - { - MethodName: "QueryMostEmojiOwner", - Handler: _Query_QueryMostEmojiOwner_Handler, - }, }, Streams: []grpc.StreamDesc{}, Metadata: "pooltoy/query.proto", @@ -411,64 +281,6 @@ func (m *QueryListUsersResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) return len(dAtA) - i, nil } -func (m *QueryMostEmojiOwnerRequest) 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 *QueryMostEmojiOwnerRequest) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *QueryMostEmojiOwnerRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - return len(dAtA) - i, nil -} - -func (m *QueryMostEmojiOwnerResponse) 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 *QueryMostEmojiOwnerResponse) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *QueryMostEmojiOwnerResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if m.Total != 0 { - i = encodeVarintQuery(dAtA, i, uint64(m.Total)) - i-- - dAtA[i] = 0x10 - } - if len(m.Address) > 0 { - i -= len(m.Address) - copy(dAtA[i:], m.Address) - i = encodeVarintQuery(dAtA, i, uint64(len(m.Address))) - i-- - dAtA[i] = 0xa - } - return len(dAtA) - i, nil -} - func encodeVarintQuery(dAtA []byte, offset int, v uint64) int { offset -= sovQuery(v) base := offset @@ -504,31 +316,6 @@ func (m *QueryListUsersResponse) Size() (n int) { return n } -func (m *QueryMostEmojiOwnerRequest) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - return n -} - -func (m *QueryMostEmojiOwnerResponse) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - l = len(m.Address) - if l > 0 { - n += 1 + l + sovQuery(uint64(l)) - } - if m.Total != 0 { - n += 1 + sovQuery(uint64(m.Total)) - } - return n -} - func sovQuery(x uint64) (n int) { return (math_bits.Len64(x|1) + 6) / 7 } @@ -669,157 +456,6 @@ func (m *QueryListUsersResponse) Unmarshal(dAtA []byte) error { } return nil } -func (m *QueryMostEmojiOwnerRequest) 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 ErrIntOverflowQuery - } - 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: QueryMostEmojiOwnerRequest: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: QueryMostEmojiOwnerRequest: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - default: - iNdEx = preIndex - skippy, err := skipQuery(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthQuery - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *QueryMostEmojiOwnerResponse) 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 ErrIntOverflowQuery - } - 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: QueryMostEmojiOwnerResponse: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: QueryMostEmojiOwnerResponse: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Address", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowQuery - } - 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 ErrInvalidLengthQuery - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthQuery - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Address = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 2: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field Total", wireType) - } - m.Total = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowQuery - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - m.Total |= int64(b&0x7F) << shift - if b < 0x80 { - break - } - } - default: - iNdEx = preIndex - skippy, err := skipQuery(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthQuery - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} func skipQuery(dAtA []byte) (n int, err error) { l := len(dAtA) iNdEx := 0 From 12c753747437184a75317d4ad64b5e1c22f1054d Mon Sep 17 00:00:00 2001 From: yaruwang Date: Tue, 20 Jul 2021 11:55:23 +0200 Subject: [PATCH 04/22] emoji rank with filter out module accounts --- x/faucet/keeper/query_server.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x/faucet/keeper/query_server.go b/x/faucet/keeper/query_server.go index b7d0ca3..e0cc97e 100644 --- a/x/faucet/keeper/query_server.go +++ b/x/faucet/keeper/query_server.go @@ -87,7 +87,7 @@ func (k Keeper) QueryEmojiRank(c context.Context, req *types.QueryEmojiRankReque amount += emoji.Amount.Int64() } } - + ranks = append(ranks, &types.Amount{Address: addr.String(), Total: amount}) } From a38db3681b46149cc3bf5acc43f08ea0ca8eba33 Mon Sep 17 00:00:00 2001 From: yaruwang Date: Tue, 20 Jul 2021 14:22:30 +0200 Subject: [PATCH 05/22] add feature queryEmojiRank --- accounts1.json | 52 --------------------------------- scripts/init.sh | 2 +- x/faucet/keeper/query_server.go | 7 ++++- 3 files changed, 7 insertions(+), 54 deletions(-) delete mode 100644 accounts1.json diff --git a/accounts1.json b/accounts1.json deleted file mode 100644 index 554204f..0000000 --- a/accounts1.json +++ /dev/null @@ -1,52 +0,0 @@ -{ - "balances": [ - { - "name": "alice", - "address": "cosmos1qd4gsa4mlnpzmv4zsf9ghdrsgkt5avs8zte65u", - "coins": [ - { - "amount": "1000", - "denom": "token" - }, - { - "amount": "100000000", - "denom": "stake" - } - ] - }, - { - "address": "cosmos1pxjvm30nf0n832sd0u02nsk8d0un0czv67t9f6", - "name": "U01JT5U5WK0", - "really": "Sean", - "coins": [ - { - "amount": "1", - "denom": "🍣" - }, - { - "amount": "1", - "denom": "🎻" - }, - { - "amount": "1", - "denom": "🛠️" - } - ] - }, - { - "address": "cosmos1zw9p9sppnxawvjqyngn9ce4hy97mu3fjp3tnm9", - "name": "U01EQ9RH73P", - "really": "Onur", - "coins": [ - { - "amount": "1", - "denom": "🆗" - }, - { - "amount": "2", - "denom": "🍍" - } - ] - } - ] -} diff --git a/scripts/init.sh b/scripts/init.sh index 2eb1c44..aaf905d 100755 --- a/scripts/init.sh +++ b/scripts/init.sh @@ -8,7 +8,7 @@ pooltoy config pooltoy init mynode --chain-id pooltoy-5 -jq -c '.balances[]' accounts1.json | while read i; do +jq -c '.balances[]' accounts.json | while read i; do echo "y" | pooltoy keys add $(echo "$i" | jq -r ".name") --keyring-backend test pooltoy add-genesis-account $(pooltoy keys show $(echo "$i" | jq -r ".name") --address) $(echo $i | jq -r '.coins | map(.amount+.denom) | join(",")') --keyring-backend test done diff --git a/x/faucet/keeper/query_server.go b/x/faucet/keeper/query_server.go index e0cc97e..eacbd77 100644 --- a/x/faucet/keeper/query_server.go +++ b/x/faucet/keeper/query_server.go @@ -2,12 +2,17 @@ package keeper import ( "context" +<<<<<<< HEAD "sort" "time" sdk "github.com/cosmos/cosmos-sdk/types" authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" "github.com/interchainberlin/pooltoy/regex" +======= + sdk "github.com/cosmos/cosmos-sdk/types" + authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" +>>>>>>> e79cb54 (add feature queryEmojiRank) "github.com/interchainberlin/pooltoy/x/faucet/types" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" @@ -87,7 +92,7 @@ func (k Keeper) QueryEmojiRank(c context.Context, req *types.QueryEmojiRankReque amount += emoji.Amount.Int64() } } - + ranks = append(ranks, &types.Amount{Address: addr.String(), Total: amount}) } From 834279111f47c4728b0f75c72fe8b14b06befb02 Mon Sep 17 00:00:00 2001 From: yaruwang Date: Wed, 21 Jul 2021 14:55:56 +0200 Subject: [PATCH 06/22] fix emoji parsing issue in mintfor cmd --- x/faucet/client/cli/tx.go | 2 + x/faucet/handler_test.go | 1 + x/faucet/keeper/keeper.go | 1 + x/faucet/keeper/query_server.go | 5 - x/faucet/types/msgs.go | 1 - x/faucet/utils/emojiCodeMap.go | 7679 ++++++++++++++++++++++++++++ x/faucet/utils/errors.go | 6 + x/faucet/utils/parse_emoji_test.go | 60 + x/faucet/utils/utils.go | 28 + 9 files changed, 7777 insertions(+), 6 deletions(-) create mode 100644 x/faucet/utils/emojiCodeMap.go create mode 100644 x/faucet/utils/errors.go create mode 100644 x/faucet/utils/parse_emoji_test.go create mode 100644 x/faucet/utils/utils.go diff --git a/x/faucet/client/cli/tx.go b/x/faucet/client/cli/tx.go index b5dc2f9..469d6ab 100644 --- a/x/faucet/client/cli/tx.go +++ b/x/faucet/client/cli/tx.go @@ -2,6 +2,7 @@ package cli import ( "fmt" + "github.com/interchainberlin/pooltoy/x/faucet/utils" "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/flags" @@ -74,6 +75,7 @@ func txMintFor() *cobra.Command { return err } msg := types.NewMsgMint(sender, minter, args[1]) + if err = msg.ValidateBasic(); err != nil { return fmt.Errorf("message validation failed: %w", err) } diff --git a/x/faucet/handler_test.go b/x/faucet/handler_test.go index 9750159..9e7bb32 100644 --- a/x/faucet/handler_test.go +++ b/x/faucet/handler_test.go @@ -2,6 +2,7 @@ package faucet import ( "fmt" + "github.com/interchainberlin/pooltoy/x/faucet/utils" "testing" sdk "github.com/cosmos/cosmos-sdk/types" diff --git a/x/faucet/keeper/keeper.go b/x/faucet/keeper/keeper.go index 80b5ac4..34dd72f 100644 --- a/x/faucet/keeper/keeper.go +++ b/x/faucet/keeper/keeper.go @@ -2,6 +2,7 @@ package keeper import ( "fmt" + "github.com/interchainberlin/pooltoy/x/faucet/utils" "time" "github.com/cosmos/cosmos-sdk/codec" diff --git a/x/faucet/keeper/query_server.go b/x/faucet/keeper/query_server.go index eacbd77..b7d0ca3 100644 --- a/x/faucet/keeper/query_server.go +++ b/x/faucet/keeper/query_server.go @@ -2,17 +2,12 @@ package keeper import ( "context" -<<<<<<< HEAD "sort" "time" sdk "github.com/cosmos/cosmos-sdk/types" authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" "github.com/interchainberlin/pooltoy/regex" -======= - sdk "github.com/cosmos/cosmos-sdk/types" - authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" ->>>>>>> e79cb54 (add feature queryEmojiRank) "github.com/interchainberlin/pooltoy/x/faucet/types" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" diff --git a/x/faucet/types/msgs.go b/x/faucet/types/msgs.go index 3cd0793..02a2186 100644 --- a/x/faucet/types/msgs.go +++ b/x/faucet/types/msgs.go @@ -2,7 +2,6 @@ package types import ( fmt "fmt" - sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" ) diff --git a/x/faucet/utils/emojiCodeMap.go b/x/faucet/utils/emojiCodeMap.go new file mode 100644 index 0000000..692dfa4 --- /dev/null +++ b/x/faucet/utils/emojiCodeMap.go @@ -0,0 +1,7679 @@ +package utils + +// NOTE: THIS FILE WAS PRODUCED BY THE +// EMOJICODEMAP CODE GENERATION TOOL (github.com/kyokomi/emoji/cmd/generateEmojiCodeMap) +// DO NOT EDIT + +// Mapping from character to concrete escape code. +var emojiCodeMap = map[string]string{ + ":+1:": "\U0001f44d", + ":-1:": "\U0001f44e", + ":100:": "\U0001f4af", + ":1234:": "\U0001f522", + ":1st_place_medal:": "\U0001f947", + ":2nd_place_medal:": "\U0001f948", + ":3rd_place_medal:": "\U0001f949", + ":8ball:": "\U0001f3b1", + ":AB_button_(blood_type):": "\U0001f18e", + ":ATM_sign:": "\U0001f3e7", + ":A_button_(blood_type):": "\U0001f170", + ":Aquarius:": "\u2652", + ":Aries:": "\u2648", + ":BACK_arrow:": "\U0001f519", + ":B_button_(blood_type):": "\U0001f171", + ":CL_button:": "\U0001f191", + ":COOL_button:": "\U0001f192", + ":Cancer:": "\u264b", + ":Capricorn:": "\u2651", + ":Christmas_tree:": "\U0001f384", + ":END_arrow:": "\U0001f51a", + ":FREE_button:": "\U0001f193", + ":Gemini:": "\u264a", + ":ID_button:": "\U0001f194", + ":Japanese_acceptable_button:": "\U0001f251", + ":Japanese_application_button:": "\U0001f238", + ":Japanese_bargain_button:": "\U0001f250", + ":Japanese_castle:": "\U0001f3ef", + ":Japanese_congratulations_button:": "\u3297", + ":Japanese_discount_button:": "\U0001f239", + ":Japanese_dolls:": "\U0001f38e", + ":Japanese_free_of_charge_button:": "\U0001f21a", + ":Japanese_here_button:": "\U0001f201", + ":Japanese_monthly_amount_button:": "\U0001f237", + ":Japanese_no_vacancy_button:": "\U0001f235", + ":Japanese_not_free_of_charge_button:": "\U0001f236", + ":Japanese_open_for_business_button:": "\U0001f23a", + ":Japanese_passing_grade_button:": "\U0001f234", + ":Japanese_post_office:": "\U0001f3e3", + ":Japanese_prohibited_button:": "\U0001f232", + ":Japanese_reserved_button:": "\U0001f22f", + ":Japanese_secret_button:": "\u3299", + ":Japanese_service_charge_button:": "\U0001f202", + ":Japanese_symbol_for_beginner:": "\U0001f530", + ":Japanese_vacancy_button:": "\U0001f233", + ":Leo:": "\u264c", + ":Libra:": "\u264e", + ":Mrs._Claus:": "\U0001f936", + ":NEW_button:": "\U0001f195", + ":NG_button:": "\U0001f196", + ":OK_button:": "\U0001f197", + ":OK_hand:": "\U0001f44c", + ":ON!_arrow:": "\U0001f51b", + ":O_button_(blood_type):": "\U0001f17e", + ":Ophiuchus:": "\u26ce", + ":P_button:": "\U0001f17f", + ":Pisces:": "\u2653", + ":SOON_arrow:": "\U0001f51c", + ":SOS_button:": "\U0001f198", + ":Sagittarius:": "\u2650", + ":Santa_Claus:": "\U0001f385", + ":Scorpio:": "\u264f", + ":Statue_of_Liberty:": "\U0001f5fd", + ":T-Rex:": "\U0001f996", + ":TOP_arrow:": "\U0001f51d", + ":Taurus:": "\u2649", + ":Tokyo_tower:": "\U0001f5fc", + ":UP!_button:": "\U0001f199", + ":VS_button:": "\U0001f19a", + ":Virgo:": "\u264d", + ":a:": "\U0001f170\ufe0f", + ":ab:": "\U0001f18e", + ":abacus:": "\U0001f9ee", + ":abc:": "\U0001f524", + ":abcd:": "\U0001f521", + ":accept:": "\U0001f251", + ":accordion:": "\U0001fa97", + ":adhesive_bandage:": "\U0001fa79", + ":admission_tickets:": "\U0001f39f\ufe0f", + ":adult:": "\U0001f9d1", + ":adult::skin-tone-1:": "\U0001f9d1\U0001f3fb", + ":adult::skin-tone-2:": "\U0001f9d1\U0001f3fc", + ":adult::skin-tone-3:": "\U0001f9d1\U0001f3fd", + ":adult::skin-tone-4:": "\U0001f9d1\U0001f3fe", + ":adult::skin-tone-5:": "\U0001f9d1\U0001f3ff", + ":aerial_tramway:": "\U0001f6a1", + ":afghanistan:": "\U0001f1e6\U0001f1eb", + ":airplane:": "\u2708\ufe0f", + ":airplane_arrival:": "\U0001f6ec", + ":airplane_arriving:": "\U0001f6ec", + ":airplane_departure:": "\U0001f6eb", + ":airplane_small:": "\U0001f6e9", + ":aland_islands:": "\U0001f1e6\U0001f1fd", + ":alarm_clock:": "\u23f0", + ":albania:": "\U0001f1e6\U0001f1f1", + ":alembic:": "\u2697\ufe0f", + ":algeria:": "\U0001f1e9\U0001f1ff", + ":alien:": "\U0001f47d", + ":alien_monster:": "\U0001f47e", + ":ambulance:": "\U0001f691", + ":american_football:": "\U0001f3c8", + ":american_samoa:": "\U0001f1e6\U0001f1f8", + ":amphora:": "\U0001f3fa", + ":anatomical_heart:": "\U0001fac0", + ":anchor:": "\u2693", + ":andorra:": "\U0001f1e6\U0001f1e9", + ":angel:": "\U0001f47c", + ":angel::skin-tone-1:": "\U0001f47c\U0001f3fb", + ":angel::skin-tone-2:": "\U0001f47c\U0001f3fc", + ":angel::skin-tone-3:": "\U0001f47c\U0001f3fd", + ":angel::skin-tone-4:": "\U0001f47c\U0001f3fe", + ":angel::skin-tone-5:": "\U0001f47c\U0001f3ff", + ":anger:": "\U0001f4a2", + ":anger_right:": "\U0001f5ef", + ":anger_symbol:": "\U0001f4a2", + ":angola:": "\U0001f1e6\U0001f1f4", + ":angry:": "\U0001f620", + ":angry_face:": "\U0001f620", + ":angry_face_with_horns:": "\U0001f47f", + ":anguilla:": "\U0001f1e6\U0001f1ee", + ":anguished:": "\U0001f627", + ":anguished_face:": "\U0001f627", + ":ant:": "\U0001f41c", + ":antarctica:": "\U0001f1e6\U0001f1f6", + ":antenna_bars:": "\U0001f4f6", + ":antigua_barbuda:": "\U0001f1e6\U0001f1ec", + ":anxious_face_with_sweat:": "\U0001f630", + ":apple:": "\U0001f34e", + ":aquarius:": "\u2652", + ":argentina:": "\U0001f1e6\U0001f1f7", + ":aries:": "\u2648", + ":armenia:": "\U0001f1e6\U0001f1f2", + ":arrow_backward:": "\u25c0\ufe0f", + ":arrow_double_down:": "\u23ec", + ":arrow_double_up:": "\u23eb", + ":arrow_down:": "\u2b07\ufe0f", + ":arrow_down_small:": "\U0001f53d", + ":arrow_forward:": "\u25b6\ufe0f", + ":arrow_heading_down:": "\u2935\ufe0f", + ":arrow_heading_up:": "\u2934\ufe0f", + ":arrow_left:": "\u2b05\ufe0f", + ":arrow_lower_left:": "\u2199\ufe0f", + ":arrow_lower_right:": "\u2198\ufe0f", + ":arrow_right:": "\u27a1\ufe0f", + ":arrow_right_hook:": "\u21aa\ufe0f", + ":arrow_up:": "\u2b06\ufe0f", + ":arrow_up_down:": "\u2195\ufe0f", + ":arrow_up_small:": "\U0001f53c", + ":arrow_upper_left:": "\u2196\ufe0f", + ":arrow_upper_right:": "\u2197\ufe0f", + ":arrows_clockwise:": "\U0001f503", + ":arrows_counterclockwise:": "\U0001f504", + ":art:": "\U0001f3a8", + ":articulated_lorry:": "\U0001f69b", + ":artificial_satellite:": "\U0001f6f0\ufe0f", + ":artist:": "\U0001f9d1\u200d\U0001f3a8", + ":artist_palette:": "\U0001f3a8", + ":aruba:": "\U0001f1e6\U0001f1fc", + ":ascension_island:": "\U0001f1e6\U0001f1e8", + ":asterisk:": "*\ufe0f\u20e3", + ":astonished:": "\U0001f632", + ":astonished_face:": "\U0001f632", + ":astronaut:": "\U0001f9d1\u200d\U0001f680", + ":athletic_shoe:": "\U0001f45f", + ":atm:": "\U0001f3e7", + ":atom:": "\u269b", + ":atom_symbol:": "\u269b\ufe0f", + ":australia:": "\U0001f1e6\U0001f1fa", + ":austria:": "\U0001f1e6\U0001f1f9", + ":auto_rickshaw:": "\U0001f6fa", + ":automobile:": "\U0001f697", + ":avocado:": "\U0001f951", + ":axe:": "\U0001fa93", + ":azerbaijan:": "\U0001f1e6\U0001f1ff", + ":b:": "\U0001f171\ufe0f", + ":baby:": "\U0001f476", + ":baby_angel:": "\U0001f47c", + ":baby_bottle:": "\U0001f37c", + ":baby_chick:": "\U0001f424", + ":baby_symbol:": "\U0001f6bc", + ":baby::skin-tone-1:": "\U0001f476\U0001f3fb", + ":baby::skin-tone-2:": "\U0001f476\U0001f3fc", + ":baby::skin-tone-3:": "\U0001f476\U0001f3fd", + ":baby::skin-tone-4:": "\U0001f476\U0001f3fe", + ":baby::skin-tone-5:": "\U0001f476\U0001f3ff", + ":back:": "\U0001f519", + ":backhand_index_pointing_down:": "\U0001f447", + ":backhand_index_pointing_left:": "\U0001f448", + ":backhand_index_pointing_right:": "\U0001f449", + ":backhand_index_pointing_up:": "\U0001f446", + ":backpack:": "\U0001f392", + ":bacon:": "\U0001f953", + ":badger:": "\U0001f9a1", + ":badminton:": "\U0001f3f8", + ":badminton_racquet_and_shuttlecock:": "\U0001f3f8", + ":bagel:": "\U0001f96f", + ":baggage_claim:": "\U0001f6c4", + ":baguette_bread:": "\U0001f956", + ":bahamas:": "\U0001f1e7\U0001f1f8", + ":bahrain:": "\U0001f1e7\U0001f1ed", + ":balance_scale:": "\u2696", + ":bald:": "\U0001f9b2", + ":bald_man:": "\U0001f468\u200d\U0001f9b2", + ":bald_person:": "\U0001f9d1\u200d\U0001f9b2", + ":bald_woman:": "\U0001f469\u200d\U0001f9b2", + ":ballet_shoes:": "\U0001fa70", + ":balloon:": "\U0001f388", + ":ballot_box:": "\U0001f5f3", + ":ballot_box_with_ballot:": "\U0001f5f3\ufe0f", + ":ballot_box_with_check:": "\u2611\ufe0f", + ":bamboo:": "\U0001f38d", + ":banana:": "\U0001f34c", + ":bangbang:": "\u203c\ufe0f", + ":bangladesh:": "\U0001f1e7\U0001f1e9", + ":banjo:": "\U0001fa95", + ":bank:": "\U0001f3e6", + ":bar_chart:": "\U0001f4ca", + ":barbados:": "\U0001f1e7\U0001f1e7", + ":barber:": "\U0001f488", + ":barber_pole:": "\U0001f488", + ":barely_sunny:": "\U0001f325\ufe0f", + ":baseball:": "\u26be", + ":basket:": "\U0001f9fa", + ":basketball:": "\U0001f3c0", + ":basketball_man:": "\u26f9\ufe0f\u200d\u2642\ufe0f", + ":basketball_woman:": "\u26f9\ufe0f\u200d\u2640\ufe0f", + ":bat:": "\U0001f987", + ":bath:": "\U0001f6c0", + ":bath::skin-tone-1:": "\U0001f6c0\U0001f3fb", + ":bath::skin-tone-2:": "\U0001f6c0\U0001f3fc", + ":bath::skin-tone-3:": "\U0001f6c0\U0001f3fd", + ":bath::skin-tone-4:": "\U0001f6c0\U0001f3fe", + ":bath::skin-tone-5:": "\U0001f6c0\U0001f3ff", + ":bathtub:": "\U0001f6c1", + ":battery:": "\U0001f50b", + ":beach:": "\U0001f3d6", + ":beach_umbrella:": "\u26f1", + ":beach_with_umbrella:": "\U0001f3d6\ufe0f", + ":beaming_face_with_smiling_eyes:": "\U0001f601", + ":bear:": "\U0001f43b", + ":bearded_person:": "\U0001f9d4", + ":bearded_person::skin-tone-1:": "\U0001f9d4\U0001f3fb", + ":bearded_person::skin-tone-2:": "\U0001f9d4\U0001f3fc", + ":bearded_person::skin-tone-3:": "\U0001f9d4\U0001f3fd", + ":bearded_person::skin-tone-4:": "\U0001f9d4\U0001f3fe", + ":bearded_person::skin-tone-5:": "\U0001f9d4\U0001f3ff", + ":beating_heart:": "\U0001f493", + ":beaver:": "\U0001f9ab", + ":bed:": "\U0001f6cf\ufe0f", + ":bee:": "\U0001f41d", + ":beer:": "\U0001f37a", + ":beer_mug:": "\U0001f37a", + ":beers:": "\U0001f37b", + ":beetle:": "\U0001f41e", + ":beginner:": "\U0001f530", + ":belarus:": "\U0001f1e7\U0001f1fe", + ":belgium:": "\U0001f1e7\U0001f1ea", + ":belize:": "\U0001f1e7\U0001f1ff", + ":bell:": "\U0001f514", + ":bell_pepper:": "\U0001fad1", + ":bell_with_slash:": "\U0001f515", + ":bellhop:": "\U0001f6ce", + ":bellhop_bell:": "\U0001f6ce\ufe0f", + ":benin:": "\U0001f1e7\U0001f1ef", + ":bento:": "\U0001f371", + ":bento_box:": "\U0001f371", + ":bermuda:": "\U0001f1e7\U0001f1f2", + ":beverage_box:": "\U0001f9c3", + ":bhutan:": "\U0001f1e7\U0001f1f9", + ":bicycle:": "\U0001f6b2", + ":bicyclist:": "\U0001f6b4\u200d\u2642\ufe0f", + ":bike:": "\U0001f6b2", + ":biking_man:": "\U0001f6b4\u200d\u2642\ufe0f", + ":biking_woman:": "\U0001f6b4\u200d\u2640\ufe0f", + ":bikini:": "\U0001f459", + ":billed_cap:": "\U0001f9e2", + ":biohazard:": "\u2623", + ":biohazard_sign:": "\u2623\ufe0f", + ":bird:": "\U0001f426", + ":birthday:": "\U0001f382", + ":birthday_cake:": "\U0001f382", + ":bison:": "\U0001f9ac", + ":black_cat:": "\U0001f408\u200d\u2b1b", + ":black_circle:": "\u26ab", + ":black_circle_for_record:": "\u23fa\ufe0f", + ":black_flag:": "\U0001f3f4", + ":black_heart:": "\U0001f5a4", + ":black_joker:": "\U0001f0cf", + ":black_large_square:": "\u2b1b", + ":black_left_pointing_double_triangle_with_vertical_bar:": "\u23ee\ufe0f", + ":black_medium-small_square:": "\u25fe", + ":black_medium_small_square:": "\u25fe", + ":black_medium_square:": "\u25fc\ufe0f", + ":black_nib:": "\u2712\ufe0f", + ":black_right_pointing_double_triangle_with_vertical_bar:": "\u23ed\ufe0f", + ":black_right_pointing_triangle_with_double_vertical_bar:": "\u23ef\ufe0f", + ":black_small_square:": "\u25aa\ufe0f", + ":black_square_button:": "\U0001f532", + ":black_square_for_stop:": "\u23f9\ufe0f", + ":blond-haired-man:": "\U0001f471\u200d\u2642\ufe0f", + ":blond-haired-woman:": "\U0001f471\u200d\u2640\ufe0f", + ":blond-haired_man:": "\U0001f471\u200d\u2642\ufe0f", + "::skin-blon-d-haired_man_tone1:": "\U0001f471\U0001f3fb\u200d\u2642\ufe0f", + "::skin-blon-d-haired_man_tone2:": "\U0001f471\U0001f3fc\u200d\u2642\ufe0f", + "::skin-blon-d-haired_man_tone3:": "\U0001f471\U0001f3fd\u200d\u2642\ufe0f", + "::skin-blon-d-haired_man_tone4:": "\U0001f471\U0001f3fe\u200d\u2642\ufe0f", + "::skin-blon-d-haired_man_tone5:": "\U0001f471\U0001f3ff\u200d\u2642\ufe0f", + ":blond-haired_woman:": "\U0001f471\u200d\u2640\ufe0f", + "::skin-blon-d-haired_woman_tone1:": "\U0001f471\U0001f3fb\u200d\u2640\ufe0f", + "::skin-blon-d-haired_woman_tone2:": "\U0001f471\U0001f3fc\u200d\u2640\ufe0f", + "::skin-blon-d-haired_woman_tone3:": "\U0001f471\U0001f3fd\u200d\u2640\ufe0f", + "::skin-blon-d-haired_woman_tone4:": "\U0001f471\U0001f3fe\u200d\u2640\ufe0f", + "::skin-blon-d-haired_woman_tone5:": "\U0001f471\U0001f3ff\u200d\u2640\ufe0f", + ":blond_haired_man:": "\U0001f471\u200d\u2642\ufe0f", + ":blond_haired_person:": "\U0001f471", + ":blond_haired_person::skin-tone-1:": "\U0001f471\U0001f3fb", + ":blond_haired_person::skin-tone-2:": "\U0001f471\U0001f3fc", + ":blond_haired_person::skin-tone-3:": "\U0001f471\U0001f3fd", + ":blond_haired_person::skin-tone-4:": "\U0001f471\U0001f3fe", + ":blond_haired_person::skin-tone-5:": "\U0001f471\U0001f3ff", + ":blond_haired_woman:": "\U0001f471\u200d\u2640\ufe0f", + ":blonde_woman:": "\U0001f471\u200d\u2640\ufe0f", + ":blossom:": "\U0001f33c", + ":blowfish:": "\U0001f421", + ":blue_book:": "\U0001f4d8", + ":blue_car:": "\U0001f699", + ":blue_circle:": "\U0001f535", + ":blue_heart:": "\U0001f499", + ":blue_square:": "\U0001f7e6", + ":blueberries:": "\U0001fad0", + ":blush:": "\U0001f60a", + ":boar:": "\U0001f417", + ":boat:": "\u26f5", + ":bolivia:": "\U0001f1e7\U0001f1f4", + ":bomb:": "\U0001f4a3", + ":bone:": "\U0001f9b4", + ":book:": "\U0001f4d6", + ":bookmark:": "\U0001f516", + ":bookmark_tabs:": "\U0001f4d1", + ":books:": "\U0001f4da", + ":boom:": "\U0001f4a5", + ":boomerang:": "\U0001fa83", + ":boot:": "\U0001f462", + ":bosnia_herzegovina:": "\U0001f1e7\U0001f1e6", + ":botswana:": "\U0001f1e7\U0001f1fc", + ":bottle_with_popping_cork:": "\U0001f37e", + ":bouncing_ball_man:": "\u26f9\ufe0f\u200d\u2642\ufe0f", + ":bouncing_ball_person:": "\u26f9\ufe0f", + ":bouncing_ball_woman:": "\u26f9\ufe0f\u200d\u2640\ufe0f", + ":bouquet:": "\U0001f490", + ":bouvet_island:": "\U0001f1e7\U0001f1fb", + ":bow:": "\U0001f647\u200d\u2642\ufe0f", + ":bow_and_arrow:": "\U0001f3f9", + ":bowing_man:": "\U0001f647\u200d\u2642\ufe0f", + ":bowing_woman:": "\U0001f647\u200d\u2640\ufe0f", + ":bowl_with_spoon:": "\U0001f963", + ":bowling:": "\U0001f3b3", + ":boxing_glove:": "\U0001f94a", + ":boy:": "\U0001f466", + ":boy::skin-tone-1:": "\U0001f466\U0001f3fb", + ":boy::skin-tone-2:": "\U0001f466\U0001f3fc", + ":boy::skin-tone-3:": "\U0001f466\U0001f3fd", + ":boy::skin-tone-4:": "\U0001f466\U0001f3fe", + ":boy::skin-tone-5:": "\U0001f466\U0001f3ff", + ":brain:": "\U0001f9e0", + ":brazil:": "\U0001f1e7\U0001f1f7", + ":bread:": "\U0001f35e", + ":breast-feeding:": "\U0001f931", + ":breast_feeding:": "\U0001f931", + ":breast_feeding::skin-tone-1:": "\U0001f931\U0001f3fb", + ":breast_feeding::skin-tone-2:": "\U0001f931\U0001f3fc", + ":breast_feeding::skin-tone-3:": "\U0001f931\U0001f3fd", + ":breast_feeding::skin-tone-4:": "\U0001f931\U0001f3fe", + ":breast_feeding::skin-tone-5:": "\U0001f931\U0001f3ff", + ":brick:": "\U0001f9f1", + ":bricks:": "\U0001f9f1", + ":bride_with_veil:": "\U0001f470", + ":bride_with_veil::skin-tone-1:": "\U0001f470\U0001f3fb", + ":bride_with_veil::skin-tone-2:": "\U0001f470\U0001f3fc", + ":bride_with_veil::skin-tone-3:": "\U0001f470\U0001f3fd", + ":bride_with_veil::skin-tone-4:": "\U0001f470\U0001f3fe", + ":bride_with_veil::skin-tone-5:": "\U0001f470\U0001f3ff", + ":bridge_at_night:": "\U0001f309", + ":briefcase:": "\U0001f4bc", + ":briefs:": "\U0001fa72", + ":bright_button:": "\U0001f506", + ":british_indian_ocean_territory:": "\U0001f1ee\U0001f1f4", + ":british_virgin_islands:": "\U0001f1fb\U0001f1ec", + ":broccoli:": "\U0001f966", + ":broken_heart:": "\U0001f494", + ":broom:": "\U0001f9f9", + ":brown_circle:": "\U0001f7e4", + ":brown_heart:": "\U0001f90e", + ":brown_square:": "\U0001f7eb", + ":brunei:": "\U0001f1e7\U0001f1f3", + ":bubble_tea:": "\U0001f9cb", + ":bucket:": "\U0001faa3", + ":bug:": "\U0001f41b", + ":building_construction:": "\U0001f3d7\ufe0f", + ":bulb:": "\U0001f4a1", + ":bulgaria:": "\U0001f1e7\U0001f1ec", + ":bullet_train:": "\U0001f685", + ":bullettrain_front:": "\U0001f685", + ":bullettrain_side:": "\U0001f684", + ":burkina_faso:": "\U0001f1e7\U0001f1eb", + ":burrito:": "\U0001f32f", + ":burundi:": "\U0001f1e7\U0001f1ee", + ":bus:": "\U0001f68c", + ":bus_stop:": "\U0001f68f", + ":business_suit_levitating:": "\U0001f574\ufe0f", + ":busstop:": "\U0001f68f", + ":bust_in_silhouette:": "\U0001f464", + ":busts_in_silhouette:": "\U0001f465", + ":butter:": "\U0001f9c8", + ":butterfly:": "\U0001f98b", + ":cactus:": "\U0001f335", + ":cake:": "\U0001f370", + ":calendar:": "\U0001f4c6", + ":calendar_spiral:": "\U0001f5d3", + ":call_me:": "\U0001f919", + ":call_me_hand:": "\U0001f919", + ":call_me::skin-tone-1:": "\U0001f919\U0001f3fb", + ":call_me::skin-tone-2:": "\U0001f919\U0001f3fc", + ":call_me::skin-tone-3:": "\U0001f919\U0001f3fd", + ":call_me::skin-tone-4:": "\U0001f919\U0001f3fe", + ":call_me::skin-tone-5:": "\U0001f919\U0001f3ff", + ":calling:": "\U0001f4f2", + ":cambodia:": "\U0001f1f0\U0001f1ed", + ":camel:": "\U0001f42b", + ":camera:": "\U0001f4f7", + ":camera_flash:": "\U0001f4f8", + ":camera_with_flash:": "\U0001f4f8", + ":cameroon:": "\U0001f1e8\U0001f1f2", + ":camping:": "\U0001f3d5\ufe0f", + ":canada:": "\U0001f1e8\U0001f1e6", + ":canary_islands:": "\U0001f1ee\U0001f1e8", + ":cancer:": "\u264b", + ":candle:": "\U0001f56f\ufe0f", + ":candy:": "\U0001f36c", + ":canned_food:": "\U0001f96b", + ":canoe:": "\U0001f6f6", + ":cape_verde:": "\U0001f1e8\U0001f1fb", + ":capital_abcd:": "\U0001f520", + ":capricorn:": "\u2651", + ":car:": "\U0001f697", + ":card_box:": "\U0001f5c3", + ":card_file_box:": "\U0001f5c3\ufe0f", + ":card_index:": "\U0001f4c7", + ":card_index_dividers:": "\U0001f5c2\ufe0f", + ":caribbean_netherlands:": "\U0001f1e7\U0001f1f6", + ":carousel_horse:": "\U0001f3a0", + ":carp_streamer:": "\U0001f38f", + ":carpentry_saw:": "\U0001fa9a", + ":carrot:": "\U0001f955", + ":cartwheeling:": "\U0001f938", + ":castle:": "\U0001f3f0", + ":cat:": "\U0001f431", + ":cat2:": "\U0001f408", + ":cat_face:": "\U0001f431", + ":cat_with_tears_of_joy:": "\U0001f639", + ":cat_with_wry_smile:": "\U0001f63c", + ":cayman_islands:": "\U0001f1f0\U0001f1fe", + ":cd:": "\U0001f4bf", + ":central_african_republic:": "\U0001f1e8\U0001f1eb", + ":ceuta_melilla:": "\U0001f1ea\U0001f1e6", + ":chad:": "\U0001f1f9\U0001f1e9", + ":chains:": "\u26d3\ufe0f", + ":chair:": "\U0001fa91", + ":champagne:": "\U0001f37e", + ":champagne_glass:": "\U0001f942", + ":chart:": "\U0001f4b9", + ":chart_decreasing:": "\U0001f4c9", + ":chart_increasing:": "\U0001f4c8", + ":chart_increasing_with_yen:": "\U0001f4b9", + ":chart_with_downwards_trend:": "\U0001f4c9", + ":chart_with_upwards_trend:": "\U0001f4c8", + ":check_box_with_check:": "\u2611", + ":check_mark:": "\u2714", + ":check_mark_button:": "\u2705", + ":checkered_flag:": "\U0001f3c1", + ":cheese:": "\U0001f9c0", + ":cheese_wedge:": "\U0001f9c0", + ":chequered_flag:": "\U0001f3c1", + ":cherries:": "\U0001f352", + ":cherry_blossom:": "\U0001f338", + ":chess_pawn:": "\u265f\ufe0f", + ":chestnut:": "\U0001f330", + ":chicken:": "\U0001f414", + ":child:": "\U0001f9d2", + ":child::skin-tone-1:": "\U0001f9d2\U0001f3fb", + ":child::skin-tone-2:": "\U0001f9d2\U0001f3fc", + ":child::skin-tone-3:": "\U0001f9d2\U0001f3fd", + ":child::skin-tone-4:": "\U0001f9d2\U0001f3fe", + ":child::skin-tone-5:": "\U0001f9d2\U0001f3ff", + ":children_crossing:": "\U0001f6b8", + ":chile:": "\U0001f1e8\U0001f1f1", + ":chipmunk:": "\U0001f43f\ufe0f", + ":chocolate_bar:": "\U0001f36b", + ":chopsticks:": "\U0001f962", + ":christmas_island:": "\U0001f1e8\U0001f1fd", + ":christmas_tree:": "\U0001f384", + ":church:": "\u26ea", + ":cigarette:": "\U0001f6ac", + ":cinema:": "\U0001f3a6", + ":circled_M:": "\u24c2", + ":circus_tent:": "\U0001f3aa", + ":city_dusk:": "\U0001f306", + ":city_sunrise:": "\U0001f307", + ":city_sunset:": "\U0001f306", + ":cityscape:": "\U0001f3d9\ufe0f", + ":cityscape_at_dusk:": "\U0001f306", + ":cl:": "\U0001f191", + ":clamp:": "\U0001f5dc", + ":clap:": "\U0001f44f", + ":clap::skin-tone-1:": "\U0001f44f\U0001f3fb", + ":clap::skin-tone-2:": "\U0001f44f\U0001f3fc", + ":clap::skin-tone-3:": "\U0001f44f\U0001f3fd", + ":clap::skin-tone-4:": "\U0001f44f\U0001f3fe", + ":clap::skin-tone-5:": "\U0001f44f\U0001f3ff", + ":clapper:": "\U0001f3ac", + ":clapper_board:": "\U0001f3ac", + ":clapping_hands:": "\U0001f44f", + ":classical_building:": "\U0001f3db\ufe0f", + ":climbing:": "\U0001f9d7", + ":climbing_man:": "\U0001f9d7\u200d\u2642\ufe0f", + ":climbing_woman:": "\U0001f9d7\u200d\u2640\ufe0f", + ":clinking_beer_mugs:": "\U0001f37b", + ":clinking_glasses:": "\U0001f942", + ":clipboard:": "\U0001f4cb", + ":clipperton_island:": "\U0001f1e8\U0001f1f5", + ":clock:": "\U0001f570", + ":clock1:": "\U0001f550", + ":clock10:": "\U0001f559", + ":clock1030:": "\U0001f565", + ":clock11:": "\U0001f55a", + ":clock1130:": "\U0001f566", + ":clock12:": "\U0001f55b", + ":clock1230:": "\U0001f567", + ":clock130:": "\U0001f55c", + ":clock2:": "\U0001f551", + ":clock230:": "\U0001f55d", + ":clock3:": "\U0001f552", + ":clock330:": "\U0001f55e", + ":clock4:": "\U0001f553", + ":clock430:": "\U0001f55f", + ":clock5:": "\U0001f554", + ":clock530:": "\U0001f560", + ":clock6:": "\U0001f555", + ":clock630:": "\U0001f561", + ":clock7:": "\U0001f556", + ":clock730:": "\U0001f562", + ":clock8:": "\U0001f557", + ":clock830:": "\U0001f563", + ":clock9:": "\U0001f558", + ":clock930:": "\U0001f564", + ":clockwise_vertical_arrows:": "\U0001f503", + ":closed_book:": "\U0001f4d5", + ":closed_lock_with_key:": "\U0001f510", + ":closed_mailbox_with_lowered_flag:": "\U0001f4ea", + ":closed_mailbox_with_raised_flag:": "\U0001f4eb", + ":closed_umbrella:": "\U0001f302", + ":cloud:": "\u2601\ufe0f", + ":cloud_lightning:": "\U0001f329", + ":cloud_rain:": "\U0001f327", + ":cloud_snow:": "\U0001f328", + ":cloud_tornado:": "\U0001f32a", + ":cloud_with_lightning:": "\U0001f329", + ":cloud_with_lightning_and_rain:": "\u26c8", + ":cloud_with_rain:": "\U0001f327", + ":cloud_with_snow:": "\U0001f328", + ":clown:": "\U0001f921", + ":clown_face:": "\U0001f921", + ":club_suit:": "\u2663", + ":clubs:": "\u2663\ufe0f", + ":clutch_bag:": "\U0001f45d", + ":cn:": "\U0001f1e8\U0001f1f3", + ":coat:": "\U0001f9e5", + ":cockroach:": "\U0001fab3", + ":cocktail:": "\U0001f378", + ":cocktail_glass:": "\U0001f378", + ":coconut:": "\U0001f965", + ":cocos_islands:": "\U0001f1e8\U0001f1e8", + ":coffee:": "\u2615", + ":coffin:": "\u26b0\ufe0f", + ":coin:": "\U0001fa99", + ":cold_face:": "\U0001f976", + ":cold_sweat:": "\U0001f630", + ":collision:": "\U0001f4a5", + ":colombia:": "\U0001f1e8\U0001f1f4", + ":comet:": "\u2604\ufe0f", + ":comoros:": "\U0001f1f0\U0001f1f2", + ":compass:": "\U0001f9ed", + ":compression:": "\U0001f5dc\ufe0f", + ":computer:": "\U0001f4bb", + ":computer_disk:": "\U0001f4bd", + ":computer_mouse:": "\U0001f5b1", + ":confetti_ball:": "\U0001f38a", + ":confounded:": "\U0001f616", + ":confounded_face:": "\U0001f616", + ":confused:": "\U0001f615", + ":confused_face:": "\U0001f615", + ":congo_brazzaville:": "\U0001f1e8\U0001f1ec", + ":congo_kinshasa:": "\U0001f1e8\U0001f1e9", + ":congratulations:": "\u3297\ufe0f", + ":construction:": "\U0001f6a7", + ":construction_site:": "\U0001f3d7", + ":construction_worker:": "\U0001f477\u200d\u2642\ufe0f", + ":construction_worker_man:": "\U0001f477\u200d\u2642\ufe0f", + ":construction_worker::skin-tone-1:": "\U0001f477\U0001f3fb", + ":construction_worker::skin-tone-2:": "\U0001f477\U0001f3fc", + ":construction_worker::skin-tone-3:": "\U0001f477\U0001f3fd", + ":construction_worker::skin-tone-4:": "\U0001f477\U0001f3fe", + ":construction_worker::skin-tone-5:": "\U0001f477\U0001f3ff", + ":construction_worker_woman:": "\U0001f477\u200d\u2640\ufe0f", + ":control_knobs:": "\U0001f39b\ufe0f", + ":convenience_store:": "\U0001f3ea", + ":cook:": "\U0001f9d1\u200d\U0001f373", + ":cook_islands:": "\U0001f1e8\U0001f1f0", + ":cooked_rice:": "\U0001f35a", + ":cookie:": "\U0001f36a", + ":cooking:": "\U0001f373", + ":cool:": "\U0001f192", + ":cop:": "\U0001f46e\u200d\u2642\ufe0f", + ":copyright:": "\u00a9\ufe0f", + ":corn:": "\U0001f33d", + ":costa_rica:": "\U0001f1e8\U0001f1f7", + ":cote_divoire:": "\U0001f1e8\U0001f1ee", + ":couch:": "\U0001f6cb", + ":couch_and_lamp:": "\U0001f6cb\ufe0f", + ":counterclockwise_arrows_button:": "\U0001f504", + ":couple:": "\U0001f46b", + ":couple_mm:": "\U0001f468\u200d\u2764\ufe0f\u200d\U0001f468", + ":couple_with_heart:": "\U0001f469\u200d\u2764\ufe0f\u200d\U0001f468", + ":couple_with_heart_man_man:": "\U0001f468\u200d\u2764\ufe0f\u200d\U0001f468", + ":couple_with_heart_woman_man:": "\U0001f469\u200d\u2764\ufe0f\u200d\U0001f468", + ":couple_with_heart_woman_woman:": "\U0001f469\u200d\u2764\ufe0f\u200d\U0001f469", + ":couple_ww:": "\U0001f469\u200d\u2764\ufe0f\u200d\U0001f469", + ":couplekiss:": "\U0001f469\u200d\u2764\ufe0f\u200d\U0001f48b\u200d\U0001f468", + ":couplekiss_man_man:": "\U0001f468\u200d\u2764\ufe0f\u200d\U0001f48b\u200d\U0001f468", + ":couplekiss_man_woman:": "\U0001f469\u200d\u2764\ufe0f\u200d\U0001f48b\u200d\U0001f468", + ":couplekiss_woman_woman:": "\U0001f469\u200d\u2764\ufe0f\u200d\U0001f48b\u200d\U0001f469", + ":cow:": "\U0001f42e", + ":cow2:": "\U0001f404", + ":cow_face:": "\U0001f42e", + ":cowboy:": "\U0001f920", + ":cowboy_hat_face:": "\U0001f920", + ":crab:": "\U0001f980", + ":crayon:": "\U0001f58d", + ":crazy_face:": "\U0001f92a", + ":credit_card:": "\U0001f4b3", + ":crescent_moon:": "\U0001f319", + ":cricket:": "\U0001f997", + ":cricket_bat_and_ball:": "\U0001f3cf", + ":cricket_game:": "\U0001f3cf", + ":croatia:": "\U0001f1ed\U0001f1f7", + ":crocodile:": "\U0001f40a", + ":croissant:": "\U0001f950", + ":cross:": "\u271d", + ":cross_mark:": "\u274c", + ":cross_mark_button:": "\u274e", + ":crossed_fingers:": "\U0001f91e", + ":crossed_flags:": "\U0001f38c", + ":crossed_swords:": "\u2694\ufe0f", + ":crown:": "\U0001f451", + ":cruise_ship:": "\U0001f6f3", + ":cry:": "\U0001f622", + ":crying_cat:": "\U0001f63f", + ":crying_cat_face:": "\U0001f63f", + ":crying_face:": "\U0001f622", + ":crystal_ball:": "\U0001f52e", + ":cuba:": "\U0001f1e8\U0001f1fa", + ":cucumber:": "\U0001f952", + ":cup_with_straw:": "\U0001f964", + ":cupcake:": "\U0001f9c1", + ":cupid:": "\U0001f498", + ":curacao:": "\U0001f1e8\U0001f1fc", + ":curling_stone:": "\U0001f94c", + ":curly_hair:": "\U0001f9b1", + ":curly_haired_man:": "\U0001f468\u200d\U0001f9b1", + ":curly_haired_person:": "\U0001f9d1\u200d\U0001f9b1", + ":curly_haired_woman:": "\U0001f469\u200d\U0001f9b1", + ":curly_loop:": "\u27b0", + ":currency_exchange:": "\U0001f4b1", + ":curry:": "\U0001f35b", + ":curry_rice:": "\U0001f35b", + ":cursing_face:": "\U0001f92c", + ":custard:": "\U0001f36e", + ":customs:": "\U0001f6c3", + ":cut_of_meat:": "\U0001f969", + ":cyclone:": "\U0001f300", + ":cyprus:": "\U0001f1e8\U0001f1fe", + ":czech_republic:": "\U0001f1e8\U0001f1ff", + ":dagger:": "\U0001f5e1", + ":dagger_knife:": "\U0001f5e1\ufe0f", + ":dancer:": "\U0001f483", + ":dancer::skin-tone-1:": "\U0001f483\U0001f3fb", + ":dancer::skin-tone-2:": "\U0001f483\U0001f3fc", + ":dancer::skin-tone-3:": "\U0001f483\U0001f3fd", + ":dancer::skin-tone-4:": "\U0001f483\U0001f3fe", + ":dancer::skin-tone-5:": "\U0001f483\U0001f3ff", + ":dancers:": "\U0001f46f\u200d\u2640\ufe0f", + ":dancing_men:": "\U0001f46f\u200d\u2642\ufe0f", + ":dancing_women:": "\U0001f46f\u200d\u2640\ufe0f", + ":dango:": "\U0001f361", + ":dark_sunglasses:": "\U0001f576\ufe0f", + ":dart:": "\U0001f3af", + ":dash:": "\U0001f4a8", + ":dashing_away:": "\U0001f4a8", + ":date:": "\U0001f4c5", + ":de:": "\U0001f1e9\U0001f1ea", + ":deaf_man:": "\U0001f9cf\u200d\u2642\ufe0f", + ":deaf_person:": "\U0001f9cf", + ":deaf_woman:": "\U0001f9cf\u200d\u2640\ufe0f", + ":deciduous_tree:": "\U0001f333", + ":deer:": "\U0001f98c", + ":delivery_truck:": "\U0001f69a", + ":denmark:": "\U0001f1e9\U0001f1f0", + ":department_store:": "\U0001f3ec", + ":derelict_house:": "\U0001f3da", + ":derelict_house_building:": "\U0001f3da\ufe0f", + ":desert:": "\U0001f3dc\ufe0f", + ":desert_island:": "\U0001f3dd\ufe0f", + ":desktop:": "\U0001f5a5", + ":desktop_computer:": "\U0001f5a5\ufe0f", + ":detective:": "\U0001f575", + ":detective::skin-tone-1:": "\U0001f575\U0001f3fb", + ":detective::skin-tone-2:": "\U0001f575\U0001f3fc", + ":detective::skin-tone-3:": "\U0001f575\U0001f3fd", + ":detective::skin-tone-4:": "\U0001f575\U0001f3fe", + ":detective::skin-tone-5:": "\U0001f575\U0001f3ff", + ":diamond_shape_with_a_dot_inside:": "\U0001f4a0", + ":diamond_suit:": "\u2666", + ":diamond_with_a_dot:": "\U0001f4a0", + ":diamonds:": "\u2666\ufe0f", + ":diego_garcia:": "\U0001f1e9\U0001f1ec", + ":dim_button:": "\U0001f505", + ":direct_hit:": "\U0001f3af", + ":disappointed:": "\U0001f61e", + ":disappointed_face:": "\U0001f61e", + ":disappointed_relieved:": "\U0001f625", + ":disguised_face:": "\U0001f978", + ":divide:": "\u2797", + ":dividers:": "\U0001f5c2", + ":diving_mask:": "\U0001f93f", + ":diya_lamp:": "\U0001fa94", + ":dizzy:": "\U0001f4ab", + ":dizzy_face:": "\U0001f635", + ":djibouti:": "\U0001f1e9\U0001f1ef", + ":dna:": "\U0001f9ec", + ":do_not_litter:": "\U0001f6af", + ":dodo:": "\U0001f9a4", + ":dog:": "\U0001f436", + ":dog2:": "\U0001f415", + ":dog_face:": "\U0001f436", + ":dollar:": "\U0001f4b5", + ":dollar_banknote:": "\U0001f4b5", + ":dolls:": "\U0001f38e", + ":dolphin:": "\U0001f42c", + ":dominica:": "\U0001f1e9\U0001f1f2", + ":dominican_republic:": "\U0001f1e9\U0001f1f4", + ":door:": "\U0001f6aa", + ":dotted_six-pointed_star:": "\U0001f52f", + ":double_curly_loop:": "\u27bf", + ":double_exclamation_mark:": "\u203c", + ":double_vertical_bar:": "\u23f8\ufe0f", + ":doughnut:": "\U0001f369", + ":dove:": "\U0001f54a", + ":dove_of_peace:": "\U0001f54a\ufe0f", + ":down-left_arrow:": "\u2199", + ":down-right_arrow:": "\u2198", + ":down_arrow:": "\u2b07", + ":downcast_face_with_sweat:": "\U0001f613", + ":downwards_button:": "\U0001f53d", + ":dragon:": "\U0001f409", + ":dragon_face:": "\U0001f432", + ":dress:": "\U0001f457", + ":dromedary_camel:": "\U0001f42a", + ":drooling_face:": "\U0001f924", + ":drop_of_blood:": "\U0001fa78", + ":droplet:": "\U0001f4a7", + ":drum:": "\U0001f941", + ":drum_with_drumsticks:": "\U0001f941", + ":duck:": "\U0001f986", + ":dumpling:": "\U0001f95f", + ":dvd:": "\U0001f4c0", + ":e-mail:": "\U0001f4e7", + ":eagle:": "\U0001f985", + ":ear:": "\U0001f442", + ":ear_of_corn:": "\U0001f33d", + ":ear_of_rice:": "\U0001f33e", + ":ear::skin-tone-1:": "\U0001f442\U0001f3fb", + ":ear::skin-tone-2:": "\U0001f442\U0001f3fc", + ":ear::skin-tone-3:": "\U0001f442\U0001f3fd", + ":ear::skin-tone-4:": "\U0001f442\U0001f3fe", + ":ear::skin-tone-5:": "\U0001f442\U0001f3ff", + ":ear_with_hearing_aid:": "\U0001f9bb", + ":earth_africa:": "\U0001f30d", + ":earth_americas:": "\U0001f30e", + ":earth_asia:": "\U0001f30f", + ":ecuador:": "\U0001f1ea\U0001f1e8", + ":egg:": "\U0001f95a", + ":eggplant:": "\U0001f346", + ":egypt:": "\U0001f1ea\U0001f1ec", + ":eight:": "8\ufe0f\u20e3", + ":eight-pointed_star:": "\u2734", + ":eight-spoked_asterisk:": "\u2733", + ":eight-thirty:": "\U0001f563", + ":eight_o’clock:": "\U0001f557", + ":eight_pointed_black_star:": "\u2734\ufe0f", + ":eight_spoked_asterisk:": "\u2733\ufe0f", + ":eject:": "\u23cf\ufe0f", + ":eject_button:": "\u23cf", + ":el_salvador:": "\U0001f1f8\U0001f1fb", + ":electric_plug:": "\U0001f50c", + ":elephant:": "\U0001f418", + ":elevator:": "\U0001f6d7", + ":eleven-thirty:": "\U0001f566", + ":eleven_o’clock:": "\U0001f55a", + ":elf:": "\U0001f9dd\u200d\u2642\ufe0f", + ":elf_man:": "\U0001f9dd\u200d\u2642\ufe0f", + ":elf::skin-tone-1:": "\U0001f9dd\U0001f3fb", + ":elf::skin-tone-2:": "\U0001f9dd\U0001f3fc", + ":elf::skin-tone-3:": "\U0001f9dd\U0001f3fd", + ":elf::skin-tone-4:": "\U0001f9dd\U0001f3fe", + ":elf::skin-tone-5:": "\U0001f9dd\U0001f3ff", + ":elf_woman:": "\U0001f9dd\u200d\u2640\ufe0f", + ":email:": "\u2709\ufe0f", + ":end:": "\U0001f51a", + ":england:": "\U0001f3f4\U000e0067\U000e0062\U000e0065\U000e006e\U000e0067\U000e007f", + ":envelope:": "\u2709", + ":envelope_with_arrow:": "\U0001f4e9", + ":equatorial_guinea:": "\U0001f1ec\U0001f1f6", + ":eritrea:": "\U0001f1ea\U0001f1f7", + ":es:": "\U0001f1ea\U0001f1f8", + ":estonia:": "\U0001f1ea\U0001f1ea", + ":ethiopia:": "\U0001f1ea\U0001f1f9", + ":eu:": "\U0001f1ea\U0001f1fa", + ":euro:": "\U0001f4b6", + ":euro_banknote:": "\U0001f4b6", + ":european_castle:": "\U0001f3f0", + ":european_post_office:": "\U0001f3e4", + ":european_union:": "\U0001f1ea\U0001f1fa", + ":evergreen_tree:": "\U0001f332", + ":ewe:": "\U0001f411", + ":exclamation:": "\u2757", + ":exclamation_mark:": "\u2757", + ":exclamation_question_mark:": "\u2049", + ":exploding_head:": "\U0001f92f", + ":expressionless:": "\U0001f611", + ":expressionless_face:": "\U0001f611", + ":eye:": "\U0001f441\ufe0f", + ":eye-in-speech-bubble:": "\U0001f441\ufe0f\u200d\U0001f5e8\ufe0f", + ":eye_in_speech_bubble:": "\U0001f441\ufe0f\u200d\U0001f5e8\ufe0f", + ":eye_speech_bubble:": "\U0001f441\ufe0f\u200d\U0001f5e8\ufe0f", + ":eyeglasses:": "\U0001f453", + ":eyes:": "\U0001f440", + ":face_blowing_a_kiss:": "\U0001f618", + ":face_palm:": "\U0001f926", + ":face_savoring_food:": "\U0001f60b", + ":face_screaming_in_fear:": "\U0001f631", + ":face_vomiting:": "\U0001f92e", + ":face_with_cowboy_hat:": "\U0001f920", + ":face_with_hand_over_mouth:": "\U0001f92d", + ":face_with_head-bandage:": "\U0001f915", + ":face_with_head_bandage:": "\U0001f915", + ":face_with_medical_mask:": "\U0001f637", + ":face_with_monocle:": "\U0001f9d0", + ":face_with_open_mouth:": "\U0001f62e", + ":face_with_raised_eyebrow:": "\U0001f928", + ":face_with_rolling_eyes:": "\U0001f644", + ":face_with_steam_from_nose:": "\U0001f624", + ":face_with_symbols_on_mouth:": "\U0001f92c", + ":face_with_symbols_over_mouth:": "\U0001f92c", + ":face_with_tears_of_joy:": "\U0001f602", + ":face_with_thermometer:": "\U0001f912", + ":face_with_tongue:": "\U0001f61b", + ":face_without_mouth:": "\U0001f636", + ":facepalm:": "\U0001f926", + ":facepunch:": "\U0001f44a", + ":factory:": "\U0001f3ed", + ":factory_worker:": "\U0001f9d1\u200d\U0001f3ed", + ":fairy:": "\U0001f9da\u200d\u2640\ufe0f", + ":fairy_man:": "\U0001f9da\u200d\u2642\ufe0f", + ":fairy::skin-tone-1:": "\U0001f9da\U0001f3fb", + ":fairy::skin-tone-2:": "\U0001f9da\U0001f3fc", + ":fairy::skin-tone-3:": "\U0001f9da\U0001f3fd", + ":fairy::skin-tone-4:": "\U0001f9da\U0001f3fe", + ":fairy::skin-tone-5:": "\U0001f9da\U0001f3ff", + ":fairy_woman:": "\U0001f9da\u200d\u2640\ufe0f", + ":falafel:": "\U0001f9c6", + ":falkland_islands:": "\U0001f1eb\U0001f1f0", + ":fallen_leaf:": "\U0001f342", + ":family:": "\U0001f468\u200d\U0001f469\u200d\U0001f466", + ":family_man_boy:": "\U0001f468\u200d\U0001f466", + ":family_man_boy_boy:": "\U0001f468\u200d\U0001f466\u200d\U0001f466", + ":family_man_girl:": "\U0001f468\u200d\U0001f467", + ":family_man_girl_boy:": "\U0001f468\u200d\U0001f467\u200d\U0001f466", + ":family_man_girl_girl:": "\U0001f468\u200d\U0001f467\u200d\U0001f467", + ":family_man_man_boy:": "\U0001f468\u200d\U0001f468\u200d\U0001f466", + ":family_man_man_boy_boy:": "\U0001f468\u200d\U0001f468\u200d\U0001f466\u200d\U0001f466", + ":family_man_man_girl:": "\U0001f468\u200d\U0001f468\u200d\U0001f467", + ":family_man_man_girl_boy:": "\U0001f468\u200d\U0001f468\u200d\U0001f467\u200d\U0001f466", + ":family_man_man_girl_girl:": "\U0001f468\u200d\U0001f468\u200d\U0001f467\u200d\U0001f467", + ":family_man_woman_boy:": "\U0001f468\u200d\U0001f469\u200d\U0001f466", + ":family_man_woman_boy_boy:": "\U0001f468\u200d\U0001f469\u200d\U0001f466\u200d\U0001f466", + ":family_man_woman_girl:": "\U0001f468\u200d\U0001f469\u200d\U0001f467", + ":family_man_woman_girl_boy:": "\U0001f468\u200d\U0001f469\u200d\U0001f467\u200d\U0001f466", + ":family_man_woman_girl_girl:": "\U0001f468\u200d\U0001f469\u200d\U0001f467\u200d\U0001f467", + ":family_mmb:": "\U0001f468\u200d\U0001f468\u200d\U0001f466", + ":family_mmbb:": "\U0001f468\u200d\U0001f468\u200d\U0001f466\u200d\U0001f466", + ":family_mmg:": "\U0001f468\u200d\U0001f468\u200d\U0001f467", + ":family_mmgb:": "\U0001f468\u200d\U0001f468\u200d\U0001f467\u200d\U0001f466", + ":family_mmgg:": "\U0001f468\u200d\U0001f468\u200d\U0001f467\u200d\U0001f467", + ":family_mwbb:": "\U0001f468\u200d\U0001f469\u200d\U0001f466\u200d\U0001f466", + ":family_mwg:": "\U0001f468\u200d\U0001f469\u200d\U0001f467", + ":family_mwgb:": "\U0001f468\u200d\U0001f469\u200d\U0001f467\u200d\U0001f466", + ":family_mwgg:": "\U0001f468\u200d\U0001f469\u200d\U0001f467\u200d\U0001f467", + ":family_woman_boy:": "\U0001f469\u200d\U0001f466", + ":family_woman_boy_boy:": "\U0001f469\u200d\U0001f466\u200d\U0001f466", + ":family_woman_girl:": "\U0001f469\u200d\U0001f467", + ":family_woman_girl_boy:": "\U0001f469\u200d\U0001f467\u200d\U0001f466", + ":family_woman_girl_girl:": "\U0001f469\u200d\U0001f467\u200d\U0001f467", + ":family_woman_woman_boy:": "\U0001f469\u200d\U0001f469\u200d\U0001f466", + ":family_woman_woman_boy_boy:": "\U0001f469\u200d\U0001f469\u200d\U0001f466\u200d\U0001f466", + ":family_woman_woman_girl:": "\U0001f469\u200d\U0001f469\u200d\U0001f467", + ":family_woman_woman_girl_boy:": "\U0001f469\u200d\U0001f469\u200d\U0001f467\u200d\U0001f466", + ":family_woman_woman_girl_girl:": "\U0001f469\u200d\U0001f469\u200d\U0001f467\u200d\U0001f467", + ":family_wwb:": "\U0001f469\u200d\U0001f469\u200d\U0001f466", + ":family_wwbb:": "\U0001f469\u200d\U0001f469\u200d\U0001f466\u200d\U0001f466", + ":family_wwg:": "\U0001f469\u200d\U0001f469\u200d\U0001f467", + ":family_wwgb:": "\U0001f469\u200d\U0001f469\u200d\U0001f467\u200d\U0001f466", + ":family_wwgg:": "\U0001f469\u200d\U0001f469\u200d\U0001f467\u200d\U0001f467", + ":farmer:": "\U0001f9d1\u200d\U0001f33e", + ":faroe_islands:": "\U0001f1eb\U0001f1f4", + ":fast-forward_button:": "\u23e9", + ":fast_down_button:": "\u23ec", + ":fast_forward:": "\u23e9", + ":fast_reverse_button:": "\u23ea", + ":fast_up_button:": "\u23eb", + ":fax:": "\U0001f4e0", + ":fax_machine:": "\U0001f4e0", + ":fearful:": "\U0001f628", + ":fearful_face:": "\U0001f628", + ":feather:": "\U0001fab6", + ":feet:": "\U0001f43e", + ":female-artist:": "\U0001f469\u200d\U0001f3a8", + ":female-astronaut:": "\U0001f469\u200d\U0001f680", + ":female-construction-worker:": "\U0001f477\u200d\u2640\ufe0f", + ":female-cook:": "\U0001f469\u200d\U0001f373", + ":female-detective:": "\U0001f575\ufe0f\u200d\u2640\ufe0f", + ":female-doctor:": "\U0001f469\u200d\u2695\ufe0f", + ":female-factory-worker:": "\U0001f469\u200d\U0001f3ed", + ":female-farmer:": "\U0001f469\u200d\U0001f33e", + ":female-firefighter:": "\U0001f469\u200d\U0001f692", + ":female-guard:": "\U0001f482\u200d\u2640\ufe0f", + ":female-judge:": "\U0001f469\u200d\u2696\ufe0f", + ":female-mechanic:": "\U0001f469\u200d\U0001f527", + ":female-office-worker:": "\U0001f469\u200d\U0001f4bc", + ":female-pilot:": "\U0001f469\u200d\u2708\ufe0f", + ":female-police-officer:": "\U0001f46e\u200d\u2640\ufe0f", + ":female-scientist:": "\U0001f469\u200d\U0001f52c", + ":female-singer:": "\U0001f469\u200d\U0001f3a4", + ":female-student:": "\U0001f469\u200d\U0001f393", + ":female-teacher:": "\U0001f469\u200d\U0001f3eb", + ":female-technologist:": "\U0001f469\u200d\U0001f4bb", + ":female_detective:": "\U0001f575\ufe0f\u200d\u2640\ufe0f", + ":female_elf:": "\U0001f9dd\u200d\u2640\ufe0f", + ":female_fairy:": "\U0001f9da\u200d\u2640\ufe0f", + ":female_genie:": "\U0001f9de\u200d\u2640\ufe0f", + ":female_mage:": "\U0001f9d9\u200d\u2640\ufe0f", + ":female_sign:": "\u2640\ufe0f", + ":female_superhero:": "\U0001f9b8\u200d\u2640\ufe0f", + ":female_supervillain:": "\U0001f9b9\u200d\u2640\ufe0f", + ":female_vampire:": "\U0001f9db\u200d\u2640\ufe0f", + ":female_zombie:": "\U0001f9df\u200d\u2640\ufe0f", + ":fencer:": "\U0001f93a", + ":ferris_wheel:": "\U0001f3a1", + ":ferry:": "\u26f4\ufe0f", + ":field_hockey:": "\U0001f3d1", + ":field_hockey_stick_and_ball:": "\U0001f3d1", + ":fiji:": "\U0001f1eb\U0001f1ef", + ":file_cabinet:": "\U0001f5c4\ufe0f", + ":file_folder:": "\U0001f4c1", + ":film_frames:": "\U0001f39e\ufe0f", + ":film_projector:": "\U0001f4fd\ufe0f", + ":film_strip:": "\U0001f39e\ufe0f", + ":fingers_crossed:": "\U0001f91e", + ":fingers_crossed::skin-tone-1:": "\U0001f91e\U0001f3fb", + ":fingers_crossed::skin-tone-2:": "\U0001f91e\U0001f3fc", + ":fingers_crossed::skin-tone-3:": "\U0001f91e\U0001f3fd", + ":fingers_crossed::skin-tone-4:": "\U0001f91e\U0001f3fe", + ":fingers_crossed::skin-tone-5:": "\U0001f91e\U0001f3ff", + ":finland:": "\U0001f1eb\U0001f1ee", + ":fire:": "\U0001f525", + ":fire_engine:": "\U0001f692", + ":fire_extinguisher:": "\U0001f9ef", + ":firecracker:": "\U0001f9e8", + ":firefighter:": "\U0001f9d1\u200d\U0001f692", + ":fireworks:": "\U0001f386", + ":first_place:": "\U0001f947", + ":first_place_medal:": "\U0001f947", + ":first_quarter_moon:": "\U0001f313", + ":first_quarter_moon_face:": "\U0001f31b", + ":first_quarter_moon_with_face:": "\U0001f31b", + ":fish:": "\U0001f41f", + ":fish_cake:": "\U0001f365", + ":fish_cake_with_swirl:": "\U0001f365", + ":fishing_pole:": "\U0001f3a3", + ":fishing_pole_and_fish:": "\U0001f3a3", + ":fist:": "\u270a", + ":fist_left:": "\U0001f91b", + ":fist_oncoming:": "\U0001f44a", + ":fist_raised:": "\u270a", + ":fist_right:": "\U0001f91c", + ":fist::skin-tone-1:": "\u270a\U0001f3fb", + ":fist::skin-tone-2:": "\u270a\U0001f3fc", + ":fist::skin-tone-3:": "\u270a\U0001f3fd", + ":fist::skin-tone-4:": "\u270a\U0001f3fe", + ":fist::skin-tone-5:": "\u270a\U0001f3ff", + ":five:": "5\ufe0f\u20e3", + ":five-thirty:": "\U0001f560", + ":five_o’clock:": "\U0001f554", + ":flag-ac:": "\U0001f1e6\U0001f1e8", + ":flag-ad:": "\U0001f1e6\U0001f1e9", + ":flag-ae:": "\U0001f1e6\U0001f1ea", + ":flag-af:": "\U0001f1e6\U0001f1eb", + ":flag-ag:": "\U0001f1e6\U0001f1ec", + ":flag-ai:": "\U0001f1e6\U0001f1ee", + ":flag-al:": "\U0001f1e6\U0001f1f1", + ":flag-am:": "\U0001f1e6\U0001f1f2", + ":flag-ao:": "\U0001f1e6\U0001f1f4", + ":flag-aq:": "\U0001f1e6\U0001f1f6", + ":flag-ar:": "\U0001f1e6\U0001f1f7", + ":flag-as:": "\U0001f1e6\U0001f1f8", + ":flag-at:": "\U0001f1e6\U0001f1f9", + ":flag-au:": "\U0001f1e6\U0001f1fa", + ":flag-aw:": "\U0001f1e6\U0001f1fc", + ":flag-ax:": "\U0001f1e6\U0001f1fd", + ":flag-az:": "\U0001f1e6\U0001f1ff", + ":flag-ba:": "\U0001f1e7\U0001f1e6", + ":flag-bb:": "\U0001f1e7\U0001f1e7", + ":flag-bd:": "\U0001f1e7\U0001f1e9", + ":flag-be:": "\U0001f1e7\U0001f1ea", + ":flag-bf:": "\U0001f1e7\U0001f1eb", + ":flag-bg:": "\U0001f1e7\U0001f1ec", + ":flag-bh:": "\U0001f1e7\U0001f1ed", + ":flag-bi:": "\U0001f1e7\U0001f1ee", + ":flag-bj:": "\U0001f1e7\U0001f1ef", + ":flag-bl:": "\U0001f1e7\U0001f1f1", + ":flag-bm:": "\U0001f1e7\U0001f1f2", + ":flag-bn:": "\U0001f1e7\U0001f1f3", + ":flag-bo:": "\U0001f1e7\U0001f1f4", + ":flag-bq:": "\U0001f1e7\U0001f1f6", + ":flag-br:": "\U0001f1e7\U0001f1f7", + ":flag-bs:": "\U0001f1e7\U0001f1f8", + ":flag-bt:": "\U0001f1e7\U0001f1f9", + ":flag-bv:": "\U0001f1e7\U0001f1fb", + ":flag-bw:": "\U0001f1e7\U0001f1fc", + ":flag-by:": "\U0001f1e7\U0001f1fe", + ":flag-bz:": "\U0001f1e7\U0001f1ff", + ":flag-ca:": "\U0001f1e8\U0001f1e6", + ":flag-cc:": "\U0001f1e8\U0001f1e8", + ":flag-cd:": "\U0001f1e8\U0001f1e9", + ":flag-cf:": "\U0001f1e8\U0001f1eb", + ":flag-cg:": "\U0001f1e8\U0001f1ec", + ":flag-ch:": "\U0001f1e8\U0001f1ed", + ":flag-ci:": "\U0001f1e8\U0001f1ee", + ":flag-ck:": "\U0001f1e8\U0001f1f0", + ":flag-cl:": "\U0001f1e8\U0001f1f1", + ":flag-cm:": "\U0001f1e8\U0001f1f2", + ":flag-co:": "\U0001f1e8\U0001f1f4", + ":flag-cp:": "\U0001f1e8\U0001f1f5", + ":flag-cr:": "\U0001f1e8\U0001f1f7", + ":flag-cu:": "\U0001f1e8\U0001f1fa", + ":flag-cv:": "\U0001f1e8\U0001f1fb", + ":flag-cw:": "\U0001f1e8\U0001f1fc", + ":flag-cx:": "\U0001f1e8\U0001f1fd", + ":flag-cy:": "\U0001f1e8\U0001f1fe", + ":flag-cz:": "\U0001f1e8\U0001f1ff", + ":flag-de:": "\U0001f1e9\U0001f1ea", + ":flag-dg:": "\U0001f1e9\U0001f1ec", + ":flag-dj:": "\U0001f1e9\U0001f1ef", + ":flag-dk:": "\U0001f1e9\U0001f1f0", + ":flag-dm:": "\U0001f1e9\U0001f1f2", + ":flag-do:": "\U0001f1e9\U0001f1f4", + ":flag-dz:": "\U0001f1e9\U0001f1ff", + ":flag-ea:": "\U0001f1ea\U0001f1e6", + ":flag-ec:": "\U0001f1ea\U0001f1e8", + ":flag-ee:": "\U0001f1ea\U0001f1ea", + ":flag-eg:": "\U0001f1ea\U0001f1ec", + ":flag-eh:": "\U0001f1ea\U0001f1ed", + ":flag-england:": "\U0001f3f4\U000e0067\U000e0062\U000e0065\U000e006e\U000e0067\U000e007f", + ":flag-er:": "\U0001f1ea\U0001f1f7", + ":flag-et:": "\U0001f1ea\U0001f1f9", + ":flag-eu:": "\U0001f1ea\U0001f1fa", + ":flag-fi:": "\U0001f1eb\U0001f1ee", + ":flag-fj:": "\U0001f1eb\U0001f1ef", + ":flag-fk:": "\U0001f1eb\U0001f1f0", + ":flag-fm:": "\U0001f1eb\U0001f1f2", + ":flag-fo:": "\U0001f1eb\U0001f1f4", + ":flag-ga:": "\U0001f1ec\U0001f1e6", + ":flag-gd:": "\U0001f1ec\U0001f1e9", + ":flag-ge:": "\U0001f1ec\U0001f1ea", + ":flag-gf:": "\U0001f1ec\U0001f1eb", + ":flag-gg:": "\U0001f1ec\U0001f1ec", + ":flag-gh:": "\U0001f1ec\U0001f1ed", + ":flag-gi:": "\U0001f1ec\U0001f1ee", + ":flag-gl:": "\U0001f1ec\U0001f1f1", + ":flag-gm:": "\U0001f1ec\U0001f1f2", + ":flag-gn:": "\U0001f1ec\U0001f1f3", + ":flag-gp:": "\U0001f1ec\U0001f1f5", + ":flag-gq:": "\U0001f1ec\U0001f1f6", + ":flag-gr:": "\U0001f1ec\U0001f1f7", + ":flag-gs:": "\U0001f1ec\U0001f1f8", + ":flag-gt:": "\U0001f1ec\U0001f1f9", + ":flag-gu:": "\U0001f1ec\U0001f1fa", + ":flag-gw:": "\U0001f1ec\U0001f1fc", + ":flag-gy:": "\U0001f1ec\U0001f1fe", + ":flag-hk:": "\U0001f1ed\U0001f1f0", + ":flag-hm:": "\U0001f1ed\U0001f1f2", + ":flag-hn:": "\U0001f1ed\U0001f1f3", + ":flag-hr:": "\U0001f1ed\U0001f1f7", + ":flag-ht:": "\U0001f1ed\U0001f1f9", + ":flag-hu:": "\U0001f1ed\U0001f1fa", + ":flag-ic:": "\U0001f1ee\U0001f1e8", + ":flag-id:": "\U0001f1ee\U0001f1e9", + ":flag-ie:": "\U0001f1ee\U0001f1ea", + ":flag-il:": "\U0001f1ee\U0001f1f1", + ":flag-im:": "\U0001f1ee\U0001f1f2", + ":flag-in:": "\U0001f1ee\U0001f1f3", + ":flag-io:": "\U0001f1ee\U0001f1f4", + ":flag-iq:": "\U0001f1ee\U0001f1f6", + ":flag-ir:": "\U0001f1ee\U0001f1f7", + ":flag-is:": "\U0001f1ee\U0001f1f8", + ":flag-je:": "\U0001f1ef\U0001f1ea", + ":flag-jm:": "\U0001f1ef\U0001f1f2", + ":flag-jo:": "\U0001f1ef\U0001f1f4", + ":flag-ke:": "\U0001f1f0\U0001f1ea", + ":flag-kg:": "\U0001f1f0\U0001f1ec", + ":flag-kh:": "\U0001f1f0\U0001f1ed", + ":flag-ki:": "\U0001f1f0\U0001f1ee", + ":flag-km:": "\U0001f1f0\U0001f1f2", + ":flag-kn:": "\U0001f1f0\U0001f1f3", + ":flag-kp:": "\U0001f1f0\U0001f1f5", + ":flag-kw:": "\U0001f1f0\U0001f1fc", + ":flag-ky:": "\U0001f1f0\U0001f1fe", + ":flag-kz:": "\U0001f1f0\U0001f1ff", + ":flag-la:": "\U0001f1f1\U0001f1e6", + ":flag-lb:": "\U0001f1f1\U0001f1e7", + ":flag-lc:": "\U0001f1f1\U0001f1e8", + ":flag-li:": "\U0001f1f1\U0001f1ee", + ":flag-lk:": "\U0001f1f1\U0001f1f0", + ":flag-lr:": "\U0001f1f1\U0001f1f7", + ":flag-ls:": "\U0001f1f1\U0001f1f8", + ":flag-lt:": "\U0001f1f1\U0001f1f9", + ":flag-lu:": "\U0001f1f1\U0001f1fa", + ":flag-lv:": "\U0001f1f1\U0001f1fb", + ":flag-ly:": "\U0001f1f1\U0001f1fe", + ":flag-ma:": "\U0001f1f2\U0001f1e6", + ":flag-mc:": "\U0001f1f2\U0001f1e8", + ":flag-md:": "\U0001f1f2\U0001f1e9", + ":flag-me:": "\U0001f1f2\U0001f1ea", + ":flag-mf:": "\U0001f1f2\U0001f1eb", + ":flag-mg:": "\U0001f1f2\U0001f1ec", + ":flag-mh:": "\U0001f1f2\U0001f1ed", + ":flag-mk:": "\U0001f1f2\U0001f1f0", + ":flag-ml:": "\U0001f1f2\U0001f1f1", + ":flag-mm:": "\U0001f1f2\U0001f1f2", + ":flag-mn:": "\U0001f1f2\U0001f1f3", + ":flag-mo:": "\U0001f1f2\U0001f1f4", + ":flag-mp:": "\U0001f1f2\U0001f1f5", + ":flag-mq:": "\U0001f1f2\U0001f1f6", + ":flag-mr:": "\U0001f1f2\U0001f1f7", + ":flag-ms:": "\U0001f1f2\U0001f1f8", + ":flag-mt:": "\U0001f1f2\U0001f1f9", + ":flag-mu:": "\U0001f1f2\U0001f1fa", + ":flag-mv:": "\U0001f1f2\U0001f1fb", + ":flag-mw:": "\U0001f1f2\U0001f1fc", + ":flag-mx:": "\U0001f1f2\U0001f1fd", + ":flag-my:": "\U0001f1f2\U0001f1fe", + ":flag-mz:": "\U0001f1f2\U0001f1ff", + ":flag-na:": "\U0001f1f3\U0001f1e6", + ":flag-nc:": "\U0001f1f3\U0001f1e8", + ":flag-ne:": "\U0001f1f3\U0001f1ea", + ":flag-nf:": "\U0001f1f3\U0001f1eb", + ":flag-ng:": "\U0001f1f3\U0001f1ec", + ":flag-ni:": "\U0001f1f3\U0001f1ee", + ":flag-nl:": "\U0001f1f3\U0001f1f1", + ":flag-no:": "\U0001f1f3\U0001f1f4", + ":flag-np:": "\U0001f1f3\U0001f1f5", + ":flag-nr:": "\U0001f1f3\U0001f1f7", + ":flag-nu:": "\U0001f1f3\U0001f1fa", + ":flag-nz:": "\U0001f1f3\U0001f1ff", + ":flag-om:": "\U0001f1f4\U0001f1f2", + ":flag-pa:": "\U0001f1f5\U0001f1e6", + ":flag-pe:": "\U0001f1f5\U0001f1ea", + ":flag-pf:": "\U0001f1f5\U0001f1eb", + ":flag-pg:": "\U0001f1f5\U0001f1ec", + ":flag-ph:": "\U0001f1f5\U0001f1ed", + ":flag-pk:": "\U0001f1f5\U0001f1f0", + ":flag-pl:": "\U0001f1f5\U0001f1f1", + ":flag-pm:": "\U0001f1f5\U0001f1f2", + ":flag-pn:": "\U0001f1f5\U0001f1f3", + ":flag-pr:": "\U0001f1f5\U0001f1f7", + ":flag-ps:": "\U0001f1f5\U0001f1f8", + ":flag-pt:": "\U0001f1f5\U0001f1f9", + ":flag-pw:": "\U0001f1f5\U0001f1fc", + ":flag-py:": "\U0001f1f5\U0001f1fe", + ":flag-qa:": "\U0001f1f6\U0001f1e6", + ":flag-re:": "\U0001f1f7\U0001f1ea", + ":flag-ro:": "\U0001f1f7\U0001f1f4", + ":flag-rs:": "\U0001f1f7\U0001f1f8", + ":flag-rw:": "\U0001f1f7\U0001f1fc", + ":flag-sa:": "\U0001f1f8\U0001f1e6", + ":flag-sb:": "\U0001f1f8\U0001f1e7", + ":flag-sc:": "\U0001f1f8\U0001f1e8", + ":flag-scotland:": "\U0001f3f4\U000e0067\U000e0062\U000e0073\U000e0063\U000e0074\U000e007f", + ":flag-sd:": "\U0001f1f8\U0001f1e9", + ":flag-se:": "\U0001f1f8\U0001f1ea", + ":flag-sg:": "\U0001f1f8\U0001f1ec", + ":flag-sh:": "\U0001f1f8\U0001f1ed", + ":flag-si:": "\U0001f1f8\U0001f1ee", + ":flag-sj:": "\U0001f1f8\U0001f1ef", + ":flag-sk:": "\U0001f1f8\U0001f1f0", + ":flag-sl:": "\U0001f1f8\U0001f1f1", + ":flag-sm:": "\U0001f1f8\U0001f1f2", + ":flag-sn:": "\U0001f1f8\U0001f1f3", + ":flag-so:": "\U0001f1f8\U0001f1f4", + ":flag-sr:": "\U0001f1f8\U0001f1f7", + ":flag-ss:": "\U0001f1f8\U0001f1f8", + ":flag-st:": "\U0001f1f8\U0001f1f9", + ":flag-sv:": "\U0001f1f8\U0001f1fb", + ":flag-sx:": "\U0001f1f8\U0001f1fd", + ":flag-sy:": "\U0001f1f8\U0001f1fe", + ":flag-sz:": "\U0001f1f8\U0001f1ff", + ":flag-ta:": "\U0001f1f9\U0001f1e6", + ":flag-tc:": "\U0001f1f9\U0001f1e8", + ":flag-td:": "\U0001f1f9\U0001f1e9", + ":flag-tf:": "\U0001f1f9\U0001f1eb", + ":flag-tg:": "\U0001f1f9\U0001f1ec", + ":flag-th:": "\U0001f1f9\U0001f1ed", + ":flag-tj:": "\U0001f1f9\U0001f1ef", + ":flag-tk:": "\U0001f1f9\U0001f1f0", + ":flag-tl:": "\U0001f1f9\U0001f1f1", + ":flag-tm:": "\U0001f1f9\U0001f1f2", + ":flag-tn:": "\U0001f1f9\U0001f1f3", + ":flag-to:": "\U0001f1f9\U0001f1f4", + ":flag-tr:": "\U0001f1f9\U0001f1f7", + ":flag-tt:": "\U0001f1f9\U0001f1f9", + ":flag-tv:": "\U0001f1f9\U0001f1fb", + ":flag-tw:": "\U0001f1f9\U0001f1fc", + ":flag-tz:": "\U0001f1f9\U0001f1ff", + ":flag-ua:": "\U0001f1fa\U0001f1e6", + ":flag-ug:": "\U0001f1fa\U0001f1ec", + ":flag-um:": "\U0001f1fa\U0001f1f2", + ":flag-un:": "\U0001f1fa\U0001f1f3", + ":flag-uy:": "\U0001f1fa\U0001f1fe", + ":flag-uz:": "\U0001f1fa\U0001f1ff", + ":flag-va:": "\U0001f1fb\U0001f1e6", + ":flag-vc:": "\U0001f1fb\U0001f1e8", + ":flag-ve:": "\U0001f1fb\U0001f1ea", + ":flag-vg:": "\U0001f1fb\U0001f1ec", + ":flag-vi:": "\U0001f1fb\U0001f1ee", + ":flag-vn:": "\U0001f1fb\U0001f1f3", + ":flag-vu:": "\U0001f1fb\U0001f1fa", + ":flag-wales:": "\U0001f3f4\U000e0067\U000e0062\U000e0077\U000e006c\U000e0073\U000e007f", + ":flag-wf:": "\U0001f1fc\U0001f1eb", + ":flag-ws:": "\U0001f1fc\U0001f1f8", + ":flag-xk:": "\U0001f1fd\U0001f1f0", + ":flag-ye:": "\U0001f1fe\U0001f1ea", + ":flag-yt:": "\U0001f1fe\U0001f1f9", + ":flag-za:": "\U0001f1ff\U0001f1e6", + ":flag-zm:": "\U0001f1ff\U0001f1f2", + ":flag-zw:": "\U0001f1ff\U0001f1fc", + ":flag_Afghanistan:": "\U0001f1e6\U0001f1eb", + ":flag_Albania:": "\U0001f1e6\U0001f1f1", + ":flag_Algeria:": "\U0001f1e9\U0001f1ff", + ":flag_American_Samoa:": "\U0001f1e6\U0001f1f8", + ":flag_Andorra:": "\U0001f1e6\U0001f1e9", + ":flag_Angola:": "\U0001f1e6\U0001f1f4", + ":flag_Anguilla:": "\U0001f1e6\U0001f1ee", + ":flag_Antarctica:": "\U0001f1e6\U0001f1f6", + ":flag_Antigua_&_Barbuda:": "\U0001f1e6\U0001f1ec", + ":flag_Argentina:": "\U0001f1e6\U0001f1f7", + ":flag_Armenia:": "\U0001f1e6\U0001f1f2", + ":flag_Aruba:": "\U0001f1e6\U0001f1fc", + ":flag_Ascension_Island:": "\U0001f1e6\U0001f1e8", + ":flag_Australia:": "\U0001f1e6\U0001f1fa", + ":flag_Austria:": "\U0001f1e6\U0001f1f9", + ":flag_Azerbaijan:": "\U0001f1e6\U0001f1ff", + ":flag_Bahamas:": "\U0001f1e7\U0001f1f8", + ":flag_Bahrain:": "\U0001f1e7\U0001f1ed", + ":flag_Bangladesh:": "\U0001f1e7\U0001f1e9", + ":flag_Barbados:": "\U0001f1e7\U0001f1e7", + ":flag_Belarus:": "\U0001f1e7\U0001f1fe", + ":flag_Belgium:": "\U0001f1e7\U0001f1ea", + ":flag_Belize:": "\U0001f1e7\U0001f1ff", + ":flag_Benin:": "\U0001f1e7\U0001f1ef", + ":flag_Bermuda:": "\U0001f1e7\U0001f1f2", + ":flag_Bhutan:": "\U0001f1e7\U0001f1f9", + ":flag_Bolivia:": "\U0001f1e7\U0001f1f4", + ":flag_Bosnia_&_Herzegovina:": "\U0001f1e7\U0001f1e6", + ":flag_Botswana:": "\U0001f1e7\U0001f1fc", + ":flag_Bouvet_Island:": "\U0001f1e7\U0001f1fb", + ":flag_Brazil:": "\U0001f1e7\U0001f1f7", + ":flag_British_Indian_Ocean_Territory:": "\U0001f1ee\U0001f1f4", + ":flag_British_Virgin_Islands:": "\U0001f1fb\U0001f1ec", + ":flag_Brunei:": "\U0001f1e7\U0001f1f3", + ":flag_Bulgaria:": "\U0001f1e7\U0001f1ec", + ":flag_Burkina_Faso:": "\U0001f1e7\U0001f1eb", + ":flag_Burundi:": "\U0001f1e7\U0001f1ee", + ":flag_Cambodia:": "\U0001f1f0\U0001f1ed", + ":flag_Cameroon:": "\U0001f1e8\U0001f1f2", + ":flag_Canada:": "\U0001f1e8\U0001f1e6", + ":flag_Canary_Islands:": "\U0001f1ee\U0001f1e8", + ":flag_Cape_Verde:": "\U0001f1e8\U0001f1fb", + ":flag_Caribbean_Netherlands:": "\U0001f1e7\U0001f1f6", + ":flag_Cayman_Islands:": "\U0001f1f0\U0001f1fe", + ":flag_Central_African_Republic:": "\U0001f1e8\U0001f1eb", + ":flag_Ceuta_&_Melilla:": "\U0001f1ea\U0001f1e6", + ":flag_Chad:": "\U0001f1f9\U0001f1e9", + ":flag_Chile:": "\U0001f1e8\U0001f1f1", + ":flag_China:": "\U0001f1e8\U0001f1f3", + ":flag_Christmas_Island:": "\U0001f1e8\U0001f1fd", + ":flag_Clipperton_Island:": "\U0001f1e8\U0001f1f5", + ":flag_Cocos_(Keeling)_Islands:": "\U0001f1e8\U0001f1e8", + ":flag_Colombia:": "\U0001f1e8\U0001f1f4", + ":flag_Comoros:": "\U0001f1f0\U0001f1f2", + ":flag_Congo_-_Brazzaville:": "\U0001f1e8\U0001f1ec", + ":flag_Congo_-_Kinshasa:": "\U0001f1e8\U0001f1e9", + ":flag_Cook_Islands:": "\U0001f1e8\U0001f1f0", + ":flag_Costa_Rica:": "\U0001f1e8\U0001f1f7", + ":flag_Croatia:": "\U0001f1ed\U0001f1f7", + ":flag_Cuba:": "\U0001f1e8\U0001f1fa", + ":flag_Curaçao:": "\U0001f1e8\U0001f1fc", + ":flag_Cyprus:": "\U0001f1e8\U0001f1fe", + ":flag_Czechia:": "\U0001f1e8\U0001f1ff", + ":flag_Côte_d’Ivoire:": "\U0001f1e8\U0001f1ee", + ":flag_Denmark:": "\U0001f1e9\U0001f1f0", + ":flag_Diego_Garcia:": "\U0001f1e9\U0001f1ec", + ":flag_Djibouti:": "\U0001f1e9\U0001f1ef", + ":flag_Dominica:": "\U0001f1e9\U0001f1f2", + ":flag_Dominican_Republic:": "\U0001f1e9\U0001f1f4", + ":flag_Ecuador:": "\U0001f1ea\U0001f1e8", + ":flag_Egypt:": "\U0001f1ea\U0001f1ec", + ":flag_El_Salvador:": "\U0001f1f8\U0001f1fb", + ":flag_England:": "\U0001f3f4\U000e0067\U000e0062\U000e0065\U000e006e\U000e0067\U000e007f", + ":flag_Equatorial_Guinea:": "\U0001f1ec\U0001f1f6", + ":flag_Eritrea:": "\U0001f1ea\U0001f1f7", + ":flag_Estonia:": "\U0001f1ea\U0001f1ea", + ":flag_Eswatini:": "\U0001f1f8\U0001f1ff", + ":flag_Ethiopia:": "\U0001f1ea\U0001f1f9", + ":flag_European_Union:": "\U0001f1ea\U0001f1fa", + ":flag_Falkland_Islands:": "\U0001f1eb\U0001f1f0", + ":flag_Faroe_Islands:": "\U0001f1eb\U0001f1f4", + ":flag_Fiji:": "\U0001f1eb\U0001f1ef", + ":flag_Finland:": "\U0001f1eb\U0001f1ee", + ":flag_France:": "\U0001f1eb\U0001f1f7", + ":flag_French_Guiana:": "\U0001f1ec\U0001f1eb", + ":flag_French_Polynesia:": "\U0001f1f5\U0001f1eb", + ":flag_French_Southern_Territories:": "\U0001f1f9\U0001f1eb", + ":flag_Gabon:": "\U0001f1ec\U0001f1e6", + ":flag_Gambia:": "\U0001f1ec\U0001f1f2", + ":flag_Georgia:": "\U0001f1ec\U0001f1ea", + ":flag_Germany:": "\U0001f1e9\U0001f1ea", + ":flag_Ghana:": "\U0001f1ec\U0001f1ed", + ":flag_Gibraltar:": "\U0001f1ec\U0001f1ee", + ":flag_Greece:": "\U0001f1ec\U0001f1f7", + ":flag_Greenland:": "\U0001f1ec\U0001f1f1", + ":flag_Grenada:": "\U0001f1ec\U0001f1e9", + ":flag_Guadeloupe:": "\U0001f1ec\U0001f1f5", + ":flag_Guam:": "\U0001f1ec\U0001f1fa", + ":flag_Guatemala:": "\U0001f1ec\U0001f1f9", + ":flag_Guernsey:": "\U0001f1ec\U0001f1ec", + ":flag_Guinea:": "\U0001f1ec\U0001f1f3", + ":flag_Guinea-Bissau:": "\U0001f1ec\U0001f1fc", + ":flag_Guyana:": "\U0001f1ec\U0001f1fe", + ":flag_Haiti:": "\U0001f1ed\U0001f1f9", + ":flag_Heard_&_McDonald_Islands:": "\U0001f1ed\U0001f1f2", + ":flag_Honduras:": "\U0001f1ed\U0001f1f3", + ":flag_Hong_Kong_SAR_China:": "\U0001f1ed\U0001f1f0", + ":flag_Hungary:": "\U0001f1ed\U0001f1fa", + ":flag_Iceland:": "\U0001f1ee\U0001f1f8", + ":flag_India:": "\U0001f1ee\U0001f1f3", + ":flag_Indonesia:": "\U0001f1ee\U0001f1e9", + ":flag_Iran:": "\U0001f1ee\U0001f1f7", + ":flag_Iraq:": "\U0001f1ee\U0001f1f6", + ":flag_Ireland:": "\U0001f1ee\U0001f1ea", + ":flag_Isle_of_Man:": "\U0001f1ee\U0001f1f2", + ":flag_Israel:": "\U0001f1ee\U0001f1f1", + ":flag_Italy:": "\U0001f1ee\U0001f1f9", + ":flag_Jamaica:": "\U0001f1ef\U0001f1f2", + ":flag_Japan:": "\U0001f1ef\U0001f1f5", + ":flag_Jersey:": "\U0001f1ef\U0001f1ea", + ":flag_Jordan:": "\U0001f1ef\U0001f1f4", + ":flag_Kazakhstan:": "\U0001f1f0\U0001f1ff", + ":flag_Kenya:": "\U0001f1f0\U0001f1ea", + ":flag_Kiribati:": "\U0001f1f0\U0001f1ee", + ":flag_Kosovo:": "\U0001f1fd\U0001f1f0", + ":flag_Kuwait:": "\U0001f1f0\U0001f1fc", + ":flag_Kyrgyzstan:": "\U0001f1f0\U0001f1ec", + ":flag_Laos:": "\U0001f1f1\U0001f1e6", + ":flag_Latvia:": "\U0001f1f1\U0001f1fb", + ":flag_Lebanon:": "\U0001f1f1\U0001f1e7", + ":flag_Lesotho:": "\U0001f1f1\U0001f1f8", + ":flag_Liberia:": "\U0001f1f1\U0001f1f7", + ":flag_Libya:": "\U0001f1f1\U0001f1fe", + ":flag_Liechtenstein:": "\U0001f1f1\U0001f1ee", + ":flag_Lithuania:": "\U0001f1f1\U0001f1f9", + ":flag_Luxembourg:": "\U0001f1f1\U0001f1fa", + ":flag_Macao_SAR_China:": "\U0001f1f2\U0001f1f4", + ":flag_Madagascar:": "\U0001f1f2\U0001f1ec", + ":flag_Malawi:": "\U0001f1f2\U0001f1fc", + ":flag_Malaysia:": "\U0001f1f2\U0001f1fe", + ":flag_Maldives:": "\U0001f1f2\U0001f1fb", + ":flag_Mali:": "\U0001f1f2\U0001f1f1", + ":flag_Malta:": "\U0001f1f2\U0001f1f9", + ":flag_Marshall_Islands:": "\U0001f1f2\U0001f1ed", + ":flag_Martinique:": "\U0001f1f2\U0001f1f6", + ":flag_Mauritania:": "\U0001f1f2\U0001f1f7", + ":flag_Mauritius:": "\U0001f1f2\U0001f1fa", + ":flag_Mayotte:": "\U0001f1fe\U0001f1f9", + ":flag_Mexico:": "\U0001f1f2\U0001f1fd", + ":flag_Micronesia:": "\U0001f1eb\U0001f1f2", + ":flag_Moldova:": "\U0001f1f2\U0001f1e9", + ":flag_Monaco:": "\U0001f1f2\U0001f1e8", + ":flag_Mongolia:": "\U0001f1f2\U0001f1f3", + ":flag_Montenegro:": "\U0001f1f2\U0001f1ea", + ":flag_Montserrat:": "\U0001f1f2\U0001f1f8", + ":flag_Morocco:": "\U0001f1f2\U0001f1e6", + ":flag_Mozambique:": "\U0001f1f2\U0001f1ff", + ":flag_Myanmar_(Burma):": "\U0001f1f2\U0001f1f2", + ":flag_Namibia:": "\U0001f1f3\U0001f1e6", + ":flag_Nauru:": "\U0001f1f3\U0001f1f7", + ":flag_Nepal:": "\U0001f1f3\U0001f1f5", + ":flag_Netherlands:": "\U0001f1f3\U0001f1f1", + ":flag_New_Caledonia:": "\U0001f1f3\U0001f1e8", + ":flag_New_Zealand:": "\U0001f1f3\U0001f1ff", + ":flag_Nicaragua:": "\U0001f1f3\U0001f1ee", + ":flag_Niger:": "\U0001f1f3\U0001f1ea", + ":flag_Nigeria:": "\U0001f1f3\U0001f1ec", + ":flag_Niue:": "\U0001f1f3\U0001f1fa", + ":flag_Norfolk_Island:": "\U0001f1f3\U0001f1eb", + ":flag_North_Korea:": "\U0001f1f0\U0001f1f5", + ":flag_North_Macedonia:": "\U0001f1f2\U0001f1f0", + ":flag_Northern_Mariana_Islands:": "\U0001f1f2\U0001f1f5", + ":flag_Norway:": "\U0001f1f3\U0001f1f4", + ":flag_Oman:": "\U0001f1f4\U0001f1f2", + ":flag_Pakistan:": "\U0001f1f5\U0001f1f0", + ":flag_Palau:": "\U0001f1f5\U0001f1fc", + ":flag_Palestinian_Territories:": "\U0001f1f5\U0001f1f8", + ":flag_Panama:": "\U0001f1f5\U0001f1e6", + ":flag_Papua_New_Guinea:": "\U0001f1f5\U0001f1ec", + ":flag_Paraguay:": "\U0001f1f5\U0001f1fe", + ":flag_Peru:": "\U0001f1f5\U0001f1ea", + ":flag_Philippines:": "\U0001f1f5\U0001f1ed", + ":flag_Pitcairn_Islands:": "\U0001f1f5\U0001f1f3", + ":flag_Poland:": "\U0001f1f5\U0001f1f1", + ":flag_Portugal:": "\U0001f1f5\U0001f1f9", + ":flag_Puerto_Rico:": "\U0001f1f5\U0001f1f7", + ":flag_Qatar:": "\U0001f1f6\U0001f1e6", + ":flag_Romania:": "\U0001f1f7\U0001f1f4", + ":flag_Russia:": "\U0001f1f7\U0001f1fa", + ":flag_Rwanda:": "\U0001f1f7\U0001f1fc", + ":flag_Réunion:": "\U0001f1f7\U0001f1ea", + ":flag_Samoa:": "\U0001f1fc\U0001f1f8", + ":flag_San_Marino:": "\U0001f1f8\U0001f1f2", + ":flag_Saudi_Arabia:": "\U0001f1f8\U0001f1e6", + ":flag_Scotland:": "\U0001f3f4\U000e0067\U000e0062\U000e0073\U000e0063\U000e0074\U000e007f", + ":flag_Senegal:": "\U0001f1f8\U0001f1f3", + ":flag_Serbia:": "\U0001f1f7\U0001f1f8", + ":flag_Seychelles:": "\U0001f1f8\U0001f1e8", + ":flag_Sierra_Leone:": "\U0001f1f8\U0001f1f1", + ":flag_Singapore:": "\U0001f1f8\U0001f1ec", + ":flag_Sint_Maarten:": "\U0001f1f8\U0001f1fd", + ":flag_Slovakia:": "\U0001f1f8\U0001f1f0", + ":flag_Slovenia:": "\U0001f1f8\U0001f1ee", + ":flag_Solomon_Islands:": "\U0001f1f8\U0001f1e7", + ":flag_Somalia:": "\U0001f1f8\U0001f1f4", + ":flag_South_Africa:": "\U0001f1ff\U0001f1e6", + ":flag_South_Georgia_&_South_Sandwich_Islands:": "\U0001f1ec\U0001f1f8", + ":flag_South_Korea:": "\U0001f1f0\U0001f1f7", + ":flag_South_Sudan:": "\U0001f1f8\U0001f1f8", + ":flag_Spain:": "\U0001f1ea\U0001f1f8", + ":flag_Sri_Lanka:": "\U0001f1f1\U0001f1f0", + ":flag_St._Barthélemy:": "\U0001f1e7\U0001f1f1", + ":flag_St._Helena:": "\U0001f1f8\U0001f1ed", + ":flag_St._Kitts_&_Nevis:": "\U0001f1f0\U0001f1f3", + ":flag_St._Lucia:": "\U0001f1f1\U0001f1e8", + ":flag_St._Martin:": "\U0001f1f2\U0001f1eb", + ":flag_St._Pierre_&_Miquelon:": "\U0001f1f5\U0001f1f2", + ":flag_St._Vincent_&_Grenadines:": "\U0001f1fb\U0001f1e8", + ":flag_Sudan:": "\U0001f1f8\U0001f1e9", + ":flag_Suriname:": "\U0001f1f8\U0001f1f7", + ":flag_Svalbard_&_Jan_Mayen:": "\U0001f1f8\U0001f1ef", + ":flag_Sweden:": "\U0001f1f8\U0001f1ea", + ":flag_Switzerland:": "\U0001f1e8\U0001f1ed", + ":flag_Syria:": "\U0001f1f8\U0001f1fe", + ":flag_São_Tomé_&_Príncipe:": "\U0001f1f8\U0001f1f9", + ":flag_Taiwan:": "\U0001f1f9\U0001f1fc", + ":flag_Tajikistan:": "\U0001f1f9\U0001f1ef", + ":flag_Tanzania:": "\U0001f1f9\U0001f1ff", + ":flag_Thailand:": "\U0001f1f9\U0001f1ed", + ":flag_Timor-Leste:": "\U0001f1f9\U0001f1f1", + ":flag_Togo:": "\U0001f1f9\U0001f1ec", + ":flag_Tokelau:": "\U0001f1f9\U0001f1f0", + ":flag_Tonga:": "\U0001f1f9\U0001f1f4", + ":flag_Trinidad_&_Tobago:": "\U0001f1f9\U0001f1f9", + ":flag_Tristan_da_Cunha:": "\U0001f1f9\U0001f1e6", + ":flag_Tunisia:": "\U0001f1f9\U0001f1f3", + ":flag_Turkey:": "\U0001f1f9\U0001f1f7", + ":flag_Turkmenistan:": "\U0001f1f9\U0001f1f2", + ":flag_Turks_&_Caicos_Islands:": "\U0001f1f9\U0001f1e8", + ":flag_Tuvalu:": "\U0001f1f9\U0001f1fb", + ":flag_U.S._Outlying_Islands:": "\U0001f1fa\U0001f1f2", + ":flag_U.S._Virgin_Islands:": "\U0001f1fb\U0001f1ee", + ":flag_Uganda:": "\U0001f1fa\U0001f1ec", + ":flag_Ukraine:": "\U0001f1fa\U0001f1e6", + ":flag_United_Arab_Emirates:": "\U0001f1e6\U0001f1ea", + ":flag_United_Kingdom:": "\U0001f1ec\U0001f1e7", + ":flag_United_Nations:": "\U0001f1fa\U0001f1f3", + ":flag_United_States:": "\U0001f1fa\U0001f1f8", + ":flag_Uruguay:": "\U0001f1fa\U0001f1fe", + ":flag_Uzbekistan:": "\U0001f1fa\U0001f1ff", + ":flag_Vanuatu:": "\U0001f1fb\U0001f1fa", + ":flag_Vatican_City:": "\U0001f1fb\U0001f1e6", + ":flag_Venezuela:": "\U0001f1fb\U0001f1ea", + ":flag_Vietnam:": "\U0001f1fb\U0001f1f3", + ":flag_Wales:": "\U0001f3f4\U000e0067\U000e0062\U000e0077\U000e006c\U000e0073\U000e007f", + ":flag_Wallis_&_Futuna:": "\U0001f1fc\U0001f1eb", + ":flag_Western_Sahara:": "\U0001f1ea\U0001f1ed", + ":flag_Yemen:": "\U0001f1fe\U0001f1ea", + ":flag_Zambia:": "\U0001f1ff\U0001f1f2", + ":flag_Zimbabwe:": "\U0001f1ff\U0001f1fc", + ":flag_ac:": "\U0001f1e6\U0001f1e8", + ":flag_ad:": "\U0001f1e6\U0001f1e9", + ":flag_ae:": "\U0001f1e6\U0001f1ea", + ":flag_af:": "\U0001f1e6\U0001f1eb", + ":flag_ag:": "\U0001f1e6\U0001f1ec", + ":flag_ai:": "\U0001f1e6\U0001f1ee", + ":flag_al:": "\U0001f1e6\U0001f1f1", + ":flag_am:": "\U0001f1e6\U0001f1f2", + ":flag_ao:": "\U0001f1e6\U0001f1f4", + ":flag_aq:": "\U0001f1e6\U0001f1f6", + ":flag_ar:": "\U0001f1e6\U0001f1f7", + ":flag_as:": "\U0001f1e6\U0001f1f8", + ":flag_at:": "\U0001f1e6\U0001f1f9", + ":flag_au:": "\U0001f1e6\U0001f1fa", + ":flag_aw:": "\U0001f1e6\U0001f1fc", + ":flag_ax:": "\U0001f1e6\U0001f1fd", + ":flag_az:": "\U0001f1e6\U0001f1ff", + ":flag_ba:": "\U0001f1e7\U0001f1e6", + ":flag_bb:": "\U0001f1e7\U0001f1e7", + ":flag_bd:": "\U0001f1e7\U0001f1e9", + ":flag_be:": "\U0001f1e7\U0001f1ea", + ":flag_bf:": "\U0001f1e7\U0001f1eb", + ":flag_bg:": "\U0001f1e7\U0001f1ec", + ":flag_bh:": "\U0001f1e7\U0001f1ed", + ":flag_bi:": "\U0001f1e7\U0001f1ee", + ":flag_bj:": "\U0001f1e7\U0001f1ef", + ":flag_bl:": "\U0001f1e7\U0001f1f1", + ":flag_black:": "\U0001f3f4", + ":flag_bm:": "\U0001f1e7\U0001f1f2", + ":flag_bn:": "\U0001f1e7\U0001f1f3", + ":flag_bo:": "\U0001f1e7\U0001f1f4", + ":flag_bq:": "\U0001f1e7\U0001f1f6", + ":flag_br:": "\U0001f1e7\U0001f1f7", + ":flag_bs:": "\U0001f1e7\U0001f1f8", + ":flag_bt:": "\U0001f1e7\U0001f1f9", + ":flag_bv:": "\U0001f1e7\U0001f1fb", + ":flag_bw:": "\U0001f1e7\U0001f1fc", + ":flag_by:": "\U0001f1e7\U0001f1fe", + ":flag_bz:": "\U0001f1e7\U0001f1ff", + ":flag_ca:": "\U0001f1e8\U0001f1e6", + ":flag_cc:": "\U0001f1e8\U0001f1e8", + ":flag_cd:": "\U0001f1e8\U0001f1e9", + ":flag_cf:": "\U0001f1e8\U0001f1eb", + ":flag_cg:": "\U0001f1e8\U0001f1ec", + ":flag_ch:": "\U0001f1e8\U0001f1ed", + ":flag_ci:": "\U0001f1e8\U0001f1ee", + ":flag_ck:": "\U0001f1e8\U0001f1f0", + ":flag_cl:": "\U0001f1e8\U0001f1f1", + ":flag_cm:": "\U0001f1e8\U0001f1f2", + ":flag_cn:": "\U0001f1e8\U0001f1f3", + ":flag_co:": "\U0001f1e8\U0001f1f4", + ":flag_cp:": "\U0001f1e8\U0001f1f5", + ":flag_cr:": "\U0001f1e8\U0001f1f7", + ":flag_cu:": "\U0001f1e8\U0001f1fa", + ":flag_cv:": "\U0001f1e8\U0001f1fb", + ":flag_cw:": "\U0001f1e8\U0001f1fc", + ":flag_cx:": "\U0001f1e8\U0001f1fd", + ":flag_cy:": "\U0001f1e8\U0001f1fe", + ":flag_cz:": "\U0001f1e8\U0001f1ff", + ":flag_de:": "\U0001f1e9\U0001f1ea", + ":flag_dg:": "\U0001f1e9\U0001f1ec", + ":flag_dj:": "\U0001f1e9\U0001f1ef", + ":flag_dk:": "\U0001f1e9\U0001f1f0", + ":flag_dm:": "\U0001f1e9\U0001f1f2", + ":flag_do:": "\U0001f1e9\U0001f1f4", + ":flag_dz:": "\U0001f1e9\U0001f1ff", + ":flag_ea:": "\U0001f1ea\U0001f1e6", + ":flag_ec:": "\U0001f1ea\U0001f1e8", + ":flag_ee:": "\U0001f1ea\U0001f1ea", + ":flag_eg:": "\U0001f1ea\U0001f1ec", + ":flag_eh:": "\U0001f1ea\U0001f1ed", + ":flag_er:": "\U0001f1ea\U0001f1f7", + ":flag_es:": "\U0001f1ea\U0001f1f8", + ":flag_et:": "\U0001f1ea\U0001f1f9", + ":flag_eu:": "\U0001f1ea\U0001f1fa", + ":flag_fi:": "\U0001f1eb\U0001f1ee", + ":flag_fj:": "\U0001f1eb\U0001f1ef", + ":flag_fk:": "\U0001f1eb\U0001f1f0", + ":flag_fm:": "\U0001f1eb\U0001f1f2", + ":flag_fo:": "\U0001f1eb\U0001f1f4", + ":flag_fr:": "\U0001f1eb\U0001f1f7", + ":flag_ga:": "\U0001f1ec\U0001f1e6", + ":flag_gb:": "\U0001f1ec\U0001f1e7", + ":flag_gd:": "\U0001f1ec\U0001f1e9", + ":flag_ge:": "\U0001f1ec\U0001f1ea", + ":flag_gf:": "\U0001f1ec\U0001f1eb", + ":flag_gg:": "\U0001f1ec\U0001f1ec", + ":flag_gh:": "\U0001f1ec\U0001f1ed", + ":flag_gi:": "\U0001f1ec\U0001f1ee", + ":flag_gl:": "\U0001f1ec\U0001f1f1", + ":flag_gm:": "\U0001f1ec\U0001f1f2", + ":flag_gn:": "\U0001f1ec\U0001f1f3", + ":flag_gp:": "\U0001f1ec\U0001f1f5", + ":flag_gq:": "\U0001f1ec\U0001f1f6", + ":flag_gr:": "\U0001f1ec\U0001f1f7", + ":flag_gs:": "\U0001f1ec\U0001f1f8", + ":flag_gt:": "\U0001f1ec\U0001f1f9", + ":flag_gu:": "\U0001f1ec\U0001f1fa", + ":flag_gw:": "\U0001f1ec\U0001f1fc", + ":flag_gy:": "\U0001f1ec\U0001f1fe", + ":flag_hk:": "\U0001f1ed\U0001f1f0", + ":flag_hm:": "\U0001f1ed\U0001f1f2", + ":flag_hn:": "\U0001f1ed\U0001f1f3", + ":flag_hr:": "\U0001f1ed\U0001f1f7", + ":flag_ht:": "\U0001f1ed\U0001f1f9", + ":flag_hu:": "\U0001f1ed\U0001f1fa", + ":flag_ic:": "\U0001f1ee\U0001f1e8", + ":flag_id:": "\U0001f1ee\U0001f1e9", + ":flag_ie:": "\U0001f1ee\U0001f1ea", + ":flag_il:": "\U0001f1ee\U0001f1f1", + ":flag_im:": "\U0001f1ee\U0001f1f2", + ":flag_in:": "\U0001f1ee\U0001f1f3", + ":flag_in_hole:": "\u26f3", + ":flag_io:": "\U0001f1ee\U0001f1f4", + ":flag_iq:": "\U0001f1ee\U0001f1f6", + ":flag_ir:": "\U0001f1ee\U0001f1f7", + ":flag_is:": "\U0001f1ee\U0001f1f8", + ":flag_it:": "\U0001f1ee\U0001f1f9", + ":flag_je:": "\U0001f1ef\U0001f1ea", + ":flag_jm:": "\U0001f1ef\U0001f1f2", + ":flag_jo:": "\U0001f1ef\U0001f1f4", + ":flag_jp:": "\U0001f1ef\U0001f1f5", + ":flag_ke:": "\U0001f1f0\U0001f1ea", + ":flag_kg:": "\U0001f1f0\U0001f1ec", + ":flag_kh:": "\U0001f1f0\U0001f1ed", + ":flag_ki:": "\U0001f1f0\U0001f1ee", + ":flag_km:": "\U0001f1f0\U0001f1f2", + ":flag_kn:": "\U0001f1f0\U0001f1f3", + ":flag_kp:": "\U0001f1f0\U0001f1f5", + ":flag_kr:": "\U0001f1f0\U0001f1f7", + ":flag_kw:": "\U0001f1f0\U0001f1fc", + ":flag_ky:": "\U0001f1f0\U0001f1fe", + ":flag_kz:": "\U0001f1f0\U0001f1ff", + ":flag_la:": "\U0001f1f1\U0001f1e6", + ":flag_lb:": "\U0001f1f1\U0001f1e7", + ":flag_lc:": "\U0001f1f1\U0001f1e8", + ":flag_li:": "\U0001f1f1\U0001f1ee", + ":flag_lk:": "\U0001f1f1\U0001f1f0", + ":flag_lr:": "\U0001f1f1\U0001f1f7", + ":flag_ls:": "\U0001f1f1\U0001f1f8", + ":flag_lt:": "\U0001f1f1\U0001f1f9", + ":flag_lu:": "\U0001f1f1\U0001f1fa", + ":flag_lv:": "\U0001f1f1\U0001f1fb", + ":flag_ly:": "\U0001f1f1\U0001f1fe", + ":flag_ma:": "\U0001f1f2\U0001f1e6", + ":flag_mc:": "\U0001f1f2\U0001f1e8", + ":flag_md:": "\U0001f1f2\U0001f1e9", + ":flag_me:": "\U0001f1f2\U0001f1ea", + ":flag_mf:": "\U0001f1f2\U0001f1eb", + ":flag_mg:": "\U0001f1f2\U0001f1ec", + ":flag_mh:": "\U0001f1f2\U0001f1ed", + ":flag_mk:": "\U0001f1f2\U0001f1f0", + ":flag_ml:": "\U0001f1f2\U0001f1f1", + ":flag_mm:": "\U0001f1f2\U0001f1f2", + ":flag_mn:": "\U0001f1f2\U0001f1f3", + ":flag_mo:": "\U0001f1f2\U0001f1f4", + ":flag_mp:": "\U0001f1f2\U0001f1f5", + ":flag_mq:": "\U0001f1f2\U0001f1f6", + ":flag_mr:": "\U0001f1f2\U0001f1f7", + ":flag_ms:": "\U0001f1f2\U0001f1f8", + ":flag_mt:": "\U0001f1f2\U0001f1f9", + ":flag_mu:": "\U0001f1f2\U0001f1fa", + ":flag_mv:": "\U0001f1f2\U0001f1fb", + ":flag_mw:": "\U0001f1f2\U0001f1fc", + ":flag_mx:": "\U0001f1f2\U0001f1fd", + ":flag_my:": "\U0001f1f2\U0001f1fe", + ":flag_mz:": "\U0001f1f2\U0001f1ff", + ":flag_na:": "\U0001f1f3\U0001f1e6", + ":flag_nc:": "\U0001f1f3\U0001f1e8", + ":flag_ne:": "\U0001f1f3\U0001f1ea", + ":flag_nf:": "\U0001f1f3\U0001f1eb", + ":flag_ng:": "\U0001f1f3\U0001f1ec", + ":flag_ni:": "\U0001f1f3\U0001f1ee", + ":flag_nl:": "\U0001f1f3\U0001f1f1", + ":flag_no:": "\U0001f1f3\U0001f1f4", + ":flag_np:": "\U0001f1f3\U0001f1f5", + ":flag_nr:": "\U0001f1f3\U0001f1f7", + ":flag_nu:": "\U0001f1f3\U0001f1fa", + ":flag_nz:": "\U0001f1f3\U0001f1ff", + ":flag_om:": "\U0001f1f4\U0001f1f2", + ":flag_pa:": "\U0001f1f5\U0001f1e6", + ":flag_pe:": "\U0001f1f5\U0001f1ea", + ":flag_pf:": "\U0001f1f5\U0001f1eb", + ":flag_pg:": "\U0001f1f5\U0001f1ec", + ":flag_ph:": "\U0001f1f5\U0001f1ed", + ":flag_pk:": "\U0001f1f5\U0001f1f0", + ":flag_pl:": "\U0001f1f5\U0001f1f1", + ":flag_pm:": "\U0001f1f5\U0001f1f2", + ":flag_pn:": "\U0001f1f5\U0001f1f3", + ":flag_pr:": "\U0001f1f5\U0001f1f7", + ":flag_ps:": "\U0001f1f5\U0001f1f8", + ":flag_pt:": "\U0001f1f5\U0001f1f9", + ":flag_pw:": "\U0001f1f5\U0001f1fc", + ":flag_py:": "\U0001f1f5\U0001f1fe", + ":flag_qa:": "\U0001f1f6\U0001f1e6", + ":flag_re:": "\U0001f1f7\U0001f1ea", + ":flag_ro:": "\U0001f1f7\U0001f1f4", + ":flag_rs:": "\U0001f1f7\U0001f1f8", + ":flag_ru:": "\U0001f1f7\U0001f1fa", + ":flag_rw:": "\U0001f1f7\U0001f1fc", + ":flag_sa:": "\U0001f1f8\U0001f1e6", + ":flag_sb:": "\U0001f1f8\U0001f1e7", + ":flag_sc:": "\U0001f1f8\U0001f1e8", + ":flag_sd:": "\U0001f1f8\U0001f1e9", + ":flag_se:": "\U0001f1f8\U0001f1ea", + ":flag_sg:": "\U0001f1f8\U0001f1ec", + ":flag_sh:": "\U0001f1f8\U0001f1ed", + ":flag_si:": "\U0001f1f8\U0001f1ee", + ":flag_sj:": "\U0001f1f8\U0001f1ef", + ":flag_sk:": "\U0001f1f8\U0001f1f0", + ":flag_sl:": "\U0001f1f8\U0001f1f1", + ":flag_sm:": "\U0001f1f8\U0001f1f2", + ":flag_sn:": "\U0001f1f8\U0001f1f3", + ":flag_so:": "\U0001f1f8\U0001f1f4", + ":flag_sr:": "\U0001f1f8\U0001f1f7", + ":flag_ss:": "\U0001f1f8\U0001f1f8", + ":flag_st:": "\U0001f1f8\U0001f1f9", + ":flag_sv:": "\U0001f1f8\U0001f1fb", + ":flag_sx:": "\U0001f1f8\U0001f1fd", + ":flag_sy:": "\U0001f1f8\U0001f1fe", + ":flag_sz:": "\U0001f1f8\U0001f1ff", + ":flag_ta:": "\U0001f1f9\U0001f1e6", + ":flag_tc:": "\U0001f1f9\U0001f1e8", + ":flag_td:": "\U0001f1f9\U0001f1e9", + ":flag_tf:": "\U0001f1f9\U0001f1eb", + ":flag_tg:": "\U0001f1f9\U0001f1ec", + ":flag_th:": "\U0001f1f9\U0001f1ed", + ":flag_tj:": "\U0001f1f9\U0001f1ef", + ":flag_tk:": "\U0001f1f9\U0001f1f0", + ":flag_tl:": "\U0001f1f9\U0001f1f1", + ":flag_tm:": "\U0001f1f9\U0001f1f2", + ":flag_tn:": "\U0001f1f9\U0001f1f3", + ":flag_to:": "\U0001f1f9\U0001f1f4", + ":flag_tr:": "\U0001f1f9\U0001f1f7", + ":flag_tt:": "\U0001f1f9\U0001f1f9", + ":flag_tv:": "\U0001f1f9\U0001f1fb", + ":flag_tw:": "\U0001f1f9\U0001f1fc", + ":flag_tz:": "\U0001f1f9\U0001f1ff", + ":flag_ua:": "\U0001f1fa\U0001f1e6", + ":flag_ug:": "\U0001f1fa\U0001f1ec", + ":flag_um:": "\U0001f1fa\U0001f1f2", + ":flag_us:": "\U0001f1fa\U0001f1f8", + ":flag_uy:": "\U0001f1fa\U0001f1fe", + ":flag_uz:": "\U0001f1fa\U0001f1ff", + ":flag_va:": "\U0001f1fb\U0001f1e6", + ":flag_vc:": "\U0001f1fb\U0001f1e8", + ":flag_ve:": "\U0001f1fb\U0001f1ea", + ":flag_vg:": "\U0001f1fb\U0001f1ec", + ":flag_vi:": "\U0001f1fb\U0001f1ee", + ":flag_vn:": "\U0001f1fb\U0001f1f3", + ":flag_vu:": "\U0001f1fb\U0001f1fa", + ":flag_wf:": "\U0001f1fc\U0001f1eb", + ":flag_white:": "\U0001f3f3", + ":flag_ws:": "\U0001f1fc\U0001f1f8", + ":flag_xk:": "\U0001f1fd\U0001f1f0", + ":flag_ye:": "\U0001f1fe\U0001f1ea", + ":flag_yt:": "\U0001f1fe\U0001f1f9", + ":flag_za:": "\U0001f1ff\U0001f1e6", + ":flag_zm:": "\U0001f1ff\U0001f1f2", + ":flag_zw:": "\U0001f1ff\U0001f1fc", + ":flag_Åland_Islands:": "\U0001f1e6\U0001f1fd", + ":flags:": "\U0001f38f", + ":flamingo:": "\U0001f9a9", + ":flashlight:": "\U0001f526", + ":flat_shoe:": "\U0001f97f", + ":flatbread:": "\U0001fad3", + ":fleur-de-lis:": "\u269c", + ":fleur_de_lis:": "\u269c\ufe0f", + ":flexed_biceps:": "\U0001f4aa", + ":flight_arrival:": "\U0001f6ec", + ":flight_departure:": "\U0001f6eb", + ":flipper:": "\U0001f42c", + ":floppy_disk:": "\U0001f4be", + ":flower_playing_cards:": "\U0001f3b4", + ":flushed:": "\U0001f633", + ":flushed_face:": "\U0001f633", + ":fly:": "\U0001fab0", + ":flying_disc:": "\U0001f94f", + ":flying_saucer:": "\U0001f6f8", + ":fog:": "\U0001f32b\ufe0f", + ":foggy:": "\U0001f301", + ":folded_hands:": "\U0001f64f", + ":fondue:": "\U0001fad5", + ":foot:": "\U0001f9b6", + ":football:": "\U0001f3c8", + ":footprints:": "\U0001f463", + ":fork_and_knife:": "\U0001f374", + ":fork_and_knife_with_plate:": "\U0001f37d", + ":fork_knife_plate:": "\U0001f37d", + ":fortune_cookie:": "\U0001f960", + ":fountain:": "\u26f2", + ":fountain_pen:": "\U0001f58b", + ":four:": "4\ufe0f\u20e3", + ":four-thirty:": "\U0001f55f", + ":four_leaf_clover:": "\U0001f340", + ":four_o’clock:": "\U0001f553", + ":fox:": "\U0001f98a", + ":fox_face:": "\U0001f98a", + ":fr:": "\U0001f1eb\U0001f1f7", + ":frame_photo:": "\U0001f5bc", + ":frame_with_picture:": "\U0001f5bc\ufe0f", + ":framed_picture:": "\U0001f5bc", + ":free:": "\U0001f193", + ":french_bread:": "\U0001f956", + ":french_fries:": "\U0001f35f", + ":french_guiana:": "\U0001f1ec\U0001f1eb", + ":french_polynesia:": "\U0001f1f5\U0001f1eb", + ":french_southern_territories:": "\U0001f1f9\U0001f1eb", + ":fried_egg:": "\U0001f373", + ":fried_shrimp:": "\U0001f364", + ":fries:": "\U0001f35f", + ":frog:": "\U0001f438", + ":front-facing_baby_chick:": "\U0001f425", + ":frowning:": "\U0001f626", + ":frowning2:": "\u2639", + ":frowning_face:": "\u2639", + ":frowning_face_with_open_mouth:": "\U0001f626", + ":frowning_man:": "\U0001f64d\u200d\u2642\ufe0f", + ":frowning_person:": "\U0001f64d", + ":frowning_woman:": "\U0001f64d\u200d\u2640\ufe0f", + ":fu:": "\U0001f595", + ":fuel_pump:": "\u26fd", + ":fuelpump:": "\u26fd", + ":full_moon:": "\U0001f315", + ":full_moon_face:": "\U0001f31d", + ":full_moon_with_face:": "\U0001f31d", + ":funeral_urn:": "\u26b1\ufe0f", + ":gabon:": "\U0001f1ec\U0001f1e6", + ":gambia:": "\U0001f1ec\U0001f1f2", + ":game_die:": "\U0001f3b2", + ":garlic:": "\U0001f9c4", + ":gb:": "\U0001f1ec\U0001f1e7", + ":gear:": "\u2699\ufe0f", + ":gem:": "\U0001f48e", + ":gem_stone:": "\U0001f48e", + ":gemini:": "\u264a", + ":genie:": "\U0001f9de\u200d\u2642\ufe0f", + ":genie_man:": "\U0001f9de\u200d\u2642\ufe0f", + ":genie_woman:": "\U0001f9de\u200d\u2640\ufe0f", + ":georgia:": "\U0001f1ec\U0001f1ea", + ":ghana:": "\U0001f1ec\U0001f1ed", + ":ghost:": "\U0001f47b", + ":gibraltar:": "\U0001f1ec\U0001f1ee", + ":gift:": "\U0001f381", + ":gift_heart:": "\U0001f49d", + ":giraffe:": "\U0001f992", + ":giraffe_face:": "\U0001f992", + ":girl:": "\U0001f467", + ":girl::skin-tone-1:": "\U0001f467\U0001f3fb", + ":girl::skin-tone-2:": "\U0001f467\U0001f3fc", + ":girl::skin-tone-3:": "\U0001f467\U0001f3fd", + ":girl::skin-tone-4:": "\U0001f467\U0001f3fe", + ":girl::skin-tone-5:": "\U0001f467\U0001f3ff", + ":glass_of_milk:": "\U0001f95b", + ":glasses:": "\U0001f453", + ":globe_showing_Americas:": "\U0001f30e", + ":globe_showing_Asia-Australia:": "\U0001f30f", + ":globe_showing_Europe-Africa:": "\U0001f30d", + ":globe_with_meridians:": "\U0001f310", + ":gloves:": "\U0001f9e4", + ":glowing_star:": "\U0001f31f", + ":goal:": "\U0001f945", + ":goal_net:": "\U0001f945", + ":goat:": "\U0001f410", + ":goblin:": "\U0001f47a", + ":goggles:": "\U0001f97d", + ":golf:": "\u26f3", + ":golfer:": "\U0001f3cc\ufe0f\u200d\u2642\ufe0f", + ":golfing:": "\U0001f3cc\ufe0f", + ":golfing_man:": "\U0001f3cc\ufe0f\u200d\u2642\ufe0f", + ":golfing_woman:": "\U0001f3cc\ufe0f\u200d\u2640\ufe0f", + ":gorilla:": "\U0001f98d", + ":graduation_cap:": "\U0001f393", + ":grapes:": "\U0001f347", + ":greece:": "\U0001f1ec\U0001f1f7", + ":green_apple:": "\U0001f34f", + ":green_book:": "\U0001f4d7", + ":green_circle:": "\U0001f7e2", + ":green_heart:": "\U0001f49a", + ":green_salad:": "\U0001f957", + ":green_square:": "\U0001f7e9", + ":greenland:": "\U0001f1ec\U0001f1f1", + ":grenada:": "\U0001f1ec\U0001f1e9", + ":grey_exclamation:": "\u2755", + ":grey_question:": "\u2754", + ":grimacing:": "\U0001f62c", + ":grimacing_face:": "\U0001f62c", + ":grin:": "\U0001f601", + ":grinning:": "\U0001f600", + ":grinning_cat:": "\U0001f63a", + ":grinning_cat_with_smiling_eyes:": "\U0001f638", + ":grinning_face:": "\U0001f600", + ":grinning_face_with_big_eyes:": "\U0001f603", + ":grinning_face_with_smiling_eyes:": "\U0001f604", + ":grinning_face_with_sweat:": "\U0001f605", + ":grinning_squinting_face:": "\U0001f606", + ":growing_heart:": "\U0001f497", + ":guadeloupe:": "\U0001f1ec\U0001f1f5", + ":guam:": "\U0001f1ec\U0001f1fa", + ":guard:": "\U0001f482", + ":guard::skin-tone-1:": "\U0001f482\U0001f3fb", + ":guard::skin-tone-2:": "\U0001f482\U0001f3fc", + ":guard::skin-tone-3:": "\U0001f482\U0001f3fd", + ":guard::skin-tone-4:": "\U0001f482\U0001f3fe", + ":guard::skin-tone-5:": "\U0001f482\U0001f3ff", + ":guardsman:": "\U0001f482\u200d\u2642\ufe0f", + ":guardswoman:": "\U0001f482\u200d\u2640\ufe0f", + ":guatemala:": "\U0001f1ec\U0001f1f9", + ":guernsey:": "\U0001f1ec\U0001f1ec", + ":guide_dog:": "\U0001f9ae", + ":guinea:": "\U0001f1ec\U0001f1f3", + ":guinea_bissau:": "\U0001f1ec\U0001f1fc", + ":guitar:": "\U0001f3b8", + ":gun:": "\U0001f52b", + ":guyana:": "\U0001f1ec\U0001f1fe", + ":haircut:": "\U0001f487\u200d\u2640\ufe0f", + ":haircut_man:": "\U0001f487\u200d\u2642\ufe0f", + ":haircut_woman:": "\U0001f487\u200d\u2640\ufe0f", + ":haiti:": "\U0001f1ed\U0001f1f9", + ":hamburger:": "\U0001f354", + ":hammer:": "\U0001f528", + ":hammer_and_pick:": "\u2692\ufe0f", + ":hammer_and_wrench:": "\U0001f6e0\ufe0f", + ":hammer_pick:": "\u2692", + ":hamster:": "\U0001f439", + ":hand:": "\u270b", + ":hand_over_mouth:": "\U0001f92d", + ":hand_splayed::skin-tone-1:": "\U0001f590\U0001f3fb", + ":hand_splayed::skin-tone-2:": "\U0001f590\U0001f3fc", + ":hand_splayed::skin-tone-3:": "\U0001f590\U0001f3fd", + ":hand_splayed::skin-tone-4:": "\U0001f590\U0001f3fe", + ":hand_splayed::skin-tone-5:": "\U0001f590\U0001f3ff", + ":hand_with_fingers_splayed:": "\U0001f590", + ":handbag:": "\U0001f45c", + ":handball:": "\U0001f93e", + ":handball_person:": "\U0001f93e", + ":handshake:": "\U0001f91d", + ":hankey:": "\U0001f4a9", + ":hash:": "#\ufe0f\u20e3", + ":hatched_chick:": "\U0001f425", + ":hatching_chick:": "\U0001f423", + ":head_bandage:": "\U0001f915", + ":headphone:": "\U0001f3a7", + ":headphones:": "\U0001f3a7", + ":headstone:": "\U0001faa6", + ":health_worker:": "\U0001f9d1\u200d\u2695\ufe0f", + ":hear-no-evil_monkey:": "\U0001f649", + ":hear_no_evil:": "\U0001f649", + ":heard_mcdonald_islands:": "\U0001f1ed\U0001f1f2", + ":heart:": "\u2764\ufe0f", + ":heart_decoration:": "\U0001f49f", + ":heart_exclamation:": "\u2763", + ":heart_eyes:": "\U0001f60d", + ":heart_eyes_cat:": "\U0001f63b", + ":heart_suit:": "\u2665", + ":heart_with_arrow:": "\U0001f498", + ":heart_with_ribbon:": "\U0001f49d", + ":heartbeat:": "\U0001f493", + ":heartpulse:": "\U0001f497", + ":hearts:": "\u2665\ufe0f", + ":heavy_check_mark:": "\u2714\ufe0f", + ":heavy_division_sign:": "\u2797", + ":heavy_dollar_sign:": "\U0001f4b2", + ":heavy_exclamation_mark:": "\u2757", + ":heavy_heart_exclamation:": "\u2763\ufe0f", + ":heavy_heart_exclamation_mark_ornament:": "\u2763\ufe0f", + ":heavy_minus_sign:": "\u2796", + ":heavy_multiplication_x:": "\u2716\ufe0f", + ":heavy_plus_sign:": "\u2795", + ":hedgehog:": "\U0001f994", + ":helicopter:": "\U0001f681", + ":helmet_with_cross:": "\u26d1", + ":helmet_with_white_cross:": "\u26d1\ufe0f", + ":herb:": "\U0001f33f", + ":hibiscus:": "\U0001f33a", + ":high-heeled_shoe:": "\U0001f460", + ":high-speed_train:": "\U0001f684", + ":high_brightness:": "\U0001f506", + ":high_heel:": "\U0001f460", + ":high_voltage:": "\u26a1", + ":hiking_boot:": "\U0001f97e", + ":hindu_temple:": "\U0001f6d5", + ":hippopotamus:": "\U0001f99b", + ":hocho:": "\U0001f52a", + ":hockey:": "\U0001f3d2", + ":hole:": "\U0001f573\ufe0f", + ":hollow_red_circle:": "\u2b55", + ":homes:": "\U0001f3d8", + ":honduras:": "\U0001f1ed\U0001f1f3", + ":honey_pot:": "\U0001f36f", + ":honeybee:": "\U0001f41d", + ":hong_kong:": "\U0001f1ed\U0001f1f0", + ":hook:": "\U0001fa9d", + ":horizontal_traffic_light:": "\U0001f6a5", + ":horse:": "\U0001f434", + ":horse_face:": "\U0001f434", + ":horse_racing:": "\U0001f3c7", + ":horse_racing::skin-tone-1:": "\U0001f3c7\U0001f3fb", + ":horse_racing::skin-tone-2:": "\U0001f3c7\U0001f3fc", + ":horse_racing::skin-tone-3:": "\U0001f3c7\U0001f3fd", + ":horse_racing::skin-tone-4:": "\U0001f3c7\U0001f3fe", + ":horse_racing::skin-tone-5:": "\U0001f3c7\U0001f3ff", + ":hospital:": "\U0001f3e5", + ":hot_beverage:": "\u2615", + ":hot_dog:": "\U0001f32d", + ":hot_face:": "\U0001f975", + ":hot_pepper:": "\U0001f336\ufe0f", + ":hot_springs:": "\u2668", + ":hotdog:": "\U0001f32d", + ":hotel:": "\U0001f3e8", + ":hotsprings:": "\u2668\ufe0f", + ":hourglass:": "\u231b", + ":hourglass_done:": "\u231b", + ":hourglass_flowing_sand:": "\u23f3", + ":hourglass_not_done:": "\u23f3", + ":house:": "\U0001f3e0", + ":house_abandoned:": "\U0001f3da", + ":house_buildings:": "\U0001f3d8\ufe0f", + ":house_with_garden:": "\U0001f3e1", + ":houses:": "\U0001f3d8", + ":hugging:": "\U0001f917", + ":hugging_face:": "\U0001f917", + ":hugs:": "\U0001f917", + ":hundred_points:": "\U0001f4af", + ":hungary:": "\U0001f1ed\U0001f1fa", + ":hushed:": "\U0001f62f", + ":hushed_face:": "\U0001f62f", + ":hut:": "\U0001f6d6", + ":i_love_you_hand_sign:": "\U0001f91f", + ":ice:": "\U0001f9ca", + ":ice_cream:": "\U0001f368", + ":ice_cube:": "\U0001f9ca", + ":ice_hockey:": "\U0001f3d2", + ":ice_hockey_stick_and_puck:": "\U0001f3d2", + ":ice_skate:": "\u26f8\ufe0f", + ":icecream:": "\U0001f366", + ":iceland:": "\U0001f1ee\U0001f1f8", + ":id:": "\U0001f194", + ":ideograph_advantage:": "\U0001f250", + ":imp:": "\U0001f47f", + ":inbox_tray:": "\U0001f4e5", + ":incoming_envelope:": "\U0001f4e8", + ":index_pointing_up:": "\u261d", + ":india:": "\U0001f1ee\U0001f1f3", + ":indonesia:": "\U0001f1ee\U0001f1e9", + ":infinity:": "\u267e\ufe0f", + ":information:": "\u2139", + ":information_desk_person:": "\U0001f481\u200d\u2640\ufe0f", + ":information_source:": "\u2139\ufe0f", + ":innocent:": "\U0001f607", + ":input_latin_letters:": "\U0001f524", + ":input_latin_lowercase:": "\U0001f521", + ":input_latin_uppercase:": "\U0001f520", + ":input_numbers:": "\U0001f522", + ":input_symbols:": "\U0001f523", + ":interrobang:": "\u2049\ufe0f", + ":iphone:": "\U0001f4f1", + ":iran:": "\U0001f1ee\U0001f1f7", + ":iraq:": "\U0001f1ee\U0001f1f6", + ":ireland:": "\U0001f1ee\U0001f1ea", + ":island:": "\U0001f3dd", + ":isle_of_man:": "\U0001f1ee\U0001f1f2", + ":israel:": "\U0001f1ee\U0001f1f1", + ":it:": "\U0001f1ee\U0001f1f9", + ":izakaya_lantern:": "\U0001f3ee", + ":jack-o-lantern:": "\U0001f383", + ":jack_o_lantern:": "\U0001f383", + ":jamaica:": "\U0001f1ef\U0001f1f2", + ":japan:": "\U0001f5fe", + ":japanese_castle:": "\U0001f3ef", + ":japanese_goblin:": "\U0001f47a", + ":japanese_ogre:": "\U0001f479", + ":jeans:": "\U0001f456", + ":jersey:": "\U0001f1ef\U0001f1ea", + ":jigsaw:": "\U0001f9e9", + ":joker:": "\U0001f0cf", + ":jordan:": "\U0001f1ef\U0001f1f4", + ":joy:": "\U0001f602", + ":joy_cat:": "\U0001f639", + ":joystick:": "\U0001f579\ufe0f", + ":jp:": "\U0001f1ef\U0001f1f5", + ":judge:": "\U0001f9d1\u200d\u2696\ufe0f", + ":juggling:": "\U0001f939", + ":juggling_person:": "\U0001f939", + ":kaaba:": "\U0001f54b", + ":kangaroo:": "\U0001f998", + ":kazakhstan:": "\U0001f1f0\U0001f1ff", + ":kenya:": "\U0001f1f0\U0001f1ea", + ":key:": "\U0001f511", + ":key2:": "\U0001f5dd", + ":keyboard:": "\u2328\ufe0f", + ":keycap_#:": "#\ufe0f\u20e3", + ":keycap_*:": "*\ufe0f\u20e3", + ":keycap_0:": "0\ufe0f\u20e3", + ":keycap_1:": "1\ufe0f\u20e3", + ":keycap_10:": "\U0001f51f", + ":keycap_2:": "2\ufe0f\u20e3", + ":keycap_3:": "3\ufe0f\u20e3", + ":keycap_4:": "4\ufe0f\u20e3", + ":keycap_5:": "5\ufe0f\u20e3", + ":keycap_6:": "6\ufe0f\u20e3", + ":keycap_7:": "7\ufe0f\u20e3", + ":keycap_8:": "8\ufe0f\u20e3", + ":keycap_9:": "9\ufe0f\u20e3", + ":keycap_star:": "*\ufe0f\u20e3", + ":keycap_ten:": "\U0001f51f", + ":kick_scooter:": "\U0001f6f4", + ":kimono:": "\U0001f458", + ":kiribati:": "\U0001f1f0\U0001f1ee", + ":kiss:": "\U0001f48b", + ":kiss_man_man:": "\U0001f468\u200d\u2764\ufe0f\u200d\U0001f48b\u200d\U0001f468", + ":kiss_mark:": "\U0001f48b", + ":kiss_mm:": "\U0001f468\u200d\u2764\ufe0f\u200d\U0001f48b\u200d\U0001f468", + ":kiss_woman_man:": "\U0001f469\u200d\u2764\ufe0f\u200d\U0001f48b\u200d\U0001f468", + ":kiss_woman_woman:": "\U0001f469\u200d\u2764\ufe0f\u200d\U0001f48b\u200d\U0001f469", + ":kiss_ww:": "\U0001f469\u200d\u2764\ufe0f\u200d\U0001f48b\u200d\U0001f469", + ":kissing:": "\U0001f617", + ":kissing_cat:": "\U0001f63d", + ":kissing_closed_eyes:": "\U0001f61a", + ":kissing_face:": "\U0001f617", + ":kissing_face_with_closed_eyes:": "\U0001f61a", + ":kissing_face_with_smiling_eyes:": "\U0001f619", + ":kissing_heart:": "\U0001f618", + ":kissing_smiling_eyes:": "\U0001f619", + ":kitchen_knife:": "\U0001f52a", + ":kite:": "\U0001fa81", + ":kiwi:": "\U0001f95d", + ":kiwi_fruit:": "\U0001f95d", + ":kiwifruit:": "\U0001f95d", + ":kneeling_man:": "\U0001f9ce\u200d\u2642\ufe0f", + ":kneeling_person:": "\U0001f9ce", + ":kneeling_woman:": "\U0001f9ce\u200d\u2640\ufe0f", + ":knife:": "\U0001f52a", + ":knife_fork_plate:": "\U0001f37d\ufe0f", + ":knot:": "\U0001faa2", + ":koala:": "\U0001f428", + ":koko:": "\U0001f201", + ":kosovo:": "\U0001f1fd\U0001f1f0", + ":kr:": "\U0001f1f0\U0001f1f7", + ":kuwait:": "\U0001f1f0\U0001f1fc", + ":kyrgyzstan:": "\U0001f1f0\U0001f1ec", + ":lab_coat:": "\U0001f97c", + ":label:": "\U0001f3f7\ufe0f", + ":lacrosse:": "\U0001f94d", + ":ladder:": "\U0001fa9c", + ":lady_beetle:": "\U0001f41e", + ":ladybug:": "\U0001f41e", + ":lantern:": "\U0001f3ee", + ":laos:": "\U0001f1f1\U0001f1e6", + ":laptop:": "\U0001f4bb", + ":large_blue_circle:": "\U0001f535", + ":large_blue_diamond:": "\U0001f537", + ":large_blue_square:": "\U0001f7e6", + ":large_brown_circle:": "\U0001f7e4", + ":large_brown_square:": "\U0001f7eb", + ":large_green_circle:": "\U0001f7e2", + ":large_green_square:": "\U0001f7e9", + ":large_orange_circle:": "\U0001f7e0", + ":large_orange_diamond:": "\U0001f536", + ":large_orange_square:": "\U0001f7e7", + ":large_purple_circle:": "\U0001f7e3", + ":large_purple_square:": "\U0001f7ea", + ":large_red_square:": "\U0001f7e5", + ":large_yellow_circle:": "\U0001f7e1", + ":large_yellow_square:": "\U0001f7e8", + ":last_quarter_moon:": "\U0001f317", + ":last_quarter_moon_face:": "\U0001f31c", + ":last_quarter_moon_with_face:": "\U0001f31c", + ":last_track_button:": "\u23ee", + ":latin_cross:": "\u271d\ufe0f", + ":latvia:": "\U0001f1f1\U0001f1fb", + ":laughing:": "\U0001f606", + ":leaf_fluttering_in_wind:": "\U0001f343", + ":leafy_green:": "\U0001f96c", + ":leaves:": "\U0001f343", + ":lebanon:": "\U0001f1f1\U0001f1e7", + ":ledger:": "\U0001f4d2", + ":left-facing_fist:": "\U0001f91b", + ":left-right_arrow:": "\u2194", + ":left_arrow:": "\u2b05", + ":left_arrow_curving_right:": "\u21aa", + ":left_facing_fist:": "\U0001f91b", + ":left_facing_fist::skin-tone-1:": "\U0001f91b\U0001f3fb", + ":left_facing_fist::skin-tone-2:": "\U0001f91b\U0001f3fc", + ":left_facing_fist::skin-tone-3:": "\U0001f91b\U0001f3fd", + ":left_facing_fist::skin-tone-4:": "\U0001f91b\U0001f3fe", + ":left_facing_fist::skin-tone-5:": "\U0001f91b\U0001f3ff", + ":left_luggage:": "\U0001f6c5", + ":left_right_arrow:": "\u2194\ufe0f", + ":left_speech_bubble:": "\U0001f5e8\ufe0f", + ":leftwards_arrow_with_hook:": "\u21a9\ufe0f", + ":leg:": "\U0001f9b5", + ":lemon:": "\U0001f34b", + ":leo:": "\u264c", + ":leopard:": "\U0001f406", + ":lesotho:": "\U0001f1f1\U0001f1f8", + ":level_slider:": "\U0001f39a\ufe0f", + ":liberia:": "\U0001f1f1\U0001f1f7", + ":libra:": "\u264e", + ":libya:": "\U0001f1f1\U0001f1fe", + ":liechtenstein:": "\U0001f1f1\U0001f1ee", + ":light_bulb:": "\U0001f4a1", + ":light_rail:": "\U0001f688", + ":lightning:": "\U0001f329\ufe0f", + ":link:": "\U0001f517", + ":linked_paperclips:": "\U0001f587\ufe0f", + ":lion:": "\U0001f981", + ":lion_face:": "\U0001f981", + ":lips:": "\U0001f444", + ":lipstick:": "\U0001f484", + ":lithuania:": "\U0001f1f1\U0001f1f9", + ":litter_in_bin_sign:": "\U0001f6ae", + ":lizard:": "\U0001f98e", + ":llama:": "\U0001f999", + ":lobster:": "\U0001f99e", + ":lock:": "\U0001f512", + ":lock_with_ink_pen:": "\U0001f50f", + ":locked:": "\U0001f512", + ":locked_with_key:": "\U0001f510", + ":locked_with_pen:": "\U0001f50f", + ":locomotive:": "\U0001f682", + ":lollipop:": "\U0001f36d", + ":long_drum:": "\U0001fa98", + ":loop:": "\u27bf", + ":lotion_bottle:": "\U0001f9f4", + ":lotus_position:": "\U0001f9d8", + ":lotus_position_man:": "\U0001f9d8\u200d\u2642\ufe0f", + ":lotus_position_woman:": "\U0001f9d8\u200d\u2640\ufe0f", + ":loud_sound:": "\U0001f50a", + ":loudly_crying_face:": "\U0001f62d", + ":loudspeaker:": "\U0001f4e2", + ":love-you_gesture:": "\U0001f91f", + ":love_hotel:": "\U0001f3e9", + ":love_letter:": "\U0001f48c", + ":love_you_gesture:": "\U0001f91f", + ":love_you_gesture::skin-tone-1:": "\U0001f91f\U0001f3fb", + ":love_you_gesture::skin-tone-2:": "\U0001f91f\U0001f3fc", + ":love_you_gesture::skin-tone-3:": "\U0001f91f\U0001f3fd", + ":love_you_gesture::skin-tone-4:": "\U0001f91f\U0001f3fe", + ":love_you_gesture::skin-tone-5:": "\U0001f91f\U0001f3ff", + ":low_brightness:": "\U0001f505", + ":lower_left_ballpoint_pen:": "\U0001f58a\ufe0f", + ":lower_left_crayon:": "\U0001f58d\ufe0f", + ":lower_left_fountain_pen:": "\U0001f58b\ufe0f", + ":lower_left_paintbrush:": "\U0001f58c\ufe0f", + ":luggage:": "\U0001f9f3", + ":lungs:": "\U0001fac1", + ":luxembourg:": "\U0001f1f1\U0001f1fa", + ":lying_face:": "\U0001f925", + ":m:": "\u24dc\ufe0f", + ":macau:": "\U0001f1f2\U0001f1f4", + ":macedonia:": "\U0001f1f2\U0001f1f0", + ":madagascar:": "\U0001f1f2\U0001f1ec", + ":mag:": "\U0001f50d", + ":mag_right:": "\U0001f50e", + ":mage:": "\U0001f9d9\u200d\u2640\ufe0f", + ":mage_man:": "\U0001f9d9\u200d\u2642\ufe0f", + ":mage::skin-tone-1:": "\U0001f9d9\U0001f3fb", + ":mage::skin-tone-2:": "\U0001f9d9\U0001f3fc", + ":mage::skin-tone-3:": "\U0001f9d9\U0001f3fd", + ":mage::skin-tone-4:": "\U0001f9d9\U0001f3fe", + ":mage::skin-tone-5:": "\U0001f9d9\U0001f3ff", + ":mage_woman:": "\U0001f9d9\u200d\u2640\ufe0f", + ":magic_wand:": "\U0001fa84", + ":magnet:": "\U0001f9f2", + ":magnifying_glass_tilted_left:": "\U0001f50d", + ":magnifying_glass_tilted_right:": "\U0001f50e", + ":mahjong:": "\U0001f004", + ":mahjong_red_dragon:": "\U0001f004", + ":mailbox:": "\U0001f4eb", + ":mailbox_closed:": "\U0001f4ea", + ":mailbox_with_mail:": "\U0001f4ec", + ":mailbox_with_no_mail:": "\U0001f4ed", + ":malawi:": "\U0001f1f2\U0001f1fc", + ":malaysia:": "\U0001f1f2\U0001f1fe", + ":maldives:": "\U0001f1f2\U0001f1fb", + ":male-artist:": "\U0001f468\u200d\U0001f3a8", + ":male-astronaut:": "\U0001f468\u200d\U0001f680", + ":male-construction-worker:": "\U0001f477\u200d\u2642\ufe0f", + ":male-cook:": "\U0001f468\u200d\U0001f373", + ":male-detective:": "\U0001f575\ufe0f\u200d\u2642\ufe0f", + ":male-doctor:": "\U0001f468\u200d\u2695\ufe0f", + ":male-factory-worker:": "\U0001f468\u200d\U0001f3ed", + ":male-farmer:": "\U0001f468\u200d\U0001f33e", + ":male-firefighter:": "\U0001f468\u200d\U0001f692", + ":male-guard:": "\U0001f482\u200d\u2642\ufe0f", + ":male-judge:": "\U0001f468\u200d\u2696\ufe0f", + ":male-mechanic:": "\U0001f468\u200d\U0001f527", + ":male-office-worker:": "\U0001f468\u200d\U0001f4bc", + ":male-pilot:": "\U0001f468\u200d\u2708\ufe0f", + ":male-police-officer:": "\U0001f46e\u200d\u2642\ufe0f", + ":male-scientist:": "\U0001f468\u200d\U0001f52c", + ":male-singer:": "\U0001f468\u200d\U0001f3a4", + ":male-student:": "\U0001f468\u200d\U0001f393", + ":male-teacher:": "\U0001f468\u200d\U0001f3eb", + ":male-technologist:": "\U0001f468\u200d\U0001f4bb", + ":male_detective:": "\U0001f575\ufe0f\u200d\u2642\ufe0f", + ":male_elf:": "\U0001f9dd\u200d\u2642\ufe0f", + ":male_fairy:": "\U0001f9da\u200d\u2642\ufe0f", + ":male_genie:": "\U0001f9de\u200d\u2642\ufe0f", + ":male_mage:": "\U0001f9d9\u200d\u2642\ufe0f", + ":male_sign:": "\u2642\ufe0f", + ":male_superhero:": "\U0001f9b8\u200d\u2642\ufe0f", + ":male_supervillain:": "\U0001f9b9\u200d\u2642\ufe0f", + ":male_vampire:": "\U0001f9db\u200d\u2642\ufe0f", + ":male_zombie:": "\U0001f9df\u200d\u2642\ufe0f", + ":mali:": "\U0001f1f2\U0001f1f1", + ":malta:": "\U0001f1f2\U0001f1f9", + ":mammoth:": "\U0001f9a3", + ":man:": "\U0001f468", + ":man-biking:": "\U0001f6b4\u200d\u2642\ufe0f", + ":man-bouncing-ball:": "\u26f9\ufe0f\u200d\u2642\ufe0f", + ":man-bowing:": "\U0001f647\u200d\u2642\ufe0f", + ":man-boy:": "\U0001f468\u200d\U0001f466", + ":man-boy-boy:": "\U0001f468\u200d\U0001f466\u200d\U0001f466", + ":man-cartwheeling:": "\U0001f938\u200d\u2642\ufe0f", + ":man-facepalming:": "\U0001f926\u200d\u2642\ufe0f", + ":man-frowning:": "\U0001f64d\u200d\u2642\ufe0f", + ":man-gesturing-no:": "\U0001f645\u200d\u2642\ufe0f", + ":man-gesturing-ok:": "\U0001f646\u200d\u2642\ufe0f", + ":man-getting-haircut:": "\U0001f487\u200d\u2642\ufe0f", + ":man-getting-massage:": "\U0001f486\u200d\u2642\ufe0f", + ":man-girl:": "\U0001f468\u200d\U0001f467", + ":man-girl-boy:": "\U0001f468\u200d\U0001f467\u200d\U0001f466", + ":man-girl-girl:": "\U0001f468\u200d\U0001f467\u200d\U0001f467", + ":man-golfing:": "\U0001f3cc\ufe0f\u200d\u2642\ufe0f", + ":man-heart-man:": "\U0001f468\u200d\u2764\ufe0f\u200d\U0001f468", + ":man-juggling:": "\U0001f939\u200d\u2642\ufe0f", + ":man-kiss-man:": "\U0001f468\u200d\u2764\ufe0f\u200d\U0001f48b\u200d\U0001f468", + ":man-lifting-weights:": "\U0001f3cb\ufe0f\u200d\u2642\ufe0f", + ":man-man-boy:": "\U0001f468\u200d\U0001f468\u200d\U0001f466", + ":man-man-boy-boy:": "\U0001f468\u200d\U0001f468\u200d\U0001f466\u200d\U0001f466", + ":man-man-girl:": "\U0001f468\u200d\U0001f468\u200d\U0001f467", + ":man-man-girl-boy:": "\U0001f468\u200d\U0001f468\u200d\U0001f467\u200d\U0001f466", + ":man-man-girl-girl:": "\U0001f468\u200d\U0001f468\u200d\U0001f467\u200d\U0001f467", + ":man-mountain-biking:": "\U0001f6b5\u200d\u2642\ufe0f", + ":man-playing-handball:": "\U0001f93e\u200d\u2642\ufe0f", + ":man-playing-water-polo:": "\U0001f93d\u200d\u2642\ufe0f", + ":man-pouting:": "\U0001f64e\u200d\u2642\ufe0f", + ":man-raising-hand:": "\U0001f64b\u200d\u2642\ufe0f", + ":man-rowing-boat:": "\U0001f6a3\u200d\u2642\ufe0f", + ":man-running:": "\U0001f3c3\u200d\u2642\ufe0f", + ":man-shrugging:": "\U0001f937\u200d\u2642\ufe0f", + ":man-surfing:": "\U0001f3c4\u200d\u2642\ufe0f", + ":man-swimming:": "\U0001f3ca\u200d\u2642\ufe0f", + ":man-tipping-hand:": "\U0001f481\u200d\u2642\ufe0f", + ":man-walking:": "\U0001f6b6\u200d\u2642\ufe0f", + ":man-wearing-turban:": "\U0001f473\u200d\u2642\ufe0f", + ":man-with-bunny-ears-partying:": "\U0001f46f\u200d\u2642\ufe0f", + ":man-woman-boy:": "\U0001f468\u200d\U0001f469\u200d\U0001f466", + ":man-woman-boy-boy:": "\U0001f468\u200d\U0001f469\u200d\U0001f466\u200d\U0001f466", + ":man-woman-girl:": "\U0001f468\u200d\U0001f469\u200d\U0001f467", + ":man-woman-girl-boy:": "\U0001f468\u200d\U0001f469\u200d\U0001f467\u200d\U0001f466", + ":man-woman-girl-girl:": "\U0001f468\u200d\U0001f469\u200d\U0001f467\u200d\U0001f467", + ":man-wrestling:": "\U0001f93c\u200d\u2642\ufe0f", + ":man_artist:": "\U0001f468\u200d\U0001f3a8", + ":man_artist::skin-tone-1:": "\U0001f468\U0001f3fb\u200d\U0001f3a8", + ":man_artist::skin-tone-2:": "\U0001f468\U0001f3fc\u200d\U0001f3a8", + ":man_artist::skin-tone-3:": "\U0001f468\U0001f3fd\u200d\U0001f3a8", + ":man_artist::skin-tone-4:": "\U0001f468\U0001f3fe\u200d\U0001f3a8", + ":man_artist::skin-tone-5:": "\U0001f468\U0001f3ff\u200d\U0001f3a8", + ":man_astronaut:": "\U0001f468\u200d\U0001f680", + ":man_astronaut::skin-tone-1:": "\U0001f468\U0001f3fb\u200d\U0001f680", + ":man_astronaut::skin-tone-2:": "\U0001f468\U0001f3fc\u200d\U0001f680", + ":man_astronaut::skin-tone-3:": "\U0001f468\U0001f3fd\u200d\U0001f680", + ":man_astronaut::skin-tone-4:": "\U0001f468\U0001f3fe\u200d\U0001f680", + ":man_astronaut::skin-tone-5:": "\U0001f468\U0001f3ff\u200d\U0001f680", + ":man_bald:": "\U0001f468\u200d\U0001f9b2", + ":man_beard:": "\U0001f9d4", + ":man_biking:": "\U0001f6b4\u200d\u2642\ufe0f", + ":man_biking::skin-tone-1:": "\U0001f6b4\U0001f3fb\u200d\u2642\ufe0f", + ":man_biking::skin-tone-2:": "\U0001f6b4\U0001f3fc\u200d\u2642\ufe0f", + ":man_biking::skin-tone-3:": "\U0001f6b4\U0001f3fd\u200d\u2642\ufe0f", + ":man_biking::skin-tone-4:": "\U0001f6b4\U0001f3fe\u200d\u2642\ufe0f", + ":man_biking::skin-tone-5:": "\U0001f6b4\U0001f3ff\u200d\u2642\ufe0f", + ":man_blond_hair:": "\U0001f471\u200d\u2642\ufe0f", + ":man_bouncing_ball:": "\u26f9\ufe0f\u200d\u2642\ufe0f", + ":man_bouncing_ball::skin-tone-1:": "\u26f9\U0001f3fb\u200d\u2642\ufe0f", + ":man_bouncing_ball::skin-tone-2:": "\u26f9\U0001f3fc\u200d\u2642\ufe0f", + ":man_bouncing_ball::skin-tone-3:": "\u26f9\U0001f3fd\u200d\u2642\ufe0f", + ":man_bouncing_ball::skin-tone-4:": "\u26f9\U0001f3fe\u200d\u2642\ufe0f", + ":man_bouncing_ball::skin-tone-5:": "\u26f9\U0001f3ff\u200d\u2642\ufe0f", + ":man_bowing:": "\U0001f647\u200d\u2642\ufe0f", + ":man_bowing::skin-tone-1:": "\U0001f647\U0001f3fb\u200d\u2642\ufe0f", + ":man_bowing::skin-tone-2:": "\U0001f647\U0001f3fc\u200d\u2642\ufe0f", + ":man_bowing::skin-tone-3:": "\U0001f647\U0001f3fd\u200d\u2642\ufe0f", + ":man_bowing::skin-tone-4:": "\U0001f647\U0001f3fe\u200d\u2642\ufe0f", + ":man_bowing::skin-tone-5:": "\U0001f647\U0001f3ff\u200d\u2642\ufe0f", + ":man_cartwheeling:": "\U0001f938\u200d\u2642\ufe0f", + ":man_cartwheeling::skin-tone-1:": "\U0001f938\U0001f3fb\u200d\u2642\ufe0f", + ":man_cartwheeling::skin-tone-2:": "\U0001f938\U0001f3fc\u200d\u2642\ufe0f", + ":man_cartwheeling::skin-tone-3:": "\U0001f938\U0001f3fd\u200d\u2642\ufe0f", + ":man_cartwheeling::skin-tone-4:": "\U0001f938\U0001f3fe\u200d\u2642\ufe0f", + ":man_cartwheeling::skin-tone-5:": "\U0001f938\U0001f3ff\u200d\u2642\ufe0f", + ":man_climbing:": "\U0001f9d7\u200d\u2642\ufe0f", + ":man_climbing::skin-tone-1:": "\U0001f9d7\U0001f3fb\u200d\u2642\ufe0f", + ":man_climbing::skin-tone-2:": "\U0001f9d7\U0001f3fc\u200d\u2642\ufe0f", + ":man_climbing::skin-tone-3:": "\U0001f9d7\U0001f3fd\u200d\u2642\ufe0f", + ":man_climbing::skin-tone-4:": "\U0001f9d7\U0001f3fe\u200d\u2642\ufe0f", + ":man_climbing::skin-tone-5:": "\U0001f9d7\U0001f3ff\u200d\u2642\ufe0f", + ":man_construction_worker:": "\U0001f477\u200d\u2642\ufe0f", + ":man_construction_worker::skin-tone-1:": "\U0001f477\U0001f3fb\u200d\u2642\ufe0f", + ":man_construction_worker::skin-tone-2:": "\U0001f477\U0001f3fc\u200d\u2642\ufe0f", + ":man_construction_worker::skin-tone-3:": "\U0001f477\U0001f3fd\u200d\u2642\ufe0f", + ":man_construction_worker::skin-tone-4:": "\U0001f477\U0001f3fe\u200d\u2642\ufe0f", + ":man_construction_worker::skin-tone-5:": "\U0001f477\U0001f3ff\u200d\u2642\ufe0f", + ":man_cook:": "\U0001f468\u200d\U0001f373", + ":man_cook::skin-tone-1:": "\U0001f468\U0001f3fb\u200d\U0001f373", + ":man_cook::skin-tone-2:": "\U0001f468\U0001f3fc\u200d\U0001f373", + ":man_cook::skin-tone-3:": "\U0001f468\U0001f3fd\u200d\U0001f373", + ":man_cook::skin-tone-4:": "\U0001f468\U0001f3fe\u200d\U0001f373", + ":man_cook::skin-tone-5:": "\U0001f468\U0001f3ff\u200d\U0001f373", + ":man_curly_hair:": "\U0001f468\u200d\U0001f9b1", + ":man_dancing:": "\U0001f57a", + ":man_dancing::skin-tone-1:": "\U0001f57a\U0001f3fb", + ":man_dancing::skin-tone-2:": "\U0001f57a\U0001f3fc", + ":man_dancing::skin-tone-3:": "\U0001f57a\U0001f3fd", + ":man_dancing::skin-tone-4:": "\U0001f57a\U0001f3fe", + ":man_dancing::skin-tone-5:": "\U0001f57a\U0001f3ff", + ":man_detective:": "\U0001f575\ufe0f\u200d\u2642\ufe0f", + ":man_detective::skin-tone-1:": "\U0001f575\U0001f3fb\u200d\u2642\ufe0f", + ":man_detective::skin-tone-2:": "\U0001f575\U0001f3fc\u200d\u2642\ufe0f", + ":man_detective::skin-tone-3:": "\U0001f575\U0001f3fd\u200d\u2642\ufe0f", + ":man_detective::skin-tone-4:": "\U0001f575\U0001f3fe\u200d\u2642\ufe0f", + ":man_detective::skin-tone-5:": "\U0001f575\U0001f3ff\u200d\u2642\ufe0f", + ":man_elf:": "\U0001f9dd\u200d\u2642\ufe0f", + ":man_elf::skin-tone-1:": "\U0001f9dd\U0001f3fb\u200d\u2642\ufe0f", + ":man_elf::skin-tone-2:": "\U0001f9dd\U0001f3fc\u200d\u2642\ufe0f", + ":man_elf::skin-tone-3:": "\U0001f9dd\U0001f3fd\u200d\u2642\ufe0f", + ":man_elf::skin-tone-4:": "\U0001f9dd\U0001f3fe\u200d\u2642\ufe0f", + ":man_elf::skin-tone-5:": "\U0001f9dd\U0001f3ff\u200d\u2642\ufe0f", + ":man_facepalming:": "\U0001f926\u200d\u2642\ufe0f", + ":man_facepalming::skin-tone-1:": "\U0001f926\U0001f3fb\u200d\u2642\ufe0f", + ":man_facepalming::skin-tone-2:": "\U0001f926\U0001f3fc\u200d\u2642\ufe0f", + ":man_facepalming::skin-tone-3:": "\U0001f926\U0001f3fd\u200d\u2642\ufe0f", + ":man_facepalming::skin-tone-4:": "\U0001f926\U0001f3fe\u200d\u2642\ufe0f", + ":man_facepalming::skin-tone-5:": "\U0001f926\U0001f3ff\u200d\u2642\ufe0f", + ":man_factory_worker:": "\U0001f468\u200d\U0001f3ed", + ":man_factory_worker::skin-tone-1:": "\U0001f468\U0001f3fb\u200d\U0001f3ed", + ":man_factory_worker::skin-tone-2:": "\U0001f468\U0001f3fc\u200d\U0001f3ed", + ":man_factory_worker::skin-tone-3:": "\U0001f468\U0001f3fd\u200d\U0001f3ed", + ":man_factory_worker::skin-tone-4:": "\U0001f468\U0001f3fe\u200d\U0001f3ed", + ":man_factory_worker::skin-tone-5:": "\U0001f468\U0001f3ff\u200d\U0001f3ed", + ":man_fairy:": "\U0001f9da\u200d\u2642\ufe0f", + ":man_fairy::skin-tone-1:": "\U0001f9da\U0001f3fb\u200d\u2642\ufe0f", + ":man_fairy::skin-tone-2:": "\U0001f9da\U0001f3fc\u200d\u2642\ufe0f", + ":man_fairy::skin-tone-3:": "\U0001f9da\U0001f3fd\u200d\u2642\ufe0f", + ":man_fairy::skin-tone-4:": "\U0001f9da\U0001f3fe\u200d\u2642\ufe0f", + ":man_fairy::skin-tone-5:": "\U0001f9da\U0001f3ff\u200d\u2642\ufe0f", + ":man_farmer:": "\U0001f468\u200d\U0001f33e", + ":man_farmer::skin-tone-1:": "\U0001f468\U0001f3fb\u200d\U0001f33e", + ":man_farmer::skin-tone-2:": "\U0001f468\U0001f3fc\u200d\U0001f33e", + ":man_farmer::skin-tone-3:": "\U0001f468\U0001f3fd\u200d\U0001f33e", + ":man_farmer::skin-tone-4:": "\U0001f468\U0001f3fe\u200d\U0001f33e", + ":man_farmer::skin-tone-5:": "\U0001f468\U0001f3ff\u200d\U0001f33e", + ":man_feeding_baby:": "\U0001f468\u200d\U0001f37c", + ":man_firefighter:": "\U0001f468\u200d\U0001f692", + ":man_firefighter::skin-tone-1:": "\U0001f468\U0001f3fb\u200d\U0001f692", + ":man_firefighter::skin-tone-2:": "\U0001f468\U0001f3fc\u200d\U0001f692", + ":man_firefighter::skin-tone-3:": "\U0001f468\U0001f3fd\u200d\U0001f692", + ":man_firefighter::skin-tone-4:": "\U0001f468\U0001f3fe\u200d\U0001f692", + ":man_firefighter::skin-tone-5:": "\U0001f468\U0001f3ff\u200d\U0001f692", + ":man_frowning:": "\U0001f64d\u200d\u2642\ufe0f", + ":man_frowning::skin-tone-1:": "\U0001f64d\U0001f3fb\u200d\u2642\ufe0f", + ":man_frowning::skin-tone-2:": "\U0001f64d\U0001f3fc\u200d\u2642\ufe0f", + ":man_frowning::skin-tone-3:": "\U0001f64d\U0001f3fd\u200d\u2642\ufe0f", + ":man_frowning::skin-tone-4:": "\U0001f64d\U0001f3fe\u200d\u2642\ufe0f", + ":man_frowning::skin-tone-5:": "\U0001f64d\U0001f3ff\u200d\u2642\ufe0f", + ":man_genie:": "\U0001f9de\u200d\u2642\ufe0f", + ":man_gesturing_NO:": "\U0001f645\u200d\u2642\ufe0f", + ":man_gesturing_OK:": "\U0001f646\u200d\u2642\ufe0f", + ":man_gesturing_no:": "\U0001f645\u200d\u2642\ufe0f", + ":man_gesturing_no::skin-tone-1:": "\U0001f645\U0001f3fb\u200d\u2642\ufe0f", + ":man_gesturing_no::skin-tone-2:": "\U0001f645\U0001f3fc\u200d\u2642\ufe0f", + ":man_gesturing_no::skin-tone-3:": "\U0001f645\U0001f3fd\u200d\u2642\ufe0f", + ":man_gesturing_no::skin-tone-4:": "\U0001f645\U0001f3fe\u200d\u2642\ufe0f", + ":man_gesturing_no::skin-tone-5:": "\U0001f645\U0001f3ff\u200d\u2642\ufe0f", + ":man_gesturing_ok:": "\U0001f646\u200d\u2642\ufe0f", + ":man_gesturing_ok::skin-tone-1:": "\U0001f646\U0001f3fb\u200d\u2642\ufe0f", + ":man_gesturing_ok::skin-tone-2:": "\U0001f646\U0001f3fc\u200d\u2642\ufe0f", + ":man_gesturing_ok::skin-tone-3:": "\U0001f646\U0001f3fd\u200d\u2642\ufe0f", + ":man_gesturing_ok::skin-tone-4:": "\U0001f646\U0001f3fe\u200d\u2642\ufe0f", + ":man_gesturing_ok::skin-tone-5:": "\U0001f646\U0001f3ff\u200d\u2642\ufe0f", + ":man_getting_face_massage:": "\U0001f486\u200d\u2642\ufe0f", + ":man_getting_face_massage::skin-tone-1:": "\U0001f486\U0001f3fb\u200d\u2642\ufe0f", + ":man_getting_face_massage::skin-tone-2:": "\U0001f486\U0001f3fc\u200d\u2642\ufe0f", + ":man_getting_face_massage::skin-tone-3:": "\U0001f486\U0001f3fd\u200d\u2642\ufe0f", + ":man_getting_face_massage::skin-tone-4:": "\U0001f486\U0001f3fe\u200d\u2642\ufe0f", + ":man_getting_face_massage::skin-tone-5:": "\U0001f486\U0001f3ff\u200d\u2642\ufe0f", + ":man_getting_haircut:": "\U0001f487\u200d\u2642\ufe0f", + ":man_getting_haircut::skin-tone-1:": "\U0001f487\U0001f3fb\u200d\u2642\ufe0f", + ":man_getting_haircut::skin-tone-2:": "\U0001f487\U0001f3fc\u200d\u2642\ufe0f", + ":man_getting_haircut::skin-tone-3:": "\U0001f487\U0001f3fd\u200d\u2642\ufe0f", + ":man_getting_haircut::skin-tone-4:": "\U0001f487\U0001f3fe\u200d\u2642\ufe0f", + ":man_getting_haircut::skin-tone-5:": "\U0001f487\U0001f3ff\u200d\u2642\ufe0f", + ":man_getting_massage:": "\U0001f486\u200d\u2642\ufe0f", + ":man_golfing:": "\U0001f3cc\ufe0f\u200d\u2642\ufe0f", + ":man_golfing::skin-tone-1:": "\U0001f3cc\U0001f3fb\u200d\u2642\ufe0f", + ":man_golfing::skin-tone-2:": "\U0001f3cc\U0001f3fc\u200d\u2642\ufe0f", + ":man_golfing::skin-tone-3:": "\U0001f3cc\U0001f3fd\u200d\u2642\ufe0f", + ":man_golfing::skin-tone-4:": "\U0001f3cc\U0001f3fe\u200d\u2642\ufe0f", + ":man_golfing::skin-tone-5:": "\U0001f3cc\U0001f3ff\u200d\u2642\ufe0f", + ":man_guard:": "\U0001f482\u200d\u2642\ufe0f", + ":man_guard::skin-tone-1:": "\U0001f482\U0001f3fb\u200d\u2642\ufe0f", + ":man_guard::skin-tone-2:": "\U0001f482\U0001f3fc\u200d\u2642\ufe0f", + ":man_guard::skin-tone-3:": "\U0001f482\U0001f3fd\u200d\u2642\ufe0f", + ":man_guard::skin-tone-4:": "\U0001f482\U0001f3fe\u200d\u2642\ufe0f", + ":man_guard::skin-tone-5:": "\U0001f482\U0001f3ff\u200d\u2642\ufe0f", + ":man_health_worker:": "\U0001f468\u200d\u2695\ufe0f", + ":man_health_worker::skin-tone-1:": "\U0001f468\U0001f3fb\u200d\u2695\ufe0f", + ":man_health_worker::skin-tone-2:": "\U0001f468\U0001f3fc\u200d\u2695\ufe0f", + ":man_health_worker::skin-tone-3:": "\U0001f468\U0001f3fd\u200d\u2695\ufe0f", + ":man_health_worker::skin-tone-4:": "\U0001f468\U0001f3fe\u200d\u2695\ufe0f", + ":man_health_worker::skin-tone-5:": "\U0001f468\U0001f3ff\u200d\u2695\ufe0f", + ":man_in_business_suit_levitating:": "\U0001f574\ufe0f", + ":man_in_business_suit_levitating::skin-tone-1:": "\U0001f574\U0001f3fb", + ":man_in_business_suit_levitating::skin-tone-2:": "\U0001f574\U0001f3fc", + ":man_in_business_suit_levitating::skin-tone-3:": "\U0001f574\U0001f3fd", + ":man_in_business_suit_levitating::skin-tone-4:": "\U0001f574\U0001f3fe", + ":man_in_business_suit_levitating::skin-tone-5:": "\U0001f574\U0001f3ff", + ":man_in_lotus_position:": "\U0001f9d8\u200d\u2642\ufe0f", + ":man_in_lotus_position::skin-tone-1:": "\U0001f9d8\U0001f3fb\u200d\u2642\ufe0f", + ":man_in_lotus_position::skin-tone-2:": "\U0001f9d8\U0001f3fc\u200d\u2642\ufe0f", + ":man_in_lotus_position::skin-tone-3:": "\U0001f9d8\U0001f3fd\u200d\u2642\ufe0f", + ":man_in_lotus_position::skin-tone-4:": "\U0001f9d8\U0001f3fe\u200d\u2642\ufe0f", + ":man_in_lotus_position::skin-tone-5:": "\U0001f9d8\U0001f3ff\u200d\u2642\ufe0f", + ":man_in_manual_wheelchair:": "\U0001f468\u200d\U0001f9bd", + ":man_in_motorized_wheelchair:": "\U0001f468\u200d\U0001f9bc", + ":man_in_steamy_room:": "\U0001f9d6\u200d\u2642\ufe0f", + ":man_in_steamy_room::skin-tone-1:": "\U0001f9d6\U0001f3fb\u200d\u2642\ufe0f", + ":man_in_steamy_room::skin-tone-2:": "\U0001f9d6\U0001f3fc\u200d\u2642\ufe0f", + ":man_in_steamy_room::skin-tone-3:": "\U0001f9d6\U0001f3fd\u200d\u2642\ufe0f", + ":man_in_steamy_room::skin-tone-4:": "\U0001f9d6\U0001f3fe\u200d\u2642\ufe0f", + ":man_in_steamy_room::skin-tone-5:": "\U0001f9d6\U0001f3ff\u200d\u2642\ufe0f", + ":man_in_tuxedo:": "\U0001f935", + ":man_in_tuxedo::skin-tone-1:": "\U0001f935\U0001f3fb", + ":man_in_tuxedo::skin-tone-2:": "\U0001f935\U0001f3fc", + ":man_in_tuxedo::skin-tone-3:": "\U0001f935\U0001f3fd", + ":man_in_tuxedo::skin-tone-4:": "\U0001f935\U0001f3fe", + ":man_in_tuxedo::skin-tone-5:": "\U0001f935\U0001f3ff", + ":man_judge:": "\U0001f468\u200d\u2696\ufe0f", + ":man_judge::skin-tone-1:": "\U0001f468\U0001f3fb\u200d\u2696\ufe0f", + ":man_judge::skin-tone-2:": "\U0001f468\U0001f3fc\u200d\u2696\ufe0f", + ":man_judge::skin-tone-3:": "\U0001f468\U0001f3fd\u200d\u2696\ufe0f", + ":man_judge::skin-tone-4:": "\U0001f468\U0001f3fe\u200d\u2696\ufe0f", + ":man_judge::skin-tone-5:": "\U0001f468\U0001f3ff\u200d\u2696\ufe0f", + ":man_juggling:": "\U0001f939\u200d\u2642\ufe0f", + ":man_juggling::skin-tone-1:": "\U0001f939\U0001f3fb\u200d\u2642\ufe0f", + ":man_juggling::skin-tone-2:": "\U0001f939\U0001f3fc\u200d\u2642\ufe0f", + ":man_juggling::skin-tone-3:": "\U0001f939\U0001f3fd\u200d\u2642\ufe0f", + ":man_juggling::skin-tone-4:": "\U0001f939\U0001f3fe\u200d\u2642\ufe0f", + ":man_juggling::skin-tone-5:": "\U0001f939\U0001f3ff\u200d\u2642\ufe0f", + ":man_kneeling:": "\U0001f9ce\u200d\u2642\ufe0f", + ":man_lifting_weights:": "\U0001f3cb\ufe0f\u200d\u2642\ufe0f", + ":man_lifting_weights::skin-tone-1:": "\U0001f3cb\U0001f3fb\u200d\u2642\ufe0f", + ":man_lifting_weights::skin-tone-2:": "\U0001f3cb\U0001f3fc\u200d\u2642\ufe0f", + ":man_lifting_weights::skin-tone-3:": "\U0001f3cb\U0001f3fd\u200d\u2642\ufe0f", + ":man_lifting_weights::skin-tone-4:": "\U0001f3cb\U0001f3fe\u200d\u2642\ufe0f", + ":man_lifting_weights::skin-tone-5:": "\U0001f3cb\U0001f3ff\u200d\u2642\ufe0f", + ":man_mage:": "\U0001f9d9\u200d\u2642\ufe0f", + ":man_mage::skin-tone-1:": "\U0001f9d9\U0001f3fb\u200d\u2642\ufe0f", + ":man_mage::skin-tone-2:": "\U0001f9d9\U0001f3fc\u200d\u2642\ufe0f", + ":man_mage::skin-tone-3:": "\U0001f9d9\U0001f3fd\u200d\u2642\ufe0f", + ":man_mage::skin-tone-4:": "\U0001f9d9\U0001f3fe\u200d\u2642\ufe0f", + ":man_mage::skin-tone-5:": "\U0001f9d9\U0001f3ff\u200d\u2642\ufe0f", + ":man_mechanic:": "\U0001f468\u200d\U0001f527", + ":man_mechanic::skin-tone-1:": "\U0001f468\U0001f3fb\u200d\U0001f527", + ":man_mechanic::skin-tone-2:": "\U0001f468\U0001f3fc\u200d\U0001f527", + ":man_mechanic::skin-tone-3:": "\U0001f468\U0001f3fd\u200d\U0001f527", + ":man_mechanic::skin-tone-4:": "\U0001f468\U0001f3fe\u200d\U0001f527", + ":man_mechanic::skin-tone-5:": "\U0001f468\U0001f3ff\u200d\U0001f527", + ":man_mountain_biking:": "\U0001f6b5\u200d\u2642\ufe0f", + ":man_mountain_biking::skin-tone-1:": "\U0001f6b5\U0001f3fb\u200d\u2642\ufe0f", + ":man_mountain_biking::skin-tone-2:": "\U0001f6b5\U0001f3fc\u200d\u2642\ufe0f", + ":man_mountain_biking::skin-tone-3:": "\U0001f6b5\U0001f3fd\u200d\u2642\ufe0f", + ":man_mountain_biking::skin-tone-4:": "\U0001f6b5\U0001f3fe\u200d\u2642\ufe0f", + ":man_mountain_biking::skin-tone-5:": "\U0001f6b5\U0001f3ff\u200d\u2642\ufe0f", + ":man_office_worker:": "\U0001f468\u200d\U0001f4bc", + ":man_office_worker::skin-tone-1:": "\U0001f468\U0001f3fb\u200d\U0001f4bc", + ":man_office_worker::skin-tone-2:": "\U0001f468\U0001f3fc\u200d\U0001f4bc", + ":man_office_worker::skin-tone-3:": "\U0001f468\U0001f3fd\u200d\U0001f4bc", + ":man_office_worker::skin-tone-4:": "\U0001f468\U0001f3fe\u200d\U0001f4bc", + ":man_office_worker::skin-tone-5:": "\U0001f468\U0001f3ff\u200d\U0001f4bc", + ":man_pilot:": "\U0001f468\u200d\u2708\ufe0f", + ":man_pilot::skin-tone-1:": "\U0001f468\U0001f3fb\u200d\u2708\ufe0f", + ":man_pilot::skin-tone-2:": "\U0001f468\U0001f3fc\u200d\u2708\ufe0f", + ":man_pilot::skin-tone-3:": "\U0001f468\U0001f3fd\u200d\u2708\ufe0f", + ":man_pilot::skin-tone-4:": "\U0001f468\U0001f3fe\u200d\u2708\ufe0f", + ":man_pilot::skin-tone-5:": "\U0001f468\U0001f3ff\u200d\u2708\ufe0f", + ":man_playing_handball:": "\U0001f93e\u200d\u2642\ufe0f", + ":man_playing_handball::skin-tone-1:": "\U0001f93e\U0001f3fb\u200d\u2642\ufe0f", + ":man_playing_handball::skin-tone-2:": "\U0001f93e\U0001f3fc\u200d\u2642\ufe0f", + ":man_playing_handball::skin-tone-3:": "\U0001f93e\U0001f3fd\u200d\u2642\ufe0f", + ":man_playing_handball::skin-tone-4:": "\U0001f93e\U0001f3fe\u200d\u2642\ufe0f", + ":man_playing_handball::skin-tone-5:": "\U0001f93e\U0001f3ff\u200d\u2642\ufe0f", + ":man_playing_water_polo:": "\U0001f93d\u200d\u2642\ufe0f", + ":man_playing_water_polo::skin-tone-1:": "\U0001f93d\U0001f3fb\u200d\u2642\ufe0f", + ":man_playing_water_polo::skin-tone-2:": "\U0001f93d\U0001f3fc\u200d\u2642\ufe0f", + ":man_playing_water_polo::skin-tone-3:": "\U0001f93d\U0001f3fd\u200d\u2642\ufe0f", + ":man_playing_water_polo::skin-tone-4:": "\U0001f93d\U0001f3fe\u200d\u2642\ufe0f", + ":man_playing_water_polo::skin-tone-5:": "\U0001f93d\U0001f3ff\u200d\u2642\ufe0f", + ":man_police_officer:": "\U0001f46e\u200d\u2642\ufe0f", + ":man_police_officer::skin-tone-1:": "\U0001f46e\U0001f3fb\u200d\u2642\ufe0f", + ":man_police_officer::skin-tone-2:": "\U0001f46e\U0001f3fc\u200d\u2642\ufe0f", + ":man_police_officer::skin-tone-3:": "\U0001f46e\U0001f3fd\u200d\u2642\ufe0f", + ":man_police_officer::skin-tone-4:": "\U0001f46e\U0001f3fe\u200d\u2642\ufe0f", + ":man_police_officer::skin-tone-5:": "\U0001f46e\U0001f3ff\u200d\u2642\ufe0f", + ":man_pouting:": "\U0001f64e\u200d\u2642\ufe0f", + ":man_pouting::skin-tone-1:": "\U0001f64e\U0001f3fb\u200d\u2642\ufe0f", + ":man_pouting::skin-tone-2:": "\U0001f64e\U0001f3fc\u200d\u2642\ufe0f", + ":man_pouting::skin-tone-3:": "\U0001f64e\U0001f3fd\u200d\u2642\ufe0f", + ":man_pouting::skin-tone-4:": "\U0001f64e\U0001f3fe\u200d\u2642\ufe0f", + ":man_pouting::skin-tone-5:": "\U0001f64e\U0001f3ff\u200d\u2642\ufe0f", + ":man_raising_hand:": "\U0001f64b\u200d\u2642\ufe0f", + ":man_raising_hand::skin-tone-1:": "\U0001f64b\U0001f3fb\u200d\u2642\ufe0f", + ":man_raising_hand::skin-tone-2:": "\U0001f64b\U0001f3fc\u200d\u2642\ufe0f", + ":man_raising_hand::skin-tone-3:": "\U0001f64b\U0001f3fd\u200d\u2642\ufe0f", + ":man_raising_hand::skin-tone-4:": "\U0001f64b\U0001f3fe\u200d\u2642\ufe0f", + ":man_raising_hand::skin-tone-5:": "\U0001f64b\U0001f3ff\u200d\u2642\ufe0f", + ":man_red_hair:": "\U0001f468\u200d\U0001f9b0", + ":man_rowing_boat:": "\U0001f6a3\u200d\u2642\ufe0f", + ":man_rowing_boat::skin-tone-1:": "\U0001f6a3\U0001f3fb\u200d\u2642\ufe0f", + ":man_rowing_boat::skin-tone-2:": "\U0001f6a3\U0001f3fc\u200d\u2642\ufe0f", + ":man_rowing_boat::skin-tone-3:": "\U0001f6a3\U0001f3fd\u200d\u2642\ufe0f", + ":man_rowing_boat::skin-tone-4:": "\U0001f6a3\U0001f3fe\u200d\u2642\ufe0f", + ":man_rowing_boat::skin-tone-5:": "\U0001f6a3\U0001f3ff\u200d\u2642\ufe0f", + ":man_running:": "\U0001f3c3\u200d\u2642\ufe0f", + ":man_running::skin-tone-1:": "\U0001f3c3\U0001f3fb\u200d\u2642\ufe0f", + ":man_running::skin-tone-2:": "\U0001f3c3\U0001f3fc\u200d\u2642\ufe0f", + ":man_running::skin-tone-3:": "\U0001f3c3\U0001f3fd\u200d\u2642\ufe0f", + ":man_running::skin-tone-4:": "\U0001f3c3\U0001f3fe\u200d\u2642\ufe0f", + ":man_running::skin-tone-5:": "\U0001f3c3\U0001f3ff\u200d\u2642\ufe0f", + ":man_scientist:": "\U0001f468\u200d\U0001f52c", + ":man_scientist::skin-tone-1:": "\U0001f468\U0001f3fb\u200d\U0001f52c", + ":man_scientist::skin-tone-2:": "\U0001f468\U0001f3fc\u200d\U0001f52c", + ":man_scientist::skin-tone-3:": "\U0001f468\U0001f3fd\u200d\U0001f52c", + ":man_scientist::skin-tone-4:": "\U0001f468\U0001f3fe\u200d\U0001f52c", + ":man_scientist::skin-tone-5:": "\U0001f468\U0001f3ff\u200d\U0001f52c", + ":man_shrugging:": "\U0001f937\u200d\u2642\ufe0f", + ":man_shrugging::skin-tone-1:": "\U0001f937\U0001f3fb\u200d\u2642\ufe0f", + ":man_shrugging::skin-tone-2:": "\U0001f937\U0001f3fc\u200d\u2642\ufe0f", + ":man_shrugging::skin-tone-3:": "\U0001f937\U0001f3fd\u200d\u2642\ufe0f", + ":man_shrugging::skin-tone-4:": "\U0001f937\U0001f3fe\u200d\u2642\ufe0f", + ":man_shrugging::skin-tone-5:": "\U0001f937\U0001f3ff\u200d\u2642\ufe0f", + ":man_singer:": "\U0001f468\u200d\U0001f3a4", + ":man_singer::skin-tone-1:": "\U0001f468\U0001f3fb\u200d\U0001f3a4", + ":man_singer::skin-tone-2:": "\U0001f468\U0001f3fc\u200d\U0001f3a4", + ":man_singer::skin-tone-3:": "\U0001f468\U0001f3fd\u200d\U0001f3a4", + ":man_singer::skin-tone-4:": "\U0001f468\U0001f3fe\u200d\U0001f3a4", + ":man_singer::skin-tone-5:": "\U0001f468\U0001f3ff\u200d\U0001f3a4", + ":man_standing:": "\U0001f9cd\u200d\u2642\ufe0f", + ":man_student:": "\U0001f468\u200d\U0001f393", + ":man_student::skin-tone-1:": "\U0001f468\U0001f3fb\u200d\U0001f393", + ":man_student::skin-tone-2:": "\U0001f468\U0001f3fc\u200d\U0001f393", + ":man_student::skin-tone-3:": "\U0001f468\U0001f3fd\u200d\U0001f393", + ":man_student::skin-tone-4:": "\U0001f468\U0001f3fe\u200d\U0001f393", + ":man_student::skin-tone-5:": "\U0001f468\U0001f3ff\u200d\U0001f393", + ":man_superhero:": "\U0001f9b8\u200d\u2642\ufe0f", + ":man_supervillain:": "\U0001f9b9\u200d\u2642\ufe0f", + ":man_surfing:": "\U0001f3c4\u200d\u2642\ufe0f", + ":man_surfing::skin-tone-1:": "\U0001f3c4\U0001f3fb\u200d\u2642\ufe0f", + ":man_surfing::skin-tone-2:": "\U0001f3c4\U0001f3fc\u200d\u2642\ufe0f", + ":man_surfing::skin-tone-3:": "\U0001f3c4\U0001f3fd\u200d\u2642\ufe0f", + ":man_surfing::skin-tone-4:": "\U0001f3c4\U0001f3fe\u200d\u2642\ufe0f", + ":man_surfing::skin-tone-5:": "\U0001f3c4\U0001f3ff\u200d\u2642\ufe0f", + ":man_swimming:": "\U0001f3ca\u200d\u2642\ufe0f", + ":man_swimming::skin-tone-1:": "\U0001f3ca\U0001f3fb\u200d\u2642\ufe0f", + ":man_swimming::skin-tone-2:": "\U0001f3ca\U0001f3fc\u200d\u2642\ufe0f", + ":man_swimming::skin-tone-3:": "\U0001f3ca\U0001f3fd\u200d\u2642\ufe0f", + ":man_swimming::skin-tone-4:": "\U0001f3ca\U0001f3fe\u200d\u2642\ufe0f", + ":man_swimming::skin-tone-5:": "\U0001f3ca\U0001f3ff\u200d\u2642\ufe0f", + ":man_teacher:": "\U0001f468\u200d\U0001f3eb", + ":man_teacher::skin-tone-1:": "\U0001f468\U0001f3fb\u200d\U0001f3eb", + ":man_teacher::skin-tone-2:": "\U0001f468\U0001f3fc\u200d\U0001f3eb", + ":man_teacher::skin-tone-3:": "\U0001f468\U0001f3fd\u200d\U0001f3eb", + ":man_teacher::skin-tone-4:": "\U0001f468\U0001f3fe\u200d\U0001f3eb", + ":man_teacher::skin-tone-5:": "\U0001f468\U0001f3ff\u200d\U0001f3eb", + ":man_technologist:": "\U0001f468\u200d\U0001f4bb", + ":man_technologist::skin-tone-1:": "\U0001f468\U0001f3fb\u200d\U0001f4bb", + ":man_technologist::skin-tone-2:": "\U0001f468\U0001f3fc\u200d\U0001f4bb", + ":man_technologist::skin-tone-3:": "\U0001f468\U0001f3fd\u200d\U0001f4bb", + ":man_technologist::skin-tone-4:": "\U0001f468\U0001f3fe\u200d\U0001f4bb", + ":man_technologist::skin-tone-5:": "\U0001f468\U0001f3ff\u200d\U0001f4bb", + ":man_tipping_hand:": "\U0001f481\u200d\u2642\ufe0f", + ":man_tipping_hand::skin-tone-1:": "\U0001f481\U0001f3fb\u200d\u2642\ufe0f", + ":man_tipping_hand::skin-tone-2:": "\U0001f481\U0001f3fc\u200d\u2642\ufe0f", + ":man_tipping_hand::skin-tone-3:": "\U0001f481\U0001f3fd\u200d\u2642\ufe0f", + ":man_tipping_hand::skin-tone-4:": "\U0001f481\U0001f3fe\u200d\u2642\ufe0f", + ":man_tipping_hand::skin-tone-5:": "\U0001f481\U0001f3ff\u200d\u2642\ufe0f", + ":man::skin-tone-1:": "\U0001f468\U0001f3fb", + ":man::skin-tone-2:": "\U0001f468\U0001f3fc", + ":man::skin-tone-3:": "\U0001f468\U0001f3fd", + ":man::skin-tone-4:": "\U0001f468\U0001f3fe", + ":man::skin-tone-5:": "\U0001f468\U0001f3ff", + ":man_vampire:": "\U0001f9db\u200d\u2642\ufe0f", + ":man_vampire::skin-tone-1:": "\U0001f9db\U0001f3fb\u200d\u2642\ufe0f", + ":man_vampire::skin-tone-2:": "\U0001f9db\U0001f3fc\u200d\u2642\ufe0f", + ":man_vampire::skin-tone-3:": "\U0001f9db\U0001f3fd\u200d\u2642\ufe0f", + ":man_vampire::skin-tone-4:": "\U0001f9db\U0001f3fe\u200d\u2642\ufe0f", + ":man_vampire::skin-tone-5:": "\U0001f9db\U0001f3ff\u200d\u2642\ufe0f", + ":man_walking:": "\U0001f6b6\u200d\u2642\ufe0f", + ":man_walking::skin-tone-1:": "\U0001f6b6\U0001f3fb\u200d\u2642\ufe0f", + ":man_walking::skin-tone-2:": "\U0001f6b6\U0001f3fc\u200d\u2642\ufe0f", + ":man_walking::skin-tone-3:": "\U0001f6b6\U0001f3fd\u200d\u2642\ufe0f", + ":man_walking::skin-tone-4:": "\U0001f6b6\U0001f3fe\u200d\u2642\ufe0f", + ":man_walking::skin-tone-5:": "\U0001f6b6\U0001f3ff\u200d\u2642\ufe0f", + ":man_wearing_turban:": "\U0001f473\u200d\u2642\ufe0f", + ":man_wearing_turban::skin-tone-1:": "\U0001f473\U0001f3fb\u200d\u2642\ufe0f", + ":man_wearing_turban::skin-tone-2:": "\U0001f473\U0001f3fc\u200d\u2642\ufe0f", + ":man_wearing_turban::skin-tone-3:": "\U0001f473\U0001f3fd\u200d\u2642\ufe0f", + ":man_wearing_turban::skin-tone-4:": "\U0001f473\U0001f3fe\u200d\u2642\ufe0f", + ":man_wearing_turban::skin-tone-5:": "\U0001f473\U0001f3ff\u200d\u2642\ufe0f", + ":man_white_hair:": "\U0001f468\u200d\U0001f9b3", + ":man_with_chinese_cap:": "\U0001f472", + ":man_with_chinese_cap::skin-tone-1:": "\U0001f472\U0001f3fb", + ":man_with_chinese_cap::skin-tone-2:": "\U0001f472\U0001f3fc", + ":man_with_chinese_cap::skin-tone-3:": "\U0001f472\U0001f3fd", + ":man_with_chinese_cap::skin-tone-4:": "\U0001f472\U0001f3fe", + ":man_with_chinese_cap::skin-tone-5:": "\U0001f472\U0001f3ff", + ":man_with_gua_pi_mao:": "\U0001f472", + ":man_with_probing_cane:": "\U0001f468\u200d\U0001f9af", + ":man_with_turban:": "\U0001f473\u200d\u2642\ufe0f", + ":man_with_veil:": "\U0001f470\u200d\u2642\ufe0f", + ":man_with_white_cane:": "\U0001f468\u200d\U0001f9af", + ":man_zombie:": "\U0001f9df\u200d\u2642\ufe0f", + ":mandarin:": "\U0001f34a", + ":mango:": "\U0001f96d", + ":mans_shoe:": "\U0001f45e", + ":mantelpiece_clock:": "\U0001f570\ufe0f", + ":manual_wheelchair:": "\U0001f9bd", + ":man’s_shoe:": "\U0001f45e", + ":map:": "\U0001f5fa", + ":map_of_Japan:": "\U0001f5fe", + ":maple_leaf:": "\U0001f341", + ":marshall_islands:": "\U0001f1f2\U0001f1ed", + ":martial_arts_uniform:": "\U0001f94b", + ":martinique:": "\U0001f1f2\U0001f1f6", + ":mask:": "\U0001f637", + ":massage:": "\U0001f486\u200d\u2640\ufe0f", + ":massage_man:": "\U0001f486\u200d\u2642\ufe0f", + ":massage_woman:": "\U0001f486\u200d\u2640\ufe0f", + ":mate:": "\U0001f9c9", + ":mate_drink:": "\U0001f9c9", + ":mauritania:": "\U0001f1f2\U0001f1f7", + ":mauritius:": "\U0001f1f2\U0001f1fa", + ":mayotte:": "\U0001f1fe\U0001f1f9", + ":meat_on_bone:": "\U0001f356", + ":mechanic:": "\U0001f9d1\u200d\U0001f527", + ":mechanical_arm:": "\U0001f9be", + ":mechanical_leg:": "\U0001f9bf", + ":medal:": "\U0001f396\ufe0f", + ":medal_military:": "\U0001f396\ufe0f", + ":medal_sports:": "\U0001f3c5", + ":medical_symbol:": "\u2695\ufe0f", + ":mega:": "\U0001f4e3", + ":megaphone:": "\U0001f4e3", + ":melon:": "\U0001f348", + ":memo:": "\U0001f4dd", + ":men_holding_hands:": "\U0001f46c", + ":men_with_bunny_ears:": "\U0001f46f\u200d\u2642\ufe0f", + ":men_with_bunny_ears_partying:": "\U0001f46f\u200d\u2642\ufe0f", + ":men_wrestling:": "\U0001f93c\u200d\u2642\ufe0f", + ":menorah:": "\U0001f54e", + ":menorah_with_nine_branches:": "\U0001f54e", + ":mens:": "\U0001f6b9", + ":men’s_room:": "\U0001f6b9", + ":mermaid:": "\U0001f9dc\u200d\u2640\ufe0f", + ":mermaid::skin-tone-1:": "\U0001f9dc\U0001f3fb\u200d\u2640\ufe0f", + ":mermaid::skin-tone-2:": "\U0001f9dc\U0001f3fc\u200d\u2640\ufe0f", + ":mermaid::skin-tone-3:": "\U0001f9dc\U0001f3fd\u200d\u2640\ufe0f", + ":mermaid::skin-tone-4:": "\U0001f9dc\U0001f3fe\u200d\u2640\ufe0f", + ":mermaid::skin-tone-5:": "\U0001f9dc\U0001f3ff\u200d\u2640\ufe0f", + ":merman:": "\U0001f9dc\u200d\u2642\ufe0f", + ":merman::skin-tone-1:": "\U0001f9dc\U0001f3fb\u200d\u2642\ufe0f", + ":merman::skin-tone-2:": "\U0001f9dc\U0001f3fc\u200d\u2642\ufe0f", + ":merman::skin-tone-3:": "\U0001f9dc\U0001f3fd\u200d\u2642\ufe0f", + ":merman::skin-tone-4:": "\U0001f9dc\U0001f3fe\u200d\u2642\ufe0f", + ":merman::skin-tone-5:": "\U0001f9dc\U0001f3ff\u200d\u2642\ufe0f", + ":merperson:": "\U0001f9dc\u200d\u2642\ufe0f", + ":merperson::skin-tone-1:": "\U0001f9dc\U0001f3fb", + ":merperson::skin-tone-2:": "\U0001f9dc\U0001f3fc", + ":merperson::skin-tone-3:": "\U0001f9dc\U0001f3fd", + ":merperson::skin-tone-4:": "\U0001f9dc\U0001f3fe", + ":merperson::skin-tone-5:": "\U0001f9dc\U0001f3ff", + ":metal:": "\U0001f918", + ":metal::skin-tone-1:": "\U0001f918\U0001f3fb", + ":metal::skin-tone-2:": "\U0001f918\U0001f3fc", + ":metal::skin-tone-3:": "\U0001f918\U0001f3fd", + ":metal::skin-tone-4:": "\U0001f918\U0001f3fe", + ":metal::skin-tone-5:": "\U0001f918\U0001f3ff", + ":metro:": "\U0001f687", + ":mexico:": "\U0001f1f2\U0001f1fd", + ":microbe:": "\U0001f9a0", + ":micronesia:": "\U0001f1eb\U0001f1f2", + ":microphone:": "\U0001f3a4", + ":microphone2:": "\U0001f399", + ":microscope:": "\U0001f52c", + ":middle_finger:": "\U0001f595", + ":middle_finger::skin-tone-1:": "\U0001f595\U0001f3fb", + ":middle_finger::skin-tone-2:": "\U0001f595\U0001f3fc", + ":middle_finger::skin-tone-3:": "\U0001f595\U0001f3fd", + ":middle_finger::skin-tone-4:": "\U0001f595\U0001f3fe", + ":middle_finger::skin-tone-5:": "\U0001f595\U0001f3ff", + ":military_helmet:": "\U0001fa96", + ":military_medal:": "\U0001f396", + ":milk:": "\U0001f95b", + ":milk_glass:": "\U0001f95b", + ":milky_way:": "\U0001f30c", + ":minibus:": "\U0001f690", + ":minidisc:": "\U0001f4bd", + ":minus:": "\u2796", + ":mirror:": "\U0001fa9e", + ":moai:": "\U0001f5ff", + ":mobile_phone:": "\U0001f4f1", + ":mobile_phone_off:": "\U0001f4f4", + ":mobile_phone_with_arrow:": "\U0001f4f2", + ":moldova:": "\U0001f1f2\U0001f1e9", + ":monaco:": "\U0001f1f2\U0001f1e8", + ":money-mouth_face:": "\U0001f911", + ":money_bag:": "\U0001f4b0", + ":money_mouth:": "\U0001f911", + ":money_mouth_face:": "\U0001f911", + ":money_with_wings:": "\U0001f4b8", + ":moneybag:": "\U0001f4b0", + ":mongolia:": "\U0001f1f2\U0001f1f3", + ":monkey:": "\U0001f412", + ":monkey_face:": "\U0001f435", + ":monocle_face:": "\U0001f9d0", + ":monorail:": "\U0001f69d", + ":montenegro:": "\U0001f1f2\U0001f1ea", + ":montserrat:": "\U0001f1f2\U0001f1f8", + ":moon:": "\U0001f314", + ":moon_cake:": "\U0001f96e", + ":moon_viewing_ceremony:": "\U0001f391", + ":morocco:": "\U0001f1f2\U0001f1e6", + ":mortar_board:": "\U0001f393", + ":mosque:": "\U0001f54c", + ":mosquito:": "\U0001f99f", + ":mostly_sunny:": "\U0001f324\ufe0f", + ":motor_boat:": "\U0001f6e5\ufe0f", + ":motor_scooter:": "\U0001f6f5", + ":motorboat:": "\U0001f6e5", + ":motorcycle:": "\U0001f3cd", + ":motorized_wheelchair:": "\U0001f9bc", + ":motorway:": "\U0001f6e3\ufe0f", + ":mount_fuji:": "\U0001f5fb", + ":mountain:": "\u26f0\ufe0f", + ":mountain_bicyclist:": "\U0001f6b5\u200d\u2642\ufe0f", + ":mountain_biking_man:": "\U0001f6b5\u200d\u2642\ufe0f", + ":mountain_biking_woman:": "\U0001f6b5\u200d\u2640\ufe0f", + ":mountain_cableway:": "\U0001f6a0", + ":mountain_railway:": "\U0001f69e", + ":mountain_snow:": "\U0001f3d4", + ":mouse:": "\U0001f42d", + ":mouse2:": "\U0001f401", + ":mouse_face:": "\U0001f42d", + ":mouse_three_button:": "\U0001f5b1", + ":mouse_trap:": "\U0001faa4", + ":mouth:": "\U0001f444", + ":movie_camera:": "\U0001f3a5", + ":moyai:": "\U0001f5ff", + ":mozambique:": "\U0001f1f2\U0001f1ff", + ":mrs_claus:": "\U0001f936", + ":mrs_claus::skin-tone-1:": "\U0001f936\U0001f3fb", + ":mrs_claus::skin-tone-2:": "\U0001f936\U0001f3fc", + ":mrs_claus::skin-tone-3:": "\U0001f936\U0001f3fd", + ":mrs_claus::skin-tone-4:": "\U0001f936\U0001f3fe", + ":mrs_claus::skin-tone-5:": "\U0001f936\U0001f3ff", + ":multiply:": "\u2716", + ":muscle:": "\U0001f4aa", + ":muscle::skin-tone-1:": "\U0001f4aa\U0001f3fb", + ":muscle::skin-tone-2:": "\U0001f4aa\U0001f3fc", + ":muscle::skin-tone-3:": "\U0001f4aa\U0001f3fd", + ":muscle::skin-tone-4:": "\U0001f4aa\U0001f3fe", + ":muscle::skin-tone-5:": "\U0001f4aa\U0001f3ff", + ":mushroom:": "\U0001f344", + ":musical_keyboard:": "\U0001f3b9", + ":musical_note:": "\U0001f3b5", + ":musical_notes:": "\U0001f3b6", + ":musical_score:": "\U0001f3bc", + ":mute:": "\U0001f507", + ":muted_speaker:": "\U0001f507", + ":mx_claus:": "\U0001f9d1\u200d\U0001f384", + ":myanmar:": "\U0001f1f2\U0001f1f2", + ":nail_care:": "\U0001f485", + ":nail_care::skin-tone-1:": "\U0001f485\U0001f3fb", + ":nail_care::skin-tone-2:": "\U0001f485\U0001f3fc", + ":nail_care::skin-tone-3:": "\U0001f485\U0001f3fd", + ":nail_care::skin-tone-4:": "\U0001f485\U0001f3fe", + ":nail_care::skin-tone-5:": "\U0001f485\U0001f3ff", + ":nail_polish:": "\U0001f485", + ":name_badge:": "\U0001f4db", + ":namibia:": "\U0001f1f3\U0001f1e6", + ":national_park:": "\U0001f3de\ufe0f", + ":nauru:": "\U0001f1f3\U0001f1f7", + ":nauseated_face:": "\U0001f922", + ":nazar_amulet:": "\U0001f9ff", + ":necktie:": "\U0001f454", + ":negative_squared_cross_mark:": "\u274e", + ":nepal:": "\U0001f1f3\U0001f1f5", + ":nerd:": "\U0001f913", + ":nerd_face:": "\U0001f913", + ":nesting_dolls:": "\U0001fa86", + ":netherlands:": "\U0001f1f3\U0001f1f1", + ":neutral_face:": "\U0001f610", + ":new:": "\U0001f195", + ":new_caledonia:": "\U0001f1f3\U0001f1e8", + ":new_moon:": "\U0001f311", + ":new_moon_face:": "\U0001f31a", + ":new_moon_with_face:": "\U0001f31a", + ":new_zealand:": "\U0001f1f3\U0001f1ff", + ":newspaper:": "\U0001f4f0", + ":newspaper2:": "\U0001f5de", + ":newspaper_roll:": "\U0001f5de\ufe0f", + ":next_track_button:": "\u23ed", + ":ng:": "\U0001f196", + ":ng_man:": "\U0001f645\u200d\u2642\ufe0f", + ":ng_woman:": "\U0001f645\u200d\u2640\ufe0f", + ":nicaragua:": "\U0001f1f3\U0001f1ee", + ":niger:": "\U0001f1f3\U0001f1ea", + ":nigeria:": "\U0001f1f3\U0001f1ec", + ":night_with_stars:": "\U0001f303", + ":nine:": "9\ufe0f\u20e3", + ":nine-thirty:": "\U0001f564", + ":nine_o’clock:": "\U0001f558", + ":ninja:": "\U0001f977", + ":niue:": "\U0001f1f3\U0001f1fa", + ":no_bell:": "\U0001f515", + ":no_bicycles:": "\U0001f6b3", + ":no_entry:": "\u26d4", + ":no_entry_sign:": "\U0001f6ab", + ":no_good:": "\U0001f645\u200d\u2640\ufe0f", + ":no_good_man:": "\U0001f645\u200d\u2642\ufe0f", + ":no_good_woman:": "\U0001f645\u200d\u2640\ufe0f", + ":no_littering:": "\U0001f6af", + ":no_mobile_phones:": "\U0001f4f5", + ":no_mouth:": "\U0001f636", + ":no_one_under_eighteen:": "\U0001f51e", + ":no_pedestrians:": "\U0001f6b7", + ":no_smoking:": "\U0001f6ad", + ":non-potable_water:": "\U0001f6b1", + ":norfolk_island:": "\U0001f1f3\U0001f1eb", + ":north_korea:": "\U0001f1f0\U0001f1f5", + ":northern_mariana_islands:": "\U0001f1f2\U0001f1f5", + ":norway:": "\U0001f1f3\U0001f1f4", + ":nose:": "\U0001f443", + ":nose::skin-tone-1:": "\U0001f443\U0001f3fb", + ":nose::skin-tone-2:": "\U0001f443\U0001f3fc", + ":nose::skin-tone-3:": "\U0001f443\U0001f3fd", + ":nose::skin-tone-4:": "\U0001f443\U0001f3fe", + ":nose::skin-tone-5:": "\U0001f443\U0001f3ff", + ":notebook:": "\U0001f4d3", + ":notebook_with_decorative_cover:": "\U0001f4d4", + ":notepad_spiral:": "\U0001f5d2", + ":notes:": "\U0001f3b6", + ":nut_and_bolt:": "\U0001f529", + ":o:": "\u2b55", + ":o2:": "\U0001f17e\ufe0f", + ":ocean:": "\U0001f30a", + ":octagonal_sign:": "\U0001f6d1", + ":octopus:": "\U0001f419", + ":oden:": "\U0001f362", + ":office:": "\U0001f3e2", + ":office_building:": "\U0001f3e2", + ":office_worker:": "\U0001f9d1\u200d\U0001f4bc", + ":ogre:": "\U0001f479", + ":oil:": "\U0001f6e2", + ":oil_drum:": "\U0001f6e2\ufe0f", + ":ok:": "\U0001f197", + ":ok_hand:": "\U0001f44c", + ":ok_hand::skin-tone-1:": "\U0001f44c\U0001f3fb", + ":ok_hand::skin-tone-2:": "\U0001f44c\U0001f3fc", + ":ok_hand::skin-tone-3:": "\U0001f44c\U0001f3fd", + ":ok_hand::skin-tone-4:": "\U0001f44c\U0001f3fe", + ":ok_hand::skin-tone-5:": "\U0001f44c\U0001f3ff", + ":ok_man:": "\U0001f646\u200d\u2642\ufe0f", + ":ok_person:": "\U0001f646", + ":ok_woman:": "\U0001f646\u200d\u2640\ufe0f", + ":old_key:": "\U0001f5dd\ufe0f", + ":old_man:": "\U0001f474", + ":old_woman:": "\U0001f475", + ":older_adult:": "\U0001f9d3", + ":older_adult::skin-tone-1:": "\U0001f9d3\U0001f3fb", + ":older_adult::skin-tone-2:": "\U0001f9d3\U0001f3fc", + ":older_adult::skin-tone-3:": "\U0001f9d3\U0001f3fd", + ":older_adult::skin-tone-4:": "\U0001f9d3\U0001f3fe", + ":older_adult::skin-tone-5:": "\U0001f9d3\U0001f3ff", + ":older_man:": "\U0001f474", + ":older_man::skin-tone-1:": "\U0001f474\U0001f3fb", + ":older_man::skin-tone-2:": "\U0001f474\U0001f3fc", + ":older_man::skin-tone-3:": "\U0001f474\U0001f3fd", + ":older_man::skin-tone-4:": "\U0001f474\U0001f3fe", + ":older_man::skin-tone-5:": "\U0001f474\U0001f3ff", + ":older_person:": "\U0001f9d3", + ":older_woman:": "\U0001f475", + ":older_woman::skin-tone-1:": "\U0001f475\U0001f3fb", + ":older_woman::skin-tone-2:": "\U0001f475\U0001f3fc", + ":older_woman::skin-tone-3:": "\U0001f475\U0001f3fd", + ":older_woman::skin-tone-4:": "\U0001f475\U0001f3fe", + ":older_woman::skin-tone-5:": "\U0001f475\U0001f3ff", + ":olive:": "\U0001fad2", + ":om:": "\U0001f549", + ":om_symbol:": "\U0001f549\ufe0f", + ":oman:": "\U0001f1f4\U0001f1f2", + ":on:": "\U0001f51b", + ":oncoming_automobile:": "\U0001f698", + ":oncoming_bus:": "\U0001f68d", + ":oncoming_fist:": "\U0001f44a", + ":oncoming_police_car:": "\U0001f694", + ":oncoming_taxi:": "\U0001f696", + ":one:": "1\ufe0f\u20e3", + ":one-piece_swimsuit:": "\U0001fa71", + ":one-thirty:": "\U0001f55c", + ":one_o’clock:": "\U0001f550", + ":one_piece_swimsuit:": "\U0001fa71", + ":onion:": "\U0001f9c5", + ":open_book:": "\U0001f4d6", + ":open_file_folder:": "\U0001f4c2", + ":open_hands:": "\U0001f450", + ":open_hands::skin-tone-1:": "\U0001f450\U0001f3fb", + ":open_hands::skin-tone-2:": "\U0001f450\U0001f3fc", + ":open_hands::skin-tone-3:": "\U0001f450\U0001f3fd", + ":open_hands::skin-tone-4:": "\U0001f450\U0001f3fe", + ":open_hands::skin-tone-5:": "\U0001f450\U0001f3ff", + ":open_mailbox_with_lowered_flag:": "\U0001f4ed", + ":open_mailbox_with_raised_flag:": "\U0001f4ec", + ":open_mouth:": "\U0001f62e", + ":open_umbrella:": "\u2602\ufe0f", + ":ophiuchus:": "\u26ce", + ":optical_disk:": "\U0001f4bf", + ":orange:": "\U0001f34a", + ":orange_book:": "\U0001f4d9", + ":orange_circle:": "\U0001f7e0", + ":orange_heart:": "\U0001f9e1", + ":orange_square:": "\U0001f7e7", + ":orangutan:": "\U0001f9a7", + ":orthodox_cross:": "\u2626\ufe0f", + ":otter:": "\U0001f9a6", + ":outbox_tray:": "\U0001f4e4", + ":owl:": "\U0001f989", + ":ox:": "\U0001f402", + ":oyster:": "\U0001f9aa", + ":package:": "\U0001f4e6", + ":page_facing_up:": "\U0001f4c4", + ":page_with_curl:": "\U0001f4c3", + ":pager:": "\U0001f4df", + ":paintbrush:": "\U0001f58c", + ":pakistan:": "\U0001f1f5\U0001f1f0", + ":palau:": "\U0001f1f5\U0001f1fc", + ":palestinian_territories:": "\U0001f1f5\U0001f1f8", + ":palm_tree:": "\U0001f334", + ":palms_up_together:": "\U0001f932", + ":palms_up_together::skin-tone-1:": "\U0001f932\U0001f3fb", + ":palms_up_together::skin-tone-2:": "\U0001f932\U0001f3fc", + ":palms_up_together::skin-tone-3:": "\U0001f932\U0001f3fd", + ":palms_up_together::skin-tone-4:": "\U0001f932\U0001f3fe", + ":palms_up_together::skin-tone-5:": "\U0001f932\U0001f3ff", + ":panama:": "\U0001f1f5\U0001f1e6", + ":pancakes:": "\U0001f95e", + ":panda:": "\U0001f43c", + ":panda_face:": "\U0001f43c", + ":paperclip:": "\U0001f4ce", + ":paperclips:": "\U0001f587", + ":papua_new_guinea:": "\U0001f1f5\U0001f1ec", + ":parachute:": "\U0001fa82", + ":paraguay:": "\U0001f1f5\U0001f1fe", + ":parasol_on_ground:": "\u26f1\ufe0f", + ":park:": "\U0001f3de", + ":parking:": "\U0001f17f\ufe0f", + ":parrot:": "\U0001f99c", + ":part_alternation_mark:": "\u303d\ufe0f", + ":partly_sunny:": "\u26c5", + ":partly_sunny_rain:": "\U0001f326\ufe0f", + ":party_popper:": "\U0001f389", + ":partying_face:": "\U0001f973", + ":passenger_ship:": "\U0001f6f3\ufe0f", + ":passport_control:": "\U0001f6c2", + ":pause_button:": "\u23f8", + ":paw_prints:": "\U0001f43e", + ":peace:": "\u262e", + ":peace_symbol:": "\u262e\ufe0f", + ":peach:": "\U0001f351", + ":peacock:": "\U0001f99a", + ":peanuts:": "\U0001f95c", + ":pear:": "\U0001f350", + ":pen:": "\U0001f58a", + ":pen_ballpoint:": "\U0001f58a", + ":pen_fountain:": "\U0001f58b", + ":pencil:": "\u270f", + ":pencil2:": "\u270f\ufe0f", + ":penguin:": "\U0001f427", + ":pensive:": "\U0001f614", + ":pensive_face:": "\U0001f614", + ":people_holding_hands:": "\U0001f9d1\u200d\U0001f91d\u200d\U0001f9d1", + ":people_hugging:": "\U0001fac2", + ":people_with_bunny_ears:": "\U0001f46f", + ":people_with_bunny_ears_partying:": "\U0001f46f", + ":people_wrestling:": "\U0001f93c", + ":performing_arts:": "\U0001f3ad", + ":persevere:": "\U0001f623", + ":persevering_face:": "\U0001f623", + ":person:": "\U0001f9d1", + ":person_bald:": "\U0001f9d1\u200d\U0001f9b2", + ":person_biking:": "\U0001f6b4", + ":person_biking::skin-tone-1:": "\U0001f6b4\U0001f3fb", + ":person_biking::skin-tone-2:": "\U0001f6b4\U0001f3fc", + ":person_biking::skin-tone-3:": "\U0001f6b4\U0001f3fd", + ":person_biking::skin-tone-4:": "\U0001f6b4\U0001f3fe", + ":person_biking::skin-tone-5:": "\U0001f6b4\U0001f3ff", + ":person_blond_hair:": "\U0001f471", + ":person_bouncing_ball:": "\u26f9", + ":person_bouncing_ball::skin-tone-1:": "\u26f9\U0001f3fb", + ":person_bouncing_ball::skin-tone-2:": "\u26f9\U0001f3fc", + ":person_bouncing_ball::skin-tone-3:": "\u26f9\U0001f3fd", + ":person_bouncing_ball::skin-tone-4:": "\u26f9\U0001f3fe", + ":person_bouncing_ball::skin-tone-5:": "\u26f9\U0001f3ff", + ":person_bowing:": "\U0001f647", + ":person_bowing::skin-tone-1:": "\U0001f647\U0001f3fb", + ":person_bowing::skin-tone-2:": "\U0001f647\U0001f3fc", + ":person_bowing::skin-tone-3:": "\U0001f647\U0001f3fd", + ":person_bowing::skin-tone-4:": "\U0001f647\U0001f3fe", + ":person_bowing::skin-tone-5:": "\U0001f647\U0001f3ff", + ":person_cartwheeling:": "\U0001f938", + ":person_climbing:": "\U0001f9d7\u200d\u2640\ufe0f", + ":person_climbing::skin-tone-1:": "\U0001f9d7\U0001f3fb", + ":person_climbing::skin-tone-2:": "\U0001f9d7\U0001f3fc", + ":person_climbing::skin-tone-3:": "\U0001f9d7\U0001f3fd", + ":person_climbing::skin-tone-4:": "\U0001f9d7\U0001f3fe", + ":person_climbing::skin-tone-5:": "\U0001f9d7\U0001f3ff", + ":person_curly_hair:": "\U0001f9d1\u200d\U0001f9b1", + ":person_doing_cartwheel:": "\U0001f938", + ":person_doing_cartwheel::skin-tone-1:": "\U0001f938\U0001f3fb", + ":person_doing_cartwheel::skin-tone-2:": "\U0001f938\U0001f3fc", + ":person_doing_cartwheel::skin-tone-3:": "\U0001f938\U0001f3fd", + ":person_doing_cartwheel::skin-tone-4:": "\U0001f938\U0001f3fe", + ":person_doing_cartwheel::skin-tone-5:": "\U0001f938\U0001f3ff", + ":person_facepalming:": "\U0001f926", + ":person_facepalming::skin-tone-1:": "\U0001f926\U0001f3fb", + ":person_facepalming::skin-tone-2:": "\U0001f926\U0001f3fc", + ":person_facepalming::skin-tone-3:": "\U0001f926\U0001f3fd", + ":person_facepalming::skin-tone-4:": "\U0001f926\U0001f3fe", + ":person_facepalming::skin-tone-5:": "\U0001f926\U0001f3ff", + ":person_feeding_baby:": "\U0001f9d1\u200d\U0001f37c", + ":person_fencing:": "\U0001f93a", + ":person_frowning:": "\U0001f64d\u200d\u2640\ufe0f", + ":person_frowning::skin-tone-1:": "\U0001f64d\U0001f3fb", + ":person_frowning::skin-tone-2:": "\U0001f64d\U0001f3fc", + ":person_frowning::skin-tone-3:": "\U0001f64d\U0001f3fd", + ":person_frowning::skin-tone-4:": "\U0001f64d\U0001f3fe", + ":person_frowning::skin-tone-5:": "\U0001f64d\U0001f3ff", + ":person_gesturing_NO:": "\U0001f645", + ":person_gesturing_OK:": "\U0001f646", + ":person_gesturing_no:": "\U0001f645", + ":person_gesturing_no::skin-tone-1:": "\U0001f645\U0001f3fb", + ":person_gesturing_no::skin-tone-2:": "\U0001f645\U0001f3fc", + ":person_gesturing_no::skin-tone-3:": "\U0001f645\U0001f3fd", + ":person_gesturing_no::skin-tone-4:": "\U0001f645\U0001f3fe", + ":person_gesturing_no::skin-tone-5:": "\U0001f645\U0001f3ff", + ":person_gesturing_ok:": "\U0001f646", + ":person_gesturing_ok::skin-tone-1:": "\U0001f646\U0001f3fb", + ":person_gesturing_ok::skin-tone-2:": "\U0001f646\U0001f3fc", + ":person_gesturing_ok::skin-tone-3:": "\U0001f646\U0001f3fd", + ":person_gesturing_ok::skin-tone-4:": "\U0001f646\U0001f3fe", + ":person_gesturing_ok::skin-tone-5:": "\U0001f646\U0001f3ff", + ":person_getting_haircut:": "\U0001f487", + ":person_getting_haircut::skin-tone-1:": "\U0001f487\U0001f3fb", + ":person_getting_haircut::skin-tone-2:": "\U0001f487\U0001f3fc", + ":person_getting_haircut::skin-tone-3:": "\U0001f487\U0001f3fd", + ":person_getting_haircut::skin-tone-4:": "\U0001f487\U0001f3fe", + ":person_getting_haircut::skin-tone-5:": "\U0001f487\U0001f3ff", + ":person_getting_massage:": "\U0001f486", + ":person_getting_massage::skin-tone-1:": "\U0001f486\U0001f3fb", + ":person_getting_massage::skin-tone-2:": "\U0001f486\U0001f3fc", + ":person_getting_massage::skin-tone-3:": "\U0001f486\U0001f3fd", + ":person_getting_massage::skin-tone-4:": "\U0001f486\U0001f3fe", + ":person_getting_massage::skin-tone-5:": "\U0001f486\U0001f3ff", + ":person_golfing:": "\U0001f3cc", + ":person_golfing::skin-tone-1:": "\U0001f3cc\U0001f3fb", + ":person_golfing::skin-tone-2:": "\U0001f3cc\U0001f3fc", + ":person_golfing::skin-tone-3:": "\U0001f3cc\U0001f3fd", + ":person_golfing::skin-tone-4:": "\U0001f3cc\U0001f3fe", + ":person_golfing::skin-tone-5:": "\U0001f3cc\U0001f3ff", + ":person_in_bed:": "\U0001f6cc", + ":person_in_bed::skin-tone-1:": "\U0001f6cc\U0001f3fb", + ":person_in_bed::skin-tone-2:": "\U0001f6cc\U0001f3fc", + ":person_in_bed::skin-tone-3:": "\U0001f6cc\U0001f3fd", + ":person_in_bed::skin-tone-4:": "\U0001f6cc\U0001f3fe", + ":person_in_bed::skin-tone-5:": "\U0001f6cc\U0001f3ff", + ":person_in_lotus_position:": "\U0001f9d8\u200d\u2640\ufe0f", + ":person_in_lotus_position::skin-tone-1:": "\U0001f9d8\U0001f3fb", + ":person_in_lotus_position::skin-tone-2:": "\U0001f9d8\U0001f3fc", + ":person_in_lotus_position::skin-tone-3:": "\U0001f9d8\U0001f3fd", + ":person_in_lotus_position::skin-tone-4:": "\U0001f9d8\U0001f3fe", + ":person_in_lotus_position::skin-tone-5:": "\U0001f9d8\U0001f3ff", + ":person_in_manual_wheelchair:": "\U0001f9d1\u200d\U0001f9bd", + ":person_in_motorized_wheelchair:": "\U0001f9d1\u200d\U0001f9bc", + ":person_in_steamy_room:": "\U0001f9d6\u200d\u2642\ufe0f", + ":person_in_steamy_room::skin-tone-1:": "\U0001f9d6\U0001f3fb", + ":person_in_steamy_room::skin-tone-2:": "\U0001f9d6\U0001f3fc", + ":person_in_steamy_room::skin-tone-3:": "\U0001f9d6\U0001f3fd", + ":person_in_steamy_room::skin-tone-4:": "\U0001f9d6\U0001f3fe", + ":person_in_steamy_room::skin-tone-5:": "\U0001f9d6\U0001f3ff", + ":person_in_suit_levitating:": "\U0001f574", + ":person_in_tuxedo:": "\U0001f935", + ":person_juggling:": "\U0001f939", + ":person_juggling::skin-tone-1:": "\U0001f939\U0001f3fb", + ":person_juggling::skin-tone-2:": "\U0001f939\U0001f3fc", + ":person_juggling::skin-tone-3:": "\U0001f939\U0001f3fd", + ":person_juggling::skin-tone-4:": "\U0001f939\U0001f3fe", + ":person_juggling::skin-tone-5:": "\U0001f939\U0001f3ff", + ":person_kneeling:": "\U0001f9ce", + ":person_lifting_weights:": "\U0001f3cb", + ":person_lifting_weights::skin-tone-1:": "\U0001f3cb\U0001f3fb", + ":person_lifting_weights::skin-tone-2:": "\U0001f3cb\U0001f3fc", + ":person_lifting_weights::skin-tone-3:": "\U0001f3cb\U0001f3fd", + ":person_lifting_weights::skin-tone-4:": "\U0001f3cb\U0001f3fe", + ":person_lifting_weights::skin-tone-5:": "\U0001f3cb\U0001f3ff", + ":person_mountain_biking:": "\U0001f6b5", + ":person_mountain_biking::skin-tone-1:": "\U0001f6b5\U0001f3fb", + ":person_mountain_biking::skin-tone-2:": "\U0001f6b5\U0001f3fc", + ":person_mountain_biking::skin-tone-3:": "\U0001f6b5\U0001f3fd", + ":person_mountain_biking::skin-tone-4:": "\U0001f6b5\U0001f3fe", + ":person_mountain_biking::skin-tone-5:": "\U0001f6b5\U0001f3ff", + ":person_playing_handball:": "\U0001f93e", + ":person_playing_handball::skin-tone-1:": "\U0001f93e\U0001f3fb", + ":person_playing_handball::skin-tone-2:": "\U0001f93e\U0001f3fc", + ":person_playing_handball::skin-tone-3:": "\U0001f93e\U0001f3fd", + ":person_playing_handball::skin-tone-4:": "\U0001f93e\U0001f3fe", + ":person_playing_handball::skin-tone-5:": "\U0001f93e\U0001f3ff", + ":person_playing_water_polo:": "\U0001f93d", + ":person_playing_water_polo::skin-tone-1:": "\U0001f93d\U0001f3fb", + ":person_playing_water_polo::skin-tone-2:": "\U0001f93d\U0001f3fc", + ":person_playing_water_polo::skin-tone-3:": "\U0001f93d\U0001f3fd", + ":person_playing_water_polo::skin-tone-4:": "\U0001f93d\U0001f3fe", + ":person_playing_water_polo::skin-tone-5:": "\U0001f93d\U0001f3ff", + ":person_pouting:": "\U0001f64e", + ":person_pouting::skin-tone-1:": "\U0001f64e\U0001f3fb", + ":person_pouting::skin-tone-2:": "\U0001f64e\U0001f3fc", + ":person_pouting::skin-tone-3:": "\U0001f64e\U0001f3fd", + ":person_pouting::skin-tone-4:": "\U0001f64e\U0001f3fe", + ":person_pouting::skin-tone-5:": "\U0001f64e\U0001f3ff", + ":person_raising_hand:": "\U0001f64b", + ":person_raising_hand::skin-tone-1:": "\U0001f64b\U0001f3fb", + ":person_raising_hand::skin-tone-2:": "\U0001f64b\U0001f3fc", + ":person_raising_hand::skin-tone-3:": "\U0001f64b\U0001f3fd", + ":person_raising_hand::skin-tone-4:": "\U0001f64b\U0001f3fe", + ":person_raising_hand::skin-tone-5:": "\U0001f64b\U0001f3ff", + ":person_red_hair:": "\U0001f9d1\u200d\U0001f9b0", + ":person_rowing_boat:": "\U0001f6a3", + ":person_rowing_boat::skin-tone-1:": "\U0001f6a3\U0001f3fb", + ":person_rowing_boat::skin-tone-2:": "\U0001f6a3\U0001f3fc", + ":person_rowing_boat::skin-tone-3:": "\U0001f6a3\U0001f3fd", + ":person_rowing_boat::skin-tone-4:": "\U0001f6a3\U0001f3fe", + ":person_rowing_boat::skin-tone-5:": "\U0001f6a3\U0001f3ff", + ":person_running:": "\U0001f3c3", + ":person_running::skin-tone-1:": "\U0001f3c3\U0001f3fb", + ":person_running::skin-tone-2:": "\U0001f3c3\U0001f3fc", + ":person_running::skin-tone-3:": "\U0001f3c3\U0001f3fd", + ":person_running::skin-tone-4:": "\U0001f3c3\U0001f3fe", + ":person_running::skin-tone-5:": "\U0001f3c3\U0001f3ff", + ":person_shrugging:": "\U0001f937", + ":person_shrugging::skin-tone-1:": "\U0001f937\U0001f3fb", + ":person_shrugging::skin-tone-2:": "\U0001f937\U0001f3fc", + ":person_shrugging::skin-tone-3:": "\U0001f937\U0001f3fd", + ":person_shrugging::skin-tone-4:": "\U0001f937\U0001f3fe", + ":person_shrugging::skin-tone-5:": "\U0001f937\U0001f3ff", + ":person_standing:": "\U0001f9cd", + ":person_surfing:": "\U0001f3c4", + ":person_surfing::skin-tone-1:": "\U0001f3c4\U0001f3fb", + ":person_surfing::skin-tone-2:": "\U0001f3c4\U0001f3fc", + ":person_surfing::skin-tone-3:": "\U0001f3c4\U0001f3fd", + ":person_surfing::skin-tone-4:": "\U0001f3c4\U0001f3fe", + ":person_surfing::skin-tone-5:": "\U0001f3c4\U0001f3ff", + ":person_swimming:": "\U0001f3ca", + ":person_swimming::skin-tone-1:": "\U0001f3ca\U0001f3fb", + ":person_swimming::skin-tone-2:": "\U0001f3ca\U0001f3fc", + ":person_swimming::skin-tone-3:": "\U0001f3ca\U0001f3fd", + ":person_swimming::skin-tone-4:": "\U0001f3ca\U0001f3fe", + ":person_swimming::skin-tone-5:": "\U0001f3ca\U0001f3ff", + ":person_taking_bath:": "\U0001f6c0", + ":person_tipping_hand:": "\U0001f481", + ":person_tipping_hand::skin-tone-1:": "\U0001f481\U0001f3fb", + ":person_tipping_hand::skin-tone-2:": "\U0001f481\U0001f3fc", + ":person_tipping_hand::skin-tone-3:": "\U0001f481\U0001f3fd", + ":person_tipping_hand::skin-tone-4:": "\U0001f481\U0001f3fe", + ":person_tipping_hand::skin-tone-5:": "\U0001f481\U0001f3ff", + ":person_walking:": "\U0001f6b6", + ":person_walking::skin-tone-1:": "\U0001f6b6\U0001f3fb", + ":person_walking::skin-tone-2:": "\U0001f6b6\U0001f3fc", + ":person_walking::skin-tone-3:": "\U0001f6b6\U0001f3fd", + ":person_walking::skin-tone-4:": "\U0001f6b6\U0001f3fe", + ":person_walking::skin-tone-5:": "\U0001f6b6\U0001f3ff", + ":person_wearing_turban:": "\U0001f473", + ":person_wearing_turban::skin-tone-1:": "\U0001f473\U0001f3fb", + ":person_wearing_turban::skin-tone-2:": "\U0001f473\U0001f3fc", + ":person_wearing_turban::skin-tone-3:": "\U0001f473\U0001f3fd", + ":person_wearing_turban::skin-tone-4:": "\U0001f473\U0001f3fe", + ":person_wearing_turban::skin-tone-5:": "\U0001f473\U0001f3ff", + ":person_white_hair:": "\U0001f9d1\u200d\U0001f9b3", + ":person_with_ball:": "\u26f9\ufe0f\u200d\u2642\ufe0f", + ":person_with_blond_hair:": "\U0001f471\u200d\u2642\ufe0f", + ":person_with_headscarf:": "\U0001f9d5", + ":person_with_pouting_face:": "\U0001f64e\u200d\u2640\ufe0f", + ":person_with_probing_cane:": "\U0001f9d1\u200d\U0001f9af", + ":person_with_skullcap:": "\U0001f472", + ":person_with_turban:": "\U0001f473", + ":person_with_veil:": "\U0001f470", + ":person_with_white_cane:": "\U0001f9d1\u200d\U0001f9af", + ":peru:": "\U0001f1f5\U0001f1ea", + ":petri_dish:": "\U0001f9eb", + ":philippines:": "\U0001f1f5\U0001f1ed", + ":phone:": "\u260e\ufe0f", + ":pi_ata:": "\U0001fa85", + ":pick:": "\u26cf\ufe0f", + ":pickup_truck:": "\U0001f6fb", + ":pie:": "\U0001f967", + ":pig:": "\U0001f437", + ":pig2:": "\U0001f416", + ":pig_face:": "\U0001f437", + ":pig_nose:": "\U0001f43d", + ":pile_of_poo:": "\U0001f4a9", + ":pill:": "\U0001f48a", + ":pilot:": "\U0001f9d1\u200d\u2708\ufe0f", + ":pinched_fingers:": "\U0001f90c", + ":pinching_hand:": "\U0001f90f", + ":pine_decoration:": "\U0001f38d", + ":pineapple:": "\U0001f34d", + ":ping_pong:": "\U0001f3d3", + ":pirate_flag:": "\U0001f3f4\u200d\u2620\ufe0f", + ":pisces:": "\u2653", + ":pistol:": "\U0001f52b", + ":pitcairn_islands:": "\U0001f1f5\U0001f1f3", + ":pizza:": "\U0001f355", + ":piñata:": "\U0001fa85", + ":placard:": "\U0001faa7", + ":place_of_worship:": "\U0001f6d0", + ":plate_with_cutlery:": "\U0001f37d\ufe0f", + ":play_button:": "\u25b6", + ":play_or_pause_button:": "\u23ef", + ":play_pause:": "\u23ef", + ":pleading_face:": "\U0001f97a", + ":plunger:": "\U0001faa0", + ":plus:": "\u2795", + ":point_down:": "\U0001f447", + ":point_down::skin-tone-1:": "\U0001f447\U0001f3fb", + ":point_down::skin-tone-2:": "\U0001f447\U0001f3fc", + ":point_down::skin-tone-3:": "\U0001f447\U0001f3fd", + ":point_down::skin-tone-4:": "\U0001f447\U0001f3fe", + ":point_down::skin-tone-5:": "\U0001f447\U0001f3ff", + ":point_left:": "\U0001f448", + ":point_left::skin-tone-1:": "\U0001f448\U0001f3fb", + ":point_left::skin-tone-2:": "\U0001f448\U0001f3fc", + ":point_left::skin-tone-3:": "\U0001f448\U0001f3fd", + ":point_left::skin-tone-4:": "\U0001f448\U0001f3fe", + ":point_left::skin-tone-5:": "\U0001f448\U0001f3ff", + ":point_right:": "\U0001f449", + ":point_right::skin-tone-1:": "\U0001f449\U0001f3fb", + ":point_right::skin-tone-2:": "\U0001f449\U0001f3fc", + ":point_right::skin-tone-3:": "\U0001f449\U0001f3fd", + ":point_right::skin-tone-4:": "\U0001f449\U0001f3fe", + ":point_right::skin-tone-5:": "\U0001f449\U0001f3ff", + ":point_up:": "\u261d\ufe0f", + ":point_up_2:": "\U0001f446", + ":point_up_2::skin-tone-1:": "\U0001f446\U0001f3fb", + ":point_up_2::skin-tone-2:": "\U0001f446\U0001f3fc", + ":point_up_2::skin-tone-3:": "\U0001f446\U0001f3fd", + ":point_up_2::skin-tone-4:": "\U0001f446\U0001f3fe", + ":point_up_2::skin-tone-5:": "\U0001f446\U0001f3ff", + ":point_up::skin-tone-1:": "\u261d\U0001f3fb", + ":point_up::skin-tone-2:": "\u261d\U0001f3fc", + ":point_up::skin-tone-3:": "\u261d\U0001f3fd", + ":point_up::skin-tone-4:": "\u261d\U0001f3fe", + ":point_up::skin-tone-5:": "\u261d\U0001f3ff", + ":poland:": "\U0001f1f5\U0001f1f1", + ":polar_bear:": "\U0001f43b\u200d\u2744\ufe0f", + ":police_car:": "\U0001f693", + ":police_car_light:": "\U0001f6a8", + ":police_officer:": "\U0001f46e", + ":police_officer::skin-tone-1:": "\U0001f46e\U0001f3fb", + ":police_officer::skin-tone-2:": "\U0001f46e\U0001f3fc", + ":police_officer::skin-tone-3:": "\U0001f46e\U0001f3fd", + ":police_officer::skin-tone-4:": "\U0001f46e\U0001f3fe", + ":police_officer::skin-tone-5:": "\U0001f46e\U0001f3ff", + ":policeman:": "\U0001f46e\u200d\u2642\ufe0f", + ":policewoman:": "\U0001f46e\u200d\u2640\ufe0f", + ":poodle:": "\U0001f429", + ":pool_8_ball:": "\U0001f3b1", + ":poop:": "\U0001f4a9", + ":popcorn:": "\U0001f37f", + ":portugal:": "\U0001f1f5\U0001f1f9", + ":post_office:": "\U0001f3e3", + ":postal_horn:": "\U0001f4ef", + ":postbox:": "\U0001f4ee", + ":pot_of_food:": "\U0001f372", + ":potable_water:": "\U0001f6b0", + ":potato:": "\U0001f954", + ":potted_plant:": "\U0001fab4", + ":pouch:": "\U0001f45d", + ":poultry_leg:": "\U0001f357", + ":pound:": "\U0001f4b7", + ":pound_banknote:": "\U0001f4b7", + ":pout:": "\U0001f621", + ":pouting_cat:": "\U0001f63e", + ":pouting_face:": "\U0001f621", + ":pouting_man:": "\U0001f64e\u200d\u2642\ufe0f", + ":pouting_woman:": "\U0001f64e\u200d\u2640\ufe0f", + ":pray:": "\U0001f64f", + ":pray::skin-tone-1:": "\U0001f64f\U0001f3fb", + ":pray::skin-tone-2:": "\U0001f64f\U0001f3fc", + ":pray::skin-tone-3:": "\U0001f64f\U0001f3fd", + ":pray::skin-tone-4:": "\U0001f64f\U0001f3fe", + ":pray::skin-tone-5:": "\U0001f64f\U0001f3ff", + ":prayer_beads:": "\U0001f4ff", + ":pregnant_woman:": "\U0001f930", + ":pregnant_woman::skin-tone-1:": "\U0001f930\U0001f3fb", + ":pregnant_woman::skin-tone-2:": "\U0001f930\U0001f3fc", + ":pregnant_woman::skin-tone-3:": "\U0001f930\U0001f3fd", + ":pregnant_woman::skin-tone-4:": "\U0001f930\U0001f3fe", + ":pregnant_woman::skin-tone-5:": "\U0001f930\U0001f3ff", + ":pretzel:": "\U0001f968", + ":previous_track_button:": "\u23ee\ufe0f", + ":prince:": "\U0001f934", + ":prince::skin-tone-1:": "\U0001f934\U0001f3fb", + ":prince::skin-tone-2:": "\U0001f934\U0001f3fc", + ":prince::skin-tone-3:": "\U0001f934\U0001f3fd", + ":prince::skin-tone-4:": "\U0001f934\U0001f3fe", + ":prince::skin-tone-5:": "\U0001f934\U0001f3ff", + ":princess:": "\U0001f478", + ":princess::skin-tone-1:": "\U0001f478\U0001f3fb", + ":princess::skin-tone-2:": "\U0001f478\U0001f3fc", + ":princess::skin-tone-3:": "\U0001f478\U0001f3fd", + ":princess::skin-tone-4:": "\U0001f478\U0001f3fe", + ":princess::skin-tone-5:": "\U0001f478\U0001f3ff", + ":printer:": "\U0001f5a8\ufe0f", + ":probing_cane:": "\U0001f9af", + ":prohibited:": "\U0001f6ab", + ":projector:": "\U0001f4fd", + ":puerto_rico:": "\U0001f1f5\U0001f1f7", + ":punch:": "\U0001f44a", + ":punch::skin-tone-1:": "\U0001f44a\U0001f3fb", + ":punch::skin-tone-2:": "\U0001f44a\U0001f3fc", + ":punch::skin-tone-3:": "\U0001f44a\U0001f3fd", + ":punch::skin-tone-4:": "\U0001f44a\U0001f3fe", + ":punch::skin-tone-5:": "\U0001f44a\U0001f3ff", + ":purple_circle:": "\U0001f7e3", + ":purple_heart:": "\U0001f49c", + ":purple_square:": "\U0001f7ea", + ":purse:": "\U0001f45b", + ":pushpin:": "\U0001f4cc", + ":put_litter_in_its_place:": "\U0001f6ae", + ":puzzle_piece:": "\U0001f9e9", + ":qatar:": "\U0001f1f6\U0001f1e6", + ":question:": "\u2753", + ":question_mark:": "\u2753", + ":rabbit:": "\U0001f430", + ":rabbit2:": "\U0001f407", + ":rabbit_face:": "\U0001f430", + ":raccoon:": "\U0001f99d", + ":race_car:": "\U0001f3ce", + ":racehorse:": "\U0001f40e", + ":racing_car:": "\U0001f3ce\ufe0f", + ":racing_motorcycle:": "\U0001f3cd\ufe0f", + ":radio:": "\U0001f4fb", + ":radio_button:": "\U0001f518", + ":radioactive:": "\u2622", + ":radioactive_sign:": "\u2622\ufe0f", + ":rage:": "\U0001f621", + ":railway_car:": "\U0001f683", + ":railway_track:": "\U0001f6e4\ufe0f", + ":rain_cloud:": "\U0001f327\ufe0f", + ":rainbow:": "\U0001f308", + ":rainbow-flag:": "\U0001f3f3\ufe0f\u200d\U0001f308", + ":rainbow_flag:": "\U0001f3f3\ufe0f\u200d\U0001f308", + ":raised_back_of_hand:": "\U0001f91a", + ":raised_back_of_hand::skin-tone-1:": "\U0001f91a\U0001f3fb", + ":raised_back_of_hand::skin-tone-2:": "\U0001f91a\U0001f3fc", + ":raised_back_of_hand::skin-tone-3:": "\U0001f91a\U0001f3fd", + ":raised_back_of_hand::skin-tone-4:": "\U0001f91a\U0001f3fe", + ":raised_back_of_hand::skin-tone-5:": "\U0001f91a\U0001f3ff", + ":raised_eyebrow:": "\U0001f928", + ":raised_fist:": "\u270a", + ":raised_hand:": "\u270b", + ":raised_hand::skin-tone-1:": "\u270b\U0001f3fb", + ":raised_hand::skin-tone-2:": "\u270b\U0001f3fc", + ":raised_hand::skin-tone-3:": "\u270b\U0001f3fd", + ":raised_hand::skin-tone-4:": "\u270b\U0001f3fe", + ":raised_hand::skin-tone-5:": "\u270b\U0001f3ff", + ":raised_hand_with_fingers_splayed:": "\U0001f590\ufe0f", + ":raised_hands:": "\U0001f64c", + ":raised_hands::skin-tone-1:": "\U0001f64c\U0001f3fb", + ":raised_hands::skin-tone-2:": "\U0001f64c\U0001f3fc", + ":raised_hands::skin-tone-3:": "\U0001f64c\U0001f3fd", + ":raised_hands::skin-tone-4:": "\U0001f64c\U0001f3fe", + ":raised_hands::skin-tone-5:": "\U0001f64c\U0001f3ff", + ":raising_hand:": "\U0001f64b\u200d\u2640\ufe0f", + ":raising_hand_man:": "\U0001f64b\u200d\u2642\ufe0f", + ":raising_hand_woman:": "\U0001f64b\u200d\u2640\ufe0f", + ":raising_hands:": "\U0001f64c", + ":ram:": "\U0001f40f", + ":ramen:": "\U0001f35c", + ":rat:": "\U0001f400", + ":razor:": "\U0001fa92", + ":receipt:": "\U0001f9fe", + ":record_button:": "\u23fa", + ":recycle:": "\u267b\ufe0f", + ":recycling_symbol:": "\u267b", + ":red_apple:": "\U0001f34e", + ":red_car:": "\U0001f697", + ":red_circle:": "\U0001f534", + ":red_envelope:": "\U0001f9e7", + ":red_hair:": "\U0001f9b0", + ":red_haired_man:": "\U0001f468\u200d\U0001f9b0", + ":red_haired_person:": "\U0001f9d1\u200d\U0001f9b0", + ":red_haired_woman:": "\U0001f469\u200d\U0001f9b0", + ":red_heart:": "\u2764", + ":red_paper_lantern:": "\U0001f3ee", + ":red_square:": "\U0001f7e5", + ":red_triangle_pointed_down:": "\U0001f53b", + ":red_triangle_pointed_up:": "\U0001f53a", + ":registered:": "\u00ae\ufe0f", + ":relaxed:": "\u263a\ufe0f", + ":relieved:": "\U0001f60c", + ":relieved_face:": "\U0001f60c", + ":reminder_ribbon:": "\U0001f397\ufe0f", + ":repeat:": "\U0001f501", + ":repeat_button:": "\U0001f501", + ":repeat_one:": "\U0001f502", + ":repeat_single_button:": "\U0001f502", + ":rescue_worker_helmet:": "\u26d1\ufe0f", + ":rescue_worker’s_helmet:": "\u26d1", + ":restroom:": "\U0001f6bb", + ":reunion:": "\U0001f1f7\U0001f1ea", + ":reverse_button:": "\u25c0", + ":revolving_hearts:": "\U0001f49e", + ":rewind:": "\u23ea", + ":rhino:": "\U0001f98f", + ":rhinoceros:": "\U0001f98f", + ":ribbon:": "\U0001f380", + ":rice:": "\U0001f35a", + ":rice_ball:": "\U0001f359", + ":rice_cracker:": "\U0001f358", + ":rice_scene:": "\U0001f391", + ":right-facing_fist:": "\U0001f91c", + ":right_anger_bubble:": "\U0001f5ef\ufe0f", + ":right_arrow:": "\u27a1", + ":right_arrow_curving_down:": "\u2935", + ":right_arrow_curving_left:": "\u21a9", + ":right_arrow_curving_up:": "\u2934", + ":right_facing_fist:": "\U0001f91c", + ":right_facing_fist::skin-tone-1:": "\U0001f91c\U0001f3fb", + ":right_facing_fist::skin-tone-2:": "\U0001f91c\U0001f3fc", + ":right_facing_fist::skin-tone-3:": "\U0001f91c\U0001f3fd", + ":right_facing_fist::skin-tone-4:": "\U0001f91c\U0001f3fe", + ":right_facing_fist::skin-tone-5:": "\U0001f91c\U0001f3ff", + ":ring:": "\U0001f48d", + ":ringed_planet:": "\U0001fa90", + ":roasted_sweet_potato:": "\U0001f360", + ":robot:": "\U0001f916", + ":robot_face:": "\U0001f916", + ":rock:": "\U0001faa8", + ":rocket:": "\U0001f680", + ":rofl:": "\U0001f923", + ":roll_eyes:": "\U0001f644", + ":roll_of_paper:": "\U0001f9fb", + ":rolled-up_newspaper:": "\U0001f5de", + ":rolled_up_newspaper:": "\U0001f5de\ufe0f", + ":roller_coaster:": "\U0001f3a2", + ":roller_skate:": "\U0001f6fc", + ":rolling_eyes:": "\U0001f644", + ":rolling_on_the_floor_laughing:": "\U0001f923", + ":romania:": "\U0001f1f7\U0001f1f4", + ":rooster:": "\U0001f413", + ":rose:": "\U0001f339", + ":rosette:": "\U0001f3f5\ufe0f", + ":rotating_light:": "\U0001f6a8", + ":round_pushpin:": "\U0001f4cd", + ":rowboat:": "\U0001f6a3\u200d\u2642\ufe0f", + ":rowing_man:": "\U0001f6a3\u200d\u2642\ufe0f", + ":rowing_woman:": "\U0001f6a3\u200d\u2640\ufe0f", + ":ru:": "\U0001f1f7\U0001f1fa", + ":rugby_football:": "\U0001f3c9", + ":runner:": "\U0001f3c3\u200d\u2642\ufe0f", + ":running:": "\U0001f3c3", + ":running_man:": "\U0001f3c3\u200d\u2642\ufe0f", + ":running_shirt:": "\U0001f3bd", + ":running_shirt_with_sash:": "\U0001f3bd", + ":running_shoe:": "\U0001f45f", + ":running_woman:": "\U0001f3c3\u200d\u2640\ufe0f", + ":rwanda:": "\U0001f1f7\U0001f1fc", + ":sa:": "\U0001f202\ufe0f", + ":sad_but_relieved_face:": "\U0001f625", + ":safety_pin:": "\U0001f9f7", + ":safety_vest:": "\U0001f9ba", + ":sagittarius:": "\u2650", + ":sailboat:": "\u26f5", + ":sake:": "\U0001f376", + ":salad:": "\U0001f957", + ":salt:": "\U0001f9c2", + ":samoa:": "\U0001f1fc\U0001f1f8", + ":san_marino:": "\U0001f1f8\U0001f1f2", + ":sandal:": "\U0001f461", + ":sandwich:": "\U0001f96a", + ":santa:": "\U0001f385", + ":santa::skin-tone-1:": "\U0001f385\U0001f3fb", + ":santa::skin-tone-2:": "\U0001f385\U0001f3fc", + ":santa::skin-tone-3:": "\U0001f385\U0001f3fd", + ":santa::skin-tone-4:": "\U0001f385\U0001f3fe", + ":santa::skin-tone-5:": "\U0001f385\U0001f3ff", + ":sao_tome_principe:": "\U0001f1f8\U0001f1f9", + ":sari:": "\U0001f97b", + ":sassy_man:": "\U0001f481\u200d\u2642\ufe0f", + ":sassy_woman:": "\U0001f481\u200d\u2640\ufe0f", + ":satellite:": "\U0001f6f0\ufe0f", + ":satellite_antenna:": "\U0001f4e1", + ":satellite_orbital:": "\U0001f6f0", + ":satisfied:": "\U0001f606", + ":saudi_arabia:": "\U0001f1f8\U0001f1e6", + ":sauna_man:": "\U0001f9d6\u200d\u2642\ufe0f", + ":sauna_person:": "\U0001f9d6", + ":sauna_woman:": "\U0001f9d6\u200d\u2640\ufe0f", + ":sauropod:": "\U0001f995", + ":saxophone:": "\U0001f3b7", + ":scales:": "\u2696\ufe0f", + ":scarf:": "\U0001f9e3", + ":school:": "\U0001f3eb", + ":school_satchel:": "\U0001f392", + ":scientist:": "\U0001f9d1\u200d\U0001f52c", + ":scissors:": "\u2702\ufe0f", + ":scooter:": "\U0001f6f4", + ":scorpion:": "\U0001f982", + ":scorpius:": "\u264f", + ":scotland:": "\U0001f3f4\U000e0067\U000e0062\U000e0073\U000e0063\U000e0074\U000e007f", + ":scream:": "\U0001f631", + ":scream_cat:": "\U0001f640", + ":screwdriver:": "\U0001fa9b", + ":scroll:": "\U0001f4dc", + ":seal:": "\U0001f9ad", + ":seat:": "\U0001f4ba", + ":second_place:": "\U0001f948", + ":second_place_medal:": "\U0001f948", + ":secret:": "\u3299\ufe0f", + ":see-no-evil_monkey:": "\U0001f648", + ":see_no_evil:": "\U0001f648", + ":seedling:": "\U0001f331", + ":selfie:": "\U0001f933", + ":selfie::skin-tone-1:": "\U0001f933\U0001f3fb", + ":selfie::skin-tone-2:": "\U0001f933\U0001f3fc", + ":selfie::skin-tone-3:": "\U0001f933\U0001f3fd", + ":selfie::skin-tone-4:": "\U0001f933\U0001f3fe", + ":selfie::skin-tone-5:": "\U0001f933\U0001f3ff", + ":senegal:": "\U0001f1f8\U0001f1f3", + ":serbia:": "\U0001f1f7\U0001f1f8", + ":service_dog:": "\U0001f415\u200d\U0001f9ba", + ":seven:": "7\ufe0f\u20e3", + ":seven-thirty:": "\U0001f562", + ":seven_o’clock:": "\U0001f556", + ":sewing_needle:": "\U0001faa1", + ":seychelles:": "\U0001f1f8\U0001f1e8", + ":shallow_pan_of_food:": "\U0001f958", + ":shamrock:": "\u2618\ufe0f", + ":shark:": "\U0001f988", + ":shaved_ice:": "\U0001f367", + ":sheaf_of_rice:": "\U0001f33e", + ":sheep:": "\U0001f411", + ":shell:": "\U0001f41a", + ":shield:": "\U0001f6e1\ufe0f", + ":shinto_shrine:": "\u26e9\ufe0f", + ":ship:": "\U0001f6a2", + ":shirt:": "\U0001f455", + ":shit:": "\U0001f4a9", + ":shoe:": "\U0001f45e", + ":shooting_star:": "\U0001f320", + ":shopping:": "\U0001f6cd\ufe0f", + ":shopping_bags:": "\U0001f6cd\ufe0f", + ":shopping_cart:": "\U0001f6d2", + ":shopping_trolley:": "\U0001f6d2", + ":shortcake:": "\U0001f370", + ":shorts:": "\U0001fa73", + ":shower:": "\U0001f6bf", + ":shrimp:": "\U0001f990", + ":shrug:": "\U0001f937", + ":shuffle_tracks_button:": "\U0001f500", + ":shushing_face:": "\U0001f92b", + ":sierra_leone:": "\U0001f1f8\U0001f1f1", + ":sign_of_the_horns:": "\U0001f918", + ":signal_strength:": "\U0001f4f6", + ":singapore:": "\U0001f1f8\U0001f1ec", + ":singer:": "\U0001f9d1\u200d\U0001f3a4", + ":sint_maarten:": "\U0001f1f8\U0001f1fd", + ":six:": "6\ufe0f\u20e3", + ":six-thirty:": "\U0001f561", + ":six_o’clock:": "\U0001f555", + ":six_pointed_star:": "\U0001f52f", + ":skateboard:": "\U0001f6f9", + ":ski:": "\U0001f3bf", + ":skier:": "\u26f7\ufe0f", + ":skin-tone-2:": "\U0001f3fb", + ":skin-tone-3:": "\U0001f3fc", + ":skin-tone-4:": "\U0001f3fd", + ":skin-tone-5:": "\U0001f3fe", + ":skin-tone-6:": "\U0001f3ff", + ":skis:": "\U0001f3bf", + ":skull:": "\U0001f480", + ":skull_and_crossbones:": "\u2620\ufe0f", + ":skull_crossbones:": "\u2620", + ":skunk:": "\U0001f9a8", + ":sled:": "\U0001f6f7", + ":sleeping:": "\U0001f634", + ":sleeping_accommodation:": "\U0001f6cc", + ":sleeping_bed:": "\U0001f6cc", + ":sleeping_face:": "\U0001f634", + ":sleepy:": "\U0001f62a", + ":sleepy_face:": "\U0001f62a", + ":sleuth_or_spy:": "\U0001f575\ufe0f\u200d\u2642\ufe0f", + ":slight_frown:": "\U0001f641", + ":slight_smile:": "\U0001f642", + ":slightly_frowning_face:": "\U0001f641", + ":slightly_smiling_face:": "\U0001f642", + ":slot_machine:": "\U0001f3b0", + ":sloth:": "\U0001f9a5", + ":slovakia:": "\U0001f1f8\U0001f1f0", + ":slovenia:": "\U0001f1f8\U0001f1ee", + ":small_airplane:": "\U0001f6e9\ufe0f", + ":small_blue_diamond:": "\U0001f539", + ":small_orange_diamond:": "\U0001f538", + ":small_red_triangle:": "\U0001f53a", + ":small_red_triangle_down:": "\U0001f53b", + ":smile:": "\U0001f604", + ":smile_cat:": "\U0001f638", + ":smiley:": "\U0001f603", + ":smiley_cat:": "\U0001f63a", + ":smiling_cat_with_heart-eyes:": "\U0001f63b", + ":smiling_face:": "\u263a", + ":smiling_face_with_3_hearts:": "\U0001f970", + ":smiling_face_with_halo:": "\U0001f607", + ":smiling_face_with_heart-eyes:": "\U0001f60d", + ":smiling_face_with_hearts:": "\U0001f970", + ":smiling_face_with_horns:": "\U0001f608", + ":smiling_face_with_smiling_eyes:": "\U0001f60a", + ":smiling_face_with_sunglasses:": "\U0001f60e", + ":smiling_face_with_tear:": "\U0001f972", + ":smiling_face_with_three_hearts:": "\U0001f970", + ":smiling_imp:": "\U0001f608", + ":smirk:": "\U0001f60f", + ":smirk_cat:": "\U0001f63c", + ":smirking_face:": "\U0001f60f", + ":smoking:": "\U0001f6ac", + ":snail:": "\U0001f40c", + ":snake:": "\U0001f40d", + ":sneezing_face:": "\U0001f927", + ":snow-capped_mountain:": "\U0001f3d4", + ":snow_capped_mountain:": "\U0001f3d4\ufe0f", + ":snow_cloud:": "\U0001f328\ufe0f", + ":snowboarder:": "\U0001f3c2", + ":snowboarder::skin-tone-1:": "\U0001f3c2\U0001f3fb", + ":snowboarder::skin-tone-2:": "\U0001f3c2\U0001f3fc", + ":snowboarder::skin-tone-3:": "\U0001f3c2\U0001f3fd", + ":snowboarder::skin-tone-4:": "\U0001f3c2\U0001f3fe", + ":snowboarder::skin-tone-5:": "\U0001f3c2\U0001f3ff", + ":snowflake:": "\u2744\ufe0f", + ":snowman:": "\u2603\ufe0f", + ":snowman2:": "\u2603", + ":snowman_with_snow:": "\u2603\ufe0f", + ":snowman_without_snow:": "\u26c4", + ":soap:": "\U0001f9fc", + ":sob:": "\U0001f62d", + ":soccer:": "\u26bd", + ":soccer_ball:": "\u26bd", + ":socks:": "\U0001f9e6", + ":soft_ice_cream:": "\U0001f366", + ":softball:": "\U0001f94e", + ":solomon_islands:": "\U0001f1f8\U0001f1e7", + ":somalia:": "\U0001f1f8\U0001f1f4", + ":soon:": "\U0001f51c", + ":sos:": "\U0001f198", + ":sound:": "\U0001f509", + ":south_africa:": "\U0001f1ff\U0001f1e6", + ":south_georgia_south_sandwich_islands:": "\U0001f1ec\U0001f1f8", + ":south_sudan:": "\U0001f1f8\U0001f1f8", + ":space_invader:": "\U0001f47e", + ":spade_suit:": "\u2660", + ":spades:": "\u2660\ufe0f", + ":spaghetti:": "\U0001f35d", + ":sparkle:": "\u2747\ufe0f", + ":sparkler:": "\U0001f387", + ":sparkles:": "\u2728", + ":sparkling_heart:": "\U0001f496", + ":speak-no-evil_monkey:": "\U0001f64a", + ":speak_no_evil:": "\U0001f64a", + ":speaker:": "\U0001f508", + ":speaker_high_volume:": "\U0001f50a", + ":speaker_low_volume:": "\U0001f508", + ":speaker_medium_volume:": "\U0001f509", + ":speaking_head:": "\U0001f5e3", + ":speaking_head_in_silhouette:": "\U0001f5e3\ufe0f", + ":speech_balloon:": "\U0001f4ac", + ":speech_left:": "\U0001f5e8", + ":speedboat:": "\U0001f6a4", + ":spider:": "\U0001f577\ufe0f", + ":spider_web:": "\U0001f578\ufe0f", + ":spiral_calendar:": "\U0001f5d3", + ":spiral_calendar_pad:": "\U0001f5d3\ufe0f", + ":spiral_note_pad:": "\U0001f5d2\ufe0f", + ":spiral_notepad:": "\U0001f5d2", + ":spiral_shell:": "\U0001f41a", + ":spock-hand:": "\U0001f596", + ":sponge:": "\U0001f9fd", + ":spoon:": "\U0001f944", + ":sport_utility_vehicle:": "\U0001f699", + ":sports_medal:": "\U0001f3c5", + ":spouting_whale:": "\U0001f433", + ":squid:": "\U0001f991", + ":squinting_face_with_tongue:": "\U0001f61d", + ":sri_lanka:": "\U0001f1f1\U0001f1f0", + ":st_barthelemy:": "\U0001f1e7\U0001f1f1", + ":st_helena:": "\U0001f1f8\U0001f1ed", + ":st_kitts_nevis:": "\U0001f1f0\U0001f1f3", + ":st_lucia:": "\U0001f1f1\U0001f1e8", + ":st_martin:": "\U0001f1f2\U0001f1eb", + ":st_pierre_miquelon:": "\U0001f1f5\U0001f1f2", + ":st_vincent_grenadines:": "\U0001f1fb\U0001f1e8", + ":stadium:": "\U0001f3df\ufe0f", + ":standing_man:": "\U0001f9cd\u200d\u2642\ufe0f", + ":standing_person:": "\U0001f9cd", + ":standing_woman:": "\U0001f9cd\u200d\u2640\ufe0f", + ":star:": "\u2b50", + ":star-struck:": "\U0001f929", + ":star2:": "\U0001f31f", + ":star_and_crescent:": "\u262a\ufe0f", + ":star_of_David:": "\u2721", + ":star_of_david:": "\u2721\ufe0f", + ":star_struck:": "\U0001f929", + ":stars:": "\U0001f320", + ":station:": "\U0001f689", + ":statue_of_liberty:": "\U0001f5fd", + ":steam_locomotive:": "\U0001f682", + ":steaming_bowl:": "\U0001f35c", + ":stethoscope:": "\U0001fa7a", + ":stew:": "\U0001f372", + ":stop_button:": "\u23f9", + ":stop_sign:": "\U0001f6d1", + ":stopwatch:": "\u23f1\ufe0f", + ":straight_ruler:": "\U0001f4cf", + ":strawberry:": "\U0001f353", + ":stuck_out_tongue:": "\U0001f61b", + ":stuck_out_tongue_closed_eyes:": "\U0001f61d", + ":stuck_out_tongue_winking_eye:": "\U0001f61c", + ":student:": "\U0001f9d1\u200d\U0001f393", + ":studio_microphone:": "\U0001f399\ufe0f", + ":stuffed_flatbread:": "\U0001f959", + ":sudan:": "\U0001f1f8\U0001f1e9", + ":sun:": "\u2600", + ":sun_behind_cloud:": "\u26c5", + ":sun_behind_large_cloud:": "\U0001f325", + ":sun_behind_rain_cloud:": "\U0001f326", + ":sun_behind_small_cloud:": "\U0001f324", + ":sun_with_face:": "\U0001f31e", + ":sunflower:": "\U0001f33b", + ":sunglasses:": "\U0001f60e", + ":sunny:": "\u2600\ufe0f", + ":sunrise:": "\U0001f305", + ":sunrise_over_mountains:": "\U0001f304", + ":sunset:": "\U0001f307", + ":superhero:": "\U0001f9b8", + ":superhero_man:": "\U0001f9b8\u200d\u2642\ufe0f", + ":superhero_woman:": "\U0001f9b8\u200d\u2640\ufe0f", + ":supervillain:": "\U0001f9b9", + ":supervillain_man:": "\U0001f9b9\u200d\u2642\ufe0f", + ":supervillain_woman:": "\U0001f9b9\u200d\u2640\ufe0f", + ":surfer:": "\U0001f3c4\u200d\u2642\ufe0f", + ":surfing_man:": "\U0001f3c4\u200d\u2642\ufe0f", + ":surfing_woman:": "\U0001f3c4\u200d\u2640\ufe0f", + ":suriname:": "\U0001f1f8\U0001f1f7", + ":sushi:": "\U0001f363", + ":suspension_railway:": "\U0001f69f", + ":svalbard_jan_mayen:": "\U0001f1f8\U0001f1ef", + ":swan:": "\U0001f9a2", + ":swaziland:": "\U0001f1f8\U0001f1ff", + ":sweat:": "\U0001f613", + ":sweat_droplets:": "\U0001f4a6", + ":sweat_drops:": "\U0001f4a6", + ":sweat_smile:": "\U0001f605", + ":sweden:": "\U0001f1f8\U0001f1ea", + ":sweet_potato:": "\U0001f360", + ":swim_brief:": "\U0001fa72", + ":swimmer:": "\U0001f3ca\u200d\u2642\ufe0f", + ":swimming_man:": "\U0001f3ca\u200d\u2642\ufe0f", + ":swimming_woman:": "\U0001f3ca\u200d\u2640\ufe0f", + ":switzerland:": "\U0001f1e8\U0001f1ed", + ":symbols:": "\U0001f523", + ":synagogue:": "\U0001f54d", + ":syria:": "\U0001f1f8\U0001f1fe", + ":syringe:": "\U0001f489", + ":t-rex:": "\U0001f996", + ":t-shirt:": "\U0001f455", + ":t_rex:": "\U0001f996", + ":table_tennis_paddle_and_ball:": "\U0001f3d3", + ":taco:": "\U0001f32e", + ":tada:": "\U0001f389", + ":taiwan:": "\U0001f1f9\U0001f1fc", + ":tajikistan:": "\U0001f1f9\U0001f1ef", + ":takeout_box:": "\U0001f961", + ":tamale:": "\U0001fad4", + ":tanabata_tree:": "\U0001f38b", + ":tangerine:": "\U0001f34a", + ":tanzania:": "\U0001f1f9\U0001f1ff", + ":taurus:": "\u2649", + ":taxi:": "\U0001f695", + ":tea:": "\U0001f375", + ":teacher:": "\U0001f9d1\u200d\U0001f3eb", + ":teacup_without_handle:": "\U0001f375", + ":teapot:": "\U0001fad6", + ":tear-off_calendar:": "\U0001f4c6", + ":technologist:": "\U0001f9d1\u200d\U0001f4bb", + ":teddy_bear:": "\U0001f9f8", + ":telephone:": "\u260e", + ":telephone_receiver:": "\U0001f4de", + ":telescope:": "\U0001f52d", + ":television:": "\U0001f4fa", + ":ten-thirty:": "\U0001f565", + ":ten_o’clock:": "\U0001f559", + ":tennis:": "\U0001f3be", + ":tent:": "\u26fa", + ":test_tube:": "\U0001f9ea", + ":thailand:": "\U0001f1f9\U0001f1ed", + ":the_horns:": "\U0001f918", + ":thermometer:": "\U0001f321\ufe0f", + ":thermometer_face:": "\U0001f912", + ":thinking:": "\U0001f914", + ":thinking_face:": "\U0001f914", + ":third_place:": "\U0001f949", + ":third_place_medal:": "\U0001f949", + ":thong_sandal:": "\U0001fa74", + ":thought_balloon:": "\U0001f4ad", + ":thread:": "\U0001f9f5", + ":three:": "3\ufe0f\u20e3", + ":three-thirty:": "\U0001f55e", + ":three_button_mouse:": "\U0001f5b1\ufe0f", + ":three_o’clock:": "\U0001f552", + ":thumbs_down:": "\U0001f44e", + ":thumbs_up:": "\U0001f44d", + ":thumbsdown:": "\U0001f44e", + ":thumbsdown::skin-tone-1:": "\U0001f44e\U0001f3fb", + ":thumbsdown::skin-tone-2:": "\U0001f44e\U0001f3fc", + ":thumbsdown::skin-tone-3:": "\U0001f44e\U0001f3fd", + ":thumbsdown::skin-tone-4:": "\U0001f44e\U0001f3fe", + ":thumbsdown::skin-tone-5:": "\U0001f44e\U0001f3ff", + ":thumbsup:": "\U0001f44d", + ":thumbsup::skin-tone-1:": "\U0001f44d\U0001f3fb", + ":thumbsup::skin-tone-2:": "\U0001f44d\U0001f3fc", + ":thumbsup::skin-tone-3:": "\U0001f44d\U0001f3fd", + ":thumbsup::skin-tone-4:": "\U0001f44d\U0001f3fe", + ":thumbsup::skin-tone-5:": "\U0001f44d\U0001f3ff", + ":thunder_cloud_and_rain:": "\u26c8\ufe0f", + ":thunder_cloud_rain:": "\u26c8", + ":ticket:": "\U0001f3ab", + ":tickets:": "\U0001f39f", + ":tiger:": "\U0001f42f", + ":tiger2:": "\U0001f405", + ":tiger_face:": "\U0001f42f", + ":timer:": "\u23f2", + ":timer_clock:": "\u23f2\ufe0f", + ":timor_leste:": "\U0001f1f9\U0001f1f1", + ":tipping_hand_man:": "\U0001f481\u200d\u2642\ufe0f", + ":tipping_hand_person:": "\U0001f481", + ":tipping_hand_woman:": "\U0001f481\u200d\u2640\ufe0f", + ":tired_face:": "\U0001f62b", + ":tm:": "\u2122\ufe0f", + ":togo:": "\U0001f1f9\U0001f1ec", + ":toilet:": "\U0001f6bd", + ":tokelau:": "\U0001f1f9\U0001f1f0", + ":tokyo_tower:": "\U0001f5fc", + ":tomato:": "\U0001f345", + ":tonga:": "\U0001f1f9\U0001f1f4", + ":tongue:": "\U0001f445", + ":toolbox:": "\U0001f9f0", + ":tools:": "\U0001f6e0", + ":tooth:": "\U0001f9b7", + ":toothbrush:": "\U0001faa5", + ":top:": "\U0001f51d", + ":top_hat:": "\U0001f3a9", + ":tophat:": "\U0001f3a9", + ":tornado:": "\U0001f32a\ufe0f", + ":tr:": "\U0001f1f9\U0001f1f7", + ":track_next:": "\u23ed", + ":track_previous:": "\u23ee", + ":trackball:": "\U0001f5b2\ufe0f", + ":tractor:": "\U0001f69c", + ":trade_mark:": "\u2122", + ":traffic_light:": "\U0001f6a5", + ":train:": "\U0001f68b", + ":train2:": "\U0001f686", + ":tram:": "\U0001f68a", + ":tram_car:": "\U0001f68b", + ":transgender_flag:": "\U0001f3f3\ufe0f\u200d\u26a7\ufe0f", + ":transgender_symbol:": "\u26a7", + ":triangular_flag:": "\U0001f6a9", + ":triangular_flag_on_post:": "\U0001f6a9", + ":triangular_ruler:": "\U0001f4d0", + ":trident:": "\U0001f531", + ":trident_emblem:": "\U0001f531", + ":trinidad_tobago:": "\U0001f1f9\U0001f1f9", + ":tristan_da_cunha:": "\U0001f1f9\U0001f1e6", + ":triumph:": "\U0001f624", + ":trolleybus:": "\U0001f68e", + ":trophy:": "\U0001f3c6", + ":tropical_drink:": "\U0001f379", + ":tropical_fish:": "\U0001f420", + ":truck:": "\U0001f69a", + ":trumpet:": "\U0001f3ba", + ":tshirt:": "\U0001f455", + ":tulip:": "\U0001f337", + ":tumbler_glass:": "\U0001f943", + ":tunisia:": "\U0001f1f9\U0001f1f3", + ":turkey:": "\U0001f983", + ":turkmenistan:": "\U0001f1f9\U0001f1f2", + ":turks_caicos_islands:": "\U0001f1f9\U0001f1e8", + ":turtle:": "\U0001f422", + ":tuvalu:": "\U0001f1f9\U0001f1fb", + ":tv:": "\U0001f4fa", + ":twelve-thirty:": "\U0001f567", + ":twelve_o’clock:": "\U0001f55b", + ":twisted_rightwards_arrows:": "\U0001f500", + ":two:": "2\ufe0f\u20e3", + ":two-hump_camel:": "\U0001f42b", + ":two-thirty:": "\U0001f55d", + ":two_hearts:": "\U0001f495", + ":two_men_holding_hands:": "\U0001f46c", + ":two_o’clock:": "\U0001f551", + ":two_women_holding_hands:": "\U0001f46d", + ":u5272:": "\U0001f239", + ":u5408:": "\U0001f234", + ":u55b6:": "\U0001f23a", + ":u6307:": "\U0001f22f", + ":u6708:": "\U0001f237\ufe0f", + ":u6709:": "\U0001f236", + ":u6e80:": "\U0001f235", + ":u7121:": "\U0001f21a", + ":u7533:": "\U0001f238", + ":u7981:": "\U0001f232", + ":u7a7a:": "\U0001f233", + ":uganda:": "\U0001f1fa\U0001f1ec", + ":uk:": "\U0001f1ec\U0001f1e7", + ":ukraine:": "\U0001f1fa\U0001f1e6", + ":umbrella:": "\u2602\ufe0f", + ":umbrella2:": "\u2602", + ":umbrella_on_ground:": "\u26f1\ufe0f", + ":umbrella_with_rain_drops:": "\u2614", + ":unamused:": "\U0001f612", + ":unamused_face:": "\U0001f612", + ":underage:": "\U0001f51e", + ":unicorn:": "\U0001f984", + ":unicorn_face:": "\U0001f984", + ":united_arab_emirates:": "\U0001f1e6\U0001f1ea", + ":united_nations:": "\U0001f1fa\U0001f1f3", + ":unlock:": "\U0001f513", + ":unlocked:": "\U0001f513", + ":up:": "\U0001f199", + ":up-down_arrow:": "\u2195", + ":up-left_arrow:": "\u2196", + ":up-right_arrow:": "\u2197", + ":up_arrow:": "\u2b06", + ":upside-down_face:": "\U0001f643", + ":upside_down:": "\U0001f643", + ":upside_down_face:": "\U0001f643", + ":upwards_button:": "\U0001f53c", + ":urn:": "\u26b1", + ":uruguay:": "\U0001f1fa\U0001f1fe", + ":us:": "\U0001f1fa\U0001f1f8", + ":us_outlying_islands:": "\U0001f1fa\U0001f1f2", + ":us_virgin_islands:": "\U0001f1fb\U0001f1ee", + ":uzbekistan:": "\U0001f1fa\U0001f1ff", + ":v:": "\u270c\ufe0f", + ":v::skin-tone-1:": "\u270c\U0001f3fb", + ":v::skin-tone-2:": "\u270c\U0001f3fc", + ":v::skin-tone-3:": "\u270c\U0001f3fd", + ":v::skin-tone-4:": "\u270c\U0001f3fe", + ":v::skin-tone-5:": "\u270c\U0001f3ff", + ":vampire:": "\U0001f9db\u200d\u2640\ufe0f", + ":vampire_man:": "\U0001f9db\u200d\u2642\ufe0f", + ":vampire::skin-tone-1:": "\U0001f9db\U0001f3fb", + ":vampire::skin-tone-2:": "\U0001f9db\U0001f3fc", + ":vampire::skin-tone-3:": "\U0001f9db\U0001f3fd", + ":vampire::skin-tone-4:": "\U0001f9db\U0001f3fe", + ":vampire::skin-tone-5:": "\U0001f9db\U0001f3ff", + ":vampire_woman:": "\U0001f9db\u200d\u2640\ufe0f", + ":vanuatu:": "\U0001f1fb\U0001f1fa", + ":vatican_city:": "\U0001f1fb\U0001f1e6", + ":venezuela:": "\U0001f1fb\U0001f1ea", + ":vertical_traffic_light:": "\U0001f6a6", + ":vhs:": "\U0001f4fc", + ":vibration_mode:": "\U0001f4f3", + ":victory_hand:": "\u270c", + ":video_camera:": "\U0001f4f9", + ":video_game:": "\U0001f3ae", + ":videocassette:": "\U0001f4fc", + ":vietnam:": "\U0001f1fb\U0001f1f3", + ":violin:": "\U0001f3bb", + ":virgo:": "\u264d", + ":volcano:": "\U0001f30b", + ":volleyball:": "\U0001f3d0", + ":vomiting_face:": "\U0001f92e", + ":vs:": "\U0001f19a", + ":vulcan:": "\U0001f596", + ":vulcan_salute:": "\U0001f596", + ":vulcan::skin-tone-1:": "\U0001f596\U0001f3fb", + ":vulcan::skin-tone-2:": "\U0001f596\U0001f3fc", + ":vulcan::skin-tone-3:": "\U0001f596\U0001f3fd", + ":vulcan::skin-tone-4:": "\U0001f596\U0001f3fe", + ":vulcan::skin-tone-5:": "\U0001f596\U0001f3ff", + ":waffle:": "\U0001f9c7", + ":wales:": "\U0001f3f4\U000e0067\U000e0062\U000e0077\U000e006c\U000e0073\U000e007f", + ":walking:": "\U0001f6b6\u200d\u2642\ufe0f", + ":walking_man:": "\U0001f6b6\u200d\u2642\ufe0f", + ":walking_woman:": "\U0001f6b6\u200d\u2640\ufe0f", + ":wallis_futuna:": "\U0001f1fc\U0001f1eb", + ":waning_crescent_moon:": "\U0001f318", + ":waning_gibbous_moon:": "\U0001f316", + ":warning:": "\u26a0\ufe0f", + ":wastebasket:": "\U0001f5d1\ufe0f", + ":watch:": "\u231a", + ":water_buffalo:": "\U0001f403", + ":water_closet:": "\U0001f6be", + ":water_polo:": "\U0001f93d", + ":water_wave:": "\U0001f30a", + ":watermelon:": "\U0001f349", + ":wave:": "\U0001f44b", + ":wave::skin-tone-1:": "\U0001f44b\U0001f3fb", + ":wave::skin-tone-2:": "\U0001f44b\U0001f3fc", + ":wave::skin-tone-3:": "\U0001f44b\U0001f3fd", + ":wave::skin-tone-4:": "\U0001f44b\U0001f3fe", + ":wave::skin-tone-5:": "\U0001f44b\U0001f3ff", + ":waving_black_flag:": "\U0001f3f4", + ":waving_hand:": "\U0001f44b", + ":waving_white_flag:": "\U0001f3f3\ufe0f", + ":wavy_dash:": "\u3030\ufe0f", + ":waxing_crescent_moon:": "\U0001f312", + ":waxing_gibbous_moon:": "\U0001f314", + ":wc:": "\U0001f6be", + ":weary:": "\U0001f629", + ":weary_cat:": "\U0001f640", + ":weary_face:": "\U0001f629", + ":wedding:": "\U0001f492", + ":weight_lifter:": "\U0001f3cb\ufe0f\u200d\u2642\ufe0f", + ":weight_lifting:": "\U0001f3cb\ufe0f", + ":weight_lifting_man:": "\U0001f3cb\ufe0f\u200d\u2642\ufe0f", + ":weight_lifting_woman:": "\U0001f3cb\ufe0f\u200d\u2640\ufe0f", + ":western_sahara:": "\U0001f1ea\U0001f1ed", + ":whale:": "\U0001f433", + ":whale2:": "\U0001f40b", + ":wheel_of_dharma:": "\u2638\ufe0f", + ":wheelchair:": "\u267f", + ":wheelchair_symbol:": "\u267f", + ":white_cane:": "\U0001f9af", + ":white_check_mark:": "\u2705", + ":white_circle:": "\u26aa", + ":white_exclamation_mark:": "\u2755", + ":white_flag:": "\U0001f3f3", + ":white_flower:": "\U0001f4ae", + ":white_frowning_face:": "\u2639\ufe0f", + ":white_hair:": "\U0001f9b3", + ":white_haired_man:": "\U0001f468\u200d\U0001f9b3", + ":white_haired_person:": "\U0001f9d1\u200d\U0001f9b3", + ":white_haired_woman:": "\U0001f469\u200d\U0001f9b3", + ":white_heart:": "\U0001f90d", + ":white_large_square:": "\u2b1c", + ":white_medium-small_square:": "\u25fd", + ":white_medium_small_square:": "\u25fd", + ":white_medium_square:": "\u25fb\ufe0f", + ":white_question_mark:": "\u2754", + ":white_small_square:": "\u25ab\ufe0f", + ":white_square_button:": "\U0001f533", + ":white_sun_cloud:": "\U0001f325", + ":white_sun_rain_cloud:": "\U0001f326", + ":white_sun_small_cloud:": "\U0001f324", + ":wilted_flower:": "\U0001f940", + ":wilted_rose:": "\U0001f940", + ":wind_blowing_face:": "\U0001f32c\ufe0f", + ":wind_chime:": "\U0001f390", + ":wind_face:": "\U0001f32c", + ":window:": "\U0001fa9f", + ":wine_glass:": "\U0001f377", + ":wink:": "\U0001f609", + ":winking_face:": "\U0001f609", + ":winking_face_with_tongue:": "\U0001f61c", + ":wolf:": "\U0001f43a", + ":woman:": "\U0001f469", + ":woman-biking:": "\U0001f6b4\u200d\u2640\ufe0f", + ":woman-bouncing-ball:": "\u26f9\ufe0f\u200d\u2640\ufe0f", + ":woman-bowing:": "\U0001f647\u200d\u2640\ufe0f", + ":woman-boy:": "\U0001f469\u200d\U0001f466", + ":woman-boy-boy:": "\U0001f469\u200d\U0001f466\u200d\U0001f466", + ":woman-cartwheeling:": "\U0001f938\u200d\u2640\ufe0f", + ":woman-facepalming:": "\U0001f926\u200d\u2640\ufe0f", + ":woman-frowning:": "\U0001f64d\u200d\u2640\ufe0f", + ":woman-gesturing-no:": "\U0001f645\u200d\u2640\ufe0f", + ":woman-gesturing-ok:": "\U0001f646\u200d\u2640\ufe0f", + ":woman-getting-haircut:": "\U0001f487\u200d\u2640\ufe0f", + ":woman-getting-massage:": "\U0001f486\u200d\u2640\ufe0f", + ":woman-girl:": "\U0001f469\u200d\U0001f467", + ":woman-girl-boy:": "\U0001f469\u200d\U0001f467\u200d\U0001f466", + ":woman-girl-girl:": "\U0001f469\u200d\U0001f467\u200d\U0001f467", + ":woman-golfing:": "\U0001f3cc\ufe0f\u200d\u2640\ufe0f", + ":woman-heart-man:": "\U0001f469\u200d\u2764\ufe0f\u200d\U0001f468", + ":woman-heart-woman:": "\U0001f469\u200d\u2764\ufe0f\u200d\U0001f469", + ":woman-juggling:": "\U0001f939\u200d\u2640\ufe0f", + ":woman-kiss-man:": "\U0001f469\u200d\u2764\ufe0f\u200d\U0001f48b\u200d\U0001f468", + ":woman-kiss-woman:": "\U0001f469\u200d\u2764\ufe0f\u200d\U0001f48b\u200d\U0001f469", + ":woman-lifting-weights:": "\U0001f3cb\ufe0f\u200d\u2640\ufe0f", + ":woman-mountain-biking:": "\U0001f6b5\u200d\u2640\ufe0f", + ":woman-playing-handball:": "\U0001f93e\u200d\u2640\ufe0f", + ":woman-playing-water-polo:": "\U0001f93d\u200d\u2640\ufe0f", + ":woman-pouting:": "\U0001f64e\u200d\u2640\ufe0f", + ":woman-raising-hand:": "\U0001f64b\u200d\u2640\ufe0f", + ":woman-rowing-boat:": "\U0001f6a3\u200d\u2640\ufe0f", + ":woman-running:": "\U0001f3c3\u200d\u2640\ufe0f", + ":woman-shrugging:": "\U0001f937\u200d\u2640\ufe0f", + ":woman-surfing:": "\U0001f3c4\u200d\u2640\ufe0f", + ":woman-swimming:": "\U0001f3ca\u200d\u2640\ufe0f", + ":woman-tipping-hand:": "\U0001f481\u200d\u2640\ufe0f", + ":woman-walking:": "\U0001f6b6\u200d\u2640\ufe0f", + ":woman-wearing-turban:": "\U0001f473\u200d\u2640\ufe0f", + ":woman-with-bunny-ears-partying:": "\U0001f46f\u200d\u2640\ufe0f", + ":woman-woman-boy:": "\U0001f469\u200d\U0001f469\u200d\U0001f466", + ":woman-woman-boy-boy:": "\U0001f469\u200d\U0001f469\u200d\U0001f466\u200d\U0001f466", + ":woman-woman-girl:": "\U0001f469\u200d\U0001f469\u200d\U0001f467", + ":woman-woman-girl-boy:": "\U0001f469\u200d\U0001f469\u200d\U0001f467\u200d\U0001f466", + ":woman-woman-girl-girl:": "\U0001f469\u200d\U0001f469\u200d\U0001f467\u200d\U0001f467", + ":woman-wrestling:": "\U0001f93c\u200d\u2640\ufe0f", + ":woman_and_man_holding_hands:": "\U0001f46b", + ":woman_artist:": "\U0001f469\u200d\U0001f3a8", + ":woman_artist::skin-tone-1:": "\U0001f469\U0001f3fb\u200d\U0001f3a8", + ":woman_artist::skin-tone-2:": "\U0001f469\U0001f3fc\u200d\U0001f3a8", + ":woman_artist::skin-tone-3:": "\U0001f469\U0001f3fd\u200d\U0001f3a8", + ":woman_artist::skin-tone-4:": "\U0001f469\U0001f3fe\u200d\U0001f3a8", + ":woman_artist::skin-tone-5:": "\U0001f469\U0001f3ff\u200d\U0001f3a8", + ":woman_astronaut:": "\U0001f469\u200d\U0001f680", + ":woman_astronaut::skin-tone-1:": "\U0001f469\U0001f3fb\u200d\U0001f680", + ":woman_astronaut::skin-tone-2:": "\U0001f469\U0001f3fc\u200d\U0001f680", + ":woman_astronaut::skin-tone-3:": "\U0001f469\U0001f3fd\u200d\U0001f680", + ":woman_astronaut::skin-tone-4:": "\U0001f469\U0001f3fe\u200d\U0001f680", + ":woman_astronaut::skin-tone-5:": "\U0001f469\U0001f3ff\u200d\U0001f680", + ":woman_bald:": "\U0001f469\u200d\U0001f9b2", + ":woman_biking:": "\U0001f6b4\u200d\u2640\ufe0f", + ":woman_biking::skin-tone-1:": "\U0001f6b4\U0001f3fb\u200d\u2640\ufe0f", + ":woman_biking::skin-tone-2:": "\U0001f6b4\U0001f3fc\u200d\u2640\ufe0f", + ":woman_biking::skin-tone-3:": "\U0001f6b4\U0001f3fd\u200d\u2640\ufe0f", + ":woman_biking::skin-tone-4:": "\U0001f6b4\U0001f3fe\u200d\u2640\ufe0f", + ":woman_biking::skin-tone-5:": "\U0001f6b4\U0001f3ff\u200d\u2640\ufe0f", + ":woman_blond_hair:": "\U0001f471\u200d\u2640\ufe0f", + ":woman_bouncing_ball:": "\u26f9\ufe0f\u200d\u2640\ufe0f", + ":woman_bouncing_ball::skin-tone-1:": "\u26f9\U0001f3fb\u200d\u2640\ufe0f", + ":woman_bouncing_ball::skin-tone-2:": "\u26f9\U0001f3fc\u200d\u2640\ufe0f", + ":woman_bouncing_ball::skin-tone-3:": "\u26f9\U0001f3fd\u200d\u2640\ufe0f", + ":woman_bouncing_ball::skin-tone-4:": "\u26f9\U0001f3fe\u200d\u2640\ufe0f", + ":woman_bouncing_ball::skin-tone-5:": "\u26f9\U0001f3ff\u200d\u2640\ufe0f", + ":woman_bowing:": "\U0001f647\u200d\u2640\ufe0f", + ":woman_bowing::skin-tone-1:": "\U0001f647\U0001f3fb\u200d\u2640\ufe0f", + ":woman_bowing::skin-tone-2:": "\U0001f647\U0001f3fc\u200d\u2640\ufe0f", + ":woman_bowing::skin-tone-3:": "\U0001f647\U0001f3fd\u200d\u2640\ufe0f", + ":woman_bowing::skin-tone-4:": "\U0001f647\U0001f3fe\u200d\u2640\ufe0f", + ":woman_bowing::skin-tone-5:": "\U0001f647\U0001f3ff\u200d\u2640\ufe0f", + ":woman_cartwheeling:": "\U0001f938\u200d\u2640\ufe0f", + ":woman_cartwheeling::skin-tone-1:": "\U0001f938\U0001f3fb\u200d\u2640\ufe0f", + ":woman_cartwheeling::skin-tone-2:": "\U0001f938\U0001f3fc\u200d\u2640\ufe0f", + ":woman_cartwheeling::skin-tone-3:": "\U0001f938\U0001f3fd\u200d\u2640\ufe0f", + ":woman_cartwheeling::skin-tone-4:": "\U0001f938\U0001f3fe\u200d\u2640\ufe0f", + ":woman_cartwheeling::skin-tone-5:": "\U0001f938\U0001f3ff\u200d\u2640\ufe0f", + ":woman_climbing:": "\U0001f9d7\u200d\u2640\ufe0f", + ":woman_climbing::skin-tone-1:": "\U0001f9d7\U0001f3fb\u200d\u2640\ufe0f", + ":woman_climbing::skin-tone-2:": "\U0001f9d7\U0001f3fc\u200d\u2640\ufe0f", + ":woman_climbing::skin-tone-3:": "\U0001f9d7\U0001f3fd\u200d\u2640\ufe0f", + ":woman_climbing::skin-tone-4:": "\U0001f9d7\U0001f3fe\u200d\u2640\ufe0f", + ":woman_climbing::skin-tone-5:": "\U0001f9d7\U0001f3ff\u200d\u2640\ufe0f", + ":woman_construction_worker:": "\U0001f477\u200d\u2640\ufe0f", + ":woman_construction_worker::skin-tone-1:": "\U0001f477\U0001f3fb\u200d\u2640\ufe0f", + ":woman_construction_worker::skin-tone-2:": "\U0001f477\U0001f3fc\u200d\u2640\ufe0f", + ":woman_construction_worker::skin-tone-3:": "\U0001f477\U0001f3fd\u200d\u2640\ufe0f", + ":woman_construction_worker::skin-tone-4:": "\U0001f477\U0001f3fe\u200d\u2640\ufe0f", + ":woman_construction_worker::skin-tone-5:": "\U0001f477\U0001f3ff\u200d\u2640\ufe0f", + ":woman_cook:": "\U0001f469\u200d\U0001f373", + ":woman_cook::skin-tone-1:": "\U0001f469\U0001f3fb\u200d\U0001f373", + ":woman_cook::skin-tone-2:": "\U0001f469\U0001f3fc\u200d\U0001f373", + ":woman_cook::skin-tone-3:": "\U0001f469\U0001f3fd\u200d\U0001f373", + ":woman_cook::skin-tone-4:": "\U0001f469\U0001f3fe\u200d\U0001f373", + ":woman_cook::skin-tone-5:": "\U0001f469\U0001f3ff\u200d\U0001f373", + ":woman_curly_hair:": "\U0001f469\u200d\U0001f9b1", + ":woman_dancing:": "\U0001f483", + ":woman_detective:": "\U0001f575\ufe0f\u200d\u2640\ufe0f", + ":woman_detective::skin-tone-1:": "\U0001f575\U0001f3fb\u200d\u2640\ufe0f", + ":woman_detective::skin-tone-2:": "\U0001f575\U0001f3fc\u200d\u2640\ufe0f", + ":woman_detective::skin-tone-3:": "\U0001f575\U0001f3fd\u200d\u2640\ufe0f", + ":woman_detective::skin-tone-4:": "\U0001f575\U0001f3fe\u200d\u2640\ufe0f", + ":woman_detective::skin-tone-5:": "\U0001f575\U0001f3ff\u200d\u2640\ufe0f", + ":woman_elf:": "\U0001f9dd\u200d\u2640\ufe0f", + ":woman_elf::skin-tone-1:": "\U0001f9dd\U0001f3fb\u200d\u2640\ufe0f", + ":woman_elf::skin-tone-2:": "\U0001f9dd\U0001f3fc\u200d\u2640\ufe0f", + ":woman_elf::skin-tone-3:": "\U0001f9dd\U0001f3fd\u200d\u2640\ufe0f", + ":woman_elf::skin-tone-4:": "\U0001f9dd\U0001f3fe\u200d\u2640\ufe0f", + ":woman_elf::skin-tone-5:": "\U0001f9dd\U0001f3ff\u200d\u2640\ufe0f", + ":woman_facepalming:": "\U0001f926\u200d\u2640\ufe0f", + ":woman_facepalming::skin-tone-1:": "\U0001f926\U0001f3fb\u200d\u2640\ufe0f", + ":woman_facepalming::skin-tone-2:": "\U0001f926\U0001f3fc\u200d\u2640\ufe0f", + ":woman_facepalming::skin-tone-3:": "\U0001f926\U0001f3fd\u200d\u2640\ufe0f", + ":woman_facepalming::skin-tone-4:": "\U0001f926\U0001f3fe\u200d\u2640\ufe0f", + ":woman_facepalming::skin-tone-5:": "\U0001f926\U0001f3ff\u200d\u2640\ufe0f", + ":woman_factory_worker:": "\U0001f469\u200d\U0001f3ed", + ":woman_factory_worker::skin-tone-1:": "\U0001f469\U0001f3fb\u200d\U0001f3ed", + ":woman_factory_worker::skin-tone-2:": "\U0001f469\U0001f3fc\u200d\U0001f3ed", + ":woman_factory_worker::skin-tone-3:": "\U0001f469\U0001f3fd\u200d\U0001f3ed", + ":woman_factory_worker::skin-tone-4:": "\U0001f469\U0001f3fe\u200d\U0001f3ed", + ":woman_factory_worker::skin-tone-5:": "\U0001f469\U0001f3ff\u200d\U0001f3ed", + ":woman_fairy:": "\U0001f9da\u200d\u2640\ufe0f", + ":woman_fairy::skin-tone-1:": "\U0001f9da\U0001f3fb\u200d\u2640\ufe0f", + ":woman_fairy::skin-tone-2:": "\U0001f9da\U0001f3fc\u200d\u2640\ufe0f", + ":woman_fairy::skin-tone-3:": "\U0001f9da\U0001f3fd\u200d\u2640\ufe0f", + ":woman_fairy::skin-tone-4:": "\U0001f9da\U0001f3fe\u200d\u2640\ufe0f", + ":woman_fairy::skin-tone-5:": "\U0001f9da\U0001f3ff\u200d\u2640\ufe0f", + ":woman_farmer:": "\U0001f469\u200d\U0001f33e", + ":woman_farmer::skin-tone-1:": "\U0001f469\U0001f3fb\u200d\U0001f33e", + ":woman_farmer::skin-tone-2:": "\U0001f469\U0001f3fc\u200d\U0001f33e", + ":woman_farmer::skin-tone-3:": "\U0001f469\U0001f3fd\u200d\U0001f33e", + ":woman_farmer::skin-tone-4:": "\U0001f469\U0001f3fe\u200d\U0001f33e", + ":woman_farmer::skin-tone-5:": "\U0001f469\U0001f3ff\u200d\U0001f33e", + ":woman_feeding_baby:": "\U0001f469\u200d\U0001f37c", + ":woman_firefighter:": "\U0001f469\u200d\U0001f692", + ":woman_firefighter::skin-tone-1:": "\U0001f469\U0001f3fb\u200d\U0001f692", + ":woman_firefighter::skin-tone-2:": "\U0001f469\U0001f3fc\u200d\U0001f692", + ":woman_firefighter::skin-tone-3:": "\U0001f469\U0001f3fd\u200d\U0001f692", + ":woman_firefighter::skin-tone-4:": "\U0001f469\U0001f3fe\u200d\U0001f692", + ":woman_firefighter::skin-tone-5:": "\U0001f469\U0001f3ff\u200d\U0001f692", + ":woman_frowning:": "\U0001f64d\u200d\u2640\ufe0f", + ":woman_frowning::skin-tone-1:": "\U0001f64d\U0001f3fb\u200d\u2640\ufe0f", + ":woman_frowning::skin-tone-2:": "\U0001f64d\U0001f3fc\u200d\u2640\ufe0f", + ":woman_frowning::skin-tone-3:": "\U0001f64d\U0001f3fd\u200d\u2640\ufe0f", + ":woman_frowning::skin-tone-4:": "\U0001f64d\U0001f3fe\u200d\u2640\ufe0f", + ":woman_frowning::skin-tone-5:": "\U0001f64d\U0001f3ff\u200d\u2640\ufe0f", + ":woman_genie:": "\U0001f9de\u200d\u2640\ufe0f", + ":woman_gesturing_NO:": "\U0001f645\u200d\u2640\ufe0f", + ":woman_gesturing_OK:": "\U0001f646\u200d\u2640\ufe0f", + ":woman_gesturing_no:": "\U0001f645\u200d\u2640\ufe0f", + ":woman_gesturing_no::skin-tone-1:": "\U0001f645\U0001f3fb\u200d\u2640\ufe0f", + ":woman_gesturing_no::skin-tone-2:": "\U0001f645\U0001f3fc\u200d\u2640\ufe0f", + ":woman_gesturing_no::skin-tone-3:": "\U0001f645\U0001f3fd\u200d\u2640\ufe0f", + ":woman_gesturing_no::skin-tone-4:": "\U0001f645\U0001f3fe\u200d\u2640\ufe0f", + ":woman_gesturing_no::skin-tone-5:": "\U0001f645\U0001f3ff\u200d\u2640\ufe0f", + ":woman_gesturing_ok:": "\U0001f646\u200d\u2640\ufe0f", + ":woman_gesturing_ok::skin-tone-1:": "\U0001f646\U0001f3fb\u200d\u2640\ufe0f", + ":woman_gesturing_ok::skin-tone-2:": "\U0001f646\U0001f3fc\u200d\u2640\ufe0f", + ":woman_gesturing_ok::skin-tone-3:": "\U0001f646\U0001f3fd\u200d\u2640\ufe0f", + ":woman_gesturing_ok::skin-tone-4:": "\U0001f646\U0001f3fe\u200d\u2640\ufe0f", + ":woman_gesturing_ok::skin-tone-5:": "\U0001f646\U0001f3ff\u200d\u2640\ufe0f", + ":woman_getting_face_massage:": "\U0001f486\u200d\u2640\ufe0f", + ":woman_getting_face_massage::skin-tone-1:": "\U0001f486\U0001f3fb\u200d\u2640\ufe0f", + ":woman_getting_face_massage::skin-tone-2:": "\U0001f486\U0001f3fc\u200d\u2640\ufe0f", + ":woman_getting_face_massage::skin-tone-3:": "\U0001f486\U0001f3fd\u200d\u2640\ufe0f", + ":woman_getting_face_massage::skin-tone-4:": "\U0001f486\U0001f3fe\u200d\u2640\ufe0f", + ":woman_getting_face_massage::skin-tone-5:": "\U0001f486\U0001f3ff\u200d\u2640\ufe0f", + ":woman_getting_haircut:": "\U0001f487\u200d\u2640\ufe0f", + ":woman_getting_haircut::skin-tone-1:": "\U0001f487\U0001f3fb\u200d\u2640\ufe0f", + ":woman_getting_haircut::skin-tone-2:": "\U0001f487\U0001f3fc\u200d\u2640\ufe0f", + ":woman_getting_haircut::skin-tone-3:": "\U0001f487\U0001f3fd\u200d\u2640\ufe0f", + ":woman_getting_haircut::skin-tone-4:": "\U0001f487\U0001f3fe\u200d\u2640\ufe0f", + ":woman_getting_haircut::skin-tone-5:": "\U0001f487\U0001f3ff\u200d\u2640\ufe0f", + ":woman_getting_massage:": "\U0001f486\u200d\u2640\ufe0f", + ":woman_golfing:": "\U0001f3cc\ufe0f\u200d\u2640\ufe0f", + ":woman_golfing::skin-tone-1:": "\U0001f3cc\U0001f3fb\u200d\u2640\ufe0f", + ":woman_golfing::skin-tone-2:": "\U0001f3cc\U0001f3fc\u200d\u2640\ufe0f", + ":woman_golfing::skin-tone-3:": "\U0001f3cc\U0001f3fd\u200d\u2640\ufe0f", + ":woman_golfing::skin-tone-4:": "\U0001f3cc\U0001f3fe\u200d\u2640\ufe0f", + ":woman_golfing::skin-tone-5:": "\U0001f3cc\U0001f3ff\u200d\u2640\ufe0f", + ":woman_guard:": "\U0001f482\u200d\u2640\ufe0f", + ":woman_guard::skin-tone-1:": "\U0001f482\U0001f3fb\u200d\u2640\ufe0f", + ":woman_guard::skin-tone-2:": "\U0001f482\U0001f3fc\u200d\u2640\ufe0f", + ":woman_guard::skin-tone-3:": "\U0001f482\U0001f3fd\u200d\u2640\ufe0f", + ":woman_guard::skin-tone-4:": "\U0001f482\U0001f3fe\u200d\u2640\ufe0f", + ":woman_guard::skin-tone-5:": "\U0001f482\U0001f3ff\u200d\u2640\ufe0f", + ":woman_health_worker:": "\U0001f469\u200d\u2695\ufe0f", + ":woman_health_worker::skin-tone-1:": "\U0001f469\U0001f3fb\u200d\u2695\ufe0f", + ":woman_health_worker::skin-tone-2:": "\U0001f469\U0001f3fc\u200d\u2695\ufe0f", + ":woman_health_worker::skin-tone-3:": "\U0001f469\U0001f3fd\u200d\u2695\ufe0f", + ":woman_health_worker::skin-tone-4:": "\U0001f469\U0001f3fe\u200d\u2695\ufe0f", + ":woman_health_worker::skin-tone-5:": "\U0001f469\U0001f3ff\u200d\u2695\ufe0f", + ":woman_in_lotus_position:": "\U0001f9d8\u200d\u2640\ufe0f", + ":woman_in_lotus_position::skin-tone-1:": "\U0001f9d8\U0001f3fb\u200d\u2640\ufe0f", + ":woman_in_lotus_position::skin-tone-2:": "\U0001f9d8\U0001f3fc\u200d\u2640\ufe0f", + ":woman_in_lotus_position::skin-tone-3:": "\U0001f9d8\U0001f3fd\u200d\u2640\ufe0f", + ":woman_in_lotus_position::skin-tone-4:": "\U0001f9d8\U0001f3fe\u200d\u2640\ufe0f", + ":woman_in_lotus_position::skin-tone-5:": "\U0001f9d8\U0001f3ff\u200d\u2640\ufe0f", + ":woman_in_manual_wheelchair:": "\U0001f469\u200d\U0001f9bd", + ":woman_in_motorized_wheelchair:": "\U0001f469\u200d\U0001f9bc", + ":woman_in_steamy_room:": "\U0001f9d6\u200d\u2640\ufe0f", + ":woman_in_steamy_room::skin-tone-1:": "\U0001f9d6\U0001f3fb\u200d\u2640\ufe0f", + ":woman_in_steamy_room::skin-tone-2:": "\U0001f9d6\U0001f3fc\u200d\u2640\ufe0f", + ":woman_in_steamy_room::skin-tone-3:": "\U0001f9d6\U0001f3fd\u200d\u2640\ufe0f", + ":woman_in_steamy_room::skin-tone-4:": "\U0001f9d6\U0001f3fe\u200d\u2640\ufe0f", + ":woman_in_steamy_room::skin-tone-5:": "\U0001f9d6\U0001f3ff\u200d\u2640\ufe0f", + ":woman_in_tuxedo:": "\U0001f935\u200d\u2640\ufe0f", + ":woman_judge:": "\U0001f469\u200d\u2696\ufe0f", + ":woman_judge::skin-tone-1:": "\U0001f469\U0001f3fb\u200d\u2696\ufe0f", + ":woman_judge::skin-tone-2:": "\U0001f469\U0001f3fc\u200d\u2696\ufe0f", + ":woman_judge::skin-tone-3:": "\U0001f469\U0001f3fd\u200d\u2696\ufe0f", + ":woman_judge::skin-tone-4:": "\U0001f469\U0001f3fe\u200d\u2696\ufe0f", + ":woman_judge::skin-tone-5:": "\U0001f469\U0001f3ff\u200d\u2696\ufe0f", + ":woman_juggling:": "\U0001f939\u200d\u2640\ufe0f", + ":woman_juggling::skin-tone-1:": "\U0001f939\U0001f3fb\u200d\u2640\ufe0f", + ":woman_juggling::skin-tone-2:": "\U0001f939\U0001f3fc\u200d\u2640\ufe0f", + ":woman_juggling::skin-tone-3:": "\U0001f939\U0001f3fd\u200d\u2640\ufe0f", + ":woman_juggling::skin-tone-4:": "\U0001f939\U0001f3fe\u200d\u2640\ufe0f", + ":woman_juggling::skin-tone-5:": "\U0001f939\U0001f3ff\u200d\u2640\ufe0f", + ":woman_kneeling:": "\U0001f9ce\u200d\u2640\ufe0f", + ":woman_lifting_weights:": "\U0001f3cb\ufe0f\u200d\u2640\ufe0f", + ":woman_lifting_weights::skin-tone-1:": "\U0001f3cb\U0001f3fb\u200d\u2640\ufe0f", + ":woman_lifting_weights::skin-tone-2:": "\U0001f3cb\U0001f3fc\u200d\u2640\ufe0f", + ":woman_lifting_weights::skin-tone-3:": "\U0001f3cb\U0001f3fd\u200d\u2640\ufe0f", + ":woman_lifting_weights::skin-tone-4:": "\U0001f3cb\U0001f3fe\u200d\u2640\ufe0f", + ":woman_lifting_weights::skin-tone-5:": "\U0001f3cb\U0001f3ff\u200d\u2640\ufe0f", + ":woman_mage:": "\U0001f9d9\u200d\u2640\ufe0f", + ":woman_mage::skin-tone-1:": "\U0001f9d9\U0001f3fb\u200d\u2640\ufe0f", + ":woman_mage::skin-tone-2:": "\U0001f9d9\U0001f3fc\u200d\u2640\ufe0f", + ":woman_mage::skin-tone-3:": "\U0001f9d9\U0001f3fd\u200d\u2640\ufe0f", + ":woman_mage::skin-tone-4:": "\U0001f9d9\U0001f3fe\u200d\u2640\ufe0f", + ":woman_mage::skin-tone-5:": "\U0001f9d9\U0001f3ff\u200d\u2640\ufe0f", + ":woman_mechanic:": "\U0001f469\u200d\U0001f527", + ":woman_mechanic::skin-tone-1:": "\U0001f469\U0001f3fb\u200d\U0001f527", + ":woman_mechanic::skin-tone-2:": "\U0001f469\U0001f3fc\u200d\U0001f527", + ":woman_mechanic::skin-tone-3:": "\U0001f469\U0001f3fd\u200d\U0001f527", + ":woman_mechanic::skin-tone-4:": "\U0001f469\U0001f3fe\u200d\U0001f527", + ":woman_mechanic::skin-tone-5:": "\U0001f469\U0001f3ff\u200d\U0001f527", + ":woman_mountain_biking:": "\U0001f6b5\u200d\u2640\ufe0f", + ":woman_mountain_biking::skin-tone-1:": "\U0001f6b5\U0001f3fb\u200d\u2640\ufe0f", + ":woman_mountain_biking::skin-tone-2:": "\U0001f6b5\U0001f3fc\u200d\u2640\ufe0f", + ":woman_mountain_biking::skin-tone-3:": "\U0001f6b5\U0001f3fd\u200d\u2640\ufe0f", + ":woman_mountain_biking::skin-tone-4:": "\U0001f6b5\U0001f3fe\u200d\u2640\ufe0f", + ":woman_mountain_biking::skin-tone-5:": "\U0001f6b5\U0001f3ff\u200d\u2640\ufe0f", + ":woman_office_worker:": "\U0001f469\u200d\U0001f4bc", + ":woman_office_worker::skin-tone-1:": "\U0001f469\U0001f3fb\u200d\U0001f4bc", + ":woman_office_worker::skin-tone-2:": "\U0001f469\U0001f3fc\u200d\U0001f4bc", + ":woman_office_worker::skin-tone-3:": "\U0001f469\U0001f3fd\u200d\U0001f4bc", + ":woman_office_worker::skin-tone-4:": "\U0001f469\U0001f3fe\u200d\U0001f4bc", + ":woman_office_worker::skin-tone-5:": "\U0001f469\U0001f3ff\u200d\U0001f4bc", + ":woman_pilot:": "\U0001f469\u200d\u2708\ufe0f", + ":woman_pilot::skin-tone-1:": "\U0001f469\U0001f3fb\u200d\u2708\ufe0f", + ":woman_pilot::skin-tone-2:": "\U0001f469\U0001f3fc\u200d\u2708\ufe0f", + ":woman_pilot::skin-tone-3:": "\U0001f469\U0001f3fd\u200d\u2708\ufe0f", + ":woman_pilot::skin-tone-4:": "\U0001f469\U0001f3fe\u200d\u2708\ufe0f", + ":woman_pilot::skin-tone-5:": "\U0001f469\U0001f3ff\u200d\u2708\ufe0f", + ":woman_playing_handball:": "\U0001f93e\u200d\u2640\ufe0f", + ":woman_playing_handball::skin-tone-1:": "\U0001f93e\U0001f3fb\u200d\u2640\ufe0f", + ":woman_playing_handball::skin-tone-2:": "\U0001f93e\U0001f3fc\u200d\u2640\ufe0f", + ":woman_playing_handball::skin-tone-3:": "\U0001f93e\U0001f3fd\u200d\u2640\ufe0f", + ":woman_playing_handball::skin-tone-4:": "\U0001f93e\U0001f3fe\u200d\u2640\ufe0f", + ":woman_playing_handball::skin-tone-5:": "\U0001f93e\U0001f3ff\u200d\u2640\ufe0f", + ":woman_playing_water_polo:": "\U0001f93d\u200d\u2640\ufe0f", + ":woman_playing_water_polo::skin-tone-1:": "\U0001f93d\U0001f3fb\u200d\u2640\ufe0f", + ":woman_playing_water_polo::skin-tone-2:": "\U0001f93d\U0001f3fc\u200d\u2640\ufe0f", + ":woman_playing_water_polo::skin-tone-3:": "\U0001f93d\U0001f3fd\u200d\u2640\ufe0f", + ":woman_playing_water_polo::skin-tone-4:": "\U0001f93d\U0001f3fe\u200d\u2640\ufe0f", + ":woman_playing_water_polo::skin-tone-5:": "\U0001f93d\U0001f3ff\u200d\u2640\ufe0f", + ":woman_police_officer:": "\U0001f46e\u200d\u2640\ufe0f", + ":woman_police_officer::skin-tone-1:": "\U0001f46e\U0001f3fb\u200d\u2640\ufe0f", + ":woman_police_officer::skin-tone-2:": "\U0001f46e\U0001f3fc\u200d\u2640\ufe0f", + ":woman_police_officer::skin-tone-3:": "\U0001f46e\U0001f3fd\u200d\u2640\ufe0f", + ":woman_police_officer::skin-tone-4:": "\U0001f46e\U0001f3fe\u200d\u2640\ufe0f", + ":woman_police_officer::skin-tone-5:": "\U0001f46e\U0001f3ff\u200d\u2640\ufe0f", + ":woman_pouting:": "\U0001f64e\u200d\u2640\ufe0f", + ":woman_pouting::skin-tone-1:": "\U0001f64e\U0001f3fb\u200d\u2640\ufe0f", + ":woman_pouting::skin-tone-2:": "\U0001f64e\U0001f3fc\u200d\u2640\ufe0f", + ":woman_pouting::skin-tone-3:": "\U0001f64e\U0001f3fd\u200d\u2640\ufe0f", + ":woman_pouting::skin-tone-4:": "\U0001f64e\U0001f3fe\u200d\u2640\ufe0f", + ":woman_pouting::skin-tone-5:": "\U0001f64e\U0001f3ff\u200d\u2640\ufe0f", + ":woman_raising_hand:": "\U0001f64b\u200d\u2640\ufe0f", + ":woman_raising_hand::skin-tone-1:": "\U0001f64b\U0001f3fb\u200d\u2640\ufe0f", + ":woman_raising_hand::skin-tone-2:": "\U0001f64b\U0001f3fc\u200d\u2640\ufe0f", + ":woman_raising_hand::skin-tone-3:": "\U0001f64b\U0001f3fd\u200d\u2640\ufe0f", + ":woman_raising_hand::skin-tone-4:": "\U0001f64b\U0001f3fe\u200d\u2640\ufe0f", + ":woman_raising_hand::skin-tone-5:": "\U0001f64b\U0001f3ff\u200d\u2640\ufe0f", + ":woman_red_hair:": "\U0001f469\u200d\U0001f9b0", + ":woman_rowing_boat:": "\U0001f6a3\u200d\u2640\ufe0f", + ":woman_rowing_boat::skin-tone-1:": "\U0001f6a3\U0001f3fb\u200d\u2640\ufe0f", + ":woman_rowing_boat::skin-tone-2:": "\U0001f6a3\U0001f3fc\u200d\u2640\ufe0f", + ":woman_rowing_boat::skin-tone-3:": "\U0001f6a3\U0001f3fd\u200d\u2640\ufe0f", + ":woman_rowing_boat::skin-tone-4:": "\U0001f6a3\U0001f3fe\u200d\u2640\ufe0f", + ":woman_rowing_boat::skin-tone-5:": "\U0001f6a3\U0001f3ff\u200d\u2640\ufe0f", + ":woman_running:": "\U0001f3c3\u200d\u2640\ufe0f", + ":woman_running::skin-tone-1:": "\U0001f3c3\U0001f3fb\u200d\u2640\ufe0f", + ":woman_running::skin-tone-2:": "\U0001f3c3\U0001f3fc\u200d\u2640\ufe0f", + ":woman_running::skin-tone-3:": "\U0001f3c3\U0001f3fd\u200d\u2640\ufe0f", + ":woman_running::skin-tone-4:": "\U0001f3c3\U0001f3fe\u200d\u2640\ufe0f", + ":woman_running::skin-tone-5:": "\U0001f3c3\U0001f3ff\u200d\u2640\ufe0f", + ":woman_scientist:": "\U0001f469\u200d\U0001f52c", + ":woman_scientist::skin-tone-1:": "\U0001f469\U0001f3fb\u200d\U0001f52c", + ":woman_scientist::skin-tone-2:": "\U0001f469\U0001f3fc\u200d\U0001f52c", + ":woman_scientist::skin-tone-3:": "\U0001f469\U0001f3fd\u200d\U0001f52c", + ":woman_scientist::skin-tone-4:": "\U0001f469\U0001f3fe\u200d\U0001f52c", + ":woman_scientist::skin-tone-5:": "\U0001f469\U0001f3ff\u200d\U0001f52c", + ":woman_shrugging:": "\U0001f937\u200d\u2640\ufe0f", + ":woman_shrugging::skin-tone-1:": "\U0001f937\U0001f3fb\u200d\u2640\ufe0f", + ":woman_shrugging::skin-tone-2:": "\U0001f937\U0001f3fc\u200d\u2640\ufe0f", + ":woman_shrugging::skin-tone-3:": "\U0001f937\U0001f3fd\u200d\u2640\ufe0f", + ":woman_shrugging::skin-tone-4:": "\U0001f937\U0001f3fe\u200d\u2640\ufe0f", + ":woman_shrugging::skin-tone-5:": "\U0001f937\U0001f3ff\u200d\u2640\ufe0f", + ":woman_singer:": "\U0001f469\u200d\U0001f3a4", + ":woman_singer::skin-tone-1:": "\U0001f469\U0001f3fb\u200d\U0001f3a4", + ":woman_singer::skin-tone-2:": "\U0001f469\U0001f3fc\u200d\U0001f3a4", + ":woman_singer::skin-tone-3:": "\U0001f469\U0001f3fd\u200d\U0001f3a4", + ":woman_singer::skin-tone-4:": "\U0001f469\U0001f3fe\u200d\U0001f3a4", + ":woman_singer::skin-tone-5:": "\U0001f469\U0001f3ff\u200d\U0001f3a4", + ":woman_standing:": "\U0001f9cd\u200d\u2640\ufe0f", + ":woman_student:": "\U0001f469\u200d\U0001f393", + ":woman_student::skin-tone-1:": "\U0001f469\U0001f3fb\u200d\U0001f393", + ":woman_student::skin-tone-2:": "\U0001f469\U0001f3fc\u200d\U0001f393", + ":woman_student::skin-tone-3:": "\U0001f469\U0001f3fd\u200d\U0001f393", + ":woman_student::skin-tone-4:": "\U0001f469\U0001f3fe\u200d\U0001f393", + ":woman_student::skin-tone-5:": "\U0001f469\U0001f3ff\u200d\U0001f393", + ":woman_superhero:": "\U0001f9b8\u200d\u2640\ufe0f", + ":woman_supervillain:": "\U0001f9b9\u200d\u2640\ufe0f", + ":woman_surfing:": "\U0001f3c4\u200d\u2640\ufe0f", + ":woman_surfing::skin-tone-1:": "\U0001f3c4\U0001f3fb\u200d\u2640\ufe0f", + ":woman_surfing::skin-tone-2:": "\U0001f3c4\U0001f3fc\u200d\u2640\ufe0f", + ":woman_surfing::skin-tone-3:": "\U0001f3c4\U0001f3fd\u200d\u2640\ufe0f", + ":woman_surfing::skin-tone-4:": "\U0001f3c4\U0001f3fe\u200d\u2640\ufe0f", + ":woman_surfing::skin-tone-5:": "\U0001f3c4\U0001f3ff\u200d\u2640\ufe0f", + ":woman_swimming:": "\U0001f3ca\u200d\u2640\ufe0f", + ":woman_swimming::skin-tone-1:": "\U0001f3ca\U0001f3fb\u200d\u2640\ufe0f", + ":woman_swimming::skin-tone-2:": "\U0001f3ca\U0001f3fc\u200d\u2640\ufe0f", + ":woman_swimming::skin-tone-3:": "\U0001f3ca\U0001f3fd\u200d\u2640\ufe0f", + ":woman_swimming::skin-tone-4:": "\U0001f3ca\U0001f3fe\u200d\u2640\ufe0f", + ":woman_swimming::skin-tone-5:": "\U0001f3ca\U0001f3ff\u200d\u2640\ufe0f", + ":woman_teacher:": "\U0001f469\u200d\U0001f3eb", + ":woman_teacher::skin-tone-1:": "\U0001f469\U0001f3fb\u200d\U0001f3eb", + ":woman_teacher::skin-tone-2:": "\U0001f469\U0001f3fc\u200d\U0001f3eb", + ":woman_teacher::skin-tone-3:": "\U0001f469\U0001f3fd\u200d\U0001f3eb", + ":woman_teacher::skin-tone-4:": "\U0001f469\U0001f3fe\u200d\U0001f3eb", + ":woman_teacher::skin-tone-5:": "\U0001f469\U0001f3ff\u200d\U0001f3eb", + ":woman_technologist:": "\U0001f469\u200d\U0001f4bb", + ":woman_technologist::skin-tone-1:": "\U0001f469\U0001f3fb\u200d\U0001f4bb", + ":woman_technologist::skin-tone-2:": "\U0001f469\U0001f3fc\u200d\U0001f4bb", + ":woman_technologist::skin-tone-3:": "\U0001f469\U0001f3fd\u200d\U0001f4bb", + ":woman_technologist::skin-tone-4:": "\U0001f469\U0001f3fe\u200d\U0001f4bb", + ":woman_technologist::skin-tone-5:": "\U0001f469\U0001f3ff\u200d\U0001f4bb", + ":woman_tipping_hand:": "\U0001f481\u200d\u2640\ufe0f", + ":woman_tipping_hand::skin-tone-1:": "\U0001f481\U0001f3fb\u200d\u2640\ufe0f", + ":woman_tipping_hand::skin-tone-2:": "\U0001f481\U0001f3fc\u200d\u2640\ufe0f", + ":woman_tipping_hand::skin-tone-3:": "\U0001f481\U0001f3fd\u200d\u2640\ufe0f", + ":woman_tipping_hand::skin-tone-4:": "\U0001f481\U0001f3fe\u200d\u2640\ufe0f", + ":woman_tipping_hand::skin-tone-5:": "\U0001f481\U0001f3ff\u200d\u2640\ufe0f", + ":woman::skin-tone-1:": "\U0001f469\U0001f3fb", + ":woman::skin-tone-2:": "\U0001f469\U0001f3fc", + ":woman::skin-tone-3:": "\U0001f469\U0001f3fd", + ":woman::skin-tone-4:": "\U0001f469\U0001f3fe", + ":woman::skin-tone-5:": "\U0001f469\U0001f3ff", + ":woman_vampire:": "\U0001f9db\u200d\u2640\ufe0f", + ":woman_vampire::skin-tone-1:": "\U0001f9db\U0001f3fb\u200d\u2640\ufe0f", + ":woman_vampire::skin-tone-2:": "\U0001f9db\U0001f3fc\u200d\u2640\ufe0f", + ":woman_vampire::skin-tone-3:": "\U0001f9db\U0001f3fd\u200d\u2640\ufe0f", + ":woman_vampire::skin-tone-4:": "\U0001f9db\U0001f3fe\u200d\u2640\ufe0f", + ":woman_vampire::skin-tone-5:": "\U0001f9db\U0001f3ff\u200d\u2640\ufe0f", + ":woman_walking:": "\U0001f6b6\u200d\u2640\ufe0f", + ":woman_walking::skin-tone-1:": "\U0001f6b6\U0001f3fb\u200d\u2640\ufe0f", + ":woman_walking::skin-tone-2:": "\U0001f6b6\U0001f3fc\u200d\u2640\ufe0f", + ":woman_walking::skin-tone-3:": "\U0001f6b6\U0001f3fd\u200d\u2640\ufe0f", + ":woman_walking::skin-tone-4:": "\U0001f6b6\U0001f3fe\u200d\u2640\ufe0f", + ":woman_walking::skin-tone-5:": "\U0001f6b6\U0001f3ff\u200d\u2640\ufe0f", + ":woman_wearing_turban:": "\U0001f473\u200d\u2640\ufe0f", + ":woman_wearing_turban::skin-tone-1:": "\U0001f473\U0001f3fb\u200d\u2640\ufe0f", + ":woman_wearing_turban::skin-tone-2:": "\U0001f473\U0001f3fc\u200d\u2640\ufe0f", + ":woman_wearing_turban::skin-tone-3:": "\U0001f473\U0001f3fd\u200d\u2640\ufe0f", + ":woman_wearing_turban::skin-tone-4:": "\U0001f473\U0001f3fe\u200d\u2640\ufe0f", + ":woman_wearing_turban::skin-tone-5:": "\U0001f473\U0001f3ff\u200d\u2640\ufe0f", + ":woman_white_hair:": "\U0001f469\u200d\U0001f9b3", + ":woman_with_headscarf:": "\U0001f9d5", + ":woman_with_headscarf::skin-tone-1:": "\U0001f9d5\U0001f3fb", + ":woman_with_headscarf::skin-tone-2:": "\U0001f9d5\U0001f3fc", + ":woman_with_headscarf::skin-tone-3:": "\U0001f9d5\U0001f3fd", + ":woman_with_headscarf::skin-tone-4:": "\U0001f9d5\U0001f3fe", + ":woman_with_headscarf::skin-tone-5:": "\U0001f9d5\U0001f3ff", + ":woman_with_probing_cane:": "\U0001f469\u200d\U0001f9af", + ":woman_with_turban:": "\U0001f473\u200d\u2640\ufe0f", + ":woman_with_veil:": "\U0001f470\u200d\u2640\ufe0f", + ":woman_with_white_cane:": "\U0001f469\u200d\U0001f9af", + ":woman_zombie:": "\U0001f9df\u200d\u2640\ufe0f", + ":womans_clothes:": "\U0001f45a", + ":womans_flat_shoe:": "\U0001f97f", + ":womans_hat:": "\U0001f452", + ":woman’s_boot:": "\U0001f462", + ":woman’s_clothes:": "\U0001f45a", + ":woman’s_hat:": "\U0001f452", + ":woman’s_sandal:": "\U0001f461", + ":women_holding_hands:": "\U0001f46d", + ":women_with_bunny_ears:": "\U0001f46f\u200d\u2640\ufe0f", + ":women_with_bunny_ears_partying:": "\U0001f46f\u200d\u2640\ufe0f", + ":women_wrestling:": "\U0001f93c\u200d\u2640\ufe0f", + ":womens:": "\U0001f6ba", + ":women’s_room:": "\U0001f6ba", + ":wood:": "\U0001fab5", + ":woozy_face:": "\U0001f974", + ":world_map:": "\U0001f5fa\ufe0f", + ":worm:": "\U0001fab1", + ":worried:": "\U0001f61f", + ":worried_face:": "\U0001f61f", + ":wrapped_gift:": "\U0001f381", + ":wrench:": "\U0001f527", + ":wrestlers:": "\U0001f93c", + ":wrestling:": "\U0001f93c", + ":writing_hand:": "\u270d\ufe0f", + ":writing_hand::skin-tone-1:": "\u270d\U0001f3fb", + ":writing_hand::skin-tone-2:": "\u270d\U0001f3fc", + ":writing_hand::skin-tone-3:": "\u270d\U0001f3fd", + ":writing_hand::skin-tone-4:": "\u270d\U0001f3fe", + ":writing_hand::skin-tone-5:": "\u270d\U0001f3ff", + ":x:": "\u274c", + ":yarn:": "\U0001f9f6", + ":yawning_face:": "\U0001f971", + ":yellow_circle:": "\U0001f7e1", + ":yellow_heart:": "\U0001f49b", + ":yellow_square:": "\U0001f7e8", + ":yemen:": "\U0001f1fe\U0001f1ea", + ":yen:": "\U0001f4b4", + ":yen_banknote:": "\U0001f4b4", + ":yin_yang:": "\u262f\ufe0f", + ":yo-yo:": "\U0001fa80", + ":yo_yo:": "\U0001fa80", + ":yum:": "\U0001f60b", + ":zambia:": "\U0001f1ff\U0001f1f2", + ":zany_face:": "\U0001f92a", + ":zap:": "\u26a1", + ":zebra:": "\U0001f993", + ":zebra_face:": "\U0001f993", + ":zero:": "0\ufe0f\u20e3", + ":zimbabwe:": "\U0001f1ff\U0001f1fc", + ":zipper-mouth_face:": "\U0001f910", + ":zipper_mouth:": "\U0001f910", + ":zipper_mouth_face:": "\U0001f910", + ":zombie:": "\U0001f9df\u200d\u2642\ufe0f", + ":zombie_man:": "\U0001f9df\u200d\u2642\ufe0f", + ":zombie_woman:": "\U0001f9df\u200d\u2640\ufe0f", + ":zzz:": "\U0001f4a4", +} + +var emojiRevCodeMap = map[string][]string{ + "#\ufe0f\u20e3": {":hash:", ":keycap_#:"}, + "*\ufe0f\u20e3": {":asterisk:", ":keycap_*:", ":keycap_star:"}, + "0\ufe0f\u20e3": {":zero:", ":keycap_0:"}, + "1\ufe0f\u20e3": {":one:", ":keycap_1:"}, + "2\ufe0f\u20e3": {":two:", ":keycap_2:"}, + "3\ufe0f\u20e3": {":three:", ":keycap_3:"}, + "4\ufe0f\u20e3": {":four:", ":keycap_4:"}, + "5\ufe0f\u20e3": {":five:", ":keycap_5:"}, + "6\ufe0f\u20e3": {":six:", ":keycap_6:"}, + "7\ufe0f\u20e3": {":seven:", ":keycap_7:"}, + "8\ufe0f\u20e3": {":eight:", ":keycap_8:"}, + "9\ufe0f\u20e3": {":nine:", ":keycap_9:"}, + "\U0001f004": {":mahjong:", ":mahjong_red_dragon:"}, + "\U0001f0cf": {":joker:", ":black_joker:"}, + "\U0001f170": {":A_button_(blood_type):"}, + "\U0001f170\ufe0f": {":a:"}, + "\U0001f171": {":B_button_(blood_type):"}, + "\U0001f171\ufe0f": {":b:"}, + "\U0001f17e": {":O_button_(blood_type):"}, + "\U0001f17e\ufe0f": {":o2:"}, + "\U0001f17f": {":P_button:"}, + "\U0001f17f\ufe0f": {":parking:"}, + "\U0001f18e": {":ab:", ":AB_button_(blood_type):"}, + "\U0001f191": {":cl:", ":CL_button:"}, + "\U0001f192": {":cool:", ":COOL_button:"}, + "\U0001f193": {":free:", ":FREE_button:"}, + "\U0001f194": {":id:", ":ID_button:"}, + "\U0001f195": {":new:", ":NEW_button:"}, + "\U0001f196": {":ng:", ":NG_button:"}, + "\U0001f197": {":ok:", ":OK_button:"}, + "\U0001f198": {":sos:", ":SOS_button:"}, + "\U0001f199": {":up:", ":UP!_button:"}, + "\U0001f19a": {":vs:", ":VS_button:"}, + "\U0001f1e6\U0001f1e8": {":flag-ac:", ":flag_ac:", ":ascension_island:", ":flag_Ascension_Island:"}, + "\U0001f1e6\U0001f1e9": {":andorra:", ":flag-ad:", ":flag_ad:", ":flag_Andorra:"}, + "\U0001f1e6\U0001f1ea": {":flag-ae:", ":flag_ae:", ":united_arab_emirates:", ":flag_United_Arab_Emirates:"}, + "\U0001f1e6\U0001f1eb": {":flag-af:", ":flag_af:", ":afghanistan:", ":flag_Afghanistan:"}, + "\U0001f1e6\U0001f1ec": {":flag-ag:", ":flag_ag:", ":antigua_barbuda:", ":flag_Antigua_&_Barbuda:"}, + "\U0001f1e6\U0001f1ee": {":flag-ai:", ":flag_ai:", ":anguilla:", ":flag_Anguilla:"}, + "\U0001f1e6\U0001f1f1": {":albania:", ":flag-al:", ":flag_al:", ":flag_Albania:"}, + "\U0001f1e6\U0001f1f2": {":armenia:", ":flag-am:", ":flag_am:", ":flag_Armenia:"}, + "\U0001f1e6\U0001f1f4": {":angola:", ":flag-ao:", ":flag_ao:", ":flag_Angola:"}, + "\U0001f1e6\U0001f1f6": {":flag-aq:", ":flag_aq:", ":antarctica:", ":flag_Antarctica:"}, + "\U0001f1e6\U0001f1f7": {":flag-ar:", ":flag_ar:", ":argentina:", ":flag_Argentina:"}, + "\U0001f1e6\U0001f1f8": {":flag-as:", ":flag_as:", ":american_samoa:", ":flag_American_Samoa:"}, + "\U0001f1e6\U0001f1f9": {":austria:", ":flag-at:", ":flag_at:", ":flag_Austria:"}, + "\U0001f1e6\U0001f1fa": {":flag-au:", ":flag_au:", ":australia:", ":flag_Australia:"}, + "\U0001f1e6\U0001f1fc": {":aruba:", ":flag-aw:", ":flag_aw:", ":flag_Aruba:"}, + "\U0001f1e6\U0001f1fd": {":flag-ax:", ":flag_ax:", ":aland_islands:", ":flag_Åland_Islands:"}, + "\U0001f1e6\U0001f1ff": {":flag-az:", ":flag_az:", ":azerbaijan:", ":flag_Azerbaijan:"}, + "\U0001f1e7\U0001f1e6": {":flag-ba:", ":flag_ba:", ":bosnia_herzegovina:", ":flag_Bosnia_&_Herzegovina:"}, + "\U0001f1e7\U0001f1e7": {":flag-bb:", ":flag_bb:", ":barbados:", ":flag_Barbados:"}, + "\U0001f1e7\U0001f1e9": {":flag-bd:", ":flag_bd:", ":bangladesh:", ":flag_Bangladesh:"}, + "\U0001f1e7\U0001f1ea": {":belgium:", ":flag-be:", ":flag_be:", ":flag_Belgium:"}, + "\U0001f1e7\U0001f1eb": {":flag-bf:", ":flag_bf:", ":burkina_faso:", ":flag_Burkina_Faso:"}, + "\U0001f1e7\U0001f1ec": {":flag-bg:", ":flag_bg:", ":bulgaria:", ":flag_Bulgaria:"}, + "\U0001f1e7\U0001f1ed": {":bahrain:", ":flag-bh:", ":flag_bh:", ":flag_Bahrain:"}, + "\U0001f1e7\U0001f1ee": {":burundi:", ":flag-bi:", ":flag_bi:", ":flag_Burundi:"}, + "\U0001f1e7\U0001f1ef": {":benin:", ":flag-bj:", ":flag_bj:", ":flag_Benin:"}, + "\U0001f1e7\U0001f1f1": {":flag-bl:", ":flag_bl:", ":st_barthelemy:", ":flag_St._Barthélemy:"}, + "\U0001f1e7\U0001f1f2": {":bermuda:", ":flag-bm:", ":flag_bm:", ":flag_Bermuda:"}, + "\U0001f1e7\U0001f1f3": {":brunei:", ":flag-bn:", ":flag_bn:", ":flag_Brunei:"}, + "\U0001f1e7\U0001f1f4": {":bolivia:", ":flag-bo:", ":flag_bo:", ":flag_Bolivia:"}, + "\U0001f1e7\U0001f1f6": {":flag-bq:", ":flag_bq:", ":caribbean_netherlands:", ":flag_Caribbean_Netherlands:"}, + "\U0001f1e7\U0001f1f7": {":brazil:", ":flag-br:", ":flag_br:", ":flag_Brazil:"}, + "\U0001f1e7\U0001f1f8": {":bahamas:", ":flag-bs:", ":flag_bs:", ":flag_Bahamas:"}, + "\U0001f1e7\U0001f1f9": {":bhutan:", ":flag-bt:", ":flag_bt:", ":flag_Bhutan:"}, + "\U0001f1e7\U0001f1fb": {":flag-bv:", ":flag_bv:", ":bouvet_island:", ":flag_Bouvet_Island:"}, + "\U0001f1e7\U0001f1fc": {":flag-bw:", ":flag_bw:", ":botswana:", ":flag_Botswana:"}, + "\U0001f1e7\U0001f1fe": {":belarus:", ":flag-by:", ":flag_by:", ":flag_Belarus:"}, + "\U0001f1e7\U0001f1ff": {":belize:", ":flag-bz:", ":flag_bz:", ":flag_Belize:"}, + "\U0001f1e8\U0001f1e6": {":canada:", ":flag-ca:", ":flag_ca:", ":flag_Canada:"}, + "\U0001f1e8\U0001f1e8": {":flag-cc:", ":flag_cc:", ":cocos_islands:", ":flag_Cocos_(Keeling)_Islands:"}, + "\U0001f1e8\U0001f1e9": {":flag-cd:", ":flag_cd:", ":congo_kinshasa:", ":flag_Congo_-_Kinshasa:"}, + "\U0001f1e8\U0001f1eb": {":flag-cf:", ":flag_cf:", ":central_african_republic:", ":flag_Central_African_Republic:"}, + "\U0001f1e8\U0001f1ec": {":flag-cg:", ":flag_cg:", ":congo_brazzaville:", ":flag_Congo_-_Brazzaville:"}, + "\U0001f1e8\U0001f1ed": {":flag-ch:", ":flag_ch:", ":switzerland:", ":flag_Switzerland:"}, + "\U0001f1e8\U0001f1ee": {":flag-ci:", ":flag_ci:", ":cote_divoire:", ":flag_Côte_d’Ivoire:"}, + "\U0001f1e8\U0001f1f0": {":flag-ck:", ":flag_ck:", ":cook_islands:", ":flag_Cook_Islands:"}, + "\U0001f1e8\U0001f1f1": {":chile:", ":flag-cl:", ":flag_cl:", ":flag_Chile:"}, + "\U0001f1e8\U0001f1f2": {":flag-cm:", ":flag_cm:", ":cameroon:", ":flag_Cameroon:"}, + "\U0001f1e8\U0001f1f3": {":cn:", ":flag_cn:", ":flag_China:"}, + "\U0001f1e8\U0001f1f4": {":flag-co:", ":flag_co:", ":colombia:", ":flag_Colombia:"}, + "\U0001f1e8\U0001f1f5": {":flag-cp:", ":flag_cp:", ":clipperton_island:", ":flag_Clipperton_Island:"}, + "\U0001f1e8\U0001f1f7": {":flag-cr:", ":flag_cr:", ":costa_rica:", ":flag_Costa_Rica:"}, + "\U0001f1e8\U0001f1fa": {":cuba:", ":flag-cu:", ":flag_cu:", ":flag_Cuba:"}, + "\U0001f1e8\U0001f1fb": {":flag-cv:", ":flag_cv:", ":cape_verde:", ":flag_Cape_Verde:"}, + "\U0001f1e8\U0001f1fc": {":curacao:", ":flag-cw:", ":flag_cw:", ":flag_Curaçao:"}, + "\U0001f1e8\U0001f1fd": {":flag-cx:", ":flag_cx:", ":christmas_island:", ":flag_Christmas_Island:"}, + "\U0001f1e8\U0001f1fe": {":cyprus:", ":flag-cy:", ":flag_cy:", ":flag_Cyprus:"}, + "\U0001f1e8\U0001f1ff": {":flag-cz:", ":flag_cz:", ":flag_Czechia:", ":czech_republic:"}, + "\U0001f1e9\U0001f1ea": {":de:", ":flag_de:", ":flag_Germany:"}, + "\U0001f1e9\U0001f1ec": {":flag-dg:", ":flag_dg:", ":diego_garcia:", ":flag_Diego_Garcia:"}, + "\U0001f1e9\U0001f1ef": {":flag-dj:", ":flag_dj:", ":djibouti:", ":flag_Djibouti:"}, + "\U0001f1e9\U0001f1f0": {":denmark:", ":flag-dk:", ":flag_dk:", ":flag_Denmark:"}, + "\U0001f1e9\U0001f1f2": {":flag-dm:", ":flag_dm:", ":dominica:", ":flag_Dominica:"}, + "\U0001f1e9\U0001f1f4": {":flag-do:", ":flag_do:", ":dominican_republic:", ":flag_Dominican_Republic:"}, + "\U0001f1e9\U0001f1ff": {":algeria:", ":flag-dz:", ":flag_dz:", ":flag_Algeria:"}, + "\U0001f1ea\U0001f1e6": {":flag-ea:", ":flag_ea:", ":ceuta_melilla:", ":flag_Ceuta_&_Melilla:"}, + "\U0001f1ea\U0001f1e8": {":ecuador:", ":flag-ec:", ":flag_ec:", ":flag_Ecuador:"}, + "\U0001f1ea\U0001f1ea": {":estonia:", ":flag-ee:", ":flag_ee:", ":flag_Estonia:"}, + "\U0001f1ea\U0001f1ec": {":egypt:", ":flag-eg:", ":flag_eg:", ":flag_Egypt:"}, + "\U0001f1ea\U0001f1ed": {":flag-eh:", ":flag_eh:", ":western_sahara:", ":flag_Western_Sahara:"}, + "\U0001f1ea\U0001f1f7": {":eritrea:", ":flag-er:", ":flag_er:", ":flag_Eritrea:"}, + "\U0001f1ea\U0001f1f8": {":es:", ":flag_es:", ":flag_Spain:"}, + "\U0001f1ea\U0001f1f9": {":flag-et:", ":flag_et:", ":ethiopia:", ":flag_Ethiopia:"}, + "\U0001f1ea\U0001f1fa": {":eu:", ":flag-eu:", ":flag_eu:", ":european_union:", ":flag_European_Union:"}, + "\U0001f1eb\U0001f1ee": {":finland:", ":flag-fi:", ":flag_fi:", ":flag_Finland:"}, + "\U0001f1eb\U0001f1ef": {":fiji:", ":flag-fj:", ":flag_fj:", ":flag_Fiji:"}, + "\U0001f1eb\U0001f1f0": {":flag-fk:", ":flag_fk:", ":falkland_islands:", ":flag_Falkland_Islands:"}, + "\U0001f1eb\U0001f1f2": {":flag-fm:", ":flag_fm:", ":micronesia:", ":flag_Micronesia:"}, + "\U0001f1eb\U0001f1f4": {":flag-fo:", ":flag_fo:", ":faroe_islands:", ":flag_Faroe_Islands:"}, + "\U0001f1eb\U0001f1f7": {":fr:", ":flag_fr:", ":flag_France:"}, + "\U0001f1ec\U0001f1e6": {":gabon:", ":flag-ga:", ":flag_ga:", ":flag_Gabon:"}, + "\U0001f1ec\U0001f1e7": {":gb:", ":uk:", ":flag_gb:", ":flag_United_Kingdom:"}, + "\U0001f1ec\U0001f1e9": {":flag-gd:", ":flag_gd:", ":grenada:", ":flag_Grenada:"}, + "\U0001f1ec\U0001f1ea": {":flag-ge:", ":flag_ge:", ":georgia:", ":flag_Georgia:"}, + "\U0001f1ec\U0001f1eb": {":flag-gf:", ":flag_gf:", ":french_guiana:", ":flag_French_Guiana:"}, + "\U0001f1ec\U0001f1ec": {":flag-gg:", ":flag_gg:", ":guernsey:", ":flag_Guernsey:"}, + "\U0001f1ec\U0001f1ed": {":ghana:", ":flag-gh:", ":flag_gh:", ":flag_Ghana:"}, + "\U0001f1ec\U0001f1ee": {":flag-gi:", ":flag_gi:", ":gibraltar:", ":flag_Gibraltar:"}, + "\U0001f1ec\U0001f1f1": {":flag-gl:", ":flag_gl:", ":greenland:", ":flag_Greenland:"}, + "\U0001f1ec\U0001f1f2": {":gambia:", ":flag-gm:", ":flag_gm:", ":flag_Gambia:"}, + "\U0001f1ec\U0001f1f3": {":guinea:", ":flag-gn:", ":flag_gn:", ":flag_Guinea:"}, + "\U0001f1ec\U0001f1f5": {":flag-gp:", ":flag_gp:", ":guadeloupe:", ":flag_Guadeloupe:"}, + "\U0001f1ec\U0001f1f6": {":flag-gq:", ":flag_gq:", ":equatorial_guinea:", ":flag_Equatorial_Guinea:"}, + "\U0001f1ec\U0001f1f7": {":greece:", ":flag-gr:", ":flag_gr:", ":flag_Greece:"}, + "\U0001f1ec\U0001f1f8": {":flag-gs:", ":flag_gs:", ":south_georgia_south_sandwich_islands:", ":flag_South_Georgia_&_South_Sandwich_Islands:"}, + "\U0001f1ec\U0001f1f9": {":flag-gt:", ":flag_gt:", ":guatemala:", ":flag_Guatemala:"}, + "\U0001f1ec\U0001f1fa": {":guam:", ":flag-gu:", ":flag_gu:", ":flag_Guam:"}, + "\U0001f1ec\U0001f1fc": {":flag-gw:", ":flag_gw:", ":guinea_bissau:", ":flag_Guinea-Bissau:"}, + "\U0001f1ec\U0001f1fe": {":guyana:", ":flag-gy:", ":flag_gy:", ":flag_Guyana:"}, + "\U0001f1ed\U0001f1f0": {":flag-hk:", ":flag_hk:", ":hong_kong:", ":flag_Hong_Kong_SAR_China:"}, + "\U0001f1ed\U0001f1f2": {":flag-hm:", ":flag_hm:", ":heard_mcdonald_islands:", ":flag_Heard_&_McDonald_Islands:"}, + "\U0001f1ed\U0001f1f3": {":flag-hn:", ":flag_hn:", ":honduras:", ":flag_Honduras:"}, + "\U0001f1ed\U0001f1f7": {":croatia:", ":flag-hr:", ":flag_hr:", ":flag_Croatia:"}, + "\U0001f1ed\U0001f1f9": {":haiti:", ":flag-ht:", ":flag_ht:", ":flag_Haiti:"}, + "\U0001f1ed\U0001f1fa": {":flag-hu:", ":flag_hu:", ":hungary:", ":flag_Hungary:"}, + "\U0001f1ee\U0001f1e8": {":flag-ic:", ":flag_ic:", ":canary_islands:", ":flag_Canary_Islands:"}, + "\U0001f1ee\U0001f1e9": {":flag-id:", ":flag_id:", ":indonesia:", ":flag_Indonesia:"}, + "\U0001f1ee\U0001f1ea": {":flag-ie:", ":flag_ie:", ":ireland:", ":flag_Ireland:"}, + "\U0001f1ee\U0001f1f1": {":israel:", ":flag-il:", ":flag_il:", ":flag_Israel:"}, + "\U0001f1ee\U0001f1f2": {":flag-im:", ":flag_im:", ":isle_of_man:", ":flag_Isle_of_Man:"}, + "\U0001f1ee\U0001f1f3": {":india:", ":flag-in:", ":flag_in:", ":flag_India:"}, + "\U0001f1ee\U0001f1f4": {":flag-io:", ":flag_io:", ":british_indian_ocean_territory:", ":flag_British_Indian_Ocean_Territory:"}, + "\U0001f1ee\U0001f1f6": {":iraq:", ":flag-iq:", ":flag_iq:", ":flag_Iraq:"}, + "\U0001f1ee\U0001f1f7": {":iran:", ":flag-ir:", ":flag_ir:", ":flag_Iran:"}, + "\U0001f1ee\U0001f1f8": {":flag-is:", ":flag_is:", ":iceland:", ":flag_Iceland:"}, + "\U0001f1ee\U0001f1f9": {":it:", ":flag_it:", ":flag_Italy:"}, + "\U0001f1ef\U0001f1ea": {":jersey:", ":flag-je:", ":flag_je:", ":flag_Jersey:"}, + "\U0001f1ef\U0001f1f2": {":flag-jm:", ":flag_jm:", ":jamaica:", ":flag_Jamaica:"}, + "\U0001f1ef\U0001f1f4": {":jordan:", ":flag-jo:", ":flag_jo:", ":flag_Jordan:"}, + "\U0001f1ef\U0001f1f5": {":jp:", ":flag_jp:", ":flag_Japan:"}, + "\U0001f1f0\U0001f1ea": {":kenya:", ":flag-ke:", ":flag_ke:", ":flag_Kenya:"}, + "\U0001f1f0\U0001f1ec": {":flag-kg:", ":flag_kg:", ":kyrgyzstan:", ":flag_Kyrgyzstan:"}, + "\U0001f1f0\U0001f1ed": {":flag-kh:", ":flag_kh:", ":cambodia:", ":flag_Cambodia:"}, + "\U0001f1f0\U0001f1ee": {":flag-ki:", ":flag_ki:", ":kiribati:", ":flag_Kiribati:"}, + "\U0001f1f0\U0001f1f2": {":comoros:", ":flag-km:", ":flag_km:", ":flag_Comoros:"}, + "\U0001f1f0\U0001f1f3": {":flag-kn:", ":flag_kn:", ":st_kitts_nevis:", ":flag_St._Kitts_&_Nevis:"}, + "\U0001f1f0\U0001f1f5": {":flag-kp:", ":flag_kp:", ":north_korea:", ":flag_North_Korea:"}, + "\U0001f1f0\U0001f1f7": {":kr:", ":flag_kr:", ":flag_South_Korea:"}, + "\U0001f1f0\U0001f1fc": {":kuwait:", ":flag-kw:", ":flag_kw:", ":flag_Kuwait:"}, + "\U0001f1f0\U0001f1fe": {":flag-ky:", ":flag_ky:", ":cayman_islands:", ":flag_Cayman_Islands:"}, + "\U0001f1f0\U0001f1ff": {":flag-kz:", ":flag_kz:", ":kazakhstan:", ":flag_Kazakhstan:"}, + "\U0001f1f1\U0001f1e6": {":laos:", ":flag-la:", ":flag_la:", ":flag_Laos:"}, + "\U0001f1f1\U0001f1e7": {":flag-lb:", ":flag_lb:", ":lebanon:", ":flag_Lebanon:"}, + "\U0001f1f1\U0001f1e8": {":flag-lc:", ":flag_lc:", ":st_lucia:", ":flag_St._Lucia:"}, + "\U0001f1f1\U0001f1ee": {":flag-li:", ":flag_li:", ":liechtenstein:", ":flag_Liechtenstein:"}, + "\U0001f1f1\U0001f1f0": {":flag-lk:", ":flag_lk:", ":sri_lanka:", ":flag_Sri_Lanka:"}, + "\U0001f1f1\U0001f1f7": {":flag-lr:", ":flag_lr:", ":liberia:", ":flag_Liberia:"}, + "\U0001f1f1\U0001f1f8": {":flag-ls:", ":flag_ls:", ":lesotho:", ":flag_Lesotho:"}, + "\U0001f1f1\U0001f1f9": {":flag-lt:", ":flag_lt:", ":lithuania:", ":flag_Lithuania:"}, + "\U0001f1f1\U0001f1fa": {":flag-lu:", ":flag_lu:", ":luxembourg:", ":flag_Luxembourg:"}, + "\U0001f1f1\U0001f1fb": {":latvia:", ":flag-lv:", ":flag_lv:", ":flag_Latvia:"}, + "\U0001f1f1\U0001f1fe": {":libya:", ":flag-ly:", ":flag_ly:", ":flag_Libya:"}, + "\U0001f1f2\U0001f1e6": {":flag-ma:", ":flag_ma:", ":morocco:", ":flag_Morocco:"}, + "\U0001f1f2\U0001f1e8": {":monaco:", ":flag-mc:", ":flag_mc:", ":flag_Monaco:"}, + "\U0001f1f2\U0001f1e9": {":flag-md:", ":flag_md:", ":moldova:", ":flag_Moldova:"}, + "\U0001f1f2\U0001f1ea": {":flag-me:", ":flag_me:", ":montenegro:", ":flag_Montenegro:"}, + "\U0001f1f2\U0001f1eb": {":flag-mf:", ":flag_mf:", ":st_martin:", ":flag_St._Martin:"}, + "\U0001f1f2\U0001f1ec": {":flag-mg:", ":flag_mg:", ":madagascar:", ":flag_Madagascar:"}, + "\U0001f1f2\U0001f1ed": {":flag-mh:", ":flag_mh:", ":marshall_islands:", ":flag_Marshall_Islands:"}, + "\U0001f1f2\U0001f1f0": {":flag-mk:", ":flag_mk:", ":macedonia:", ":flag_North_Macedonia:"}, + "\U0001f1f2\U0001f1f1": {":mali:", ":flag-ml:", ":flag_ml:", ":flag_Mali:"}, + "\U0001f1f2\U0001f1f2": {":flag-mm:", ":flag_mm:", ":myanmar:", ":flag_Myanmar_(Burma):"}, + "\U0001f1f2\U0001f1f3": {":flag-mn:", ":flag_mn:", ":mongolia:", ":flag_Mongolia:"}, + "\U0001f1f2\U0001f1f4": {":macau:", ":flag-mo:", ":flag_mo:", ":flag_Macao_SAR_China:"}, + "\U0001f1f2\U0001f1f5": {":flag-mp:", ":flag_mp:", ":northern_mariana_islands:", ":flag_Northern_Mariana_Islands:"}, + "\U0001f1f2\U0001f1f6": {":flag-mq:", ":flag_mq:", ":martinique:", ":flag_Martinique:"}, + "\U0001f1f2\U0001f1f7": {":flag-mr:", ":flag_mr:", ":mauritania:", ":flag_Mauritania:"}, + "\U0001f1f2\U0001f1f8": {":flag-ms:", ":flag_ms:", ":montserrat:", ":flag_Montserrat:"}, + "\U0001f1f2\U0001f1f9": {":malta:", ":flag-mt:", ":flag_mt:", ":flag_Malta:"}, + "\U0001f1f2\U0001f1fa": {":flag-mu:", ":flag_mu:", ":mauritius:", ":flag_Mauritius:"}, + "\U0001f1f2\U0001f1fb": {":flag-mv:", ":flag_mv:", ":maldives:", ":flag_Maldives:"}, + "\U0001f1f2\U0001f1fc": {":malawi:", ":flag-mw:", ":flag_mw:", ":flag_Malawi:"}, + "\U0001f1f2\U0001f1fd": {":mexico:", ":flag-mx:", ":flag_mx:", ":flag_Mexico:"}, + "\U0001f1f2\U0001f1fe": {":flag-my:", ":flag_my:", ":malaysia:", ":flag_Malaysia:"}, + "\U0001f1f2\U0001f1ff": {":flag-mz:", ":flag_mz:", ":mozambique:", ":flag_Mozambique:"}, + "\U0001f1f3\U0001f1e6": {":flag-na:", ":flag_na:", ":namibia:", ":flag_Namibia:"}, + "\U0001f1f3\U0001f1e8": {":flag-nc:", ":flag_nc:", ":new_caledonia:", ":flag_New_Caledonia:"}, + "\U0001f1f3\U0001f1ea": {":niger:", ":flag-ne:", ":flag_ne:", ":flag_Niger:"}, + "\U0001f1f3\U0001f1eb": {":flag-nf:", ":flag_nf:", ":norfolk_island:", ":flag_Norfolk_Island:"}, + "\U0001f1f3\U0001f1ec": {":flag-ng:", ":flag_ng:", ":nigeria:", ":flag_Nigeria:"}, + "\U0001f1f3\U0001f1ee": {":flag-ni:", ":flag_ni:", ":nicaragua:", ":flag_Nicaragua:"}, + "\U0001f1f3\U0001f1f1": {":flag-nl:", ":flag_nl:", ":netherlands:", ":flag_Netherlands:"}, + "\U0001f1f3\U0001f1f4": {":norway:", ":flag-no:", ":flag_no:", ":flag_Norway:"}, + "\U0001f1f3\U0001f1f5": {":nepal:", ":flag-np:", ":flag_np:", ":flag_Nepal:"}, + "\U0001f1f3\U0001f1f7": {":nauru:", ":flag-nr:", ":flag_nr:", ":flag_Nauru:"}, + "\U0001f1f3\U0001f1fa": {":niue:", ":flag-nu:", ":flag_nu:", ":flag_Niue:"}, + "\U0001f1f3\U0001f1ff": {":flag-nz:", ":flag_nz:", ":new_zealand:", ":flag_New_Zealand:"}, + "\U0001f1f4\U0001f1f2": {":oman:", ":flag-om:", ":flag_om:", ":flag_Oman:"}, + "\U0001f1f5\U0001f1e6": {":panama:", ":flag-pa:", ":flag_pa:", ":flag_Panama:"}, + "\U0001f1f5\U0001f1ea": {":peru:", ":flag-pe:", ":flag_pe:", ":flag_Peru:"}, + "\U0001f1f5\U0001f1eb": {":flag-pf:", ":flag_pf:", ":french_polynesia:", ":flag_French_Polynesia:"}, + "\U0001f1f5\U0001f1ec": {":flag-pg:", ":flag_pg:", ":papua_new_guinea:", ":flag_Papua_New_Guinea:"}, + "\U0001f1f5\U0001f1ed": {":flag-ph:", ":flag_ph:", ":philippines:", ":flag_Philippines:"}, + "\U0001f1f5\U0001f1f0": {":flag-pk:", ":flag_pk:", ":pakistan:", ":flag_Pakistan:"}, + "\U0001f1f5\U0001f1f1": {":poland:", ":flag-pl:", ":flag_pl:", ":flag_Poland:"}, + "\U0001f1f5\U0001f1f2": {":flag-pm:", ":flag_pm:", ":st_pierre_miquelon:", ":flag_St._Pierre_&_Miquelon:"}, + "\U0001f1f5\U0001f1f3": {":flag-pn:", ":flag_pn:", ":pitcairn_islands:", ":flag_Pitcairn_Islands:"}, + "\U0001f1f5\U0001f1f7": {":flag-pr:", ":flag_pr:", ":puerto_rico:", ":flag_Puerto_Rico:"}, + "\U0001f1f5\U0001f1f8": {":flag-ps:", ":flag_ps:", ":palestinian_territories:", ":flag_Palestinian_Territories:"}, + "\U0001f1f5\U0001f1f9": {":flag-pt:", ":flag_pt:", ":portugal:", ":flag_Portugal:"}, + "\U0001f1f5\U0001f1fc": {":palau:", ":flag-pw:", ":flag_pw:", ":flag_Palau:"}, + "\U0001f1f5\U0001f1fe": {":flag-py:", ":flag_py:", ":paraguay:", ":flag_Paraguay:"}, + "\U0001f1f6\U0001f1e6": {":qatar:", ":flag-qa:", ":flag_qa:", ":flag_Qatar:"}, + "\U0001f1f7\U0001f1ea": {":flag-re:", ":flag_re:", ":reunion:", ":flag_Réunion:"}, + "\U0001f1f7\U0001f1f4": {":flag-ro:", ":flag_ro:", ":romania:", ":flag_Romania:"}, + "\U0001f1f7\U0001f1f8": {":serbia:", ":flag-rs:", ":flag_rs:", ":flag_Serbia:"}, + "\U0001f1f7\U0001f1fa": {":ru:", ":flag_ru:", ":flag_Russia:"}, + "\U0001f1f7\U0001f1fc": {":rwanda:", ":flag-rw:", ":flag_rw:", ":flag_Rwanda:"}, + "\U0001f1f8\U0001f1e6": {":flag-sa:", ":flag_sa:", ":saudi_arabia:", ":flag_Saudi_Arabia:"}, + "\U0001f1f8\U0001f1e7": {":flag-sb:", ":flag_sb:", ":solomon_islands:", ":flag_Solomon_Islands:"}, + "\U0001f1f8\U0001f1e8": {":flag-sc:", ":flag_sc:", ":seychelles:", ":flag_Seychelles:"}, + "\U0001f1f8\U0001f1e9": {":sudan:", ":flag-sd:", ":flag_sd:", ":flag_Sudan:"}, + "\U0001f1f8\U0001f1ea": {":sweden:", ":flag-se:", ":flag_se:", ":flag_Sweden:"}, + "\U0001f1f8\U0001f1ec": {":flag-sg:", ":flag_sg:", ":singapore:", ":flag_Singapore:"}, + "\U0001f1f8\U0001f1ed": {":flag-sh:", ":flag_sh:", ":st_helena:", ":flag_St._Helena:"}, + "\U0001f1f8\U0001f1ee": {":flag-si:", ":flag_si:", ":slovenia:", ":flag_Slovenia:"}, + "\U0001f1f8\U0001f1ef": {":flag-sj:", ":flag_sj:", ":svalbard_jan_mayen:", ":flag_Svalbard_&_Jan_Mayen:"}, + "\U0001f1f8\U0001f1f0": {":flag-sk:", ":flag_sk:", ":slovakia:", ":flag_Slovakia:"}, + "\U0001f1f8\U0001f1f1": {":flag-sl:", ":flag_sl:", ":sierra_leone:", ":flag_Sierra_Leone:"}, + "\U0001f1f8\U0001f1f2": {":flag-sm:", ":flag_sm:", ":san_marino:", ":flag_San_Marino:"}, + "\U0001f1f8\U0001f1f3": {":flag-sn:", ":flag_sn:", ":senegal:", ":flag_Senegal:"}, + "\U0001f1f8\U0001f1f4": {":flag-so:", ":flag_so:", ":somalia:", ":flag_Somalia:"}, + "\U0001f1f8\U0001f1f7": {":flag-sr:", ":flag_sr:", ":suriname:", ":flag_Suriname:"}, + "\U0001f1f8\U0001f1f8": {":flag-ss:", ":flag_ss:", ":south_sudan:", ":flag_South_Sudan:"}, + "\U0001f1f8\U0001f1f9": {":flag-st:", ":flag_st:", ":sao_tome_principe:", ":flag_São_Tomé_&_Príncipe:"}, + "\U0001f1f8\U0001f1fb": {":flag-sv:", ":flag_sv:", ":el_salvador:", ":flag_El_Salvador:"}, + "\U0001f1f8\U0001f1fd": {":flag-sx:", ":flag_sx:", ":sint_maarten:", ":flag_Sint_Maarten:"}, + "\U0001f1f8\U0001f1fe": {":syria:", ":flag-sy:", ":flag_sy:", ":flag_Syria:"}, + "\U0001f1f8\U0001f1ff": {":flag-sz:", ":flag_sz:", ":swaziland:", ":flag_Eswatini:"}, + "\U0001f1f9\U0001f1e6": {":flag-ta:", ":flag_ta:", ":tristan_da_cunha:", ":flag_Tristan_da_Cunha:"}, + "\U0001f1f9\U0001f1e8": {":flag-tc:", ":flag_tc:", ":turks_caicos_islands:", ":flag_Turks_&_Caicos_Islands:"}, + "\U0001f1f9\U0001f1e9": {":chad:", ":flag-td:", ":flag_td:", ":flag_Chad:"}, + "\U0001f1f9\U0001f1eb": {":flag-tf:", ":flag_tf:", ":french_southern_territories:", ":flag_French_Southern_Territories:"}, + "\U0001f1f9\U0001f1ec": {":togo:", ":flag-tg:", ":flag_tg:", ":flag_Togo:"}, + "\U0001f1f9\U0001f1ed": {":flag-th:", ":flag_th:", ":thailand:", ":flag_Thailand:"}, + "\U0001f1f9\U0001f1ef": {":flag-tj:", ":flag_tj:", ":tajikistan:", ":flag_Tajikistan:"}, + "\U0001f1f9\U0001f1f0": {":flag-tk:", ":flag_tk:", ":tokelau:", ":flag_Tokelau:"}, + "\U0001f1f9\U0001f1f1": {":flag-tl:", ":flag_tl:", ":timor_leste:", ":flag_Timor-Leste:"}, + "\U0001f1f9\U0001f1f2": {":flag-tm:", ":flag_tm:", ":turkmenistan:", ":flag_Turkmenistan:"}, + "\U0001f1f9\U0001f1f3": {":flag-tn:", ":flag_tn:", ":tunisia:", ":flag_Tunisia:"}, + "\U0001f1f9\U0001f1f4": {":tonga:", ":flag-to:", ":flag_to:", ":flag_Tonga:"}, + "\U0001f1f9\U0001f1f7": {":tr:", ":flag-tr:", ":flag_tr:", ":flag_Turkey:"}, + "\U0001f1f9\U0001f1f9": {":flag-tt:", ":flag_tt:", ":trinidad_tobago:", ":flag_Trinidad_&_Tobago:"}, + "\U0001f1f9\U0001f1fb": {":tuvalu:", ":flag-tv:", ":flag_tv:", ":flag_Tuvalu:"}, + "\U0001f1f9\U0001f1fc": {":taiwan:", ":flag-tw:", ":flag_tw:", ":flag_Taiwan:"}, + "\U0001f1f9\U0001f1ff": {":flag-tz:", ":flag_tz:", ":tanzania:", ":flag_Tanzania:"}, + "\U0001f1fa\U0001f1e6": {":flag-ua:", ":flag_ua:", ":ukraine:", ":flag_Ukraine:"}, + "\U0001f1fa\U0001f1ec": {":uganda:", ":flag-ug:", ":flag_ug:", ":flag_Uganda:"}, + "\U0001f1fa\U0001f1f2": {":flag-um:", ":flag_um:", ":us_outlying_islands:", ":flag_U.S._Outlying_Islands:"}, + "\U0001f1fa\U0001f1f3": {":flag-un:", ":united_nations:", ":flag_United_Nations:"}, + "\U0001f1fa\U0001f1f8": {":us:", ":flag_us:", ":flag_United_States:"}, + "\U0001f1fa\U0001f1fe": {":flag-uy:", ":flag_uy:", ":uruguay:", ":flag_Uruguay:"}, + "\U0001f1fa\U0001f1ff": {":flag-uz:", ":flag_uz:", ":uzbekistan:", ":flag_Uzbekistan:"}, + "\U0001f1fb\U0001f1e6": {":flag-va:", ":flag_va:", ":vatican_city:", ":flag_Vatican_City:"}, + "\U0001f1fb\U0001f1e8": {":flag-vc:", ":flag_vc:", ":st_vincent_grenadines:", ":flag_St._Vincent_&_Grenadines:"}, + "\U0001f1fb\U0001f1ea": {":flag-ve:", ":flag_ve:", ":venezuela:", ":flag_Venezuela:"}, + "\U0001f1fb\U0001f1ec": {":flag-vg:", ":flag_vg:", ":british_virgin_islands:", ":flag_British_Virgin_Islands:"}, + "\U0001f1fb\U0001f1ee": {":flag-vi:", ":flag_vi:", ":us_virgin_islands:", ":flag_U.S._Virgin_Islands:"}, + "\U0001f1fb\U0001f1f3": {":flag-vn:", ":flag_vn:", ":vietnam:", ":flag_Vietnam:"}, + "\U0001f1fb\U0001f1fa": {":flag-vu:", ":flag_vu:", ":vanuatu:", ":flag_Vanuatu:"}, + "\U0001f1fc\U0001f1eb": {":flag-wf:", ":flag_wf:", ":wallis_futuna:", ":flag_Wallis_&_Futuna:"}, + "\U0001f1fc\U0001f1f8": {":samoa:", ":flag-ws:", ":flag_ws:", ":flag_Samoa:"}, + "\U0001f1fd\U0001f1f0": {":kosovo:", ":flag-xk:", ":flag_xk:", ":flag_Kosovo:"}, + "\U0001f1fe\U0001f1ea": {":yemen:", ":flag-ye:", ":flag_ye:", ":flag_Yemen:"}, + "\U0001f1fe\U0001f1f9": {":flag-yt:", ":flag_yt:", ":mayotte:", ":flag_Mayotte:"}, + "\U0001f1ff\U0001f1e6": {":flag-za:", ":flag_za:", ":south_africa:", ":flag_South_Africa:"}, + "\U0001f1ff\U0001f1f2": {":zambia:", ":flag-zm:", ":flag_zm:", ":flag_Zambia:"}, + "\U0001f1ff\U0001f1fc": {":flag-zw:", ":flag_zw:", ":zimbabwe:", ":flag_Zimbabwe:"}, + "\U0001f201": {":koko:", ":Japanese_here_button:"}, + "\U0001f202": {":Japanese_service_charge_button:"}, + "\U0001f202\ufe0f": {":sa:"}, + "\U0001f21a": {":u7121:", ":Japanese_free_of_charge_button:"}, + "\U0001f22f": {":u6307:", ":Japanese_reserved_button:"}, + "\U0001f232": {":u7981:", ":Japanese_prohibited_button:"}, + "\U0001f233": {":u7a7a:", ":Japanese_vacancy_button:"}, + "\U0001f234": {":u5408:", ":Japanese_passing_grade_button:"}, + "\U0001f235": {":u6e80:", ":Japanese_no_vacancy_button:"}, + "\U0001f236": {":u6709:", ":Japanese_not_free_of_charge_button:"}, + "\U0001f237": {":Japanese_monthly_amount_button:"}, + "\U0001f237\ufe0f": {":u6708:"}, + "\U0001f238": {":u7533:", ":Japanese_application_button:"}, + "\U0001f239": {":u5272:", ":Japanese_discount_button:"}, + "\U0001f23a": {":u55b6:", ":Japanese_open_for_business_button:"}, + "\U0001f250": {":ideograph_advantage:", ":Japanese_bargain_button:"}, + "\U0001f251": {":accept:", ":Japanese_acceptable_button:"}, + "\U0001f300": {":cyclone:"}, + "\U0001f301": {":foggy:"}, + "\U0001f302": {":closed_umbrella:"}, + "\U0001f303": {":night_with_stars:"}, + "\U0001f304": {":sunrise_over_mountains:"}, + "\U0001f305": {":sunrise:"}, + "\U0001f306": {":city_dusk:", ":city_sunset:", ":cityscape_at_dusk:"}, + "\U0001f307": {":sunset:", ":city_sunrise:"}, + "\U0001f308": {":rainbow:"}, + "\U0001f309": {":bridge_at_night:"}, + "\U0001f30a": {":ocean:", ":water_wave:"}, + "\U0001f30b": {":volcano:"}, + "\U0001f30c": {":milky_way:"}, + "\U0001f30d": {":earth_africa:", ":globe_showing_Europe-Africa:"}, + "\U0001f30e": {":earth_americas:", ":globe_showing_Americas:"}, + "\U0001f30f": {":earth_asia:", ":globe_showing_Asia-Australia:"}, + "\U0001f310": {":globe_with_meridians:"}, + "\U0001f311": {":new_moon:"}, + "\U0001f312": {":waxing_crescent_moon:"}, + "\U0001f313": {":first_quarter_moon:"}, + "\U0001f314": {":moon:", ":waxing_gibbous_moon:"}, + "\U0001f315": {":full_moon:"}, + "\U0001f316": {":waning_gibbous_moon:"}, + "\U0001f317": {":last_quarter_moon:"}, + "\U0001f318": {":waning_crescent_moon:"}, + "\U0001f319": {":crescent_moon:"}, + "\U0001f31a": {":new_moon_face:", ":new_moon_with_face:"}, + "\U0001f31b": {":first_quarter_moon_face:", ":first_quarter_moon_with_face:"}, + "\U0001f31c": {":last_quarter_moon_face:", ":last_quarter_moon_with_face:"}, + "\U0001f31d": {":full_moon_face:", ":full_moon_with_face:"}, + "\U0001f31e": {":sun_with_face:"}, + "\U0001f31f": {":star2:", ":glowing_star:"}, + "\U0001f320": {":stars:", ":shooting_star:"}, + "\U0001f321\ufe0f": {":thermometer:"}, + "\U0001f324": {":white_sun_small_cloud:", ":sun_behind_small_cloud:"}, + "\U0001f324\ufe0f": {":mostly_sunny:"}, + "\U0001f325": {":white_sun_cloud:", ":sun_behind_large_cloud:"}, + "\U0001f325\ufe0f": {":barely_sunny:"}, + "\U0001f326": {":white_sun_rain_cloud:", ":sun_behind_rain_cloud:"}, + "\U0001f326\ufe0f": {":partly_sunny_rain:"}, + "\U0001f327": {":cloud_rain:", ":cloud_with_rain:"}, + "\U0001f327\ufe0f": {":rain_cloud:"}, + "\U0001f328": {":cloud_snow:", ":cloud_with_snow:"}, + "\U0001f328\ufe0f": {":snow_cloud:"}, + "\U0001f329": {":cloud_lightning:", ":cloud_with_lightning:"}, + "\U0001f329\ufe0f": {":lightning:"}, + "\U0001f32a": {":cloud_tornado:"}, + "\U0001f32a\ufe0f": {":tornado:"}, + "\U0001f32b\ufe0f": {":fog:"}, + "\U0001f32c": {":wind_face:"}, + "\U0001f32c\ufe0f": {":wind_blowing_face:"}, + "\U0001f32d": {":hotdog:", ":hot_dog:"}, + "\U0001f32e": {":taco:"}, + "\U0001f32f": {":burrito:"}, + "\U0001f330": {":chestnut:"}, + "\U0001f331": {":seedling:"}, + "\U0001f332": {":evergreen_tree:"}, + "\U0001f333": {":deciduous_tree:"}, + "\U0001f334": {":palm_tree:"}, + "\U0001f335": {":cactus:"}, + "\U0001f336\ufe0f": {":hot_pepper:"}, + "\U0001f337": {":tulip:"}, + "\U0001f338": {":cherry_blossom:"}, + "\U0001f339": {":rose:"}, + "\U0001f33a": {":hibiscus:"}, + "\U0001f33b": {":sunflower:"}, + "\U0001f33c": {":blossom:"}, + "\U0001f33d": {":corn:", ":ear_of_corn:"}, + "\U0001f33e": {":ear_of_rice:", ":sheaf_of_rice:"}, + "\U0001f33f": {":herb:"}, + "\U0001f340": {":four_leaf_clover:"}, + "\U0001f341": {":maple_leaf:"}, + "\U0001f342": {":fallen_leaf:"}, + "\U0001f343": {":leaves:", ":leaf_fluttering_in_wind:"}, + "\U0001f344": {":mushroom:"}, + "\U0001f345": {":tomato:"}, + "\U0001f346": {":eggplant:"}, + "\U0001f347": {":grapes:"}, + "\U0001f348": {":melon:"}, + "\U0001f349": {":watermelon:"}, + "\U0001f34a": {":orange:", ":mandarin:", ":tangerine:"}, + "\U0001f34b": {":lemon:"}, + "\U0001f34c": {":banana:"}, + "\U0001f34d": {":pineapple:"}, + "\U0001f34e": {":apple:", ":red_apple:"}, + "\U0001f34f": {":green_apple:"}, + "\U0001f350": {":pear:"}, + "\U0001f351": {":peach:"}, + "\U0001f352": {":cherries:"}, + "\U0001f353": {":strawberry:"}, + "\U0001f354": {":hamburger:"}, + "\U0001f355": {":pizza:"}, + "\U0001f356": {":meat_on_bone:"}, + "\U0001f357": {":poultry_leg:"}, + "\U0001f358": {":rice_cracker:"}, + "\U0001f359": {":rice_ball:"}, + "\U0001f35a": {":rice:", ":cooked_rice:"}, + "\U0001f35b": {":curry:", ":curry_rice:"}, + "\U0001f35c": {":ramen:", ":steaming_bowl:"}, + "\U0001f35d": {":spaghetti:"}, + "\U0001f35e": {":bread:"}, + "\U0001f35f": {":fries:", ":french_fries:"}, + "\U0001f360": {":sweet_potato:", ":roasted_sweet_potato:"}, + "\U0001f361": {":dango:"}, + "\U0001f362": {":oden:"}, + "\U0001f363": {":sushi:"}, + "\U0001f364": {":fried_shrimp:"}, + "\U0001f365": {":fish_cake:", ":fish_cake_with_swirl:"}, + "\U0001f366": {":icecream:", ":soft_ice_cream:"}, + "\U0001f367": {":shaved_ice:"}, + "\U0001f368": {":ice_cream:"}, + "\U0001f369": {":doughnut:"}, + "\U0001f36a": {":cookie:"}, + "\U0001f36b": {":chocolate_bar:"}, + "\U0001f36c": {":candy:"}, + "\U0001f36d": {":lollipop:"}, + "\U0001f36e": {":custard:"}, + "\U0001f36f": {":honey_pot:"}, + "\U0001f370": {":cake:", ":shortcake:"}, + "\U0001f371": {":bento:", ":bento_box:"}, + "\U0001f372": {":stew:", ":pot_of_food:"}, + "\U0001f373": {":cooking:", ":fried_egg:"}, + "\U0001f374": {":fork_and_knife:"}, + "\U0001f375": {":tea:", ":teacup_without_handle:"}, + "\U0001f376": {":sake:"}, + "\U0001f377": {":wine_glass:"}, + "\U0001f378": {":cocktail:", ":cocktail_glass:"}, + "\U0001f379": {":tropical_drink:"}, + "\U0001f37a": {":beer:", ":beer_mug:"}, + "\U0001f37b": {":beers:", ":clinking_beer_mugs:"}, + "\U0001f37c": {":baby_bottle:"}, + "\U0001f37d": {":fork_knife_plate:", ":fork_and_knife_with_plate:"}, + "\U0001f37d\ufe0f": {":knife_fork_plate:", ":plate_with_cutlery:"}, + "\U0001f37e": {":champagne:", ":bottle_with_popping_cork:"}, + "\U0001f37f": {":popcorn:"}, + "\U0001f380": {":ribbon:"}, + "\U0001f381": {":gift:", ":wrapped_gift:"}, + "\U0001f382": {":birthday:", ":birthday_cake:"}, + "\U0001f383": {":jack-o-lantern:", ":jack_o_lantern:"}, + "\U0001f384": {":Christmas_tree:", ":christmas_tree:"}, + "\U0001f385": {":santa:", ":Santa_Claus:"}, + "\U0001f385\U0001f3fb": {":santa_tone1:"}, + "\U0001f385\U0001f3fc": {":santa_tone2:"}, + "\U0001f385\U0001f3fd": {":santa_tone3:"}, + "\U0001f385\U0001f3fe": {":santa_tone4:"}, + "\U0001f385\U0001f3ff": {":santa_tone5:"}, + "\U0001f386": {":fireworks:"}, + "\U0001f387": {":sparkler:"}, + "\U0001f388": {":balloon:"}, + "\U0001f389": {":tada:", ":party_popper:"}, + "\U0001f38a": {":confetti_ball:"}, + "\U0001f38b": {":tanabata_tree:"}, + "\U0001f38c": {":crossed_flags:"}, + "\U0001f38d": {":bamboo:", ":pine_decoration:"}, + "\U0001f38e": {":dolls:", ":Japanese_dolls:"}, + "\U0001f38f": {":flags:", ":carp_streamer:"}, + "\U0001f390": {":wind_chime:"}, + "\U0001f391": {":rice_scene:", ":moon_viewing_ceremony:"}, + "\U0001f392": {":backpack:", ":school_satchel:"}, + "\U0001f393": {":mortar_board:", ":graduation_cap:"}, + "\U0001f396": {":military_medal:"}, + "\U0001f396\ufe0f": {":medal:", ":medal_military:"}, + "\U0001f397\ufe0f": {":reminder_ribbon:"}, + "\U0001f399": {":microphone2:"}, + "\U0001f399\ufe0f": {":studio_microphone:"}, + "\U0001f39a\ufe0f": {":level_slider:"}, + "\U0001f39b\ufe0f": {":control_knobs:"}, + "\U0001f39e\ufe0f": {":film_strip:", ":film_frames:"}, + "\U0001f39f": {":tickets:"}, + "\U0001f39f\ufe0f": {":admission_tickets:"}, + "\U0001f3a0": {":carousel_horse:"}, + "\U0001f3a1": {":ferris_wheel:"}, + "\U0001f3a2": {":roller_coaster:"}, + "\U0001f3a3": {":fishing_pole:", ":fishing_pole_and_fish:"}, + "\U0001f3a4": {":microphone:"}, + "\U0001f3a5": {":movie_camera:"}, + "\U0001f3a6": {":cinema:"}, + "\U0001f3a7": {":headphone:", ":headphones:"}, + "\U0001f3a8": {":art:", ":artist_palette:"}, + "\U0001f3a9": {":tophat:", ":top_hat:"}, + "\U0001f3aa": {":circus_tent:"}, + "\U0001f3ab": {":ticket:"}, + "\U0001f3ac": {":clapper:", ":clapper_board:"}, + "\U0001f3ad": {":performing_arts:"}, + "\U0001f3ae": {":video_game:"}, + "\U0001f3af": {":dart:", ":direct_hit:"}, + "\U0001f3b0": {":slot_machine:"}, + "\U0001f3b1": {":8ball:", ":pool_8_ball:"}, + "\U0001f3b2": {":game_die:"}, + "\U0001f3b3": {":bowling:"}, + "\U0001f3b4": {":flower_playing_cards:"}, + "\U0001f3b5": {":musical_note:"}, + "\U0001f3b6": {":notes:", ":musical_notes:"}, + "\U0001f3b7": {":saxophone:"}, + "\U0001f3b8": {":guitar:"}, + "\U0001f3b9": {":musical_keyboard:"}, + "\U0001f3ba": {":trumpet:"}, + "\U0001f3bb": {":violin:"}, + "\U0001f3bc": {":musical_score:"}, + "\U0001f3bd": {":running_shirt:", ":running_shirt_with_sash:"}, + "\U0001f3be": {":tennis:"}, + "\U0001f3bf": {":ski:", ":skis:"}, + "\U0001f3c0": {":basketball:"}, + "\U0001f3c1": {":checkered_flag:", ":chequered_flag:"}, + "\U0001f3c2": {":snowboarder:"}, + "\U0001f3c2\U0001f3fb": {":snowboarder_tone1:"}, + "\U0001f3c2\U0001f3fc": {":snowboarder_tone2:"}, + "\U0001f3c2\U0001f3fd": {":snowboarder_tone3:"}, + "\U0001f3c2\U0001f3fe": {":snowboarder_tone4:"}, + "\U0001f3c2\U0001f3ff": {":snowboarder_tone5:"}, + "\U0001f3c3": {":running:", ":person_running:"}, + "\U0001f3c3\U0001f3fb": {":person_running_tone1:"}, + "\U0001f3c3\U0001f3fb\u200d\u2640\ufe0f": {":woman_running_tone1:"}, + "\U0001f3c3\U0001f3fb\u200d\u2642\ufe0f": {":man_running_tone1:"}, + "\U0001f3c3\U0001f3fc": {":person_running_tone2:"}, + "\U0001f3c3\U0001f3fc\u200d\u2640\ufe0f": {":woman_running_tone2:"}, + "\U0001f3c3\U0001f3fc\u200d\u2642\ufe0f": {":man_running_tone2:"}, + "\U0001f3c3\U0001f3fd": {":person_running_tone3:"}, + "\U0001f3c3\U0001f3fd\u200d\u2640\ufe0f": {":woman_running_tone3:"}, + "\U0001f3c3\U0001f3fd\u200d\u2642\ufe0f": {":man_running_tone3:"}, + "\U0001f3c3\U0001f3fe": {":person_running_tone4:"}, + "\U0001f3c3\U0001f3fe\u200d\u2640\ufe0f": {":woman_running_tone4:"}, + "\U0001f3c3\U0001f3fe\u200d\u2642\ufe0f": {":man_running_tone4:"}, + "\U0001f3c3\U0001f3ff": {":person_running_tone5:"}, + "\U0001f3c3\U0001f3ff\u200d\u2640\ufe0f": {":woman_running_tone5:"}, + "\U0001f3c3\U0001f3ff\u200d\u2642\ufe0f": {":man_running_tone5:"}, + "\U0001f3c3\u200d\u2640\ufe0f": {":running_woman:", ":woman-running:", ":woman_running:"}, + "\U0001f3c3\u200d\u2642\ufe0f": {":runner:", ":man-running:", ":man_running:", ":running_man:"}, + "\U0001f3c4": {":person_surfing:"}, + "\U0001f3c4\U0001f3fb": {":person_surfing_tone1:"}, + "\U0001f3c4\U0001f3fb\u200d\u2640\ufe0f": {":woman_surfing_tone1:"}, + "\U0001f3c4\U0001f3fb\u200d\u2642\ufe0f": {":man_surfing_tone1:"}, + "\U0001f3c4\U0001f3fc": {":person_surfing_tone2:"}, + "\U0001f3c4\U0001f3fc\u200d\u2640\ufe0f": {":woman_surfing_tone2:"}, + "\U0001f3c4\U0001f3fc\u200d\u2642\ufe0f": {":man_surfing_tone2:"}, + "\U0001f3c4\U0001f3fd": {":person_surfing_tone3:"}, + "\U0001f3c4\U0001f3fd\u200d\u2640\ufe0f": {":woman_surfing_tone3:"}, + "\U0001f3c4\U0001f3fd\u200d\u2642\ufe0f": {":man_surfing_tone3:"}, + "\U0001f3c4\U0001f3fe": {":person_surfing_tone4:"}, + "\U0001f3c4\U0001f3fe\u200d\u2640\ufe0f": {":woman_surfing_tone4:"}, + "\U0001f3c4\U0001f3fe\u200d\u2642\ufe0f": {":man_surfing_tone4:"}, + "\U0001f3c4\U0001f3ff": {":person_surfing_tone5:"}, + "\U0001f3c4\U0001f3ff\u200d\u2640\ufe0f": {":woman_surfing_tone5:"}, + "\U0001f3c4\U0001f3ff\u200d\u2642\ufe0f": {":man_surfing_tone5:"}, + "\U0001f3c4\u200d\u2640\ufe0f": {":surfing_woman:", ":woman-surfing:", ":woman_surfing:"}, + "\U0001f3c4\u200d\u2642\ufe0f": {":surfer:", ":man-surfing:", ":man_surfing:", ":surfing_man:"}, + "\U0001f3c5": {":medal_sports:", ":sports_medal:"}, + "\U0001f3c6": {":trophy:"}, + "\U0001f3c7": {":horse_racing:"}, + "\U0001f3c7\U0001f3fb": {":horse_racing_tone1:"}, + "\U0001f3c7\U0001f3fc": {":horse_racing_tone2:"}, + "\U0001f3c7\U0001f3fd": {":horse_racing_tone3:"}, + "\U0001f3c7\U0001f3fe": {":horse_racing_tone4:"}, + "\U0001f3c7\U0001f3ff": {":horse_racing_tone5:"}, + "\U0001f3c8": {":football:", ":american_football:"}, + "\U0001f3c9": {":rugby_football:"}, + "\U0001f3ca": {":person_swimming:"}, + "\U0001f3ca\U0001f3fb": {":person_swimming_tone1:"}, + "\U0001f3ca\U0001f3fb\u200d\u2640\ufe0f": {":woman_swimming_tone1:"}, + "\U0001f3ca\U0001f3fb\u200d\u2642\ufe0f": {":man_swimming_tone1:"}, + "\U0001f3ca\U0001f3fc": {":person_swimming_tone2:"}, + "\U0001f3ca\U0001f3fc\u200d\u2640\ufe0f": {":woman_swimming_tone2:"}, + "\U0001f3ca\U0001f3fc\u200d\u2642\ufe0f": {":man_swimming_tone2:"}, + "\U0001f3ca\U0001f3fd": {":person_swimming_tone3:"}, + "\U0001f3ca\U0001f3fd\u200d\u2640\ufe0f": {":woman_swimming_tone3:"}, + "\U0001f3ca\U0001f3fd\u200d\u2642\ufe0f": {":man_swimming_tone3:"}, + "\U0001f3ca\U0001f3fe": {":person_swimming_tone4:"}, + "\U0001f3ca\U0001f3fe\u200d\u2640\ufe0f": {":woman_swimming_tone4:"}, + "\U0001f3ca\U0001f3fe\u200d\u2642\ufe0f": {":man_swimming_tone4:"}, + "\U0001f3ca\U0001f3ff": {":person_swimming_tone5:"}, + "\U0001f3ca\U0001f3ff\u200d\u2640\ufe0f": {":woman_swimming_tone5:"}, + "\U0001f3ca\U0001f3ff\u200d\u2642\ufe0f": {":man_swimming_tone5:"}, + "\U0001f3ca\u200d\u2640\ufe0f": {":swimming_woman:", ":woman-swimming:", ":woman_swimming:"}, + "\U0001f3ca\u200d\u2642\ufe0f": {":swimmer:", ":man-swimming:", ":man_swimming:", ":swimming_man:"}, + "\U0001f3cb": {":person_lifting_weights:"}, + "\U0001f3cb\U0001f3fb": {":person_lifting_weights_tone1:"}, + "\U0001f3cb\U0001f3fb\u200d\u2640\ufe0f": {":woman_lifting_weights_tone1:"}, + "\U0001f3cb\U0001f3fb\u200d\u2642\ufe0f": {":man_lifting_weights_tone1:"}, + "\U0001f3cb\U0001f3fc": {":person_lifting_weights_tone2:"}, + "\U0001f3cb\U0001f3fc\u200d\u2640\ufe0f": {":woman_lifting_weights_tone2:"}, + "\U0001f3cb\U0001f3fc\u200d\u2642\ufe0f": {":man_lifting_weights_tone2:"}, + "\U0001f3cb\U0001f3fd": {":person_lifting_weights_tone3:"}, + "\U0001f3cb\U0001f3fd\u200d\u2640\ufe0f": {":woman_lifting_weights_tone3:"}, + "\U0001f3cb\U0001f3fd\u200d\u2642\ufe0f": {":man_lifting_weights_tone3:"}, + "\U0001f3cb\U0001f3fe": {":person_lifting_weights_tone4:"}, + "\U0001f3cb\U0001f3fe\u200d\u2640\ufe0f": {":woman_lifting_weights_tone4:"}, + "\U0001f3cb\U0001f3fe\u200d\u2642\ufe0f": {":man_lifting_weights_tone4:"}, + "\U0001f3cb\U0001f3ff": {":person_lifting_weights_tone5:"}, + "\U0001f3cb\U0001f3ff\u200d\u2640\ufe0f": {":woman_lifting_weights_tone5:"}, + "\U0001f3cb\U0001f3ff\u200d\u2642\ufe0f": {":man_lifting_weights_tone5:"}, + "\U0001f3cb\ufe0f": {":weight_lifting:"}, + "\U0001f3cb\ufe0f\u200d\u2640\ufe0f": {":weight_lifting_woman:", ":woman-lifting-weights:", ":woman_lifting_weights:"}, + "\U0001f3cb\ufe0f\u200d\u2642\ufe0f": {":weight_lifter:", ":weight_lifting_man:", ":man-lifting-weights:", ":man_lifting_weights:"}, + "\U0001f3cc": {":person_golfing:"}, + "\U0001f3cc\U0001f3fb": {":person_golfing_tone1:"}, + "\U0001f3cc\U0001f3fb\u200d\u2640\ufe0f": {":woman_golfing_tone1:"}, + "\U0001f3cc\U0001f3fb\u200d\u2642\ufe0f": {":man_golfing_tone1:"}, + "\U0001f3cc\U0001f3fc": {":person_golfing_tone2:"}, + "\U0001f3cc\U0001f3fc\u200d\u2640\ufe0f": {":woman_golfing_tone2:"}, + "\U0001f3cc\U0001f3fc\u200d\u2642\ufe0f": {":man_golfing_tone2:"}, + "\U0001f3cc\U0001f3fd": {":person_golfing_tone3:"}, + "\U0001f3cc\U0001f3fd\u200d\u2640\ufe0f": {":woman_golfing_tone3:"}, + "\U0001f3cc\U0001f3fd\u200d\u2642\ufe0f": {":man_golfing_tone3:"}, + "\U0001f3cc\U0001f3fe": {":person_golfing_tone4:"}, + "\U0001f3cc\U0001f3fe\u200d\u2640\ufe0f": {":woman_golfing_tone4:"}, + "\U0001f3cc\U0001f3fe\u200d\u2642\ufe0f": {":man_golfing_tone4:"}, + "\U0001f3cc\U0001f3ff": {":person_golfing_tone5:"}, + "\U0001f3cc\U0001f3ff\u200d\u2640\ufe0f": {":woman_golfing_tone5:"}, + "\U0001f3cc\U0001f3ff\u200d\u2642\ufe0f": {":man_golfing_tone5:"}, + "\U0001f3cc\ufe0f": {":golfing:"}, + "\U0001f3cc\ufe0f\u200d\u2640\ufe0f": {":golfing_woman:", ":woman-golfing:", ":woman_golfing:"}, + "\U0001f3cc\ufe0f\u200d\u2642\ufe0f": {":golfer:", ":golfing_man:", ":man-golfing:", ":man_golfing:"}, + "\U0001f3cd": {":motorcycle:"}, + "\U0001f3cd\ufe0f": {":racing_motorcycle:"}, + "\U0001f3ce": {":race_car:"}, + "\U0001f3ce\ufe0f": {":racing_car:"}, + "\U0001f3cf": {":cricket_game:", ":cricket_bat_and_ball:"}, + "\U0001f3d0": {":volleyball:"}, + "\U0001f3d1": {":field_hockey:", ":field_hockey_stick_and_ball:"}, + "\U0001f3d2": {":hockey:", ":ice_hockey:", ":ice_hockey_stick_and_puck:"}, + "\U0001f3d3": {":ping_pong:", ":table_tennis_paddle_and_ball:"}, + "\U0001f3d4": {":mountain_snow:", ":snow-capped_mountain:"}, + "\U0001f3d4\ufe0f": {":snow_capped_mountain:"}, + "\U0001f3d5\ufe0f": {":camping:"}, + "\U0001f3d6": {":beach:"}, + "\U0001f3d6\ufe0f": {":beach_with_umbrella:"}, + "\U0001f3d7": {":construction_site:"}, + "\U0001f3d7\ufe0f": {":building_construction:"}, + "\U0001f3d8": {":homes:", ":houses:"}, + "\U0001f3d8\ufe0f": {":house_buildings:"}, + "\U0001f3d9\ufe0f": {":cityscape:"}, + "\U0001f3da": {":derelict_house:", ":house_abandoned:"}, + "\U0001f3da\ufe0f": {":derelict_house_building:"}, + "\U0001f3db\ufe0f": {":classical_building:"}, + "\U0001f3dc\ufe0f": {":desert:"}, + "\U0001f3dd": {":island:"}, + "\U0001f3dd\ufe0f": {":desert_island:"}, + "\U0001f3de": {":park:"}, + "\U0001f3de\ufe0f": {":national_park:"}, + "\U0001f3df\ufe0f": {":stadium:"}, + "\U0001f3e0": {":house:"}, + "\U0001f3e1": {":house_with_garden:"}, + "\U0001f3e2": {":office:", ":office_building:"}, + "\U0001f3e3": {":post_office:", ":Japanese_post_office:"}, + "\U0001f3e4": {":european_post_office:"}, + "\U0001f3e5": {":hospital:"}, + "\U0001f3e6": {":bank:"}, + "\U0001f3e7": {":atm:", ":ATM_sign:"}, + "\U0001f3e8": {":hotel:"}, + "\U0001f3e9": {":love_hotel:"}, + "\U0001f3ea": {":convenience_store:"}, + "\U0001f3eb": {":school:"}, + "\U0001f3ec": {":department_store:"}, + "\U0001f3ed": {":factory:"}, + "\U0001f3ee": {":lantern:", ":izakaya_lantern:", ":red_paper_lantern:"}, + "\U0001f3ef": {":Japanese_castle:", ":japanese_castle:"}, + "\U0001f3f0": {":castle:", ":european_castle:"}, + "\U0001f3f3": {":flag_white:", ":white_flag:"}, + "\U0001f3f3\ufe0f": {":waving_white_flag:"}, + "\U0001f3f3\ufe0f\u200d\U0001f308": {":rainbow-flag:", ":rainbow_flag:"}, + "\U0001f3f3\ufe0f\u200d\u26a7\ufe0f": {":transgender_flag:"}, + "\U0001f3f4": {":black_flag:", ":flag_black:", ":waving_black_flag:"}, + "\U0001f3f4\U000e0067\U000e0062\U000e0065\U000e006e\U000e0067\U000e007f": {":england:", ":flag-england:", ":flag_England:"}, + "\U0001f3f4\U000e0067\U000e0062\U000e0073\U000e0063\U000e0074\U000e007f": {":scotland:", ":flag-scotland:", ":flag_Scotland:"}, + "\U0001f3f4\U000e0067\U000e0062\U000e0077\U000e006c\U000e0073\U000e007f": {":wales:", ":flag-wales:", ":flag_Wales:"}, + "\U0001f3f4\u200d\u2620\ufe0f": {":pirate_flag:"}, + "\U0001f3f5\ufe0f": {":rosette:"}, + "\U0001f3f7\ufe0f": {":label:"}, + "\U0001f3f8": {":badminton:", ":badminton_racquet_and_shuttlecock:"}, + "\U0001f3f9": {":bow_and_arrow:"}, + "\U0001f3fa": {":amphora:"}, + "\U0001f3fb": {":skin-tone-2:"}, + "\U0001f3fc": {":skin-tone-3:"}, + "\U0001f3fd": {":skin-tone-4:"}, + "\U0001f3fe": {":skin-tone-5:"}, + "\U0001f3ff": {":skin-tone-6:"}, + "\U0001f400": {":rat:"}, + "\U0001f401": {":mouse2:"}, + "\U0001f402": {":ox:"}, + "\U0001f403": {":water_buffalo:"}, + "\U0001f404": {":cow2:"}, + "\U0001f405": {":tiger2:"}, + "\U0001f406": {":leopard:"}, + "\U0001f407": {":rabbit2:"}, + "\U0001f408": {":cat2:"}, + "\U0001f408\u200d\u2b1b": {":black_cat:"}, + "\U0001f409": {":dragon:"}, + "\U0001f40a": {":crocodile:"}, + "\U0001f40b": {":whale2:"}, + "\U0001f40c": {":snail:"}, + "\U0001f40d": {":snake:"}, + "\U0001f40e": {":racehorse:"}, + "\U0001f40f": {":ram:"}, + "\U0001f410": {":goat:"}, + "\U0001f411": {":ewe:", ":sheep:"}, + "\U0001f412": {":monkey:"}, + "\U0001f413": {":rooster:"}, + "\U0001f414": {":chicken:"}, + "\U0001f415": {":dog2:"}, + "\U0001f415\u200d\U0001f9ba": {":service_dog:"}, + "\U0001f416": {":pig2:"}, + "\U0001f417": {":boar:"}, + "\U0001f418": {":elephant:"}, + "\U0001f419": {":octopus:"}, + "\U0001f41a": {":shell:", ":spiral_shell:"}, + "\U0001f41b": {":bug:"}, + "\U0001f41c": {":ant:"}, + "\U0001f41d": {":bee:", ":honeybee:"}, + "\U0001f41e": {":beetle:", ":lady_beetle:"}, + "\U0001f41f": {":fish:"}, + "\U0001f420": {":tropical_fish:"}, + "\U0001f421": {":blowfish:"}, + "\U0001f422": {":turtle:"}, + "\U0001f423": {":hatching_chick:"}, + "\U0001f424": {":baby_chick:"}, + "\U0001f425": {":hatched_chick:", ":front-facing_baby_chick:"}, + "\U0001f426": {":bird:"}, + "\U0001f427": {":penguin:"}, + "\U0001f428": {":koala:"}, + "\U0001f429": {":poodle:"}, + "\U0001f42a": {":dromedary_camel:"}, + "\U0001f42b": {":camel:", ":two-hump_camel:"}, + "\U0001f42c": {":dolphin:", ":flipper:"}, + "\U0001f42d": {":mouse:", ":mouse_face:"}, + "\U0001f42e": {":cow:", ":cow_face:"}, + "\U0001f42f": {":tiger:", ":tiger_face:"}, + "\U0001f430": {":rabbit:", ":rabbit_face:"}, + "\U0001f431": {":cat:", ":cat_face:"}, + "\U0001f432": {":dragon_face:"}, + "\U0001f433": {":whale:", ":spouting_whale:"}, + "\U0001f434": {":horse:", ":horse_face:"}, + "\U0001f435": {":monkey_face:"}, + "\U0001f436": {":dog:", ":dog_face:"}, + "\U0001f437": {":pig:", ":pig_face:"}, + "\U0001f438": {":frog:"}, + "\U0001f439": {":hamster:"}, + "\U0001f43a": {":wolf:"}, + "\U0001f43b": {":bear:"}, + "\U0001f43b\u200d\u2744\ufe0f": {":polar_bear:"}, + "\U0001f43c": {":panda:", ":panda_face:"}, + "\U0001f43d": {":pig_nose:"}, + "\U0001f43e": {":feet:", ":paw_prints:"}, + "\U0001f43f\ufe0f": {":chipmunk:"}, + "\U0001f440": {":eyes:"}, + "\U0001f441\ufe0f": {":eye:"}, + "\U0001f441\ufe0f\u200d\U0001f5e8\ufe0f": {":eye_speech_bubble:", ":eye-in-speech-bubble:", ":eye_in_speech_bubble:"}, + "\U0001f442": {":ear:"}, + "\U0001f442\U0001f3fb": {":ear_tone1:"}, + "\U0001f442\U0001f3fc": {":ear_tone2:"}, + "\U0001f442\U0001f3fd": {":ear_tone3:"}, + "\U0001f442\U0001f3fe": {":ear_tone4:"}, + "\U0001f442\U0001f3ff": {":ear_tone5:"}, + "\U0001f443": {":nose:"}, + "\U0001f443\U0001f3fb": {":nose_tone1:"}, + "\U0001f443\U0001f3fc": {":nose_tone2:"}, + "\U0001f443\U0001f3fd": {":nose_tone3:"}, + "\U0001f443\U0001f3fe": {":nose_tone4:"}, + "\U0001f443\U0001f3ff": {":nose_tone5:"}, + "\U0001f444": {":lips:", ":mouth:"}, + "\U0001f445": {":tongue:"}, + "\U0001f446": {":point_up_2:", ":backhand_index_pointing_up:"}, + "\U0001f446\U0001f3fb": {":point_up_2_tone1:"}, + "\U0001f446\U0001f3fc": {":point_up_2_tone2:"}, + "\U0001f446\U0001f3fd": {":point_up_2_tone3:"}, + "\U0001f446\U0001f3fe": {":point_up_2_tone4:"}, + "\U0001f446\U0001f3ff": {":point_up_2_tone5:"}, + "\U0001f447": {":point_down:", ":backhand_index_pointing_down:"}, + "\U0001f447\U0001f3fb": {":point_down_tone1:"}, + "\U0001f447\U0001f3fc": {":point_down_tone2:"}, + "\U0001f447\U0001f3fd": {":point_down_tone3:"}, + "\U0001f447\U0001f3fe": {":point_down_tone4:"}, + "\U0001f447\U0001f3ff": {":point_down_tone5:"}, + "\U0001f448": {":point_left:", ":backhand_index_pointing_left:"}, + "\U0001f448\U0001f3fb": {":point_left_tone1:"}, + "\U0001f448\U0001f3fc": {":point_left_tone2:"}, + "\U0001f448\U0001f3fd": {":point_left_tone3:"}, + "\U0001f448\U0001f3fe": {":point_left_tone4:"}, + "\U0001f448\U0001f3ff": {":point_left_tone5:"}, + "\U0001f449": {":point_right:", ":backhand_index_pointing_right:"}, + "\U0001f449\U0001f3fb": {":point_right_tone1:"}, + "\U0001f449\U0001f3fc": {":point_right_tone2:"}, + "\U0001f449\U0001f3fd": {":point_right_tone3:"}, + "\U0001f449\U0001f3fe": {":point_right_tone4:"}, + "\U0001f449\U0001f3ff": {":point_right_tone5:"}, + "\U0001f44a": {":punch:", ":facepunch:", ":fist_oncoming:", ":oncoming_fist:"}, + "\U0001f44a\U0001f3fb": {":punch_tone1:"}, + "\U0001f44a\U0001f3fc": {":punch_tone2:"}, + "\U0001f44a\U0001f3fd": {":punch_tone3:"}, + "\U0001f44a\U0001f3fe": {":punch_tone4:"}, + "\U0001f44a\U0001f3ff": {":punch_tone5:"}, + "\U0001f44b": {":wave:", ":waving_hand:"}, + "\U0001f44b\U0001f3fb": {":wave_tone1:"}, + "\U0001f44b\U0001f3fc": {":wave_tone2:"}, + "\U0001f44b\U0001f3fd": {":wave_tone3:"}, + "\U0001f44b\U0001f3fe": {":wave_tone4:"}, + "\U0001f44b\U0001f3ff": {":wave_tone5:"}, + "\U0001f44c": {":OK_hand:", ":ok_hand:"}, + "\U0001f44c\U0001f3fb": {":ok_hand_tone1:"}, + "\U0001f44c\U0001f3fc": {":ok_hand_tone2:"}, + "\U0001f44c\U0001f3fd": {":ok_hand_tone3:"}, + "\U0001f44c\U0001f3fe": {":ok_hand_tone4:"}, + "\U0001f44c\U0001f3ff": {":ok_hand_tone5:"}, + "\U0001f44d": {":+1:", ":thumbsup:", ":thumbs_up:"}, + "\U0001f44d\U0001f3fb": {":thumbsup_tone1:"}, + "\U0001f44d\U0001f3fc": {":thumbsup_tone2:"}, + "\U0001f44d\U0001f3fd": {":thumbsup_tone3:"}, + "\U0001f44d\U0001f3fe": {":thumbsup_tone4:"}, + "\U0001f44d\U0001f3ff": {":thumbsup_tone5:"}, + "\U0001f44e": {":-1:", ":thumbsdown:", ":thumbs_down:"}, + "\U0001f44e\U0001f3fb": {":thumbsdown_tone1:"}, + "\U0001f44e\U0001f3fc": {":thumbsdown_tone2:"}, + "\U0001f44e\U0001f3fd": {":thumbsdown_tone3:"}, + "\U0001f44e\U0001f3fe": {":thumbsdown_tone4:"}, + "\U0001f44e\U0001f3ff": {":thumbsdown_tone5:"}, + "\U0001f44f": {":clap:", ":clapping_hands:"}, + "\U0001f44f\U0001f3fb": {":clap_tone1:"}, + "\U0001f44f\U0001f3fc": {":clap_tone2:"}, + "\U0001f44f\U0001f3fd": {":clap_tone3:"}, + "\U0001f44f\U0001f3fe": {":clap_tone4:"}, + "\U0001f44f\U0001f3ff": {":clap_tone5:"}, + "\U0001f450": {":open_hands:"}, + "\U0001f450\U0001f3fb": {":open_hands_tone1:"}, + "\U0001f450\U0001f3fc": {":open_hands_tone2:"}, + "\U0001f450\U0001f3fd": {":open_hands_tone3:"}, + "\U0001f450\U0001f3fe": {":open_hands_tone4:"}, + "\U0001f450\U0001f3ff": {":open_hands_tone5:"}, + "\U0001f451": {":crown:"}, + "\U0001f452": {":womans_hat:", ":woman’s_hat:"}, + "\U0001f453": {":glasses:", ":eyeglasses:"}, + "\U0001f454": {":necktie:"}, + "\U0001f455": {":shirt:", ":tshirt:", ":t-shirt:"}, + "\U0001f456": {":jeans:"}, + "\U0001f457": {":dress:"}, + "\U0001f458": {":kimono:"}, + "\U0001f459": {":bikini:"}, + "\U0001f45a": {":womans_clothes:", ":woman’s_clothes:"}, + "\U0001f45b": {":purse:"}, + "\U0001f45c": {":handbag:"}, + "\U0001f45d": {":pouch:", ":clutch_bag:"}, + "\U0001f45e": {":shoe:", ":mans_shoe:", ":man’s_shoe:"}, + "\U0001f45f": {":running_shoe:", ":athletic_shoe:"}, + "\U0001f460": {":high_heel:", ":high-heeled_shoe:"}, + "\U0001f461": {":sandal:", ":woman’s_sandal:"}, + "\U0001f462": {":boot:", ":woman’s_boot:"}, + "\U0001f463": {":footprints:"}, + "\U0001f464": {":bust_in_silhouette:"}, + "\U0001f465": {":busts_in_silhouette:"}, + "\U0001f466": {":boy:"}, + "\U0001f466\U0001f3fb": {":boy_tone1:"}, + "\U0001f466\U0001f3fc": {":boy_tone2:"}, + "\U0001f466\U0001f3fd": {":boy_tone3:"}, + "\U0001f466\U0001f3fe": {":boy_tone4:"}, + "\U0001f466\U0001f3ff": {":boy_tone5:"}, + "\U0001f467": {":girl:"}, + "\U0001f467\U0001f3fb": {":girl_tone1:"}, + "\U0001f467\U0001f3fc": {":girl_tone2:"}, + "\U0001f467\U0001f3fd": {":girl_tone3:"}, + "\U0001f467\U0001f3fe": {":girl_tone4:"}, + "\U0001f467\U0001f3ff": {":girl_tone5:"}, + "\U0001f468": {":man:"}, + "\U0001f468\U0001f3fb": {":man_tone1:"}, + "\U0001f468\U0001f3fb\u200d\U0001f33e": {":man_farmer_tone1:"}, + "\U0001f468\U0001f3fb\u200d\U0001f373": {":man_cook_tone1:"}, + "\U0001f468\U0001f3fb\u200d\U0001f393": {":man_student_tone1:"}, + "\U0001f468\U0001f3fb\u200d\U0001f3a4": {":man_singer_tone1:"}, + "\U0001f468\U0001f3fb\u200d\U0001f3a8": {":man_artist_tone1:"}, + "\U0001f468\U0001f3fb\u200d\U0001f3eb": {":man_teacher_tone1:"}, + "\U0001f468\U0001f3fb\u200d\U0001f3ed": {":man_factory_worker_tone1:"}, + "\U0001f468\U0001f3fb\u200d\U0001f4bb": {":man_technologist_tone1:"}, + "\U0001f468\U0001f3fb\u200d\U0001f4bc": {":man_office_worker_tone1:"}, + "\U0001f468\U0001f3fb\u200d\U0001f527": {":man_mechanic_tone1:"}, + "\U0001f468\U0001f3fb\u200d\U0001f52c": {":man_scientist_tone1:"}, + "\U0001f468\U0001f3fb\u200d\U0001f680": {":man_astronaut_tone1:"}, + "\U0001f468\U0001f3fb\u200d\U0001f692": {":man_firefighter_tone1:"}, + "\U0001f468\U0001f3fb\u200d\u2695\ufe0f": {":man_health_worker_tone1:"}, + "\U0001f468\U0001f3fb\u200d\u2696\ufe0f": {":man_judge_tone1:"}, + "\U0001f468\U0001f3fb\u200d\u2708\ufe0f": {":man_pilot_tone1:"}, + "\U0001f468\U0001f3fc": {":man_tone2:"}, + "\U0001f468\U0001f3fc\u200d\U0001f33e": {":man_farmer_tone2:"}, + "\U0001f468\U0001f3fc\u200d\U0001f373": {":man_cook_tone2:"}, + "\U0001f468\U0001f3fc\u200d\U0001f393": {":man_student_tone2:"}, + "\U0001f468\U0001f3fc\u200d\U0001f3a4": {":man_singer_tone2:"}, + "\U0001f468\U0001f3fc\u200d\U0001f3a8": {":man_artist_tone2:"}, + "\U0001f468\U0001f3fc\u200d\U0001f3eb": {":man_teacher_tone2:"}, + "\U0001f468\U0001f3fc\u200d\U0001f3ed": {":man_factory_worker_tone2:"}, + "\U0001f468\U0001f3fc\u200d\U0001f4bb": {":man_technologist_tone2:"}, + "\U0001f468\U0001f3fc\u200d\U0001f4bc": {":man_office_worker_tone2:"}, + "\U0001f468\U0001f3fc\u200d\U0001f527": {":man_mechanic_tone2:"}, + "\U0001f468\U0001f3fc\u200d\U0001f52c": {":man_scientist_tone2:"}, + "\U0001f468\U0001f3fc\u200d\U0001f680": {":man_astronaut_tone2:"}, + "\U0001f468\U0001f3fc\u200d\U0001f692": {":man_firefighter_tone2:"}, + "\U0001f468\U0001f3fc\u200d\u2695\ufe0f": {":man_health_worker_tone2:"}, + "\U0001f468\U0001f3fc\u200d\u2696\ufe0f": {":man_judge_tone2:"}, + "\U0001f468\U0001f3fc\u200d\u2708\ufe0f": {":man_pilot_tone2:"}, + "\U0001f468\U0001f3fd": {":man_tone3:"}, + "\U0001f468\U0001f3fd\u200d\U0001f33e": {":man_farmer_tone3:"}, + "\U0001f468\U0001f3fd\u200d\U0001f373": {":man_cook_tone3:"}, + "\U0001f468\U0001f3fd\u200d\U0001f393": {":man_student_tone3:"}, + "\U0001f468\U0001f3fd\u200d\U0001f3a4": {":man_singer_tone3:"}, + "\U0001f468\U0001f3fd\u200d\U0001f3a8": {":man_artist_tone3:"}, + "\U0001f468\U0001f3fd\u200d\U0001f3eb": {":man_teacher_tone3:"}, + "\U0001f468\U0001f3fd\u200d\U0001f3ed": {":man_factory_worker_tone3:"}, + "\U0001f468\U0001f3fd\u200d\U0001f4bb": {":man_technologist_tone3:"}, + "\U0001f468\U0001f3fd\u200d\U0001f4bc": {":man_office_worker_tone3:"}, + "\U0001f468\U0001f3fd\u200d\U0001f527": {":man_mechanic_tone3:"}, + "\U0001f468\U0001f3fd\u200d\U0001f52c": {":man_scientist_tone3:"}, + "\U0001f468\U0001f3fd\u200d\U0001f680": {":man_astronaut_tone3:"}, + "\U0001f468\U0001f3fd\u200d\U0001f692": {":man_firefighter_tone3:"}, + "\U0001f468\U0001f3fd\u200d\u2695\ufe0f": {":man_health_worker_tone3:"}, + "\U0001f468\U0001f3fd\u200d\u2696\ufe0f": {":man_judge_tone3:"}, + "\U0001f468\U0001f3fd\u200d\u2708\ufe0f": {":man_pilot_tone3:"}, + "\U0001f468\U0001f3fe": {":man_tone4:"}, + "\U0001f468\U0001f3fe\u200d\U0001f33e": {":man_farmer_tone4:"}, + "\U0001f468\U0001f3fe\u200d\U0001f373": {":man_cook_tone4:"}, + "\U0001f468\U0001f3fe\u200d\U0001f393": {":man_student_tone4:"}, + "\U0001f468\U0001f3fe\u200d\U0001f3a4": {":man_singer_tone4:"}, + "\U0001f468\U0001f3fe\u200d\U0001f3a8": {":man_artist_tone4:"}, + "\U0001f468\U0001f3fe\u200d\U0001f3eb": {":man_teacher_tone4:"}, + "\U0001f468\U0001f3fe\u200d\U0001f3ed": {":man_factory_worker_tone4:"}, + "\U0001f468\U0001f3fe\u200d\U0001f4bb": {":man_technologist_tone4:"}, + "\U0001f468\U0001f3fe\u200d\U0001f4bc": {":man_office_worker_tone4:"}, + "\U0001f468\U0001f3fe\u200d\U0001f527": {":man_mechanic_tone4:"}, + "\U0001f468\U0001f3fe\u200d\U0001f52c": {":man_scientist_tone4:"}, + "\U0001f468\U0001f3fe\u200d\U0001f680": {":man_astronaut_tone4:"}, + "\U0001f468\U0001f3fe\u200d\U0001f692": {":man_firefighter_tone4:"}, + "\U0001f468\U0001f3fe\u200d\u2695\ufe0f": {":man_health_worker_tone4:"}, + "\U0001f468\U0001f3fe\u200d\u2696\ufe0f": {":man_judge_tone4:"}, + "\U0001f468\U0001f3fe\u200d\u2708\ufe0f": {":man_pilot_tone4:"}, + "\U0001f468\U0001f3ff": {":man_tone5:"}, + "\U0001f468\U0001f3ff\u200d\U0001f33e": {":man_farmer_tone5:"}, + "\U0001f468\U0001f3ff\u200d\U0001f373": {":man_cook_tone5:"}, + "\U0001f468\U0001f3ff\u200d\U0001f393": {":man_student_tone5:"}, + "\U0001f468\U0001f3ff\u200d\U0001f3a4": {":man_singer_tone5:"}, + "\U0001f468\U0001f3ff\u200d\U0001f3a8": {":man_artist_tone5:"}, + "\U0001f468\U0001f3ff\u200d\U0001f3eb": {":man_teacher_tone5:"}, + "\U0001f468\U0001f3ff\u200d\U0001f3ed": {":man_factory_worker_tone5:"}, + "\U0001f468\U0001f3ff\u200d\U0001f4bb": {":man_technologist_tone5:"}, + "\U0001f468\U0001f3ff\u200d\U0001f4bc": {":man_office_worker_tone5:"}, + "\U0001f468\U0001f3ff\u200d\U0001f527": {":man_mechanic_tone5:"}, + "\U0001f468\U0001f3ff\u200d\U0001f52c": {":man_scientist_tone5:"}, + "\U0001f468\U0001f3ff\u200d\U0001f680": {":man_astronaut_tone5:"}, + "\U0001f468\U0001f3ff\u200d\U0001f692": {":man_firefighter_tone5:"}, + "\U0001f468\U0001f3ff\u200d\u2695\ufe0f": {":man_health_worker_tone5:"}, + "\U0001f468\U0001f3ff\u200d\u2696\ufe0f": {":man_judge_tone5:"}, + "\U0001f468\U0001f3ff\u200d\u2708\ufe0f": {":man_pilot_tone5:"}, + "\U0001f468\u200d\U0001f33e": {":man_farmer:", ":male-farmer:"}, + "\U0001f468\u200d\U0001f373": {":man_cook:", ":male-cook:"}, + "\U0001f468\u200d\U0001f37c": {":man_feeding_baby:"}, + "\U0001f468\u200d\U0001f393": {":man_student:", ":male-student:"}, + "\U0001f468\u200d\U0001f3a4": {":man_singer:", ":male-singer:"}, + "\U0001f468\u200d\U0001f3a8": {":man_artist:", ":male-artist:"}, + "\U0001f468\u200d\U0001f3eb": {":man_teacher:", ":male-teacher:"}, + "\U0001f468\u200d\U0001f3ed": {":man_factory_worker:", ":male-factory-worker:"}, + "\U0001f468\u200d\U0001f466": {":man-boy:", ":family_man_boy:"}, + "\U0001f468\u200d\U0001f466\u200d\U0001f466": {":man-boy-boy:", ":family_man_boy_boy:"}, + "\U0001f468\u200d\U0001f467": {":man-girl:", ":family_man_girl:"}, + "\U0001f468\u200d\U0001f467\u200d\U0001f466": {":man-girl-boy:", ":family_man_girl_boy:"}, + "\U0001f468\u200d\U0001f467\u200d\U0001f467": {":man-girl-girl:", ":family_man_girl_girl:"}, + "\U0001f468\u200d\U0001f468\u200d\U0001f466": {":family_mmb:", ":man-man-boy:", ":family_man_man_boy:"}, + "\U0001f468\u200d\U0001f468\u200d\U0001f466\u200d\U0001f466": {":family_mmbb:", ":man-man-boy-boy:", ":family_man_man_boy_boy:"}, + "\U0001f468\u200d\U0001f468\u200d\U0001f467": {":family_mmg:", ":man-man-girl:", ":family_man_man_girl:"}, + "\U0001f468\u200d\U0001f468\u200d\U0001f467\u200d\U0001f466": {":family_mmgb:", ":man-man-girl-boy:", ":family_man_man_girl_boy:"}, + "\U0001f468\u200d\U0001f468\u200d\U0001f467\u200d\U0001f467": {":family_mmgg:", ":man-man-girl-girl:", ":family_man_man_girl_girl:"}, + "\U0001f468\u200d\U0001f469\u200d\U0001f466": {":family:", ":man-woman-boy:", ":family_man_woman_boy:"}, + "\U0001f468\u200d\U0001f469\u200d\U0001f466\u200d\U0001f466": {":family_mwbb:", ":man-woman-boy-boy:", ":family_man_woman_boy_boy:"}, + "\U0001f468\u200d\U0001f469\u200d\U0001f467": {":family_mwg:", ":man-woman-girl:", ":family_man_woman_girl:"}, + "\U0001f468\u200d\U0001f469\u200d\U0001f467\u200d\U0001f466": {":family_mwgb:", ":man-woman-girl-boy:", ":family_man_woman_girl_boy:"}, + "\U0001f468\u200d\U0001f469\u200d\U0001f467\u200d\U0001f467": {":family_mwgg:", ":man-woman-girl-girl:", ":family_man_woman_girl_girl:"}, + "\U0001f468\u200d\U0001f4bb": {":man_technologist:", ":male-technologist:"}, + "\U0001f468\u200d\U0001f4bc": {":man_office_worker:", ":male-office-worker:"}, + "\U0001f468\u200d\U0001f527": {":man_mechanic:", ":male-mechanic:"}, + "\U0001f468\u200d\U0001f52c": {":man_scientist:", ":male-scientist:"}, + "\U0001f468\u200d\U0001f680": {":man_astronaut:", ":male-astronaut:"}, + "\U0001f468\u200d\U0001f692": {":man_firefighter:", ":male-firefighter:"}, + "\U0001f468\u200d\U0001f9af": {":man_with_white_cane:", ":man_with_probing_cane:"}, + "\U0001f468\u200d\U0001f9b0": {":man_red_hair:", ":red_haired_man:"}, + "\U0001f468\u200d\U0001f9b1": {":man_curly_hair:", ":curly_haired_man:"}, + "\U0001f468\u200d\U0001f9b2": {":bald_man:", ":man_bald:"}, + "\U0001f468\u200d\U0001f9b3": {":man_white_hair:", ":white_haired_man:"}, + "\U0001f468\u200d\U0001f9bc": {":man_in_motorized_wheelchair:"}, + "\U0001f468\u200d\U0001f9bd": {":man_in_manual_wheelchair:"}, + "\U0001f468\u200d\u2695\ufe0f": {":male-doctor:", ":man_health_worker:"}, + "\U0001f468\u200d\u2696\ufe0f": {":man_judge:", ":male-judge:"}, + "\U0001f468\u200d\u2708\ufe0f": {":man_pilot:", ":male-pilot:"}, + "\U0001f468\u200d\u2764\ufe0f\u200d\U0001f468": {":couple_mm:", ":man-heart-man:", ":couple_with_heart_man_man:"}, + "\U0001f468\u200d\u2764\ufe0f\u200d\U0001f48b\u200d\U0001f468": {":kiss_mm:", ":kiss_man_man:", ":man-kiss-man:", ":couplekiss_man_man:"}, + "\U0001f469": {":woman:"}, + "\U0001f469\U0001f3fb": {":woman_tone1:"}, + "\U0001f469\U0001f3fb\u200d\U0001f33e": {":woman_farmer_tone1:"}, + "\U0001f469\U0001f3fb\u200d\U0001f373": {":woman_cook_tone1:"}, + "\U0001f469\U0001f3fb\u200d\U0001f393": {":woman_student_tone1:"}, + "\U0001f469\U0001f3fb\u200d\U0001f3a4": {":woman_singer_tone1:"}, + "\U0001f469\U0001f3fb\u200d\U0001f3a8": {":woman_artist_tone1:"}, + "\U0001f469\U0001f3fb\u200d\U0001f3eb": {":woman_teacher_tone1:"}, + "\U0001f469\U0001f3fb\u200d\U0001f3ed": {":woman_factory_worker_tone1:"}, + "\U0001f469\U0001f3fb\u200d\U0001f4bb": {":woman_technologist_tone1:"}, + "\U0001f469\U0001f3fb\u200d\U0001f4bc": {":woman_office_worker_tone1:"}, + "\U0001f469\U0001f3fb\u200d\U0001f527": {":woman_mechanic_tone1:"}, + "\U0001f469\U0001f3fb\u200d\U0001f52c": {":woman_scientist_tone1:"}, + "\U0001f469\U0001f3fb\u200d\U0001f680": {":woman_astronaut_tone1:"}, + "\U0001f469\U0001f3fb\u200d\U0001f692": {":woman_firefighter_tone1:"}, + "\U0001f469\U0001f3fb\u200d\u2695\ufe0f": {":woman_health_worker_tone1:"}, + "\U0001f469\U0001f3fb\u200d\u2696\ufe0f": {":woman_judge_tone1:"}, + "\U0001f469\U0001f3fb\u200d\u2708\ufe0f": {":woman_pilot_tone1:"}, + "\U0001f469\U0001f3fc": {":woman_tone2:"}, + "\U0001f469\U0001f3fc\u200d\U0001f33e": {":woman_farmer_tone2:"}, + "\U0001f469\U0001f3fc\u200d\U0001f373": {":woman_cook_tone2:"}, + "\U0001f469\U0001f3fc\u200d\U0001f393": {":woman_student_tone2:"}, + "\U0001f469\U0001f3fc\u200d\U0001f3a4": {":woman_singer_tone2:"}, + "\U0001f469\U0001f3fc\u200d\U0001f3a8": {":woman_artist_tone2:"}, + "\U0001f469\U0001f3fc\u200d\U0001f3eb": {":woman_teacher_tone2:"}, + "\U0001f469\U0001f3fc\u200d\U0001f3ed": {":woman_factory_worker_tone2:"}, + "\U0001f469\U0001f3fc\u200d\U0001f4bb": {":woman_technologist_tone2:"}, + "\U0001f469\U0001f3fc\u200d\U0001f4bc": {":woman_office_worker_tone2:"}, + "\U0001f469\U0001f3fc\u200d\U0001f527": {":woman_mechanic_tone2:"}, + "\U0001f469\U0001f3fc\u200d\U0001f52c": {":woman_scientist_tone2:"}, + "\U0001f469\U0001f3fc\u200d\U0001f680": {":woman_astronaut_tone2:"}, + "\U0001f469\U0001f3fc\u200d\U0001f692": {":woman_firefighter_tone2:"}, + "\U0001f469\U0001f3fc\u200d\u2695\ufe0f": {":woman_health_worker_tone2:"}, + "\U0001f469\U0001f3fc\u200d\u2696\ufe0f": {":woman_judge_tone2:"}, + "\U0001f469\U0001f3fc\u200d\u2708\ufe0f": {":woman_pilot_tone2:"}, + "\U0001f469\U0001f3fd": {":woman_tone3:"}, + "\U0001f469\U0001f3fd\u200d\U0001f33e": {":woman_farmer_tone3:"}, + "\U0001f469\U0001f3fd\u200d\U0001f373": {":woman_cook_tone3:"}, + "\U0001f469\U0001f3fd\u200d\U0001f393": {":woman_student_tone3:"}, + "\U0001f469\U0001f3fd\u200d\U0001f3a4": {":woman_singer_tone3:"}, + "\U0001f469\U0001f3fd\u200d\U0001f3a8": {":woman_artist_tone3:"}, + "\U0001f469\U0001f3fd\u200d\U0001f3eb": {":woman_teacher_tone3:"}, + "\U0001f469\U0001f3fd\u200d\U0001f3ed": {":woman_factory_worker_tone3:"}, + "\U0001f469\U0001f3fd\u200d\U0001f4bb": {":woman_technologist_tone3:"}, + "\U0001f469\U0001f3fd\u200d\U0001f4bc": {":woman_office_worker_tone3:"}, + "\U0001f469\U0001f3fd\u200d\U0001f527": {":woman_mechanic_tone3:"}, + "\U0001f469\U0001f3fd\u200d\U0001f52c": {":woman_scientist_tone3:"}, + "\U0001f469\U0001f3fd\u200d\U0001f680": {":woman_astronaut_tone3:"}, + "\U0001f469\U0001f3fd\u200d\U0001f692": {":woman_firefighter_tone3:"}, + "\U0001f469\U0001f3fd\u200d\u2695\ufe0f": {":woman_health_worker_tone3:"}, + "\U0001f469\U0001f3fd\u200d\u2696\ufe0f": {":woman_judge_tone3:"}, + "\U0001f469\U0001f3fd\u200d\u2708\ufe0f": {":woman_pilot_tone3:"}, + "\U0001f469\U0001f3fe": {":woman_tone4:"}, + "\U0001f469\U0001f3fe\u200d\U0001f33e": {":woman_farmer_tone4:"}, + "\U0001f469\U0001f3fe\u200d\U0001f373": {":woman_cook_tone4:"}, + "\U0001f469\U0001f3fe\u200d\U0001f393": {":woman_student_tone4:"}, + "\U0001f469\U0001f3fe\u200d\U0001f3a4": {":woman_singer_tone4:"}, + "\U0001f469\U0001f3fe\u200d\U0001f3a8": {":woman_artist_tone4:"}, + "\U0001f469\U0001f3fe\u200d\U0001f3eb": {":woman_teacher_tone4:"}, + "\U0001f469\U0001f3fe\u200d\U0001f3ed": {":woman_factory_worker_tone4:"}, + "\U0001f469\U0001f3fe\u200d\U0001f4bb": {":woman_technologist_tone4:"}, + "\U0001f469\U0001f3fe\u200d\U0001f4bc": {":woman_office_worker_tone4:"}, + "\U0001f469\U0001f3fe\u200d\U0001f527": {":woman_mechanic_tone4:"}, + "\U0001f469\U0001f3fe\u200d\U0001f52c": {":woman_scientist_tone4:"}, + "\U0001f469\U0001f3fe\u200d\U0001f680": {":woman_astronaut_tone4:"}, + "\U0001f469\U0001f3fe\u200d\U0001f692": {":woman_firefighter_tone4:"}, + "\U0001f469\U0001f3fe\u200d\u2695\ufe0f": {":woman_health_worker_tone4:"}, + "\U0001f469\U0001f3fe\u200d\u2696\ufe0f": {":woman_judge_tone4:"}, + "\U0001f469\U0001f3fe\u200d\u2708\ufe0f": {":woman_pilot_tone4:"}, + "\U0001f469\U0001f3ff": {":woman_tone5:"}, + "\U0001f469\U0001f3ff\u200d\U0001f33e": {":woman_farmer_tone5:"}, + "\U0001f469\U0001f3ff\u200d\U0001f373": {":woman_cook_tone5:"}, + "\U0001f469\U0001f3ff\u200d\U0001f393": {":woman_student_tone5:"}, + "\U0001f469\U0001f3ff\u200d\U0001f3a4": {":woman_singer_tone5:"}, + "\U0001f469\U0001f3ff\u200d\U0001f3a8": {":woman_artist_tone5:"}, + "\U0001f469\U0001f3ff\u200d\U0001f3eb": {":woman_teacher_tone5:"}, + "\U0001f469\U0001f3ff\u200d\U0001f3ed": {":woman_factory_worker_tone5:"}, + "\U0001f469\U0001f3ff\u200d\U0001f4bb": {":woman_technologist_tone5:"}, + "\U0001f469\U0001f3ff\u200d\U0001f4bc": {":woman_office_worker_tone5:"}, + "\U0001f469\U0001f3ff\u200d\U0001f527": {":woman_mechanic_tone5:"}, + "\U0001f469\U0001f3ff\u200d\U0001f52c": {":woman_scientist_tone5:"}, + "\U0001f469\U0001f3ff\u200d\U0001f680": {":woman_astronaut_tone5:"}, + "\U0001f469\U0001f3ff\u200d\U0001f692": {":woman_firefighter_tone5:"}, + "\U0001f469\U0001f3ff\u200d\u2695\ufe0f": {":woman_health_worker_tone5:"}, + "\U0001f469\U0001f3ff\u200d\u2696\ufe0f": {":woman_judge_tone5:"}, + "\U0001f469\U0001f3ff\u200d\u2708\ufe0f": {":woman_pilot_tone5:"}, + "\U0001f469\u200d\U0001f33e": {":woman_farmer:", ":female-farmer:"}, + "\U0001f469\u200d\U0001f373": {":woman_cook:", ":female-cook:"}, + "\U0001f469\u200d\U0001f37c": {":woman_feeding_baby:"}, + "\U0001f469\u200d\U0001f393": {":woman_student:", ":female-student:"}, + "\U0001f469\u200d\U0001f3a4": {":woman_singer:", ":female-singer:"}, + "\U0001f469\u200d\U0001f3a8": {":woman_artist:", ":female-artist:"}, + "\U0001f469\u200d\U0001f3eb": {":woman_teacher:", ":female-teacher:"}, + "\U0001f469\u200d\U0001f3ed": {":woman_factory_worker:", ":female-factory-worker:"}, + "\U0001f469\u200d\U0001f466": {":woman-boy:", ":family_woman_boy:"}, + "\U0001f469\u200d\U0001f466\u200d\U0001f466": {":woman-boy-boy:", ":family_woman_boy_boy:"}, + "\U0001f469\u200d\U0001f467": {":woman-girl:", ":family_woman_girl:"}, + "\U0001f469\u200d\U0001f467\u200d\U0001f466": {":woman-girl-boy:", ":family_woman_girl_boy:"}, + "\U0001f469\u200d\U0001f467\u200d\U0001f467": {":woman-girl-girl:", ":family_woman_girl_girl:"}, + "\U0001f469\u200d\U0001f469\u200d\U0001f466": {":family_wwb:", ":woman-woman-boy:", ":family_woman_woman_boy:"}, + "\U0001f469\u200d\U0001f469\u200d\U0001f466\u200d\U0001f466": {":family_wwbb:", ":woman-woman-boy-boy:", ":family_woman_woman_boy_boy:"}, + "\U0001f469\u200d\U0001f469\u200d\U0001f467": {":family_wwg:", ":woman-woman-girl:", ":family_woman_woman_girl:"}, + "\U0001f469\u200d\U0001f469\u200d\U0001f467\u200d\U0001f466": {":family_wwgb:", ":woman-woman-girl-boy:", ":family_woman_woman_girl_boy:"}, + "\U0001f469\u200d\U0001f469\u200d\U0001f467\u200d\U0001f467": {":family_wwgg:", ":woman-woman-girl-girl:", ":family_woman_woman_girl_girl:"}, + "\U0001f469\u200d\U0001f4bb": {":woman_technologist:", ":female-technologist:"}, + "\U0001f469\u200d\U0001f4bc": {":woman_office_worker:", ":female-office-worker:"}, + "\U0001f469\u200d\U0001f527": {":woman_mechanic:", ":female-mechanic:"}, + "\U0001f469\u200d\U0001f52c": {":woman_scientist:", ":female-scientist:"}, + "\U0001f469\u200d\U0001f680": {":woman_astronaut:", ":female-astronaut:"}, + "\U0001f469\u200d\U0001f692": {":woman_firefighter:", ":female-firefighter:"}, + "\U0001f469\u200d\U0001f9af": {":woman_with_white_cane:", ":woman_with_probing_cane:"}, + "\U0001f469\u200d\U0001f9b0": {":woman_red_hair:", ":red_haired_woman:"}, + "\U0001f469\u200d\U0001f9b1": {":woman_curly_hair:", ":curly_haired_woman:"}, + "\U0001f469\u200d\U0001f9b2": {":bald_woman:", ":woman_bald:"}, + "\U0001f469\u200d\U0001f9b3": {":woman_white_hair:", ":white_haired_woman:"}, + "\U0001f469\u200d\U0001f9bc": {":woman_in_motorized_wheelchair:"}, + "\U0001f469\u200d\U0001f9bd": {":woman_in_manual_wheelchair:"}, + "\U0001f469\u200d\u2695\ufe0f": {":female-doctor:", ":woman_health_worker:"}, + "\U0001f469\u200d\u2696\ufe0f": {":woman_judge:", ":female-judge:"}, + "\U0001f469\u200d\u2708\ufe0f": {":woman_pilot:", ":female-pilot:"}, + "\U0001f469\u200d\u2764\ufe0f\u200d\U0001f468": {":woman-heart-man:", ":couple_with_heart:", ":couple_with_heart_woman_man:"}, + "\U0001f469\u200d\u2764\ufe0f\u200d\U0001f469": {":couple_ww:", ":woman-heart-woman:", ":couple_with_heart_woman_woman:"}, + "\U0001f469\u200d\u2764\ufe0f\u200d\U0001f48b\u200d\U0001f468": {":couplekiss:", ":kiss_woman_man:", ":woman-kiss-man:", ":couplekiss_man_woman:"}, + "\U0001f469\u200d\u2764\ufe0f\u200d\U0001f48b\u200d\U0001f469": {":kiss_ww:", ":kiss_woman_woman:", ":woman-kiss-woman:", ":couplekiss_woman_woman:"}, + "\U0001f46b": {":couple:", ":woman_and_man_holding_hands:"}, + "\U0001f46c": {":men_holding_hands:", ":two_men_holding_hands:"}, + "\U0001f46d": {":women_holding_hands:", ":two_women_holding_hands:"}, + "\U0001f46e": {":police_officer:"}, + "\U0001f46e\U0001f3fb": {":police_officer_tone1:"}, + "\U0001f46e\U0001f3fb\u200d\u2640\ufe0f": {":woman_police_officer_tone1:"}, + "\U0001f46e\U0001f3fb\u200d\u2642\ufe0f": {":man_police_officer_tone1:"}, + "\U0001f46e\U0001f3fc": {":police_officer_tone2:"}, + "\U0001f46e\U0001f3fc\u200d\u2640\ufe0f": {":woman_police_officer_tone2:"}, + "\U0001f46e\U0001f3fc\u200d\u2642\ufe0f": {":man_police_officer_tone2:"}, + "\U0001f46e\U0001f3fd": {":police_officer_tone3:"}, + "\U0001f46e\U0001f3fd\u200d\u2640\ufe0f": {":woman_police_officer_tone3:"}, + "\U0001f46e\U0001f3fd\u200d\u2642\ufe0f": {":man_police_officer_tone3:"}, + "\U0001f46e\U0001f3fe": {":police_officer_tone4:"}, + "\U0001f46e\U0001f3fe\u200d\u2640\ufe0f": {":woman_police_officer_tone4:"}, + "\U0001f46e\U0001f3fe\u200d\u2642\ufe0f": {":man_police_officer_tone4:"}, + "\U0001f46e\U0001f3ff": {":police_officer_tone5:"}, + "\U0001f46e\U0001f3ff\u200d\u2640\ufe0f": {":woman_police_officer_tone5:"}, + "\U0001f46e\U0001f3ff\u200d\u2642\ufe0f": {":man_police_officer_tone5:"}, + "\U0001f46e\u200d\u2640\ufe0f": {":policewoman:", ":woman_police_officer:", ":female-police-officer:"}, + "\U0001f46e\u200d\u2642\ufe0f": {":cop:", ":policeman:", ":man_police_officer:", ":male-police-officer:"}, + "\U0001f46f": {":people_with_bunny_ears:", ":people_with_bunny_ears_partying:"}, + "\U0001f46f\u200d\u2640\ufe0f": {":dancers:", ":dancing_women:", ":women_with_bunny_ears:", ":woman-with-bunny-ears-partying:", ":women_with_bunny_ears_partying:"}, + "\U0001f46f\u200d\u2642\ufe0f": {":dancing_men:", ":men_with_bunny_ears:", ":man-with-bunny-ears-partying:", ":men_with_bunny_ears_partying:"}, + "\U0001f470": {":bride_with_veil:", ":person_with_veil:"}, + "\U0001f470\U0001f3fb": {":bride_with_veil_tone1:"}, + "\U0001f470\U0001f3fc": {":bride_with_veil_tone2:"}, + "\U0001f470\U0001f3fd": {":bride_with_veil_tone3:"}, + "\U0001f470\U0001f3fe": {":bride_with_veil_tone4:"}, + "\U0001f470\U0001f3ff": {":bride_with_veil_tone5:"}, + "\U0001f470\u200d\u2640\ufe0f": {":woman_with_veil:"}, + "\U0001f470\u200d\u2642\ufe0f": {":man_with_veil:"}, + "\U0001f471": {":person_blond_hair:", ":blond_haired_person:"}, + "\U0001f471\U0001f3fb": {":blond_haired_person_tone1:"}, + "\U0001f471\U0001f3fb\u200d\u2640\ufe0f": {":blond-haired_woman_tone1:"}, + "\U0001f471\U0001f3fb\u200d\u2642\ufe0f": {":blond-haired_man_tone1:"}, + "\U0001f471\U0001f3fc": {":blond_haired_person_tone2:"}, + "\U0001f471\U0001f3fc\u200d\u2640\ufe0f": {":blond-haired_woman_tone2:"}, + "\U0001f471\U0001f3fc\u200d\u2642\ufe0f": {":blond-haired_man_tone2:"}, + "\U0001f471\U0001f3fd": {":blond_haired_person_tone3:"}, + "\U0001f471\U0001f3fd\u200d\u2640\ufe0f": {":blond-haired_woman_tone3:"}, + "\U0001f471\U0001f3fd\u200d\u2642\ufe0f": {":blond-haired_man_tone3:"}, + "\U0001f471\U0001f3fe": {":blond_haired_person_tone4:"}, + "\U0001f471\U0001f3fe\u200d\u2640\ufe0f": {":blond-haired_woman_tone4:"}, + "\U0001f471\U0001f3fe\u200d\u2642\ufe0f": {":blond-haired_man_tone4:"}, + "\U0001f471\U0001f3ff": {":blond_haired_person_tone5:"}, + "\U0001f471\U0001f3ff\u200d\u2640\ufe0f": {":blond-haired_woman_tone5:"}, + "\U0001f471\U0001f3ff\u200d\u2642\ufe0f": {":blond-haired_man_tone5:"}, + "\U0001f471\u200d\u2640\ufe0f": {":blonde_woman:", ":woman_blond_hair:", ":blond-haired-woman:", ":blond-haired_woman:", ":blond_haired_woman:"}, + "\U0001f471\u200d\u2642\ufe0f": {":man_blond_hair:", ":blond-haired-man:", ":blond-haired_man:", ":blond_haired_man:", ":person_with_blond_hair:"}, + "\U0001f472": {":man_with_gua_pi_mao:", ":man_with_chinese_cap:", ":person_with_skullcap:"}, + "\U0001f472\U0001f3fb": {":man_with_chinese_cap_tone1:"}, + "\U0001f472\U0001f3fc": {":man_with_chinese_cap_tone2:"}, + "\U0001f472\U0001f3fd": {":man_with_chinese_cap_tone3:"}, + "\U0001f472\U0001f3fe": {":man_with_chinese_cap_tone4:"}, + "\U0001f472\U0001f3ff": {":man_with_chinese_cap_tone5:"}, + "\U0001f473": {":person_with_turban:", ":person_wearing_turban:"}, + "\U0001f473\U0001f3fb": {":person_wearing_turban_tone1:"}, + "\U0001f473\U0001f3fb\u200d\u2640\ufe0f": {":woman_wearing_turban_tone1:"}, + "\U0001f473\U0001f3fb\u200d\u2642\ufe0f": {":man_wearing_turban_tone1:"}, + "\U0001f473\U0001f3fc": {":person_wearing_turban_tone2:"}, + "\U0001f473\U0001f3fc\u200d\u2640\ufe0f": {":woman_wearing_turban_tone2:"}, + "\U0001f473\U0001f3fc\u200d\u2642\ufe0f": {":man_wearing_turban_tone2:"}, + "\U0001f473\U0001f3fd": {":person_wearing_turban_tone3:"}, + "\U0001f473\U0001f3fd\u200d\u2640\ufe0f": {":woman_wearing_turban_tone3:"}, + "\U0001f473\U0001f3fd\u200d\u2642\ufe0f": {":man_wearing_turban_tone3:"}, + "\U0001f473\U0001f3fe": {":person_wearing_turban_tone4:"}, + "\U0001f473\U0001f3fe\u200d\u2640\ufe0f": {":woman_wearing_turban_tone4:"}, + "\U0001f473\U0001f3fe\u200d\u2642\ufe0f": {":man_wearing_turban_tone4:"}, + "\U0001f473\U0001f3ff": {":person_wearing_turban_tone5:"}, + "\U0001f473\U0001f3ff\u200d\u2640\ufe0f": {":woman_wearing_turban_tone5:"}, + "\U0001f473\U0001f3ff\u200d\u2642\ufe0f": {":man_wearing_turban_tone5:"}, + "\U0001f473\u200d\u2640\ufe0f": {":woman_with_turban:", ":woman-wearing-turban:", ":woman_wearing_turban:"}, + "\U0001f473\u200d\u2642\ufe0f": {":man_with_turban:", ":man-wearing-turban:", ":man_wearing_turban:"}, + "\U0001f474": {":old_man:", ":older_man:"}, + "\U0001f474\U0001f3fb": {":older_man_tone1:"}, + "\U0001f474\U0001f3fc": {":older_man_tone2:"}, + "\U0001f474\U0001f3fd": {":older_man_tone3:"}, + "\U0001f474\U0001f3fe": {":older_man_tone4:"}, + "\U0001f474\U0001f3ff": {":older_man_tone5:"}, + "\U0001f475": {":old_woman:", ":older_woman:"}, + "\U0001f475\U0001f3fb": {":older_woman_tone1:"}, + "\U0001f475\U0001f3fc": {":older_woman_tone2:"}, + "\U0001f475\U0001f3fd": {":older_woman_tone3:"}, + "\U0001f475\U0001f3fe": {":older_woman_tone4:"}, + "\U0001f475\U0001f3ff": {":older_woman_tone5:"}, + "\U0001f476": {":baby:"}, + "\U0001f476\U0001f3fb": {":baby_tone1:"}, + "\U0001f476\U0001f3fc": {":baby_tone2:"}, + "\U0001f476\U0001f3fd": {":baby_tone3:"}, + "\U0001f476\U0001f3fe": {":baby_tone4:"}, + "\U0001f476\U0001f3ff": {":baby_tone5:"}, + "\U0001f477\U0001f3fb": {":construction_worker_tone1:"}, + "\U0001f477\U0001f3fb\u200d\u2640\ufe0f": {":woman_construction_worker_tone1:"}, + "\U0001f477\U0001f3fb\u200d\u2642\ufe0f": {":man_construction_worker_tone1:"}, + "\U0001f477\U0001f3fc": {":construction_worker_tone2:"}, + "\U0001f477\U0001f3fc\u200d\u2640\ufe0f": {":woman_construction_worker_tone2:"}, + "\U0001f477\U0001f3fc\u200d\u2642\ufe0f": {":man_construction_worker_tone2:"}, + "\U0001f477\U0001f3fd": {":construction_worker_tone3:"}, + "\U0001f477\U0001f3fd\u200d\u2640\ufe0f": {":woman_construction_worker_tone3:"}, + "\U0001f477\U0001f3fd\u200d\u2642\ufe0f": {":man_construction_worker_tone3:"}, + "\U0001f477\U0001f3fe": {":construction_worker_tone4:"}, + "\U0001f477\U0001f3fe\u200d\u2640\ufe0f": {":woman_construction_worker_tone4:"}, + "\U0001f477\U0001f3fe\u200d\u2642\ufe0f": {":man_construction_worker_tone4:"}, + "\U0001f477\U0001f3ff": {":construction_worker_tone5:"}, + "\U0001f477\U0001f3ff\u200d\u2640\ufe0f": {":woman_construction_worker_tone5:"}, + "\U0001f477\U0001f3ff\u200d\u2642\ufe0f": {":man_construction_worker_tone5:"}, + "\U0001f477\u200d\u2640\ufe0f": {":construction_worker_woman:", ":woman_construction_worker:", ":female-construction-worker:"}, + "\U0001f477\u200d\u2642\ufe0f": {":construction_worker:", ":construction_worker_man:", ":man_construction_worker:", ":male-construction-worker:"}, + "\U0001f478": {":princess:"}, + "\U0001f478\U0001f3fb": {":princess_tone1:"}, + "\U0001f478\U0001f3fc": {":princess_tone2:"}, + "\U0001f478\U0001f3fd": {":princess_tone3:"}, + "\U0001f478\U0001f3fe": {":princess_tone4:"}, + "\U0001f478\U0001f3ff": {":princess_tone5:"}, + "\U0001f479": {":ogre:", ":japanese_ogre:"}, + "\U0001f47a": {":goblin:", ":japanese_goblin:"}, + "\U0001f47b": {":ghost:"}, + "\U0001f47c": {":angel:", ":baby_angel:"}, + "\U0001f47c\U0001f3fb": {":angel_tone1:"}, + "\U0001f47c\U0001f3fc": {":angel_tone2:"}, + "\U0001f47c\U0001f3fd": {":angel_tone3:"}, + "\U0001f47c\U0001f3fe": {":angel_tone4:"}, + "\U0001f47c\U0001f3ff": {":angel_tone5:"}, + "\U0001f47d": {":alien:"}, + "\U0001f47e": {":alien_monster:", ":space_invader:"}, + "\U0001f47f": {":imp:", ":angry_face_with_horns:"}, + "\U0001f480": {":skull:"}, + "\U0001f481": {":person_tipping_hand:", ":tipping_hand_person:"}, + "\U0001f481\U0001f3fb": {":person_tipping_hand_tone1:"}, + "\U0001f481\U0001f3fb\u200d\u2640\ufe0f": {":woman_tipping_hand_tone1:"}, + "\U0001f481\U0001f3fb\u200d\u2642\ufe0f": {":man_tipping_hand_tone1:"}, + "\U0001f481\U0001f3fc": {":person_tipping_hand_tone2:"}, + "\U0001f481\U0001f3fc\u200d\u2640\ufe0f": {":woman_tipping_hand_tone2:"}, + "\U0001f481\U0001f3fc\u200d\u2642\ufe0f": {":man_tipping_hand_tone2:"}, + "\U0001f481\U0001f3fd": {":person_tipping_hand_tone3:"}, + "\U0001f481\U0001f3fd\u200d\u2640\ufe0f": {":woman_tipping_hand_tone3:"}, + "\U0001f481\U0001f3fd\u200d\u2642\ufe0f": {":man_tipping_hand_tone3:"}, + "\U0001f481\U0001f3fe": {":person_tipping_hand_tone4:"}, + "\U0001f481\U0001f3fe\u200d\u2640\ufe0f": {":woman_tipping_hand_tone4:"}, + "\U0001f481\U0001f3fe\u200d\u2642\ufe0f": {":man_tipping_hand_tone4:"}, + "\U0001f481\U0001f3ff": {":person_tipping_hand_tone5:"}, + "\U0001f481\U0001f3ff\u200d\u2640\ufe0f": {":woman_tipping_hand_tone5:"}, + "\U0001f481\U0001f3ff\u200d\u2642\ufe0f": {":man_tipping_hand_tone5:"}, + "\U0001f481\u200d\u2640\ufe0f": {":sassy_woman:", ":tipping_hand_woman:", ":woman-tipping-hand:", ":woman_tipping_hand:", ":information_desk_person:"}, + "\U0001f481\u200d\u2642\ufe0f": {":sassy_man:", ":man-tipping-hand:", ":man_tipping_hand:", ":tipping_hand_man:"}, + "\U0001f482": {":guard:"}, + "\U0001f482\U0001f3fb": {":guard_tone1:"}, + "\U0001f482\U0001f3fb\u200d\u2640\ufe0f": {":woman_guard_tone1:"}, + "\U0001f482\U0001f3fb\u200d\u2642\ufe0f": {":man_guard_tone1:"}, + "\U0001f482\U0001f3fc": {":guard_tone2:"}, + "\U0001f482\U0001f3fc\u200d\u2640\ufe0f": {":woman_guard_tone2:"}, + "\U0001f482\U0001f3fc\u200d\u2642\ufe0f": {":man_guard_tone2:"}, + "\U0001f482\U0001f3fd": {":guard_tone3:"}, + "\U0001f482\U0001f3fd\u200d\u2640\ufe0f": {":woman_guard_tone3:"}, + "\U0001f482\U0001f3fd\u200d\u2642\ufe0f": {":man_guard_tone3:"}, + "\U0001f482\U0001f3fe": {":guard_tone4:"}, + "\U0001f482\U0001f3fe\u200d\u2640\ufe0f": {":woman_guard_tone4:"}, + "\U0001f482\U0001f3fe\u200d\u2642\ufe0f": {":man_guard_tone4:"}, + "\U0001f482\U0001f3ff": {":guard_tone5:"}, + "\U0001f482\U0001f3ff\u200d\u2640\ufe0f": {":woman_guard_tone5:"}, + "\U0001f482\U0001f3ff\u200d\u2642\ufe0f": {":man_guard_tone5:"}, + "\U0001f482\u200d\u2640\ufe0f": {":guardswoman:", ":woman_guard:", ":female-guard:"}, + "\U0001f482\u200d\u2642\ufe0f": {":guardsman:", ":man_guard:", ":male-guard:"}, + "\U0001f483": {":dancer:", ":woman_dancing:"}, + "\U0001f483\U0001f3fb": {":dancer_tone1:"}, + "\U0001f483\U0001f3fc": {":dancer_tone2:"}, + "\U0001f483\U0001f3fd": {":dancer_tone3:"}, + "\U0001f483\U0001f3fe": {":dancer_tone4:"}, + "\U0001f483\U0001f3ff": {":dancer_tone5:"}, + "\U0001f484": {":lipstick:"}, + "\U0001f485": {":nail_care:", ":nail_polish:"}, + "\U0001f485\U0001f3fb": {":nail_care_tone1:"}, + "\U0001f485\U0001f3fc": {":nail_care_tone2:"}, + "\U0001f485\U0001f3fd": {":nail_care_tone3:"}, + "\U0001f485\U0001f3fe": {":nail_care_tone4:"}, + "\U0001f485\U0001f3ff": {":nail_care_tone5:"}, + "\U0001f486": {":person_getting_massage:"}, + "\U0001f486\U0001f3fb": {":person_getting_massage_tone1:"}, + "\U0001f486\U0001f3fb\u200d\u2640\ufe0f": {":woman_getting_face_massage_tone1:"}, + "\U0001f486\U0001f3fb\u200d\u2642\ufe0f": {":man_getting_face_massage_tone1:"}, + "\U0001f486\U0001f3fc": {":person_getting_massage_tone2:"}, + "\U0001f486\U0001f3fc\u200d\u2640\ufe0f": {":woman_getting_face_massage_tone2:"}, + "\U0001f486\U0001f3fc\u200d\u2642\ufe0f": {":man_getting_face_massage_tone2:"}, + "\U0001f486\U0001f3fd": {":person_getting_massage_tone3:"}, + "\U0001f486\U0001f3fd\u200d\u2640\ufe0f": {":woman_getting_face_massage_tone3:"}, + "\U0001f486\U0001f3fd\u200d\u2642\ufe0f": {":man_getting_face_massage_tone3:"}, + "\U0001f486\U0001f3fe": {":person_getting_massage_tone4:"}, + "\U0001f486\U0001f3fe\u200d\u2640\ufe0f": {":woman_getting_face_massage_tone4:"}, + "\U0001f486\U0001f3fe\u200d\u2642\ufe0f": {":man_getting_face_massage_tone4:"}, + "\U0001f486\U0001f3ff": {":person_getting_massage_tone5:"}, + "\U0001f486\U0001f3ff\u200d\u2640\ufe0f": {":woman_getting_face_massage_tone5:"}, + "\U0001f486\U0001f3ff\u200d\u2642\ufe0f": {":man_getting_face_massage_tone5:"}, + "\U0001f486\u200d\u2640\ufe0f": {":massage:", ":massage_woman:", ":woman-getting-massage:", ":woman_getting_massage:", ":woman_getting_face_massage:"}, + "\U0001f486\u200d\u2642\ufe0f": {":massage_man:", ":man-getting-massage:", ":man_getting_massage:", ":man_getting_face_massage:"}, + "\U0001f487": {":person_getting_haircut:"}, + "\U0001f487\U0001f3fb": {":person_getting_haircut_tone1:"}, + "\U0001f487\U0001f3fb\u200d\u2640\ufe0f": {":woman_getting_haircut_tone1:"}, + "\U0001f487\U0001f3fb\u200d\u2642\ufe0f": {":man_getting_haircut_tone1:"}, + "\U0001f487\U0001f3fc": {":person_getting_haircut_tone2:"}, + "\U0001f487\U0001f3fc\u200d\u2640\ufe0f": {":woman_getting_haircut_tone2:"}, + "\U0001f487\U0001f3fc\u200d\u2642\ufe0f": {":man_getting_haircut_tone2:"}, + "\U0001f487\U0001f3fd": {":person_getting_haircut_tone3:"}, + "\U0001f487\U0001f3fd\u200d\u2640\ufe0f": {":woman_getting_haircut_tone3:"}, + "\U0001f487\U0001f3fd\u200d\u2642\ufe0f": {":man_getting_haircut_tone3:"}, + "\U0001f487\U0001f3fe": {":person_getting_haircut_tone4:"}, + "\U0001f487\U0001f3fe\u200d\u2640\ufe0f": {":woman_getting_haircut_tone4:"}, + "\U0001f487\U0001f3fe\u200d\u2642\ufe0f": {":man_getting_haircut_tone4:"}, + "\U0001f487\U0001f3ff": {":person_getting_haircut_tone5:"}, + "\U0001f487\U0001f3ff\u200d\u2640\ufe0f": {":woman_getting_haircut_tone5:"}, + "\U0001f487\U0001f3ff\u200d\u2642\ufe0f": {":man_getting_haircut_tone5:"}, + "\U0001f487\u200d\u2640\ufe0f": {":haircut:", ":haircut_woman:", ":woman-getting-haircut:", ":woman_getting_haircut:"}, + "\U0001f487\u200d\u2642\ufe0f": {":haircut_man:", ":man-getting-haircut:", ":man_getting_haircut:"}, + "\U0001f488": {":barber:", ":barber_pole:"}, + "\U0001f489": {":syringe:"}, + "\U0001f48a": {":pill:"}, + "\U0001f48b": {":kiss:", ":kiss_mark:"}, + "\U0001f48c": {":love_letter:"}, + "\U0001f48d": {":ring:"}, + "\U0001f48e": {":gem:", ":gem_stone:"}, + "\U0001f490": {":bouquet:"}, + "\U0001f492": {":wedding:"}, + "\U0001f493": {":heartbeat:", ":beating_heart:"}, + "\U0001f494": {":broken_heart:"}, + "\U0001f495": {":two_hearts:"}, + "\U0001f496": {":sparkling_heart:"}, + "\U0001f497": {":heartpulse:", ":growing_heart:"}, + "\U0001f498": {":cupid:", ":heart_with_arrow:"}, + "\U0001f499": {":blue_heart:"}, + "\U0001f49a": {":green_heart:"}, + "\U0001f49b": {":yellow_heart:"}, + "\U0001f49c": {":purple_heart:"}, + "\U0001f49d": {":gift_heart:", ":heart_with_ribbon:"}, + "\U0001f49e": {":revolving_hearts:"}, + "\U0001f49f": {":heart_decoration:"}, + "\U0001f4a0": {":diamond_with_a_dot:", ":diamond_shape_with_a_dot_inside:"}, + "\U0001f4a1": {":bulb:", ":light_bulb:"}, + "\U0001f4a2": {":anger:", ":anger_symbol:"}, + "\U0001f4a3": {":bomb:"}, + "\U0001f4a4": {":zzz:"}, + "\U0001f4a5": {":boom:", ":collision:"}, + "\U0001f4a6": {":sweat_drops:", ":sweat_droplets:"}, + "\U0001f4a7": {":droplet:"}, + "\U0001f4a8": {":dash:", ":dashing_away:"}, + "\U0001f4a9": {":poop:", ":shit:", ":hankey:", ":pile_of_poo:"}, + "\U0001f4aa": {":muscle:", ":flexed_biceps:"}, + "\U0001f4aa\U0001f3fb": {":muscle_tone1:"}, + "\U0001f4aa\U0001f3fc": {":muscle_tone2:"}, + "\U0001f4aa\U0001f3fd": {":muscle_tone3:"}, + "\U0001f4aa\U0001f3fe": {":muscle_tone4:"}, + "\U0001f4aa\U0001f3ff": {":muscle_tone5:"}, + "\U0001f4ab": {":dizzy:"}, + "\U0001f4ac": {":speech_balloon:"}, + "\U0001f4ad": {":thought_balloon:"}, + "\U0001f4ae": {":white_flower:"}, + "\U0001f4af": {":100:", ":hundred_points:"}, + "\U0001f4b0": {":moneybag:", ":money_bag:"}, + "\U0001f4b1": {":currency_exchange:"}, + "\U0001f4b2": {":heavy_dollar_sign:"}, + "\U0001f4b3": {":credit_card:"}, + "\U0001f4b4": {":yen:", ":yen_banknote:"}, + "\U0001f4b5": {":dollar:", ":dollar_banknote:"}, + "\U0001f4b6": {":euro:", ":euro_banknote:"}, + "\U0001f4b7": {":pound:", ":pound_banknote:"}, + "\U0001f4b8": {":money_with_wings:"}, + "\U0001f4b9": {":chart:", ":chart_increasing_with_yen:"}, + "\U0001f4ba": {":seat:"}, + "\U0001f4bb": {":laptop:", ":computer:"}, + "\U0001f4bc": {":briefcase:"}, + "\U0001f4bd": {":minidisc:", ":computer_disk:"}, + "\U0001f4be": {":floppy_disk:"}, + "\U0001f4bf": {":cd:", ":optical_disk:"}, + "\U0001f4c0": {":dvd:"}, + "\U0001f4c1": {":file_folder:"}, + "\U0001f4c2": {":open_file_folder:"}, + "\U0001f4c3": {":page_with_curl:"}, + "\U0001f4c4": {":page_facing_up:"}, + "\U0001f4c5": {":date:"}, + "\U0001f4c6": {":calendar:", ":tear-off_calendar:"}, + "\U0001f4c7": {":card_index:"}, + "\U0001f4c8": {":chart_increasing:", ":chart_with_upwards_trend:"}, + "\U0001f4c9": {":chart_decreasing:", ":chart_with_downwards_trend:"}, + "\U0001f4ca": {":bar_chart:"}, + "\U0001f4cb": {":clipboard:"}, + "\U0001f4cc": {":pushpin:"}, + "\U0001f4cd": {":round_pushpin:"}, + "\U0001f4ce": {":paperclip:"}, + "\U0001f4cf": {":straight_ruler:"}, + "\U0001f4d0": {":triangular_ruler:"}, + "\U0001f4d1": {":bookmark_tabs:"}, + "\U0001f4d2": {":ledger:"}, + "\U0001f4d3": {":notebook:"}, + "\U0001f4d4": {":notebook_with_decorative_cover:"}, + "\U0001f4d5": {":closed_book:"}, + "\U0001f4d6": {":book:", ":open_book:"}, + "\U0001f4d7": {":green_book:"}, + "\U0001f4d8": {":blue_book:"}, + "\U0001f4d9": {":orange_book:"}, + "\U0001f4da": {":books:"}, + "\U0001f4db": {":name_badge:"}, + "\U0001f4dc": {":scroll:"}, + "\U0001f4dd": {":memo:"}, + "\U0001f4de": {":telephone_receiver:"}, + "\U0001f4df": {":pager:"}, + "\U0001f4e0": {":fax:", ":fax_machine:"}, + "\U0001f4e1": {":satellite_antenna:"}, + "\U0001f4e2": {":loudspeaker:"}, + "\U0001f4e3": {":mega:", ":megaphone:"}, + "\U0001f4e4": {":outbox_tray:"}, + "\U0001f4e5": {":inbox_tray:"}, + "\U0001f4e6": {":package:"}, + "\U0001f4e7": {":e-mail:"}, + "\U0001f4e8": {":incoming_envelope:"}, + "\U0001f4e9": {":envelope_with_arrow:"}, + "\U0001f4ea": {":mailbox_closed:", ":closed_mailbox_with_lowered_flag:"}, + "\U0001f4eb": {":mailbox:", ":closed_mailbox_with_raised_flag:"}, + "\U0001f4ec": {":mailbox_with_mail:", ":open_mailbox_with_raised_flag:"}, + "\U0001f4ed": {":mailbox_with_no_mail:", ":open_mailbox_with_lowered_flag:"}, + "\U0001f4ee": {":postbox:"}, + "\U0001f4ef": {":postal_horn:"}, + "\U0001f4f0": {":newspaper:"}, + "\U0001f4f1": {":iphone:", ":mobile_phone:"}, + "\U0001f4f2": {":calling:", ":mobile_phone_with_arrow:"}, + "\U0001f4f3": {":vibration_mode:"}, + "\U0001f4f4": {":mobile_phone_off:"}, + "\U0001f4f5": {":no_mobile_phones:"}, + "\U0001f4f6": {":antenna_bars:", ":signal_strength:"}, + "\U0001f4f7": {":camera:"}, + "\U0001f4f8": {":camera_flash:", ":camera_with_flash:"}, + "\U0001f4f9": {":video_camera:"}, + "\U0001f4fa": {":tv:", ":television:"}, + "\U0001f4fb": {":radio:"}, + "\U0001f4fc": {":vhs:", ":videocassette:"}, + "\U0001f4fd": {":projector:"}, + "\U0001f4fd\ufe0f": {":film_projector:"}, + "\U0001f4ff": {":prayer_beads:"}, + "\U0001f500": {":shuffle_tracks_button:", ":twisted_rightwards_arrows:"}, + "\U0001f501": {":repeat:", ":repeat_button:"}, + "\U0001f502": {":repeat_one:", ":repeat_single_button:"}, + "\U0001f503": {":arrows_clockwise:", ":clockwise_vertical_arrows:"}, + "\U0001f504": {":arrows_counterclockwise:", ":counterclockwise_arrows_button:"}, + "\U0001f505": {":dim_button:", ":low_brightness:"}, + "\U0001f506": {":bright_button:", ":high_brightness:"}, + "\U0001f507": {":mute:", ":muted_speaker:"}, + "\U0001f508": {":speaker:", ":speaker_low_volume:"}, + "\U0001f509": {":sound:", ":speaker_medium_volume:"}, + "\U0001f50a": {":loud_sound:", ":speaker_high_volume:"}, + "\U0001f50b": {":battery:"}, + "\U0001f50c": {":electric_plug:"}, + "\U0001f50d": {":mag:", ":magnifying_glass_tilted_left:"}, + "\U0001f50e": {":mag_right:", ":magnifying_glass_tilted_right:"}, + "\U0001f50f": {":locked_with_pen:", ":lock_with_ink_pen:"}, + "\U0001f510": {":locked_with_key:", ":closed_lock_with_key:"}, + "\U0001f511": {":key:"}, + "\U0001f512": {":lock:", ":locked:"}, + "\U0001f513": {":unlock:", ":unlocked:"}, + "\U0001f514": {":bell:"}, + "\U0001f515": {":no_bell:", ":bell_with_slash:"}, + "\U0001f516": {":bookmark:"}, + "\U0001f517": {":link:"}, + "\U0001f518": {":radio_button:"}, + "\U0001f519": {":back:", ":BACK_arrow:"}, + "\U0001f51a": {":end:", ":END_arrow:"}, + "\U0001f51b": {":on:", ":ON!_arrow:"}, + "\U0001f51c": {":soon:", ":SOON_arrow:"}, + "\U0001f51d": {":top:", ":TOP_arrow:"}, + "\U0001f51e": {":underage:", ":no_one_under_eighteen:"}, + "\U0001f51f": {":keycap_10:", ":keycap_ten:"}, + "\U0001f520": {":capital_abcd:", ":input_latin_uppercase:"}, + "\U0001f521": {":abcd:", ":input_latin_lowercase:"}, + "\U0001f522": {":1234:", ":input_numbers:"}, + "\U0001f523": {":symbols:", ":input_symbols:"}, + "\U0001f524": {":abc:", ":input_latin_letters:"}, + "\U0001f525": {":fire:"}, + "\U0001f526": {":flashlight:"}, + "\U0001f527": {":wrench:"}, + "\U0001f528": {":hammer:"}, + "\U0001f529": {":nut_and_bolt:"}, + "\U0001f52a": {":hocho:", ":knife:", ":kitchen_knife:"}, + "\U0001f52b": {":gun:", ":pistol:"}, + "\U0001f52c": {":microscope:"}, + "\U0001f52d": {":telescope:"}, + "\U0001f52e": {":crystal_ball:"}, + "\U0001f52f": {":six_pointed_star:", ":dotted_six-pointed_star:"}, + "\U0001f530": {":beginner:", ":Japanese_symbol_for_beginner:"}, + "\U0001f531": {":trident:", ":trident_emblem:"}, + "\U0001f532": {":black_square_button:"}, + "\U0001f533": {":white_square_button:"}, + "\U0001f534": {":red_circle:"}, + "\U0001f535": {":blue_circle:", ":large_blue_circle:"}, + "\U0001f536": {":large_orange_diamond:"}, + "\U0001f537": {":large_blue_diamond:"}, + "\U0001f538": {":small_orange_diamond:"}, + "\U0001f539": {":small_blue_diamond:"}, + "\U0001f53a": {":small_red_triangle:", ":red_triangle_pointed_up:"}, + "\U0001f53b": {":small_red_triangle_down:", ":red_triangle_pointed_down:"}, + "\U0001f53c": {":arrow_up_small:", ":upwards_button:"}, + "\U0001f53d": {":arrow_down_small:", ":downwards_button:"}, + "\U0001f549": {":om:"}, + "\U0001f549\ufe0f": {":om_symbol:"}, + "\U0001f54a": {":dove:"}, + "\U0001f54a\ufe0f": {":dove_of_peace:"}, + "\U0001f54b": {":kaaba:"}, + "\U0001f54c": {":mosque:"}, + "\U0001f54d": {":synagogue:"}, + "\U0001f54e": {":menorah:", ":menorah_with_nine_branches:"}, + "\U0001f550": {":clock1:", ":one_o’clock:"}, + "\U0001f551": {":clock2:", ":two_o’clock:"}, + "\U0001f552": {":clock3:", ":three_o’clock:"}, + "\U0001f553": {":clock4:", ":four_o’clock:"}, + "\U0001f554": {":clock5:", ":five_o’clock:"}, + "\U0001f555": {":clock6:", ":six_o’clock:"}, + "\U0001f556": {":clock7:", ":seven_o’clock:"}, + "\U0001f557": {":clock8:", ":eight_o’clock:"}, + "\U0001f558": {":clock9:", ":nine_o’clock:"}, + "\U0001f559": {":clock10:", ":ten_o’clock:"}, + "\U0001f55a": {":clock11:", ":eleven_o’clock:"}, + "\U0001f55b": {":clock12:", ":twelve_o’clock:"}, + "\U0001f55c": {":clock130:", ":one-thirty:"}, + "\U0001f55d": {":clock230:", ":two-thirty:"}, + "\U0001f55e": {":clock330:", ":three-thirty:"}, + "\U0001f55f": {":clock430:", ":four-thirty:"}, + "\U0001f560": {":clock530:", ":five-thirty:"}, + "\U0001f561": {":clock630:", ":six-thirty:"}, + "\U0001f562": {":clock730:", ":seven-thirty:"}, + "\U0001f563": {":clock830:", ":eight-thirty:"}, + "\U0001f564": {":clock930:", ":nine-thirty:"}, + "\U0001f565": {":clock1030:", ":ten-thirty:"}, + "\U0001f566": {":clock1130:", ":eleven-thirty:"}, + "\U0001f567": {":clock1230:", ":twelve-thirty:"}, + "\U0001f56f\ufe0f": {":candle:"}, + "\U0001f570": {":clock:"}, + "\U0001f570\ufe0f": {":mantelpiece_clock:"}, + "\U0001f573\ufe0f": {":hole:"}, + "\U0001f574": {":person_in_suit_levitating:"}, + "\U0001f574\U0001f3fb": {":man_in_business_suit_levitating_tone1:"}, + "\U0001f574\U0001f3fc": {":man_in_business_suit_levitating_tone2:"}, + "\U0001f574\U0001f3fd": {":man_in_business_suit_levitating_tone3:"}, + "\U0001f574\U0001f3fe": {":man_in_business_suit_levitating_tone4:"}, + "\U0001f574\U0001f3ff": {":man_in_business_suit_levitating_tone5:"}, + "\U0001f574\ufe0f": {":business_suit_levitating:", ":man_in_business_suit_levitating:"}, + "\U0001f575": {":detective:"}, + "\U0001f575\U0001f3fb": {":detective_tone1:"}, + "\U0001f575\U0001f3fb\u200d\u2640\ufe0f": {":woman_detective_tone1:"}, + "\U0001f575\U0001f3fb\u200d\u2642\ufe0f": {":man_detective_tone1:"}, + "\U0001f575\U0001f3fc": {":detective_tone2:"}, + "\U0001f575\U0001f3fc\u200d\u2640\ufe0f": {":woman_detective_tone2:"}, + "\U0001f575\U0001f3fc\u200d\u2642\ufe0f": {":man_detective_tone2:"}, + "\U0001f575\U0001f3fd": {":detective_tone3:"}, + "\U0001f575\U0001f3fd\u200d\u2640\ufe0f": {":woman_detective_tone3:"}, + "\U0001f575\U0001f3fd\u200d\u2642\ufe0f": {":man_detective_tone3:"}, + "\U0001f575\U0001f3fe": {":detective_tone4:"}, + "\U0001f575\U0001f3fe\u200d\u2640\ufe0f": {":woman_detective_tone4:"}, + "\U0001f575\U0001f3fe\u200d\u2642\ufe0f": {":man_detective_tone4:"}, + "\U0001f575\U0001f3ff": {":detective_tone5:"}, + "\U0001f575\U0001f3ff\u200d\u2640\ufe0f": {":woman_detective_tone5:"}, + "\U0001f575\U0001f3ff\u200d\u2642\ufe0f": {":man_detective_tone5:"}, + "\U0001f575\ufe0f\u200d\u2640\ufe0f": {":woman_detective:", ":female-detective:", ":female_detective:"}, + "\U0001f575\ufe0f\u200d\u2642\ufe0f": {":man_detective:", ":sleuth_or_spy:", ":male-detective:", ":male_detective:"}, + "\U0001f576\ufe0f": {":dark_sunglasses:"}, + "\U0001f577\ufe0f": {":spider:"}, + "\U0001f578\ufe0f": {":spider_web:"}, + "\U0001f579\ufe0f": {":joystick:"}, + "\U0001f57a": {":man_dancing:"}, + "\U0001f57a\U0001f3fb": {":man_dancing_tone1:"}, + "\U0001f57a\U0001f3fc": {":man_dancing_tone2:"}, + "\U0001f57a\U0001f3fd": {":man_dancing_tone3:"}, + "\U0001f57a\U0001f3fe": {":man_dancing_tone4:"}, + "\U0001f57a\U0001f3ff": {":man_dancing_tone5:"}, + "\U0001f587": {":paperclips:"}, + "\U0001f587\ufe0f": {":linked_paperclips:"}, + "\U0001f58a": {":pen:", ":pen_ballpoint:"}, + "\U0001f58a\ufe0f": {":lower_left_ballpoint_pen:"}, + "\U0001f58b": {":fountain_pen:", ":pen_fountain:"}, + "\U0001f58b\ufe0f": {":lower_left_fountain_pen:"}, + "\U0001f58c": {":paintbrush:"}, + "\U0001f58c\ufe0f": {":lower_left_paintbrush:"}, + "\U0001f58d": {":crayon:"}, + "\U0001f58d\ufe0f": {":lower_left_crayon:"}, + "\U0001f590": {":hand_with_fingers_splayed:"}, + "\U0001f590\U0001f3fb": {":hand_splayed_tone1:"}, + "\U0001f590\U0001f3fc": {":hand_splayed_tone2:"}, + "\U0001f590\U0001f3fd": {":hand_splayed_tone3:"}, + "\U0001f590\U0001f3fe": {":hand_splayed_tone4:"}, + "\U0001f590\U0001f3ff": {":hand_splayed_tone5:"}, + "\U0001f590\ufe0f": {":raised_hand_with_fingers_splayed:"}, + "\U0001f595": {":fu:", ":middle_finger:"}, + "\U0001f595\U0001f3fb": {":middle_finger_tone1:"}, + "\U0001f595\U0001f3fc": {":middle_finger_tone2:"}, + "\U0001f595\U0001f3fd": {":middle_finger_tone3:"}, + "\U0001f595\U0001f3fe": {":middle_finger_tone4:"}, + "\U0001f595\U0001f3ff": {":middle_finger_tone5:"}, + "\U0001f596": {":vulcan:", ":spock-hand:", ":vulcan_salute:"}, + "\U0001f596\U0001f3fb": {":vulcan_tone1:"}, + "\U0001f596\U0001f3fc": {":vulcan_tone2:"}, + "\U0001f596\U0001f3fd": {":vulcan_tone3:"}, + "\U0001f596\U0001f3fe": {":vulcan_tone4:"}, + "\U0001f596\U0001f3ff": {":vulcan_tone5:"}, + "\U0001f5a4": {":black_heart:"}, + "\U0001f5a5": {":desktop:"}, + "\U0001f5a5\ufe0f": {":desktop_computer:"}, + "\U0001f5a8\ufe0f": {":printer:"}, + "\U0001f5b1": {":computer_mouse:", ":mouse_three_button:"}, + "\U0001f5b1\ufe0f": {":three_button_mouse:"}, + "\U0001f5b2\ufe0f": {":trackball:"}, + "\U0001f5bc": {":frame_photo:", ":framed_picture:"}, + "\U0001f5bc\ufe0f": {":frame_with_picture:"}, + "\U0001f5c2": {":dividers:"}, + "\U0001f5c2\ufe0f": {":card_index_dividers:"}, + "\U0001f5c3": {":card_box:"}, + "\U0001f5c3\ufe0f": {":card_file_box:"}, + "\U0001f5c4\ufe0f": {":file_cabinet:"}, + "\U0001f5d1\ufe0f": {":wastebasket:"}, + "\U0001f5d2": {":notepad_spiral:", ":spiral_notepad:"}, + "\U0001f5d2\ufe0f": {":spiral_note_pad:"}, + "\U0001f5d3": {":calendar_spiral:", ":spiral_calendar:"}, + "\U0001f5d3\ufe0f": {":spiral_calendar_pad:"}, + "\U0001f5dc": {":clamp:"}, + "\U0001f5dc\ufe0f": {":compression:"}, + "\U0001f5dd": {":key2:"}, + "\U0001f5dd\ufe0f": {":old_key:"}, + "\U0001f5de": {":newspaper2:", ":rolled-up_newspaper:"}, + "\U0001f5de\ufe0f": {":newspaper_roll:", ":rolled_up_newspaper:"}, + "\U0001f5e1": {":dagger:"}, + "\U0001f5e1\ufe0f": {":dagger_knife:"}, + "\U0001f5e3": {":speaking_head:"}, + "\U0001f5e3\ufe0f": {":speaking_head_in_silhouette:"}, + "\U0001f5e8": {":speech_left:"}, + "\U0001f5e8\ufe0f": {":left_speech_bubble:"}, + "\U0001f5ef": {":anger_right:"}, + "\U0001f5ef\ufe0f": {":right_anger_bubble:"}, + "\U0001f5f3": {":ballot_box:"}, + "\U0001f5f3\ufe0f": {":ballot_box_with_ballot:"}, + "\U0001f5fa": {":map:"}, + "\U0001f5fa\ufe0f": {":world_map:"}, + "\U0001f5fb": {":mount_fuji:"}, + "\U0001f5fc": {":Tokyo_tower:", ":tokyo_tower:"}, + "\U0001f5fd": {":Statue_of_Liberty:", ":statue_of_liberty:"}, + "\U0001f5fe": {":japan:", ":map_of_Japan:"}, + "\U0001f5ff": {":moai:", ":moyai:"}, + "\U0001f600": {":grinning:", ":grinning_face:"}, + "\U0001f601": {":grin:", ":beaming_face_with_smiling_eyes:"}, + "\U0001f602": {":joy:", ":face_with_tears_of_joy:"}, + "\U0001f603": {":smiley:", ":grinning_face_with_big_eyes:"}, + "\U0001f604": {":smile:", ":grinning_face_with_smiling_eyes:"}, + "\U0001f605": {":sweat_smile:", ":grinning_face_with_sweat:"}, + "\U0001f606": {":laughing:", ":satisfied:", ":grinning_squinting_face:"}, + "\U0001f607": {":innocent:", ":smiling_face_with_halo:"}, + "\U0001f608": {":smiling_imp:", ":smiling_face_with_horns:"}, + "\U0001f609": {":wink:", ":winking_face:"}, + "\U0001f60a": {":blush:", ":smiling_face_with_smiling_eyes:"}, + "\U0001f60b": {":yum:", ":face_savoring_food:"}, + "\U0001f60c": {":relieved:", ":relieved_face:"}, + "\U0001f60d": {":heart_eyes:", ":smiling_face_with_heart-eyes:"}, + "\U0001f60e": {":sunglasses:", ":smiling_face_with_sunglasses:"}, + "\U0001f60f": {":smirk:", ":smirking_face:"}, + "\U0001f610": {":neutral_face:"}, + "\U0001f611": {":expressionless:", ":expressionless_face:"}, + "\U0001f612": {":unamused:", ":unamused_face:"}, + "\U0001f613": {":sweat:", ":downcast_face_with_sweat:"}, + "\U0001f614": {":pensive:", ":pensive_face:"}, + "\U0001f615": {":confused:", ":confused_face:"}, + "\U0001f616": {":confounded:", ":confounded_face:"}, + "\U0001f617": {":kissing:", ":kissing_face:"}, + "\U0001f618": {":kissing_heart:", ":face_blowing_a_kiss:"}, + "\U0001f619": {":kissing_smiling_eyes:", ":kissing_face_with_smiling_eyes:"}, + "\U0001f61a": {":kissing_closed_eyes:", ":kissing_face_with_closed_eyes:"}, + "\U0001f61b": {":face_with_tongue:", ":stuck_out_tongue:"}, + "\U0001f61c": {":winking_face_with_tongue:", ":stuck_out_tongue_winking_eye:"}, + "\U0001f61d": {":squinting_face_with_tongue:", ":stuck_out_tongue_closed_eyes:"}, + "\U0001f61e": {":disappointed:", ":disappointed_face:"}, + "\U0001f61f": {":worried:", ":worried_face:"}, + "\U0001f620": {":angry:", ":angry_face:"}, + "\U0001f621": {":pout:", ":rage:", ":pouting_face:"}, + "\U0001f622": {":cry:", ":crying_face:"}, + "\U0001f623": {":persevere:", ":persevering_face:"}, + "\U0001f624": {":triumph:", ":face_with_steam_from_nose:"}, + "\U0001f625": {":disappointed_relieved:", ":sad_but_relieved_face:"}, + "\U0001f626": {":frowning:", ":frowning_face_with_open_mouth:"}, + "\U0001f627": {":anguished:", ":anguished_face:"}, + "\U0001f628": {":fearful:", ":fearful_face:"}, + "\U0001f629": {":weary:", ":weary_face:"}, + "\U0001f62a": {":sleepy:", ":sleepy_face:"}, + "\U0001f62b": {":tired_face:"}, + "\U0001f62c": {":grimacing:", ":grimacing_face:"}, + "\U0001f62d": {":sob:", ":loudly_crying_face:"}, + "\U0001f62e": {":open_mouth:", ":face_with_open_mouth:"}, + "\U0001f62f": {":hushed:", ":hushed_face:"}, + "\U0001f630": {":cold_sweat:", ":anxious_face_with_sweat:"}, + "\U0001f631": {":scream:", ":face_screaming_in_fear:"}, + "\U0001f632": {":astonished:", ":astonished_face:"}, + "\U0001f633": {":flushed:", ":flushed_face:"}, + "\U0001f634": {":sleeping:", ":sleeping_face:"}, + "\U0001f635": {":dizzy_face:"}, + "\U0001f636": {":no_mouth:", ":face_without_mouth:"}, + "\U0001f637": {":mask:", ":face_with_medical_mask:"}, + "\U0001f638": {":smile_cat:", ":grinning_cat_with_smiling_eyes:"}, + "\U0001f639": {":joy_cat:", ":cat_with_tears_of_joy:"}, + "\U0001f63a": {":smiley_cat:", ":grinning_cat:"}, + "\U0001f63b": {":heart_eyes_cat:", ":smiling_cat_with_heart-eyes:"}, + "\U0001f63c": {":smirk_cat:", ":cat_with_wry_smile:"}, + "\U0001f63d": {":kissing_cat:"}, + "\U0001f63e": {":pouting_cat:"}, + "\U0001f63f": {":crying_cat:", ":crying_cat_face:"}, + "\U0001f640": {":weary_cat:", ":scream_cat:"}, + "\U0001f641": {":slight_frown:", ":slightly_frowning_face:"}, + "\U0001f642": {":slight_smile:", ":slightly_smiling_face:"}, + "\U0001f643": {":upside_down:", ":upside-down_face:", ":upside_down_face:"}, + "\U0001f644": {":roll_eyes:", ":rolling_eyes:", ":face_with_rolling_eyes:"}, + "\U0001f645": {":person_gesturing_NO:", ":person_gesturing_no:"}, + "\U0001f645\U0001f3fb": {":person_gesturing_no_tone1:"}, + "\U0001f645\U0001f3fb\u200d\u2640\ufe0f": {":woman_gesturing_no_tone1:"}, + "\U0001f645\U0001f3fb\u200d\u2642\ufe0f": {":man_gesturing_no_tone1:"}, + "\U0001f645\U0001f3fc": {":person_gesturing_no_tone2:"}, + "\U0001f645\U0001f3fc\u200d\u2640\ufe0f": {":woman_gesturing_no_tone2:"}, + "\U0001f645\U0001f3fc\u200d\u2642\ufe0f": {":man_gesturing_no_tone2:"}, + "\U0001f645\U0001f3fd": {":person_gesturing_no_tone3:"}, + "\U0001f645\U0001f3fd\u200d\u2640\ufe0f": {":woman_gesturing_no_tone3:"}, + "\U0001f645\U0001f3fd\u200d\u2642\ufe0f": {":man_gesturing_no_tone3:"}, + "\U0001f645\U0001f3fe": {":person_gesturing_no_tone4:"}, + "\U0001f645\U0001f3fe\u200d\u2640\ufe0f": {":woman_gesturing_no_tone4:"}, + "\U0001f645\U0001f3fe\u200d\u2642\ufe0f": {":man_gesturing_no_tone4:"}, + "\U0001f645\U0001f3ff": {":person_gesturing_no_tone5:"}, + "\U0001f645\U0001f3ff\u200d\u2640\ufe0f": {":woman_gesturing_no_tone5:"}, + "\U0001f645\U0001f3ff\u200d\u2642\ufe0f": {":man_gesturing_no_tone5:"}, + "\U0001f645\u200d\u2640\ufe0f": {":no_good:", ":ng_woman:", ":no_good_woman:", ":woman-gesturing-no:", ":woman_gesturing_NO:", ":woman_gesturing_no:"}, + "\U0001f645\u200d\u2642\ufe0f": {":ng_man:", ":no_good_man:", ":man-gesturing-no:", ":man_gesturing_NO:", ":man_gesturing_no:"}, + "\U0001f646": {":ok_person:", ":person_gesturing_OK:", ":person_gesturing_ok:"}, + "\U0001f646\U0001f3fb": {":person_gesturing_ok_tone1:"}, + "\U0001f646\U0001f3fb\u200d\u2640\ufe0f": {":woman_gesturing_ok_tone1:"}, + "\U0001f646\U0001f3fb\u200d\u2642\ufe0f": {":man_gesturing_ok_tone1:"}, + "\U0001f646\U0001f3fc": {":person_gesturing_ok_tone2:"}, + "\U0001f646\U0001f3fc\u200d\u2640\ufe0f": {":woman_gesturing_ok_tone2:"}, + "\U0001f646\U0001f3fc\u200d\u2642\ufe0f": {":man_gesturing_ok_tone2:"}, + "\U0001f646\U0001f3fd": {":person_gesturing_ok_tone3:"}, + "\U0001f646\U0001f3fd\u200d\u2640\ufe0f": {":woman_gesturing_ok_tone3:"}, + "\U0001f646\U0001f3fd\u200d\u2642\ufe0f": {":man_gesturing_ok_tone3:"}, + "\U0001f646\U0001f3fe": {":person_gesturing_ok_tone4:"}, + "\U0001f646\U0001f3fe\u200d\u2640\ufe0f": {":woman_gesturing_ok_tone4:"}, + "\U0001f646\U0001f3fe\u200d\u2642\ufe0f": {":man_gesturing_ok_tone4:"}, + "\U0001f646\U0001f3ff": {":person_gesturing_ok_tone5:"}, + "\U0001f646\U0001f3ff\u200d\u2640\ufe0f": {":woman_gesturing_ok_tone5:"}, + "\U0001f646\U0001f3ff\u200d\u2642\ufe0f": {":man_gesturing_ok_tone5:"}, + "\U0001f646\u200d\u2640\ufe0f": {":ok_woman:", ":woman-gesturing-ok:", ":woman_gesturing_OK:", ":woman_gesturing_ok:"}, + "\U0001f646\u200d\u2642\ufe0f": {":ok_man:", ":man-gesturing-ok:", ":man_gesturing_OK:", ":man_gesturing_ok:"}, + "\U0001f647": {":person_bowing:"}, + "\U0001f647\U0001f3fb": {":person_bowing_tone1:"}, + "\U0001f647\U0001f3fb\u200d\u2640\ufe0f": {":woman_bowing_tone1:"}, + "\U0001f647\U0001f3fb\u200d\u2642\ufe0f": {":man_bowing_tone1:"}, + "\U0001f647\U0001f3fc": {":person_bowing_tone2:"}, + "\U0001f647\U0001f3fc\u200d\u2640\ufe0f": {":woman_bowing_tone2:"}, + "\U0001f647\U0001f3fc\u200d\u2642\ufe0f": {":man_bowing_tone2:"}, + "\U0001f647\U0001f3fd": {":person_bowing_tone3:"}, + "\U0001f647\U0001f3fd\u200d\u2640\ufe0f": {":woman_bowing_tone3:"}, + "\U0001f647\U0001f3fd\u200d\u2642\ufe0f": {":man_bowing_tone3:"}, + "\U0001f647\U0001f3fe": {":person_bowing_tone4:"}, + "\U0001f647\U0001f3fe\u200d\u2640\ufe0f": {":woman_bowing_tone4:"}, + "\U0001f647\U0001f3fe\u200d\u2642\ufe0f": {":man_bowing_tone4:"}, + "\U0001f647\U0001f3ff": {":person_bowing_tone5:"}, + "\U0001f647\U0001f3ff\u200d\u2640\ufe0f": {":woman_bowing_tone5:"}, + "\U0001f647\U0001f3ff\u200d\u2642\ufe0f": {":man_bowing_tone5:"}, + "\U0001f647\u200d\u2640\ufe0f": {":bowing_woman:", ":woman-bowing:", ":woman_bowing:"}, + "\U0001f647\u200d\u2642\ufe0f": {":bow:", ":bowing_man:", ":man-bowing:", ":man_bowing:"}, + "\U0001f648": {":see_no_evil:", ":see-no-evil_monkey:"}, + "\U0001f649": {":hear_no_evil:", ":hear-no-evil_monkey:"}, + "\U0001f64a": {":speak_no_evil:", ":speak-no-evil_monkey:"}, + "\U0001f64b": {":person_raising_hand:"}, + "\U0001f64b\U0001f3fb": {":person_raising_hand_tone1:"}, + "\U0001f64b\U0001f3fb\u200d\u2640\ufe0f": {":woman_raising_hand_tone1:"}, + "\U0001f64b\U0001f3fb\u200d\u2642\ufe0f": {":man_raising_hand_tone1:"}, + "\U0001f64b\U0001f3fc": {":person_raising_hand_tone2:"}, + "\U0001f64b\U0001f3fc\u200d\u2640\ufe0f": {":woman_raising_hand_tone2:"}, + "\U0001f64b\U0001f3fc\u200d\u2642\ufe0f": {":man_raising_hand_tone2:"}, + "\U0001f64b\U0001f3fd": {":person_raising_hand_tone3:"}, + "\U0001f64b\U0001f3fd\u200d\u2640\ufe0f": {":woman_raising_hand_tone3:"}, + "\U0001f64b\U0001f3fd\u200d\u2642\ufe0f": {":man_raising_hand_tone3:"}, + "\U0001f64b\U0001f3fe": {":person_raising_hand_tone4:"}, + "\U0001f64b\U0001f3fe\u200d\u2640\ufe0f": {":woman_raising_hand_tone4:"}, + "\U0001f64b\U0001f3fe\u200d\u2642\ufe0f": {":man_raising_hand_tone4:"}, + "\U0001f64b\U0001f3ff": {":person_raising_hand_tone5:"}, + "\U0001f64b\U0001f3ff\u200d\u2640\ufe0f": {":woman_raising_hand_tone5:"}, + "\U0001f64b\U0001f3ff\u200d\u2642\ufe0f": {":man_raising_hand_tone5:"}, + "\U0001f64b\u200d\u2640\ufe0f": {":raising_hand:", ":raising_hand_woman:", ":woman-raising-hand:", ":woman_raising_hand:"}, + "\U0001f64b\u200d\u2642\ufe0f": {":man-raising-hand:", ":man_raising_hand:", ":raising_hand_man:"}, + "\U0001f64c": {":raised_hands:", ":raising_hands:"}, + "\U0001f64c\U0001f3fb": {":raised_hands_tone1:"}, + "\U0001f64c\U0001f3fc": {":raised_hands_tone2:"}, + "\U0001f64c\U0001f3fd": {":raised_hands_tone3:"}, + "\U0001f64c\U0001f3fe": {":raised_hands_tone4:"}, + "\U0001f64c\U0001f3ff": {":raised_hands_tone5:"}, + "\U0001f64d": {":frowning_person:"}, + "\U0001f64d\U0001f3fb": {":person_frowning_tone1:"}, + "\U0001f64d\U0001f3fb\u200d\u2640\ufe0f": {":woman_frowning_tone1:"}, + "\U0001f64d\U0001f3fb\u200d\u2642\ufe0f": {":man_frowning_tone1:"}, + "\U0001f64d\U0001f3fc": {":person_frowning_tone2:"}, + "\U0001f64d\U0001f3fc\u200d\u2640\ufe0f": {":woman_frowning_tone2:"}, + "\U0001f64d\U0001f3fc\u200d\u2642\ufe0f": {":man_frowning_tone2:"}, + "\U0001f64d\U0001f3fd": {":person_frowning_tone3:"}, + "\U0001f64d\U0001f3fd\u200d\u2640\ufe0f": {":woman_frowning_tone3:"}, + "\U0001f64d\U0001f3fd\u200d\u2642\ufe0f": {":man_frowning_tone3:"}, + "\U0001f64d\U0001f3fe": {":person_frowning_tone4:"}, + "\U0001f64d\U0001f3fe\u200d\u2640\ufe0f": {":woman_frowning_tone4:"}, + "\U0001f64d\U0001f3fe\u200d\u2642\ufe0f": {":man_frowning_tone4:"}, + "\U0001f64d\U0001f3ff": {":person_frowning_tone5:"}, + "\U0001f64d\U0001f3ff\u200d\u2640\ufe0f": {":woman_frowning_tone5:"}, + "\U0001f64d\U0001f3ff\u200d\u2642\ufe0f": {":man_frowning_tone5:"}, + "\U0001f64d\u200d\u2640\ufe0f": {":frowning_woman:", ":woman-frowning:", ":woman_frowning:", ":person_frowning:"}, + "\U0001f64d\u200d\u2642\ufe0f": {":frowning_man:", ":man-frowning:", ":man_frowning:"}, + "\U0001f64e": {":person_pouting:"}, + "\U0001f64e\U0001f3fb": {":person_pouting_tone1:"}, + "\U0001f64e\U0001f3fb\u200d\u2640\ufe0f": {":woman_pouting_tone1:"}, + "\U0001f64e\U0001f3fb\u200d\u2642\ufe0f": {":man_pouting_tone1:"}, + "\U0001f64e\U0001f3fc": {":person_pouting_tone2:"}, + "\U0001f64e\U0001f3fc\u200d\u2640\ufe0f": {":woman_pouting_tone2:"}, + "\U0001f64e\U0001f3fc\u200d\u2642\ufe0f": {":man_pouting_tone2:"}, + "\U0001f64e\U0001f3fd": {":person_pouting_tone3:"}, + "\U0001f64e\U0001f3fd\u200d\u2640\ufe0f": {":woman_pouting_tone3:"}, + "\U0001f64e\U0001f3fd\u200d\u2642\ufe0f": {":man_pouting_tone3:"}, + "\U0001f64e\U0001f3fe": {":person_pouting_tone4:"}, + "\U0001f64e\U0001f3fe\u200d\u2640\ufe0f": {":woman_pouting_tone4:"}, + "\U0001f64e\U0001f3fe\u200d\u2642\ufe0f": {":man_pouting_tone4:"}, + "\U0001f64e\U0001f3ff": {":person_pouting_tone5:"}, + "\U0001f64e\U0001f3ff\u200d\u2640\ufe0f": {":woman_pouting_tone5:"}, + "\U0001f64e\U0001f3ff\u200d\u2642\ufe0f": {":man_pouting_tone5:"}, + "\U0001f64e\u200d\u2640\ufe0f": {":pouting_woman:", ":woman-pouting:", ":woman_pouting:", ":person_with_pouting_face:"}, + "\U0001f64e\u200d\u2642\ufe0f": {":man-pouting:", ":man_pouting:", ":pouting_man:"}, + "\U0001f64f": {":pray:", ":folded_hands:"}, + "\U0001f64f\U0001f3fb": {":pray_tone1:"}, + "\U0001f64f\U0001f3fc": {":pray_tone2:"}, + "\U0001f64f\U0001f3fd": {":pray_tone3:"}, + "\U0001f64f\U0001f3fe": {":pray_tone4:"}, + "\U0001f64f\U0001f3ff": {":pray_tone5:"}, + "\U0001f680": {":rocket:"}, + "\U0001f681": {":helicopter:"}, + "\U0001f682": {":locomotive:", ":steam_locomotive:"}, + "\U0001f683": {":railway_car:"}, + "\U0001f684": {":bullettrain_side:", ":high-speed_train:"}, + "\U0001f685": {":bullet_train:", ":bullettrain_front:"}, + "\U0001f686": {":train2:"}, + "\U0001f687": {":metro:"}, + "\U0001f688": {":light_rail:"}, + "\U0001f689": {":station:"}, + "\U0001f68a": {":tram:"}, + "\U0001f68b": {":train:", ":tram_car:"}, + "\U0001f68c": {":bus:"}, + "\U0001f68d": {":oncoming_bus:"}, + "\U0001f68e": {":trolleybus:"}, + "\U0001f68f": {":busstop:", ":bus_stop:"}, + "\U0001f690": {":minibus:"}, + "\U0001f691": {":ambulance:"}, + "\U0001f692": {":fire_engine:"}, + "\U0001f693": {":police_car:"}, + "\U0001f694": {":oncoming_police_car:"}, + "\U0001f695": {":taxi:"}, + "\U0001f696": {":oncoming_taxi:"}, + "\U0001f697": {":car:", ":red_car:", ":automobile:"}, + "\U0001f698": {":oncoming_automobile:"}, + "\U0001f699": {":blue_car:", ":sport_utility_vehicle:"}, + "\U0001f69a": {":truck:", ":delivery_truck:"}, + "\U0001f69b": {":articulated_lorry:"}, + "\U0001f69c": {":tractor:"}, + "\U0001f69d": {":monorail:"}, + "\U0001f69e": {":mountain_railway:"}, + "\U0001f69f": {":suspension_railway:"}, + "\U0001f6a0": {":mountain_cableway:"}, + "\U0001f6a1": {":aerial_tramway:"}, + "\U0001f6a2": {":ship:"}, + "\U0001f6a3": {":person_rowing_boat:"}, + "\U0001f6a3\U0001f3fb": {":person_rowing_boat_tone1:"}, + "\U0001f6a3\U0001f3fb\u200d\u2640\ufe0f": {":woman_rowing_boat_tone1:"}, + "\U0001f6a3\U0001f3fb\u200d\u2642\ufe0f": {":man_rowing_boat_tone1:"}, + "\U0001f6a3\U0001f3fc": {":person_rowing_boat_tone2:"}, + "\U0001f6a3\U0001f3fc\u200d\u2640\ufe0f": {":woman_rowing_boat_tone2:"}, + "\U0001f6a3\U0001f3fc\u200d\u2642\ufe0f": {":man_rowing_boat_tone2:"}, + "\U0001f6a3\U0001f3fd": {":person_rowing_boat_tone3:"}, + "\U0001f6a3\U0001f3fd\u200d\u2640\ufe0f": {":woman_rowing_boat_tone3:"}, + "\U0001f6a3\U0001f3fd\u200d\u2642\ufe0f": {":man_rowing_boat_tone3:"}, + "\U0001f6a3\U0001f3fe": {":person_rowing_boat_tone4:"}, + "\U0001f6a3\U0001f3fe\u200d\u2640\ufe0f": {":woman_rowing_boat_tone4:"}, + "\U0001f6a3\U0001f3fe\u200d\u2642\ufe0f": {":man_rowing_boat_tone4:"}, + "\U0001f6a3\U0001f3ff": {":person_rowing_boat_tone5:"}, + "\U0001f6a3\U0001f3ff\u200d\u2640\ufe0f": {":woman_rowing_boat_tone5:"}, + "\U0001f6a3\U0001f3ff\u200d\u2642\ufe0f": {":man_rowing_boat_tone5:"}, + "\U0001f6a3\u200d\u2640\ufe0f": {":rowing_woman:", ":woman-rowing-boat:", ":woman_rowing_boat:"}, + "\U0001f6a3\u200d\u2642\ufe0f": {":rowboat:", ":rowing_man:", ":man-rowing-boat:", ":man_rowing_boat:"}, + "\U0001f6a4": {":speedboat:"}, + "\U0001f6a5": {":traffic_light:", ":horizontal_traffic_light:"}, + "\U0001f6a6": {":vertical_traffic_light:"}, + "\U0001f6a7": {":construction:"}, + "\U0001f6a8": {":rotating_light:", ":police_car_light:"}, + "\U0001f6a9": {":triangular_flag:", ":triangular_flag_on_post:"}, + "\U0001f6aa": {":door:"}, + "\U0001f6ab": {":prohibited:", ":no_entry_sign:"}, + "\U0001f6ac": {":smoking:", ":cigarette:"}, + "\U0001f6ad": {":no_smoking:"}, + "\U0001f6ae": {":litter_in_bin_sign:", ":put_litter_in_its_place:"}, + "\U0001f6af": {":no_littering:", ":do_not_litter:"}, + "\U0001f6b0": {":potable_water:"}, + "\U0001f6b1": {":non-potable_water:"}, + "\U0001f6b2": {":bike:", ":bicycle:"}, + "\U0001f6b3": {":no_bicycles:"}, + "\U0001f6b4": {":person_biking:"}, + "\U0001f6b4\U0001f3fb": {":person_biking_tone1:"}, + "\U0001f6b4\U0001f3fb\u200d\u2640\ufe0f": {":woman_biking_tone1:"}, + "\U0001f6b4\U0001f3fb\u200d\u2642\ufe0f": {":man_biking_tone1:"}, + "\U0001f6b4\U0001f3fc": {":person_biking_tone2:"}, + "\U0001f6b4\U0001f3fc\u200d\u2640\ufe0f": {":woman_biking_tone2:"}, + "\U0001f6b4\U0001f3fc\u200d\u2642\ufe0f": {":man_biking_tone2:"}, + "\U0001f6b4\U0001f3fd": {":person_biking_tone3:"}, + "\U0001f6b4\U0001f3fd\u200d\u2640\ufe0f": {":woman_biking_tone3:"}, + "\U0001f6b4\U0001f3fd\u200d\u2642\ufe0f": {":man_biking_tone3:"}, + "\U0001f6b4\U0001f3fe": {":person_biking_tone4:"}, + "\U0001f6b4\U0001f3fe\u200d\u2640\ufe0f": {":woman_biking_tone4:"}, + "\U0001f6b4\U0001f3fe\u200d\u2642\ufe0f": {":man_biking_tone4:"}, + "\U0001f6b4\U0001f3ff": {":person_biking_tone5:"}, + "\U0001f6b4\U0001f3ff\u200d\u2640\ufe0f": {":woman_biking_tone5:"}, + "\U0001f6b4\U0001f3ff\u200d\u2642\ufe0f": {":man_biking_tone5:"}, + "\U0001f6b4\u200d\u2640\ufe0f": {":biking_woman:", ":woman-biking:", ":woman_biking:"}, + "\U0001f6b4\u200d\u2642\ufe0f": {":bicyclist:", ":biking_man:", ":man-biking:", ":man_biking:"}, + "\U0001f6b5": {":person_mountain_biking:"}, + "\U0001f6b5\U0001f3fb": {":person_mountain_biking_tone1:"}, + "\U0001f6b5\U0001f3fb\u200d\u2640\ufe0f": {":woman_mountain_biking_tone1:"}, + "\U0001f6b5\U0001f3fb\u200d\u2642\ufe0f": {":man_mountain_biking_tone1:"}, + "\U0001f6b5\U0001f3fc": {":person_mountain_biking_tone2:"}, + "\U0001f6b5\U0001f3fc\u200d\u2640\ufe0f": {":woman_mountain_biking_tone2:"}, + "\U0001f6b5\U0001f3fc\u200d\u2642\ufe0f": {":man_mountain_biking_tone2:"}, + "\U0001f6b5\U0001f3fd": {":person_mountain_biking_tone3:"}, + "\U0001f6b5\U0001f3fd\u200d\u2640\ufe0f": {":woman_mountain_biking_tone3:"}, + "\U0001f6b5\U0001f3fd\u200d\u2642\ufe0f": {":man_mountain_biking_tone3:"}, + "\U0001f6b5\U0001f3fe": {":person_mountain_biking_tone4:"}, + "\U0001f6b5\U0001f3fe\u200d\u2640\ufe0f": {":woman_mountain_biking_tone4:"}, + "\U0001f6b5\U0001f3fe\u200d\u2642\ufe0f": {":man_mountain_biking_tone4:"}, + "\U0001f6b5\U0001f3ff": {":person_mountain_biking_tone5:"}, + "\U0001f6b5\U0001f3ff\u200d\u2640\ufe0f": {":woman_mountain_biking_tone5:"}, + "\U0001f6b5\U0001f3ff\u200d\u2642\ufe0f": {":man_mountain_biking_tone5:"}, + "\U0001f6b5\u200d\u2640\ufe0f": {":mountain_biking_woman:", ":woman-mountain-biking:", ":woman_mountain_biking:"}, + "\U0001f6b5\u200d\u2642\ufe0f": {":mountain_bicyclist:", ":man-mountain-biking:", ":man_mountain_biking:", ":mountain_biking_man:"}, + "\U0001f6b6": {":person_walking:"}, + "\U0001f6b6\U0001f3fb": {":person_walking_tone1:"}, + "\U0001f6b6\U0001f3fb\u200d\u2640\ufe0f": {":woman_walking_tone1:"}, + "\U0001f6b6\U0001f3fb\u200d\u2642\ufe0f": {":man_walking_tone1:"}, + "\U0001f6b6\U0001f3fc": {":person_walking_tone2:"}, + "\U0001f6b6\U0001f3fc\u200d\u2640\ufe0f": {":woman_walking_tone2:"}, + "\U0001f6b6\U0001f3fc\u200d\u2642\ufe0f": {":man_walking_tone2:"}, + "\U0001f6b6\U0001f3fd": {":person_walking_tone3:"}, + "\U0001f6b6\U0001f3fd\u200d\u2640\ufe0f": {":woman_walking_tone3:"}, + "\U0001f6b6\U0001f3fd\u200d\u2642\ufe0f": {":man_walking_tone3:"}, + "\U0001f6b6\U0001f3fe": {":person_walking_tone4:"}, + "\U0001f6b6\U0001f3fe\u200d\u2640\ufe0f": {":woman_walking_tone4:"}, + "\U0001f6b6\U0001f3fe\u200d\u2642\ufe0f": {":man_walking_tone4:"}, + "\U0001f6b6\U0001f3ff": {":person_walking_tone5:"}, + "\U0001f6b6\U0001f3ff\u200d\u2640\ufe0f": {":woman_walking_tone5:"}, + "\U0001f6b6\U0001f3ff\u200d\u2642\ufe0f": {":man_walking_tone5:"}, + "\U0001f6b6\u200d\u2640\ufe0f": {":walking_woman:", ":woman-walking:", ":woman_walking:"}, + "\U0001f6b6\u200d\u2642\ufe0f": {":walking:", ":man-walking:", ":man_walking:", ":walking_man:"}, + "\U0001f6b7": {":no_pedestrians:"}, + "\U0001f6b8": {":children_crossing:"}, + "\U0001f6b9": {":mens:", ":men’s_room:"}, + "\U0001f6ba": {":womens:", ":women’s_room:"}, + "\U0001f6bb": {":restroom:"}, + "\U0001f6bc": {":baby_symbol:"}, + "\U0001f6bd": {":toilet:"}, + "\U0001f6be": {":wc:", ":water_closet:"}, + "\U0001f6bf": {":shower:"}, + "\U0001f6c0": {":bath:", ":person_taking_bath:"}, + "\U0001f6c0\U0001f3fb": {":bath_tone1:"}, + "\U0001f6c0\U0001f3fc": {":bath_tone2:"}, + "\U0001f6c0\U0001f3fd": {":bath_tone3:"}, + "\U0001f6c0\U0001f3fe": {":bath_tone4:"}, + "\U0001f6c0\U0001f3ff": {":bath_tone5:"}, + "\U0001f6c1": {":bathtub:"}, + "\U0001f6c2": {":passport_control:"}, + "\U0001f6c3": {":customs:"}, + "\U0001f6c4": {":baggage_claim:"}, + "\U0001f6c5": {":left_luggage:"}, + "\U0001f6cb": {":couch:"}, + "\U0001f6cb\ufe0f": {":couch_and_lamp:"}, + "\U0001f6cc": {":sleeping_bed:", ":person_in_bed:", ":sleeping_accommodation:"}, + "\U0001f6cc\U0001f3fb": {":person_in_bed_tone1:"}, + "\U0001f6cc\U0001f3fc": {":person_in_bed_tone2:"}, + "\U0001f6cc\U0001f3fd": {":person_in_bed_tone3:"}, + "\U0001f6cc\U0001f3fe": {":person_in_bed_tone4:"}, + "\U0001f6cc\U0001f3ff": {":person_in_bed_tone5:"}, + "\U0001f6cd\ufe0f": {":shopping:", ":shopping_bags:"}, + "\U0001f6ce": {":bellhop:"}, + "\U0001f6ce\ufe0f": {":bellhop_bell:"}, + "\U0001f6cf\ufe0f": {":bed:"}, + "\U0001f6d0": {":place_of_worship:"}, + "\U0001f6d1": {":stop_sign:", ":octagonal_sign:"}, + "\U0001f6d2": {":shopping_cart:", ":shopping_trolley:"}, + "\U0001f6d5": {":hindu_temple:"}, + "\U0001f6d6": {":hut:"}, + "\U0001f6d7": {":elevator:"}, + "\U0001f6e0": {":tools:"}, + "\U0001f6e0\ufe0f": {":hammer_and_wrench:"}, + "\U0001f6e1\ufe0f": {":shield:"}, + "\U0001f6e2": {":oil:"}, + "\U0001f6e2\ufe0f": {":oil_drum:"}, + "\U0001f6e3\ufe0f": {":motorway:"}, + "\U0001f6e4\ufe0f": {":railway_track:"}, + "\U0001f6e5": {":motorboat:"}, + "\U0001f6e5\ufe0f": {":motor_boat:"}, + "\U0001f6e9": {":airplane_small:"}, + "\U0001f6e9\ufe0f": {":small_airplane:"}, + "\U0001f6eb": {":flight_departure:", ":airplane_departure:"}, + "\U0001f6ec": {":flight_arrival:", ":airplane_arrival:", ":airplane_arriving:"}, + "\U0001f6f0": {":satellite_orbital:"}, + "\U0001f6f0\ufe0f": {":satellite:", ":artificial_satellite:"}, + "\U0001f6f3": {":cruise_ship:"}, + "\U0001f6f3\ufe0f": {":passenger_ship:"}, + "\U0001f6f4": {":scooter:", ":kick_scooter:"}, + "\U0001f6f5": {":motor_scooter:"}, + "\U0001f6f6": {":canoe:"}, + "\U0001f6f7": {":sled:"}, + "\U0001f6f8": {":flying_saucer:"}, + "\U0001f6f9": {":skateboard:"}, + "\U0001f6fa": {":auto_rickshaw:"}, + "\U0001f6fb": {":pickup_truck:"}, + "\U0001f6fc": {":roller_skate:"}, + "\U0001f7e0": {":orange_circle:", ":large_orange_circle:"}, + "\U0001f7e1": {":yellow_circle:", ":large_yellow_circle:"}, + "\U0001f7e2": {":green_circle:", ":large_green_circle:"}, + "\U0001f7e3": {":purple_circle:", ":large_purple_circle:"}, + "\U0001f7e4": {":brown_circle:", ":large_brown_circle:"}, + "\U0001f7e5": {":red_square:", ":large_red_square:"}, + "\U0001f7e6": {":blue_square:", ":large_blue_square:"}, + "\U0001f7e7": {":orange_square:", ":large_orange_square:"}, + "\U0001f7e8": {":yellow_square:", ":large_yellow_square:"}, + "\U0001f7e9": {":green_square:", ":large_green_square:"}, + "\U0001f7ea": {":purple_square:", ":large_purple_square:"}, + "\U0001f7eb": {":brown_square:", ":large_brown_square:"}, + "\U0001f90c": {":pinched_fingers:"}, + "\U0001f90d": {":white_heart:"}, + "\U0001f90e": {":brown_heart:"}, + "\U0001f90f": {":pinching_hand:"}, + "\U0001f910": {":zipper_mouth:", ":zipper-mouth_face:", ":zipper_mouth_face:"}, + "\U0001f911": {":money_mouth:", ":money-mouth_face:", ":money_mouth_face:"}, + "\U0001f912": {":thermometer_face:", ":face_with_thermometer:"}, + "\U0001f913": {":nerd:", ":nerd_face:"}, + "\U0001f914": {":thinking:", ":thinking_face:"}, + "\U0001f915": {":head_bandage:", ":face_with_head-bandage:", ":face_with_head_bandage:"}, + "\U0001f916": {":robot:", ":robot_face:"}, + "\U0001f917": {":hugs:", ":hugging:", ":hugging_face:"}, + "\U0001f918": {":metal:", ":the_horns:", ":sign_of_the_horns:"}, + "\U0001f918\U0001f3fb": {":metal_tone1:"}, + "\U0001f918\U0001f3fc": {":metal_tone2:"}, + "\U0001f918\U0001f3fd": {":metal_tone3:"}, + "\U0001f918\U0001f3fe": {":metal_tone4:"}, + "\U0001f918\U0001f3ff": {":metal_tone5:"}, + "\U0001f919": {":call_me:", ":call_me_hand:"}, + "\U0001f919\U0001f3fb": {":call_me_tone1:"}, + "\U0001f919\U0001f3fc": {":call_me_tone2:"}, + "\U0001f919\U0001f3fd": {":call_me_tone3:"}, + "\U0001f919\U0001f3fe": {":call_me_tone4:"}, + "\U0001f919\U0001f3ff": {":call_me_tone5:"}, + "\U0001f91a": {":raised_back_of_hand:"}, + "\U0001f91a\U0001f3fb": {":raised_back_of_hand_tone1:"}, + "\U0001f91a\U0001f3fc": {":raised_back_of_hand_tone2:"}, + "\U0001f91a\U0001f3fd": {":raised_back_of_hand_tone3:"}, + "\U0001f91a\U0001f3fe": {":raised_back_of_hand_tone4:"}, + "\U0001f91a\U0001f3ff": {":raised_back_of_hand_tone5:"}, + "\U0001f91b": {":fist_left:", ":left-facing_fist:", ":left_facing_fist:"}, + "\U0001f91b\U0001f3fb": {":left_facing_fist_tone1:"}, + "\U0001f91b\U0001f3fc": {":left_facing_fist_tone2:"}, + "\U0001f91b\U0001f3fd": {":left_facing_fist_tone3:"}, + "\U0001f91b\U0001f3fe": {":left_facing_fist_tone4:"}, + "\U0001f91b\U0001f3ff": {":left_facing_fist_tone5:"}, + "\U0001f91c": {":fist_right:", ":right-facing_fist:", ":right_facing_fist:"}, + "\U0001f91c\U0001f3fb": {":right_facing_fist_tone1:"}, + "\U0001f91c\U0001f3fc": {":right_facing_fist_tone2:"}, + "\U0001f91c\U0001f3fd": {":right_facing_fist_tone3:"}, + "\U0001f91c\U0001f3fe": {":right_facing_fist_tone4:"}, + "\U0001f91c\U0001f3ff": {":right_facing_fist_tone5:"}, + "\U0001f91d": {":handshake:"}, + "\U0001f91e": {":crossed_fingers:", ":fingers_crossed:"}, + "\U0001f91e\U0001f3fb": {":fingers_crossed_tone1:"}, + "\U0001f91e\U0001f3fc": {":fingers_crossed_tone2:"}, + "\U0001f91e\U0001f3fd": {":fingers_crossed_tone3:"}, + "\U0001f91e\U0001f3fe": {":fingers_crossed_tone4:"}, + "\U0001f91e\U0001f3ff": {":fingers_crossed_tone5:"}, + "\U0001f91f": {":love-you_gesture:", ":love_you_gesture:", ":i_love_you_hand_sign:"}, + "\U0001f91f\U0001f3fb": {":love_you_gesture_tone1:"}, + "\U0001f91f\U0001f3fc": {":love_you_gesture_tone2:"}, + "\U0001f91f\U0001f3fd": {":love_you_gesture_tone3:"}, + "\U0001f91f\U0001f3fe": {":love_you_gesture_tone4:"}, + "\U0001f91f\U0001f3ff": {":love_you_gesture_tone5:"}, + "\U0001f920": {":cowboy:", ":cowboy_hat_face:", ":face_with_cowboy_hat:"}, + "\U0001f921": {":clown:", ":clown_face:"}, + "\U0001f922": {":nauseated_face:"}, + "\U0001f923": {":rofl:", ":rolling_on_the_floor_laughing:"}, + "\U0001f924": {":drooling_face:"}, + "\U0001f925": {":lying_face:"}, + "\U0001f926": {":facepalm:", ":face_palm:", ":person_facepalming:"}, + "\U0001f926\U0001f3fb": {":person_facepalming_tone1:"}, + "\U0001f926\U0001f3fb\u200d\u2640\ufe0f": {":woman_facepalming_tone1:"}, + "\U0001f926\U0001f3fb\u200d\u2642\ufe0f": {":man_facepalming_tone1:"}, + "\U0001f926\U0001f3fc": {":person_facepalming_tone2:"}, + "\U0001f926\U0001f3fc\u200d\u2640\ufe0f": {":woman_facepalming_tone2:"}, + "\U0001f926\U0001f3fc\u200d\u2642\ufe0f": {":man_facepalming_tone2:"}, + "\U0001f926\U0001f3fd": {":person_facepalming_tone3:"}, + "\U0001f926\U0001f3fd\u200d\u2640\ufe0f": {":woman_facepalming_tone3:"}, + "\U0001f926\U0001f3fd\u200d\u2642\ufe0f": {":man_facepalming_tone3:"}, + "\U0001f926\U0001f3fe": {":person_facepalming_tone4:"}, + "\U0001f926\U0001f3fe\u200d\u2640\ufe0f": {":woman_facepalming_tone4:"}, + "\U0001f926\U0001f3fe\u200d\u2642\ufe0f": {":man_facepalming_tone4:"}, + "\U0001f926\U0001f3ff": {":person_facepalming_tone5:"}, + "\U0001f926\U0001f3ff\u200d\u2640\ufe0f": {":woman_facepalming_tone5:"}, + "\U0001f926\U0001f3ff\u200d\u2642\ufe0f": {":man_facepalming_tone5:"}, + "\U0001f926\u200d\u2640\ufe0f": {":woman-facepalming:", ":woman_facepalming:"}, + "\U0001f926\u200d\u2642\ufe0f": {":man-facepalming:", ":man_facepalming:"}, + "\U0001f927": {":sneezing_face:"}, + "\U0001f928": {":raised_eyebrow:", ":face_with_raised_eyebrow:"}, + "\U0001f929": {":star-struck:", ":star_struck:"}, + "\U0001f92a": {":zany_face:", ":crazy_face:"}, + "\U0001f92b": {":shushing_face:"}, + "\U0001f92c": {":cursing_face:", ":face_with_symbols_on_mouth:", ":face_with_symbols_over_mouth:"}, + "\U0001f92d": {":hand_over_mouth:", ":face_with_hand_over_mouth:"}, + "\U0001f92e": {":face_vomiting:", ":vomiting_face:"}, + "\U0001f92f": {":exploding_head:"}, + "\U0001f930": {":pregnant_woman:"}, + "\U0001f930\U0001f3fb": {":pregnant_woman_tone1:"}, + "\U0001f930\U0001f3fc": {":pregnant_woman_tone2:"}, + "\U0001f930\U0001f3fd": {":pregnant_woman_tone3:"}, + "\U0001f930\U0001f3fe": {":pregnant_woman_tone4:"}, + "\U0001f930\U0001f3ff": {":pregnant_woman_tone5:"}, + "\U0001f931": {":breast-feeding:", ":breast_feeding:"}, + "\U0001f931\U0001f3fb": {":breast_feeding_tone1:"}, + "\U0001f931\U0001f3fc": {":breast_feeding_tone2:"}, + "\U0001f931\U0001f3fd": {":breast_feeding_tone3:"}, + "\U0001f931\U0001f3fe": {":breast_feeding_tone4:"}, + "\U0001f931\U0001f3ff": {":breast_feeding_tone5:"}, + "\U0001f932": {":palms_up_together:"}, + "\U0001f932\U0001f3fb": {":palms_up_together_tone1:"}, + "\U0001f932\U0001f3fc": {":palms_up_together_tone2:"}, + "\U0001f932\U0001f3fd": {":palms_up_together_tone3:"}, + "\U0001f932\U0001f3fe": {":palms_up_together_tone4:"}, + "\U0001f932\U0001f3ff": {":palms_up_together_tone5:"}, + "\U0001f933": {":selfie:"}, + "\U0001f933\U0001f3fb": {":selfie_tone1:"}, + "\U0001f933\U0001f3fc": {":selfie_tone2:"}, + "\U0001f933\U0001f3fd": {":selfie_tone3:"}, + "\U0001f933\U0001f3fe": {":selfie_tone4:"}, + "\U0001f933\U0001f3ff": {":selfie_tone5:"}, + "\U0001f934": {":prince:"}, + "\U0001f934\U0001f3fb": {":prince_tone1:"}, + "\U0001f934\U0001f3fc": {":prince_tone2:"}, + "\U0001f934\U0001f3fd": {":prince_tone3:"}, + "\U0001f934\U0001f3fe": {":prince_tone4:"}, + "\U0001f934\U0001f3ff": {":prince_tone5:"}, + "\U0001f935": {":man_in_tuxedo:", ":person_in_tuxedo:"}, + "\U0001f935\U0001f3fb": {":man_in_tuxedo_tone1:"}, + "\U0001f935\U0001f3fc": {":man_in_tuxedo_tone2:"}, + "\U0001f935\U0001f3fd": {":man_in_tuxedo_tone3:"}, + "\U0001f935\U0001f3fe": {":man_in_tuxedo_tone4:"}, + "\U0001f935\U0001f3ff": {":man_in_tuxedo_tone5:"}, + "\U0001f935\u200d\u2640\ufe0f": {":woman_in_tuxedo:"}, + "\U0001f936": {":mrs_claus:", ":Mrs._Claus:"}, + "\U0001f936\U0001f3fb": {":mrs_claus_tone1:"}, + "\U0001f936\U0001f3fc": {":mrs_claus_tone2:"}, + "\U0001f936\U0001f3fd": {":mrs_claus_tone3:"}, + "\U0001f936\U0001f3fe": {":mrs_claus_tone4:"}, + "\U0001f936\U0001f3ff": {":mrs_claus_tone5:"}, + "\U0001f937": {":shrug:", ":person_shrugging:"}, + "\U0001f937\U0001f3fb": {":person_shrugging_tone1:"}, + "\U0001f937\U0001f3fb\u200d\u2640\ufe0f": {":woman_shrugging_tone1:"}, + "\U0001f937\U0001f3fb\u200d\u2642\ufe0f": {":man_shrugging_tone1:"}, + "\U0001f937\U0001f3fc": {":person_shrugging_tone2:"}, + "\U0001f937\U0001f3fc\u200d\u2640\ufe0f": {":woman_shrugging_tone2:"}, + "\U0001f937\U0001f3fc\u200d\u2642\ufe0f": {":man_shrugging_tone2:"}, + "\U0001f937\U0001f3fd": {":person_shrugging_tone3:"}, + "\U0001f937\U0001f3fd\u200d\u2640\ufe0f": {":woman_shrugging_tone3:"}, + "\U0001f937\U0001f3fd\u200d\u2642\ufe0f": {":man_shrugging_tone3:"}, + "\U0001f937\U0001f3fe": {":person_shrugging_tone4:"}, + "\U0001f937\U0001f3fe\u200d\u2640\ufe0f": {":woman_shrugging_tone4:"}, + "\U0001f937\U0001f3fe\u200d\u2642\ufe0f": {":man_shrugging_tone4:"}, + "\U0001f937\U0001f3ff": {":person_shrugging_tone5:"}, + "\U0001f937\U0001f3ff\u200d\u2640\ufe0f": {":woman_shrugging_tone5:"}, + "\U0001f937\U0001f3ff\u200d\u2642\ufe0f": {":man_shrugging_tone5:"}, + "\U0001f937\u200d\u2640\ufe0f": {":woman-shrugging:", ":woman_shrugging:"}, + "\U0001f937\u200d\u2642\ufe0f": {":man-shrugging:", ":man_shrugging:"}, + "\U0001f938": {":cartwheeling:", ":person_cartwheeling:", ":person_doing_cartwheel:"}, + "\U0001f938\U0001f3fb": {":person_doing_cartwheel_tone1:"}, + "\U0001f938\U0001f3fb\u200d\u2640\ufe0f": {":woman_cartwheeling_tone1:"}, + "\U0001f938\U0001f3fb\u200d\u2642\ufe0f": {":man_cartwheeling_tone1:"}, + "\U0001f938\U0001f3fc": {":person_doing_cartwheel_tone2:"}, + "\U0001f938\U0001f3fc\u200d\u2640\ufe0f": {":woman_cartwheeling_tone2:"}, + "\U0001f938\U0001f3fc\u200d\u2642\ufe0f": {":man_cartwheeling_tone2:"}, + "\U0001f938\U0001f3fd": {":person_doing_cartwheel_tone3:"}, + "\U0001f938\U0001f3fd\u200d\u2640\ufe0f": {":woman_cartwheeling_tone3:"}, + "\U0001f938\U0001f3fd\u200d\u2642\ufe0f": {":man_cartwheeling_tone3:"}, + "\U0001f938\U0001f3fe": {":person_doing_cartwheel_tone4:"}, + "\U0001f938\U0001f3fe\u200d\u2640\ufe0f": {":woman_cartwheeling_tone4:"}, + "\U0001f938\U0001f3fe\u200d\u2642\ufe0f": {":man_cartwheeling_tone4:"}, + "\U0001f938\U0001f3ff": {":person_doing_cartwheel_tone5:"}, + "\U0001f938\U0001f3ff\u200d\u2640\ufe0f": {":woman_cartwheeling_tone5:"}, + "\U0001f938\U0001f3ff\u200d\u2642\ufe0f": {":man_cartwheeling_tone5:"}, + "\U0001f938\u200d\u2640\ufe0f": {":woman-cartwheeling:", ":woman_cartwheeling:"}, + "\U0001f938\u200d\u2642\ufe0f": {":man-cartwheeling:", ":man_cartwheeling:"}, + "\U0001f939": {":juggling:", ":juggling_person:", ":person_juggling:"}, + "\U0001f939\U0001f3fb": {":person_juggling_tone1:"}, + "\U0001f939\U0001f3fb\u200d\u2640\ufe0f": {":woman_juggling_tone1:"}, + "\U0001f939\U0001f3fb\u200d\u2642\ufe0f": {":man_juggling_tone1:"}, + "\U0001f939\U0001f3fc": {":person_juggling_tone2:"}, + "\U0001f939\U0001f3fc\u200d\u2640\ufe0f": {":woman_juggling_tone2:"}, + "\U0001f939\U0001f3fc\u200d\u2642\ufe0f": {":man_juggling_tone2:"}, + "\U0001f939\U0001f3fd": {":person_juggling_tone3:"}, + "\U0001f939\U0001f3fd\u200d\u2640\ufe0f": {":woman_juggling_tone3:"}, + "\U0001f939\U0001f3fd\u200d\u2642\ufe0f": {":man_juggling_tone3:"}, + "\U0001f939\U0001f3fe": {":person_juggling_tone4:"}, + "\U0001f939\U0001f3fe\u200d\u2640\ufe0f": {":woman_juggling_tone4:"}, + "\U0001f939\U0001f3fe\u200d\u2642\ufe0f": {":man_juggling_tone4:"}, + "\U0001f939\U0001f3ff": {":person_juggling_tone5:"}, + "\U0001f939\U0001f3ff\u200d\u2640\ufe0f": {":woman_juggling_tone5:"}, + "\U0001f939\U0001f3ff\u200d\u2642\ufe0f": {":man_juggling_tone5:"}, + "\U0001f939\u200d\u2640\ufe0f": {":woman-juggling:", ":woman_juggling:"}, + "\U0001f939\u200d\u2642\ufe0f": {":man-juggling:", ":man_juggling:"}, + "\U0001f93a": {":fencer:", ":person_fencing:"}, + "\U0001f93c": {":wrestlers:", ":wrestling:", ":people_wrestling:"}, + "\U0001f93c\u200d\u2640\ufe0f": {":woman-wrestling:", ":women_wrestling:"}, + "\U0001f93c\u200d\u2642\ufe0f": {":man-wrestling:", ":men_wrestling:"}, + "\U0001f93d": {":water_polo:", ":person_playing_water_polo:"}, + "\U0001f93d\U0001f3fb": {":person_playing_water_polo_tone1:"}, + "\U0001f93d\U0001f3fb\u200d\u2640\ufe0f": {":woman_playing_water_polo_tone1:"}, + "\U0001f93d\U0001f3fb\u200d\u2642\ufe0f": {":man_playing_water_polo_tone1:"}, + "\U0001f93d\U0001f3fc": {":person_playing_water_polo_tone2:"}, + "\U0001f93d\U0001f3fc\u200d\u2640\ufe0f": {":woman_playing_water_polo_tone2:"}, + "\U0001f93d\U0001f3fc\u200d\u2642\ufe0f": {":man_playing_water_polo_tone2:"}, + "\U0001f93d\U0001f3fd": {":person_playing_water_polo_tone3:"}, + "\U0001f93d\U0001f3fd\u200d\u2640\ufe0f": {":woman_playing_water_polo_tone3:"}, + "\U0001f93d\U0001f3fd\u200d\u2642\ufe0f": {":man_playing_water_polo_tone3:"}, + "\U0001f93d\U0001f3fe": {":person_playing_water_polo_tone4:"}, + "\U0001f93d\U0001f3fe\u200d\u2640\ufe0f": {":woman_playing_water_polo_tone4:"}, + "\U0001f93d\U0001f3fe\u200d\u2642\ufe0f": {":man_playing_water_polo_tone4:"}, + "\U0001f93d\U0001f3ff": {":person_playing_water_polo_tone5:"}, + "\U0001f93d\U0001f3ff\u200d\u2640\ufe0f": {":woman_playing_water_polo_tone5:"}, + "\U0001f93d\U0001f3ff\u200d\u2642\ufe0f": {":man_playing_water_polo_tone5:"}, + "\U0001f93d\u200d\u2640\ufe0f": {":woman-playing-water-polo:", ":woman_playing_water_polo:"}, + "\U0001f93d\u200d\u2642\ufe0f": {":man-playing-water-polo:", ":man_playing_water_polo:"}, + "\U0001f93e": {":handball:", ":handball_person:", ":person_playing_handball:"}, + "\U0001f93e\U0001f3fb": {":person_playing_handball_tone1:"}, + "\U0001f93e\U0001f3fb\u200d\u2640\ufe0f": {":woman_playing_handball_tone1:"}, + "\U0001f93e\U0001f3fb\u200d\u2642\ufe0f": {":man_playing_handball_tone1:"}, + "\U0001f93e\U0001f3fc": {":person_playing_handball_tone2:"}, + "\U0001f93e\U0001f3fc\u200d\u2640\ufe0f": {":woman_playing_handball_tone2:"}, + "\U0001f93e\U0001f3fc\u200d\u2642\ufe0f": {":man_playing_handball_tone2:"}, + "\U0001f93e\U0001f3fd": {":person_playing_handball_tone3:"}, + "\U0001f93e\U0001f3fd\u200d\u2640\ufe0f": {":woman_playing_handball_tone3:"}, + "\U0001f93e\U0001f3fd\u200d\u2642\ufe0f": {":man_playing_handball_tone3:"}, + "\U0001f93e\U0001f3fe": {":person_playing_handball_tone4:"}, + "\U0001f93e\U0001f3fe\u200d\u2640\ufe0f": {":woman_playing_handball_tone4:"}, + "\U0001f93e\U0001f3fe\u200d\u2642\ufe0f": {":man_playing_handball_tone4:"}, + "\U0001f93e\U0001f3ff": {":person_playing_handball_tone5:"}, + "\U0001f93e\U0001f3ff\u200d\u2640\ufe0f": {":woman_playing_handball_tone5:"}, + "\U0001f93e\U0001f3ff\u200d\u2642\ufe0f": {":man_playing_handball_tone5:"}, + "\U0001f93e\u200d\u2640\ufe0f": {":woman-playing-handball:", ":woman_playing_handball:"}, + "\U0001f93e\u200d\u2642\ufe0f": {":man-playing-handball:", ":man_playing_handball:"}, + "\U0001f93f": {":diving_mask:"}, + "\U0001f940": {":wilted_rose:", ":wilted_flower:"}, + "\U0001f941": {":drum:", ":drum_with_drumsticks:"}, + "\U0001f942": {":champagne_glass:", ":clinking_glasses:"}, + "\U0001f943": {":tumbler_glass:"}, + "\U0001f944": {":spoon:"}, + "\U0001f945": {":goal:", ":goal_net:"}, + "\U0001f947": {":first_place:", ":1st_place_medal:", ":first_place_medal:"}, + "\U0001f948": {":second_place:", ":2nd_place_medal:", ":second_place_medal:"}, + "\U0001f949": {":third_place:", ":3rd_place_medal:", ":third_place_medal:"}, + "\U0001f94a": {":boxing_glove:"}, + "\U0001f94b": {":martial_arts_uniform:"}, + "\U0001f94c": {":curling_stone:"}, + "\U0001f94d": {":lacrosse:"}, + "\U0001f94e": {":softball:"}, + "\U0001f94f": {":flying_disc:"}, + "\U0001f950": {":croissant:"}, + "\U0001f951": {":avocado:"}, + "\U0001f952": {":cucumber:"}, + "\U0001f953": {":bacon:"}, + "\U0001f954": {":potato:"}, + "\U0001f955": {":carrot:"}, + "\U0001f956": {":french_bread:", ":baguette_bread:"}, + "\U0001f957": {":salad:", ":green_salad:"}, + "\U0001f958": {":shallow_pan_of_food:"}, + "\U0001f959": {":stuffed_flatbread:"}, + "\U0001f95a": {":egg:"}, + "\U0001f95b": {":milk:", ":milk_glass:", ":glass_of_milk:"}, + "\U0001f95c": {":peanuts:"}, + "\U0001f95d": {":kiwi:", ":kiwifruit:", ":kiwi_fruit:"}, + "\U0001f95e": {":pancakes:"}, + "\U0001f95f": {":dumpling:"}, + "\U0001f960": {":fortune_cookie:"}, + "\U0001f961": {":takeout_box:"}, + "\U0001f962": {":chopsticks:"}, + "\U0001f963": {":bowl_with_spoon:"}, + "\U0001f964": {":cup_with_straw:"}, + "\U0001f965": {":coconut:"}, + "\U0001f966": {":broccoli:"}, + "\U0001f967": {":pie:"}, + "\U0001f968": {":pretzel:"}, + "\U0001f969": {":cut_of_meat:"}, + "\U0001f96a": {":sandwich:"}, + "\U0001f96b": {":canned_food:"}, + "\U0001f96c": {":leafy_green:"}, + "\U0001f96d": {":mango:"}, + "\U0001f96e": {":moon_cake:"}, + "\U0001f96f": {":bagel:"}, + "\U0001f970": {":smiling_face_with_hearts:", ":smiling_face_with_3_hearts:", ":smiling_face_with_three_hearts:"}, + "\U0001f971": {":yawning_face:"}, + "\U0001f972": {":smiling_face_with_tear:"}, + "\U0001f973": {":partying_face:"}, + "\U0001f974": {":woozy_face:"}, + "\U0001f975": {":hot_face:"}, + "\U0001f976": {":cold_face:"}, + "\U0001f977": {":ninja:"}, + "\U0001f978": {":disguised_face:"}, + "\U0001f97a": {":pleading_face:"}, + "\U0001f97b": {":sari:"}, + "\U0001f97c": {":lab_coat:"}, + "\U0001f97d": {":goggles:"}, + "\U0001f97e": {":hiking_boot:"}, + "\U0001f97f": {":flat_shoe:", ":womans_flat_shoe:"}, + "\U0001f980": {":crab:"}, + "\U0001f981": {":lion:", ":lion_face:"}, + "\U0001f982": {":scorpion:"}, + "\U0001f983": {":turkey:"}, + "\U0001f984": {":unicorn:", ":unicorn_face:"}, + "\U0001f985": {":eagle:"}, + "\U0001f986": {":duck:"}, + "\U0001f987": {":bat:"}, + "\U0001f988": {":shark:"}, + "\U0001f989": {":owl:"}, + "\U0001f98a": {":fox:", ":fox_face:"}, + "\U0001f98b": {":butterfly:"}, + "\U0001f98c": {":deer:"}, + "\U0001f98d": {":gorilla:"}, + "\U0001f98e": {":lizard:"}, + "\U0001f98f": {":rhino:", ":rhinoceros:"}, + "\U0001f990": {":shrimp:"}, + "\U0001f991": {":squid:"}, + "\U0001f992": {":giraffe:", ":giraffe_face:"}, + "\U0001f993": {":zebra:", ":zebra_face:"}, + "\U0001f994": {":hedgehog:"}, + "\U0001f995": {":sauropod:"}, + "\U0001f996": {":T-Rex:", ":t-rex:", ":t_rex:"}, + "\U0001f997": {":cricket:"}, + "\U0001f998": {":kangaroo:"}, + "\U0001f999": {":llama:"}, + "\U0001f99a": {":peacock:"}, + "\U0001f99b": {":hippopotamus:"}, + "\U0001f99c": {":parrot:"}, + "\U0001f99d": {":raccoon:"}, + "\U0001f99e": {":lobster:"}, + "\U0001f99f": {":mosquito:"}, + "\U0001f9a0": {":microbe:"}, + "\U0001f9a1": {":badger:"}, + "\U0001f9a2": {":swan:"}, + "\U0001f9a3": {":mammoth:"}, + "\U0001f9a4": {":dodo:"}, + "\U0001f9a5": {":sloth:"}, + "\U0001f9a6": {":otter:"}, + "\U0001f9a7": {":orangutan:"}, + "\U0001f9a8": {":skunk:"}, + "\U0001f9a9": {":flamingo:"}, + "\U0001f9aa": {":oyster:"}, + "\U0001f9ab": {":beaver:"}, + "\U0001f9ac": {":bison:"}, + "\U0001f9ad": {":seal:"}, + "\U0001f9ae": {":guide_dog:"}, + "\U0001f9af": {":white_cane:", ":probing_cane:"}, + "\U0001f9b0": {":red_hair:"}, + "\U0001f9b1": {":curly_hair:"}, + "\U0001f9b2": {":bald:"}, + "\U0001f9b3": {":white_hair:"}, + "\U0001f9b4": {":bone:"}, + "\U0001f9b5": {":leg:"}, + "\U0001f9b6": {":foot:"}, + "\U0001f9b7": {":tooth:"}, + "\U0001f9b8": {":superhero:"}, + "\U0001f9b8\u200d\u2640\ufe0f": {":superhero_woman:", ":woman_superhero:", ":female_superhero:"}, + "\U0001f9b8\u200d\u2642\ufe0f": {":man_superhero:", ":superhero_man:", ":male_superhero:"}, + "\U0001f9b9": {":supervillain:"}, + "\U0001f9b9\u200d\u2640\ufe0f": {":supervillain_woman:", ":woman_supervillain:", ":female_supervillain:"}, + "\U0001f9b9\u200d\u2642\ufe0f": {":man_supervillain:", ":supervillain_man:", ":male_supervillain:"}, + "\U0001f9ba": {":safety_vest:"}, + "\U0001f9bb": {":ear_with_hearing_aid:"}, + "\U0001f9bc": {":motorized_wheelchair:"}, + "\U0001f9bd": {":manual_wheelchair:"}, + "\U0001f9be": {":mechanical_arm:"}, + "\U0001f9bf": {":mechanical_leg:"}, + "\U0001f9c0": {":cheese:", ":cheese_wedge:"}, + "\U0001f9c1": {":cupcake:"}, + "\U0001f9c2": {":salt:"}, + "\U0001f9c3": {":beverage_box:"}, + "\U0001f9c4": {":garlic:"}, + "\U0001f9c5": {":onion:"}, + "\U0001f9c6": {":falafel:"}, + "\U0001f9c7": {":waffle:"}, + "\U0001f9c8": {":butter:"}, + "\U0001f9c9": {":mate:", ":mate_drink:"}, + "\U0001f9ca": {":ice:", ":ice_cube:"}, + "\U0001f9cb": {":bubble_tea:"}, + "\U0001f9cd": {":person_standing:", ":standing_person:"}, + "\U0001f9cd\u200d\u2640\ufe0f": {":standing_woman:", ":woman_standing:"}, + "\U0001f9cd\u200d\u2642\ufe0f": {":man_standing:", ":standing_man:"}, + "\U0001f9ce": {":kneeling_person:", ":person_kneeling:"}, + "\U0001f9ce\u200d\u2640\ufe0f": {":kneeling_woman:", ":woman_kneeling:"}, + "\U0001f9ce\u200d\u2642\ufe0f": {":kneeling_man:", ":man_kneeling:"}, + "\U0001f9cf": {":deaf_person:"}, + "\U0001f9cf\u200d\u2640\ufe0f": {":deaf_woman:"}, + "\U0001f9cf\u200d\u2642\ufe0f": {":deaf_man:"}, + "\U0001f9d0": {":monocle_face:", ":face_with_monocle:"}, + "\U0001f9d1": {":adult:", ":person:"}, + "\U0001f9d1\U0001f3fb": {":adult_tone1:"}, + "\U0001f9d1\U0001f3fc": {":adult_tone2:"}, + "\U0001f9d1\U0001f3fd": {":adult_tone3:"}, + "\U0001f9d1\U0001f3fe": {":adult_tone4:"}, + "\U0001f9d1\U0001f3ff": {":adult_tone5:"}, + "\U0001f9d1\u200d\U0001f33e": {":farmer:"}, + "\U0001f9d1\u200d\U0001f373": {":cook:"}, + "\U0001f9d1\u200d\U0001f37c": {":person_feeding_baby:"}, + "\U0001f9d1\u200d\U0001f384": {":mx_claus:"}, + "\U0001f9d1\u200d\U0001f393": {":student:"}, + "\U0001f9d1\u200d\U0001f3a4": {":singer:"}, + "\U0001f9d1\u200d\U0001f3a8": {":artist:"}, + "\U0001f9d1\u200d\U0001f3eb": {":teacher:"}, + "\U0001f9d1\u200d\U0001f3ed": {":factory_worker:"}, + "\U0001f9d1\u200d\U0001f4bb": {":technologist:"}, + "\U0001f9d1\u200d\U0001f4bc": {":office_worker:"}, + "\U0001f9d1\u200d\U0001f527": {":mechanic:"}, + "\U0001f9d1\u200d\U0001f52c": {":scientist:"}, + "\U0001f9d1\u200d\U0001f680": {":astronaut:"}, + "\U0001f9d1\u200d\U0001f692": {":firefighter:"}, + "\U0001f9d1\u200d\U0001f91d\u200d\U0001f9d1": {":people_holding_hands:"}, + "\U0001f9d1\u200d\U0001f9af": {":person_with_white_cane:", ":person_with_probing_cane:"}, + "\U0001f9d1\u200d\U0001f9b0": {":person_red_hair:", ":red_haired_person:"}, + "\U0001f9d1\u200d\U0001f9b1": {":person_curly_hair:", ":curly_haired_person:"}, + "\U0001f9d1\u200d\U0001f9b2": {":bald_person:", ":person_bald:"}, + "\U0001f9d1\u200d\U0001f9b3": {":person_white_hair:", ":white_haired_person:"}, + "\U0001f9d1\u200d\U0001f9bc": {":person_in_motorized_wheelchair:"}, + "\U0001f9d1\u200d\U0001f9bd": {":person_in_manual_wheelchair:"}, + "\U0001f9d1\u200d\u2695\ufe0f": {":health_worker:"}, + "\U0001f9d1\u200d\u2696\ufe0f": {":judge:"}, + "\U0001f9d1\u200d\u2708\ufe0f": {":pilot:"}, + "\U0001f9d2": {":child:"}, + "\U0001f9d2\U0001f3fb": {":child_tone1:"}, + "\U0001f9d2\U0001f3fc": {":child_tone2:"}, + "\U0001f9d2\U0001f3fd": {":child_tone3:"}, + "\U0001f9d2\U0001f3fe": {":child_tone4:"}, + "\U0001f9d2\U0001f3ff": {":child_tone5:"}, + "\U0001f9d3": {":older_adult:", ":older_person:"}, + "\U0001f9d3\U0001f3fb": {":older_adult_tone1:"}, + "\U0001f9d3\U0001f3fc": {":older_adult_tone2:"}, + "\U0001f9d3\U0001f3fd": {":older_adult_tone3:"}, + "\U0001f9d3\U0001f3fe": {":older_adult_tone4:"}, + "\U0001f9d3\U0001f3ff": {":older_adult_tone5:"}, + "\U0001f9d4": {":man_beard:", ":bearded_person:"}, + "\U0001f9d4\U0001f3fb": {":bearded_person_tone1:"}, + "\U0001f9d4\U0001f3fc": {":bearded_person_tone2:"}, + "\U0001f9d4\U0001f3fd": {":bearded_person_tone3:"}, + "\U0001f9d4\U0001f3fe": {":bearded_person_tone4:"}, + "\U0001f9d4\U0001f3ff": {":bearded_person_tone5:"}, + "\U0001f9d5": {":woman_with_headscarf:", ":person_with_headscarf:"}, + "\U0001f9d5\U0001f3fb": {":woman_with_headscarf_tone1:"}, + "\U0001f9d5\U0001f3fc": {":woman_with_headscarf_tone2:"}, + "\U0001f9d5\U0001f3fd": {":woman_with_headscarf_tone3:"}, + "\U0001f9d5\U0001f3fe": {":woman_with_headscarf_tone4:"}, + "\U0001f9d5\U0001f3ff": {":woman_with_headscarf_tone5:"}, + "\U0001f9d6": {":sauna_person:"}, + "\U0001f9d6\U0001f3fb": {":person_in_steamy_room_tone1:"}, + "\U0001f9d6\U0001f3fb\u200d\u2640\ufe0f": {":woman_in_steamy_room_tone1:"}, + "\U0001f9d6\U0001f3fb\u200d\u2642\ufe0f": {":man_in_steamy_room_tone1:"}, + "\U0001f9d6\U0001f3fc": {":person_in_steamy_room_tone2:"}, + "\U0001f9d6\U0001f3fc\u200d\u2640\ufe0f": {":woman_in_steamy_room_tone2:"}, + "\U0001f9d6\U0001f3fc\u200d\u2642\ufe0f": {":man_in_steamy_room_tone2:"}, + "\U0001f9d6\U0001f3fd": {":person_in_steamy_room_tone3:"}, + "\U0001f9d6\U0001f3fd\u200d\u2640\ufe0f": {":woman_in_steamy_room_tone3:"}, + "\U0001f9d6\U0001f3fd\u200d\u2642\ufe0f": {":man_in_steamy_room_tone3:"}, + "\U0001f9d6\U0001f3fe": {":person_in_steamy_room_tone4:"}, + "\U0001f9d6\U0001f3fe\u200d\u2640\ufe0f": {":woman_in_steamy_room_tone4:"}, + "\U0001f9d6\U0001f3fe\u200d\u2642\ufe0f": {":man_in_steamy_room_tone4:"}, + "\U0001f9d6\U0001f3ff": {":person_in_steamy_room_tone5:"}, + "\U0001f9d6\U0001f3ff\u200d\u2640\ufe0f": {":woman_in_steamy_room_tone5:"}, + "\U0001f9d6\U0001f3ff\u200d\u2642\ufe0f": {":man_in_steamy_room_tone5:"}, + "\U0001f9d6\u200d\u2640\ufe0f": {":sauna_woman:", ":woman_in_steamy_room:"}, + "\U0001f9d6\u200d\u2642\ufe0f": {":sauna_man:", ":man_in_steamy_room:", ":person_in_steamy_room:"}, + "\U0001f9d7": {":climbing:"}, + "\U0001f9d7\U0001f3fb": {":person_climbing_tone1:"}, + "\U0001f9d7\U0001f3fb\u200d\u2640\ufe0f": {":woman_climbing_tone1:"}, + "\U0001f9d7\U0001f3fb\u200d\u2642\ufe0f": {":man_climbing_tone1:"}, + "\U0001f9d7\U0001f3fc": {":person_climbing_tone2:"}, + "\U0001f9d7\U0001f3fc\u200d\u2640\ufe0f": {":woman_climbing_tone2:"}, + "\U0001f9d7\U0001f3fc\u200d\u2642\ufe0f": {":man_climbing_tone2:"}, + "\U0001f9d7\U0001f3fd": {":person_climbing_tone3:"}, + "\U0001f9d7\U0001f3fd\u200d\u2640\ufe0f": {":woman_climbing_tone3:"}, + "\U0001f9d7\U0001f3fd\u200d\u2642\ufe0f": {":man_climbing_tone3:"}, + "\U0001f9d7\U0001f3fe": {":person_climbing_tone4:"}, + "\U0001f9d7\U0001f3fe\u200d\u2640\ufe0f": {":woman_climbing_tone4:"}, + "\U0001f9d7\U0001f3fe\u200d\u2642\ufe0f": {":man_climbing_tone4:"}, + "\U0001f9d7\U0001f3ff": {":person_climbing_tone5:"}, + "\U0001f9d7\U0001f3ff\u200d\u2640\ufe0f": {":woman_climbing_tone5:"}, + "\U0001f9d7\U0001f3ff\u200d\u2642\ufe0f": {":man_climbing_tone5:"}, + "\U0001f9d7\u200d\u2640\ufe0f": {":climbing_woman:", ":woman_climbing:", ":person_climbing:"}, + "\U0001f9d7\u200d\u2642\ufe0f": {":climbing_man:", ":man_climbing:"}, + "\U0001f9d8": {":lotus_position:"}, + "\U0001f9d8\U0001f3fb": {":person_in_lotus_position_tone1:"}, + "\U0001f9d8\U0001f3fb\u200d\u2640\ufe0f": {":woman_in_lotus_position_tone1:"}, + "\U0001f9d8\U0001f3fb\u200d\u2642\ufe0f": {":man_in_lotus_position_tone1:"}, + "\U0001f9d8\U0001f3fc": {":person_in_lotus_position_tone2:"}, + "\U0001f9d8\U0001f3fc\u200d\u2640\ufe0f": {":woman_in_lotus_position_tone2:"}, + "\U0001f9d8\U0001f3fc\u200d\u2642\ufe0f": {":man_in_lotus_position_tone2:"}, + "\U0001f9d8\U0001f3fd": {":person_in_lotus_position_tone3:"}, + "\U0001f9d8\U0001f3fd\u200d\u2640\ufe0f": {":woman_in_lotus_position_tone3:"}, + "\U0001f9d8\U0001f3fd\u200d\u2642\ufe0f": {":man_in_lotus_position_tone3:"}, + "\U0001f9d8\U0001f3fe": {":person_in_lotus_position_tone4:"}, + "\U0001f9d8\U0001f3fe\u200d\u2640\ufe0f": {":woman_in_lotus_position_tone4:"}, + "\U0001f9d8\U0001f3fe\u200d\u2642\ufe0f": {":man_in_lotus_position_tone4:"}, + "\U0001f9d8\U0001f3ff": {":person_in_lotus_position_tone5:"}, + "\U0001f9d8\U0001f3ff\u200d\u2640\ufe0f": {":woman_in_lotus_position_tone5:"}, + "\U0001f9d8\U0001f3ff\u200d\u2642\ufe0f": {":man_in_lotus_position_tone5:"}, + "\U0001f9d8\u200d\u2640\ufe0f": {":lotus_position_woman:", ":woman_in_lotus_position:", ":person_in_lotus_position:"}, + "\U0001f9d8\u200d\u2642\ufe0f": {":lotus_position_man:", ":man_in_lotus_position:"}, + "\U0001f9d9\U0001f3fb": {":mage_tone1:"}, + "\U0001f9d9\U0001f3fb\u200d\u2640\ufe0f": {":woman_mage_tone1:"}, + "\U0001f9d9\U0001f3fb\u200d\u2642\ufe0f": {":man_mage_tone1:"}, + "\U0001f9d9\U0001f3fc": {":mage_tone2:"}, + "\U0001f9d9\U0001f3fc\u200d\u2640\ufe0f": {":woman_mage_tone2:"}, + "\U0001f9d9\U0001f3fc\u200d\u2642\ufe0f": {":man_mage_tone2:"}, + "\U0001f9d9\U0001f3fd": {":mage_tone3:"}, + "\U0001f9d9\U0001f3fd\u200d\u2640\ufe0f": {":woman_mage_tone3:"}, + "\U0001f9d9\U0001f3fd\u200d\u2642\ufe0f": {":man_mage_tone3:"}, + "\U0001f9d9\U0001f3fe": {":mage_tone4:"}, + "\U0001f9d9\U0001f3fe\u200d\u2640\ufe0f": {":woman_mage_tone4:"}, + "\U0001f9d9\U0001f3fe\u200d\u2642\ufe0f": {":man_mage_tone4:"}, + "\U0001f9d9\U0001f3ff": {":mage_tone5:"}, + "\U0001f9d9\U0001f3ff\u200d\u2640\ufe0f": {":woman_mage_tone5:"}, + "\U0001f9d9\U0001f3ff\u200d\u2642\ufe0f": {":man_mage_tone5:"}, + "\U0001f9d9\u200d\u2640\ufe0f": {":mage:", ":mage_woman:", ":woman_mage:", ":female_mage:"}, + "\U0001f9d9\u200d\u2642\ufe0f": {":mage_man:", ":man_mage:", ":male_mage:"}, + "\U0001f9da\U0001f3fb": {":fairy_tone1:"}, + "\U0001f9da\U0001f3fb\u200d\u2640\ufe0f": {":woman_fairy_tone1:"}, + "\U0001f9da\U0001f3fb\u200d\u2642\ufe0f": {":man_fairy_tone1:"}, + "\U0001f9da\U0001f3fc": {":fairy_tone2:"}, + "\U0001f9da\U0001f3fc\u200d\u2640\ufe0f": {":woman_fairy_tone2:"}, + "\U0001f9da\U0001f3fc\u200d\u2642\ufe0f": {":man_fairy_tone2:"}, + "\U0001f9da\U0001f3fd": {":fairy_tone3:"}, + "\U0001f9da\U0001f3fd\u200d\u2640\ufe0f": {":woman_fairy_tone3:"}, + "\U0001f9da\U0001f3fd\u200d\u2642\ufe0f": {":man_fairy_tone3:"}, + "\U0001f9da\U0001f3fe": {":fairy_tone4:"}, + "\U0001f9da\U0001f3fe\u200d\u2640\ufe0f": {":woman_fairy_tone4:"}, + "\U0001f9da\U0001f3fe\u200d\u2642\ufe0f": {":man_fairy_tone4:"}, + "\U0001f9da\U0001f3ff": {":fairy_tone5:"}, + "\U0001f9da\U0001f3ff\u200d\u2640\ufe0f": {":woman_fairy_tone5:"}, + "\U0001f9da\U0001f3ff\u200d\u2642\ufe0f": {":man_fairy_tone5:"}, + "\U0001f9da\u200d\u2640\ufe0f": {":fairy:", ":fairy_woman:", ":woman_fairy:", ":female_fairy:"}, + "\U0001f9da\u200d\u2642\ufe0f": {":fairy_man:", ":man_fairy:", ":male_fairy:"}, + "\U0001f9db\U0001f3fb": {":vampire_tone1:"}, + "\U0001f9db\U0001f3fb\u200d\u2640\ufe0f": {":woman_vampire_tone1:"}, + "\U0001f9db\U0001f3fb\u200d\u2642\ufe0f": {":man_vampire_tone1:"}, + "\U0001f9db\U0001f3fc": {":vampire_tone2:"}, + "\U0001f9db\U0001f3fc\u200d\u2640\ufe0f": {":woman_vampire_tone2:"}, + "\U0001f9db\U0001f3fc\u200d\u2642\ufe0f": {":man_vampire_tone2:"}, + "\U0001f9db\U0001f3fd": {":vampire_tone3:"}, + "\U0001f9db\U0001f3fd\u200d\u2640\ufe0f": {":woman_vampire_tone3:"}, + "\U0001f9db\U0001f3fd\u200d\u2642\ufe0f": {":man_vampire_tone3:"}, + "\U0001f9db\U0001f3fe": {":vampire_tone4:"}, + "\U0001f9db\U0001f3fe\u200d\u2640\ufe0f": {":woman_vampire_tone4:"}, + "\U0001f9db\U0001f3fe\u200d\u2642\ufe0f": {":man_vampire_tone4:"}, + "\U0001f9db\U0001f3ff": {":vampire_tone5:"}, + "\U0001f9db\U0001f3ff\u200d\u2640\ufe0f": {":woman_vampire_tone5:"}, + "\U0001f9db\U0001f3ff\u200d\u2642\ufe0f": {":man_vampire_tone5:"}, + "\U0001f9db\u200d\u2640\ufe0f": {":vampire:", ":vampire_woman:", ":woman_vampire:", ":female_vampire:"}, + "\U0001f9db\u200d\u2642\ufe0f": {":man_vampire:", ":vampire_man:", ":male_vampire:"}, + "\U0001f9dc\U0001f3fb": {":merperson_tone1:"}, + "\U0001f9dc\U0001f3fb\u200d\u2640\ufe0f": {":mermaid_tone1:"}, + "\U0001f9dc\U0001f3fb\u200d\u2642\ufe0f": {":merman_tone1:"}, + "\U0001f9dc\U0001f3fc": {":merperson_tone2:"}, + "\U0001f9dc\U0001f3fc\u200d\u2640\ufe0f": {":mermaid_tone2:"}, + "\U0001f9dc\U0001f3fc\u200d\u2642\ufe0f": {":merman_tone2:"}, + "\U0001f9dc\U0001f3fd": {":merperson_tone3:"}, + "\U0001f9dc\U0001f3fd\u200d\u2640\ufe0f": {":mermaid_tone3:"}, + "\U0001f9dc\U0001f3fd\u200d\u2642\ufe0f": {":merman_tone3:"}, + "\U0001f9dc\U0001f3fe": {":merperson_tone4:"}, + "\U0001f9dc\U0001f3fe\u200d\u2640\ufe0f": {":mermaid_tone4:"}, + "\U0001f9dc\U0001f3fe\u200d\u2642\ufe0f": {":merman_tone4:"}, + "\U0001f9dc\U0001f3ff": {":merperson_tone5:"}, + "\U0001f9dc\U0001f3ff\u200d\u2640\ufe0f": {":mermaid_tone5:"}, + "\U0001f9dc\U0001f3ff\u200d\u2642\ufe0f": {":merman_tone5:"}, + "\U0001f9dc\u200d\u2640\ufe0f": {":mermaid:"}, + "\U0001f9dc\u200d\u2642\ufe0f": {":merman:", ":merperson:"}, + "\U0001f9dd\U0001f3fb": {":elf_tone1:"}, + "\U0001f9dd\U0001f3fb\u200d\u2640\ufe0f": {":woman_elf_tone1:"}, + "\U0001f9dd\U0001f3fb\u200d\u2642\ufe0f": {":man_elf_tone1:"}, + "\U0001f9dd\U0001f3fc": {":elf_tone2:"}, + "\U0001f9dd\U0001f3fc\u200d\u2640\ufe0f": {":woman_elf_tone2:"}, + "\U0001f9dd\U0001f3fc\u200d\u2642\ufe0f": {":man_elf_tone2:"}, + "\U0001f9dd\U0001f3fd": {":elf_tone3:"}, + "\U0001f9dd\U0001f3fd\u200d\u2640\ufe0f": {":woman_elf_tone3:"}, + "\U0001f9dd\U0001f3fd\u200d\u2642\ufe0f": {":man_elf_tone3:"}, + "\U0001f9dd\U0001f3fe": {":elf_tone4:"}, + "\U0001f9dd\U0001f3fe\u200d\u2640\ufe0f": {":woman_elf_tone4:"}, + "\U0001f9dd\U0001f3fe\u200d\u2642\ufe0f": {":man_elf_tone4:"}, + "\U0001f9dd\U0001f3ff": {":elf_tone5:"}, + "\U0001f9dd\U0001f3ff\u200d\u2640\ufe0f": {":woman_elf_tone5:"}, + "\U0001f9dd\U0001f3ff\u200d\u2642\ufe0f": {":man_elf_tone5:"}, + "\U0001f9dd\u200d\u2640\ufe0f": {":elf_woman:", ":woman_elf:", ":female_elf:"}, + "\U0001f9dd\u200d\u2642\ufe0f": {":elf:", ":elf_man:", ":man_elf:", ":male_elf:"}, + "\U0001f9de\u200d\u2640\ufe0f": {":genie_woman:", ":woman_genie:", ":female_genie:"}, + "\U0001f9de\u200d\u2642\ufe0f": {":genie:", ":genie_man:", ":man_genie:", ":male_genie:"}, + "\U0001f9df\u200d\u2640\ufe0f": {":woman_zombie:", ":zombie_woman:", ":female_zombie:"}, + "\U0001f9df\u200d\u2642\ufe0f": {":zombie:", ":man_zombie:", ":zombie_man:", ":male_zombie:"}, + "\U0001f9e0": {":brain:"}, + "\U0001f9e1": {":orange_heart:"}, + "\U0001f9e2": {":billed_cap:"}, + "\U0001f9e3": {":scarf:"}, + "\U0001f9e4": {":gloves:"}, + "\U0001f9e5": {":coat:"}, + "\U0001f9e6": {":socks:"}, + "\U0001f9e7": {":red_envelope:"}, + "\U0001f9e8": {":firecracker:"}, + "\U0001f9e9": {":jigsaw:", ":puzzle_piece:"}, + "\U0001f9ea": {":test_tube:"}, + "\U0001f9eb": {":petri_dish:"}, + "\U0001f9ec": {":dna:"}, + "\U0001f9ed": {":compass:"}, + "\U0001f9ee": {":abacus:"}, + "\U0001f9ef": {":fire_extinguisher:"}, + "\U0001f9f0": {":toolbox:"}, + "\U0001f9f1": {":brick:", ":bricks:"}, + "\U0001f9f2": {":magnet:"}, + "\U0001f9f3": {":luggage:"}, + "\U0001f9f4": {":lotion_bottle:"}, + "\U0001f9f5": {":thread:"}, + "\U0001f9f6": {":yarn:"}, + "\U0001f9f7": {":safety_pin:"}, + "\U0001f9f8": {":teddy_bear:"}, + "\U0001f9f9": {":broom:"}, + "\U0001f9fa": {":basket:"}, + "\U0001f9fb": {":roll_of_paper:"}, + "\U0001f9fc": {":soap:"}, + "\U0001f9fd": {":sponge:"}, + "\U0001f9fe": {":receipt:"}, + "\U0001f9ff": {":nazar_amulet:"}, + "\U0001fa70": {":ballet_shoes:"}, + "\U0001fa71": {":one-piece_swimsuit:", ":one_piece_swimsuit:"}, + "\U0001fa72": {":briefs:", ":swim_brief:"}, + "\U0001fa73": {":shorts:"}, + "\U0001fa74": {":thong_sandal:"}, + "\U0001fa78": {":drop_of_blood:"}, + "\U0001fa79": {":adhesive_bandage:"}, + "\U0001fa7a": {":stethoscope:"}, + "\U0001fa80": {":yo-yo:", ":yo_yo:"}, + "\U0001fa81": {":kite:"}, + "\U0001fa82": {":parachute:"}, + "\U0001fa83": {":boomerang:"}, + "\U0001fa84": {":magic_wand:"}, + "\U0001fa85": {":pi_ata:", ":piñata:"}, + "\U0001fa86": {":nesting_dolls:"}, + "\U0001fa90": {":ringed_planet:"}, + "\U0001fa91": {":chair:"}, + "\U0001fa92": {":razor:"}, + "\U0001fa93": {":axe:"}, + "\U0001fa94": {":diya_lamp:"}, + "\U0001fa95": {":banjo:"}, + "\U0001fa96": {":military_helmet:"}, + "\U0001fa97": {":accordion:"}, + "\U0001fa98": {":long_drum:"}, + "\U0001fa99": {":coin:"}, + "\U0001fa9a": {":carpentry_saw:"}, + "\U0001fa9b": {":screwdriver:"}, + "\U0001fa9c": {":ladder:"}, + "\U0001fa9d": {":hook:"}, + "\U0001fa9e": {":mirror:"}, + "\U0001fa9f": {":window:"}, + "\U0001faa0": {":plunger:"}, + "\U0001faa1": {":sewing_needle:"}, + "\U0001faa2": {":knot:"}, + "\U0001faa3": {":bucket:"}, + "\U0001faa4": {":mouse_trap:"}, + "\U0001faa5": {":toothbrush:"}, + "\U0001faa6": {":headstone:"}, + "\U0001faa7": {":placard:"}, + "\U0001faa8": {":rock:"}, + "\U0001fab0": {":fly:"}, + "\U0001fab1": {":worm:"}, + "\U0001fab3": {":cockroach:"}, + "\U0001fab4": {":potted_plant:"}, + "\U0001fab5": {":wood:"}, + "\U0001fab6": {":feather:"}, + "\U0001fac0": {":anatomical_heart:"}, + "\U0001fac1": {":lungs:"}, + "\U0001fac2": {":people_hugging:"}, + "\U0001fad0": {":blueberries:"}, + "\U0001fad1": {":bell_pepper:"}, + "\U0001fad2": {":olive:"}, + "\U0001fad3": {":flatbread:"}, + "\U0001fad4": {":tamale:"}, + "\U0001fad5": {":fondue:"}, + "\U0001fad6": {":teapot:"}, + "\u00a9\ufe0f": {":copyright:"}, + "\u00ae\ufe0f": {":registered:"}, + "\u203c": {":double_exclamation_mark:"}, + "\u203c\ufe0f": {":bangbang:"}, + "\u2049": {":exclamation_question_mark:"}, + "\u2049\ufe0f": {":interrobang:"}, + "\u2122": {":trade_mark:"}, + "\u2122\ufe0f": {":tm:"}, + "\u2139": {":information:"}, + "\u2139\ufe0f": {":information_source:"}, + "\u2194": {":left-right_arrow:"}, + "\u2194\ufe0f": {":left_right_arrow:"}, + "\u2195": {":up-down_arrow:"}, + "\u2195\ufe0f": {":arrow_up_down:"}, + "\u2196": {":up-left_arrow:"}, + "\u2196\ufe0f": {":arrow_upper_left:"}, + "\u2197": {":up-right_arrow:"}, + "\u2197\ufe0f": {":arrow_upper_right:"}, + "\u2198": {":down-right_arrow:"}, + "\u2198\ufe0f": {":arrow_lower_right:"}, + "\u2199": {":down-left_arrow:"}, + "\u2199\ufe0f": {":arrow_lower_left:"}, + "\u21a9": {":right_arrow_curving_left:"}, + "\u21a9\ufe0f": {":leftwards_arrow_with_hook:"}, + "\u21aa": {":left_arrow_curving_right:"}, + "\u21aa\ufe0f": {":arrow_right_hook:"}, + "\u231a": {":watch:"}, + "\u231b": {":hourglass:", ":hourglass_done:"}, + "\u2328\ufe0f": {":keyboard:"}, + "\u23cf": {":eject_button:"}, + "\u23cf\ufe0f": {":eject:"}, + "\u23e9": {":fast_forward:", ":fast-forward_button:"}, + "\u23ea": {":rewind:", ":fast_reverse_button:"}, + "\u23eb": {":fast_up_button:", ":arrow_double_up:"}, + "\u23ec": {":fast_down_button:", ":arrow_double_down:"}, + "\u23ed": {":track_next:", ":next_track_button:"}, + "\u23ed\ufe0f": {":black_right_pointing_double_triangle_with_vertical_bar:"}, + "\u23ee": {":track_previous:", ":last_track_button:"}, + "\u23ee\ufe0f": {":previous_track_button:", ":black_left_pointing_double_triangle_with_vertical_bar:"}, + "\u23ef": {":play_pause:", ":play_or_pause_button:"}, + "\u23ef\ufe0f": {":black_right_pointing_triangle_with_double_vertical_bar:"}, + "\u23f0": {":alarm_clock:"}, + "\u23f1\ufe0f": {":stopwatch:"}, + "\u23f2": {":timer:"}, + "\u23f2\ufe0f": {":timer_clock:"}, + "\u23f3": {":hourglass_not_done:", ":hourglass_flowing_sand:"}, + "\u23f8": {":pause_button:"}, + "\u23f8\ufe0f": {":double_vertical_bar:"}, + "\u23f9": {":stop_button:"}, + "\u23f9\ufe0f": {":black_square_for_stop:"}, + "\u23fa": {":record_button:"}, + "\u23fa\ufe0f": {":black_circle_for_record:"}, + "\u24c2": {":circled_M:"}, + "\u24dc\ufe0f": {":m:"}, + "\u25aa\ufe0f": {":black_small_square:"}, + "\u25ab\ufe0f": {":white_small_square:"}, + "\u25b6": {":play_button:"}, + "\u25b6\ufe0f": {":arrow_forward:"}, + "\u25c0": {":reverse_button:"}, + "\u25c0\ufe0f": {":arrow_backward:"}, + "\u25fb\ufe0f": {":white_medium_square:"}, + "\u25fc\ufe0f": {":black_medium_square:"}, + "\u25fd": {":white_medium-small_square:", ":white_medium_small_square:"}, + "\u25fe": {":black_medium-small_square:", ":black_medium_small_square:"}, + "\u2600": {":sun:"}, + "\u2600\ufe0f": {":sunny:"}, + "\u2601\ufe0f": {":cloud:"}, + "\u2602": {":umbrella2:"}, + "\u2602\ufe0f": {":umbrella:", ":open_umbrella:"}, + "\u2603": {":snowman2:"}, + "\u2603\ufe0f": {":snowman:", ":snowman_with_snow:"}, + "\u2604\ufe0f": {":comet:"}, + "\u260e": {":telephone:"}, + "\u260e\ufe0f": {":phone:"}, + "\u2611": {":check_box_with_check:"}, + "\u2611\ufe0f": {":ballot_box_with_check:"}, + "\u2614": {":umbrella_with_rain_drops:"}, + "\u2615": {":coffee:", ":hot_beverage:"}, + "\u2618\ufe0f": {":shamrock:"}, + "\u261d": {":index_pointing_up:"}, + "\u261d\U0001f3fb": {":point_up_tone1:"}, + "\u261d\U0001f3fc": {":point_up_tone2:"}, + "\u261d\U0001f3fd": {":point_up_tone3:"}, + "\u261d\U0001f3fe": {":point_up_tone4:"}, + "\u261d\U0001f3ff": {":point_up_tone5:"}, + "\u261d\ufe0f": {":point_up:"}, + "\u2620": {":skull_crossbones:"}, + "\u2620\ufe0f": {":skull_and_crossbones:"}, + "\u2622": {":radioactive:"}, + "\u2622\ufe0f": {":radioactive_sign:"}, + "\u2623": {":biohazard:"}, + "\u2623\ufe0f": {":biohazard_sign:"}, + "\u2626\ufe0f": {":orthodox_cross:"}, + "\u262a\ufe0f": {":star_and_crescent:"}, + "\u262e": {":peace:"}, + "\u262e\ufe0f": {":peace_symbol:"}, + "\u262f\ufe0f": {":yin_yang:"}, + "\u2638\ufe0f": {":wheel_of_dharma:"}, + "\u2639": {":frowning2:", ":frowning_face:"}, + "\u2639\ufe0f": {":white_frowning_face:"}, + "\u263a": {":smiling_face:"}, + "\u263a\ufe0f": {":relaxed:"}, + "\u2640\ufe0f": {":female_sign:"}, + "\u2642\ufe0f": {":male_sign:"}, + "\u2648": {":Aries:", ":aries:"}, + "\u2649": {":Taurus:", ":taurus:"}, + "\u264a": {":Gemini:", ":gemini:"}, + "\u264b": {":Cancer:", ":cancer:"}, + "\u264c": {":Leo:", ":leo:"}, + "\u264d": {":Virgo:", ":virgo:"}, + "\u264e": {":Libra:", ":libra:"}, + "\u264f": {":Scorpio:", ":scorpius:"}, + "\u2650": {":Sagittarius:", ":sagittarius:"}, + "\u2651": {":Capricorn:", ":capricorn:"}, + "\u2652": {":Aquarius:", ":aquarius:"}, + "\u2653": {":Pisces:", ":pisces:"}, + "\u265f\ufe0f": {":chess_pawn:"}, + "\u2660": {":spade_suit:"}, + "\u2660\ufe0f": {":spades:"}, + "\u2663": {":club_suit:"}, + "\u2663\ufe0f": {":clubs:"}, + "\u2665": {":heart_suit:"}, + "\u2665\ufe0f": {":hearts:"}, + "\u2666": {":diamond_suit:"}, + "\u2666\ufe0f": {":diamonds:"}, + "\u2668": {":hot_springs:"}, + "\u2668\ufe0f": {":hotsprings:"}, + "\u267b": {":recycling_symbol:"}, + "\u267b\ufe0f": {":recycle:"}, + "\u267e\ufe0f": {":infinity:"}, + "\u267f": {":wheelchair:", ":wheelchair_symbol:"}, + "\u2692": {":hammer_pick:"}, + "\u2692\ufe0f": {":hammer_and_pick:"}, + "\u2693": {":anchor:"}, + "\u2694\ufe0f": {":crossed_swords:"}, + "\u2695\ufe0f": {":medical_symbol:"}, + "\u2696": {":balance_scale:"}, + "\u2696\ufe0f": {":scales:"}, + "\u2697\ufe0f": {":alembic:"}, + "\u2699\ufe0f": {":gear:"}, + "\u269b": {":atom:"}, + "\u269b\ufe0f": {":atom_symbol:"}, + "\u269c": {":fleur-de-lis:"}, + "\u269c\ufe0f": {":fleur_de_lis:"}, + "\u26a0\ufe0f": {":warning:"}, + "\u26a1": {":zap:", ":high_voltage:"}, + "\u26a7": {":transgender_symbol:"}, + "\u26aa": {":white_circle:"}, + "\u26ab": {":black_circle:"}, + "\u26b0\ufe0f": {":coffin:"}, + "\u26b1": {":urn:"}, + "\u26b1\ufe0f": {":funeral_urn:"}, + "\u26bd": {":soccer:", ":soccer_ball:"}, + "\u26be": {":baseball:"}, + "\u26c4": {":snowman_without_snow:"}, + "\u26c5": {":partly_sunny:", ":sun_behind_cloud:"}, + "\u26c8": {":thunder_cloud_rain:", ":cloud_with_lightning_and_rain:"}, + "\u26c8\ufe0f": {":thunder_cloud_and_rain:"}, + "\u26ce": {":Ophiuchus:", ":ophiuchus:"}, + "\u26cf\ufe0f": {":pick:"}, + "\u26d1": {":helmet_with_cross:", ":rescue_worker’s_helmet:"}, + "\u26d1\ufe0f": {":rescue_worker_helmet:", ":helmet_with_white_cross:"}, + "\u26d3\ufe0f": {":chains:"}, + "\u26d4": {":no_entry:"}, + "\u26e9\ufe0f": {":shinto_shrine:"}, + "\u26ea": {":church:"}, + "\u26f0\ufe0f": {":mountain:"}, + "\u26f1": {":beach_umbrella:"}, + "\u26f1\ufe0f": {":parasol_on_ground:", ":umbrella_on_ground:"}, + "\u26f2": {":fountain:"}, + "\u26f3": {":golf:", ":flag_in_hole:"}, + "\u26f4\ufe0f": {":ferry:"}, + "\u26f5": {":boat:", ":sailboat:"}, + "\u26f7\ufe0f": {":skier:"}, + "\u26f8\ufe0f": {":ice_skate:"}, + "\u26f9": {":person_bouncing_ball:"}, + "\u26f9\U0001f3fb": {":person_bouncing_ball_tone1:"}, + "\u26f9\U0001f3fb\u200d\u2640\ufe0f": {":woman_bouncing_ball_tone1:"}, + "\u26f9\U0001f3fb\u200d\u2642\ufe0f": {":man_bouncing_ball_tone1:"}, + "\u26f9\U0001f3fc": {":person_bouncing_ball_tone2:"}, + "\u26f9\U0001f3fc\u200d\u2640\ufe0f": {":woman_bouncing_ball_tone2:"}, + "\u26f9\U0001f3fc\u200d\u2642\ufe0f": {":man_bouncing_ball_tone2:"}, + "\u26f9\U0001f3fd": {":person_bouncing_ball_tone3:"}, + "\u26f9\U0001f3fd\u200d\u2640\ufe0f": {":woman_bouncing_ball_tone3:"}, + "\u26f9\U0001f3fd\u200d\u2642\ufe0f": {":man_bouncing_ball_tone3:"}, + "\u26f9\U0001f3fe": {":person_bouncing_ball_tone4:"}, + "\u26f9\U0001f3fe\u200d\u2640\ufe0f": {":woman_bouncing_ball_tone4:"}, + "\u26f9\U0001f3fe\u200d\u2642\ufe0f": {":man_bouncing_ball_tone4:"}, + "\u26f9\U0001f3ff": {":person_bouncing_ball_tone5:"}, + "\u26f9\U0001f3ff\u200d\u2640\ufe0f": {":woman_bouncing_ball_tone5:"}, + "\u26f9\U0001f3ff\u200d\u2642\ufe0f": {":man_bouncing_ball_tone5:"}, + "\u26f9\ufe0f": {":bouncing_ball_person:"}, + "\u26f9\ufe0f\u200d\u2640\ufe0f": {":basketball_woman:", ":bouncing_ball_woman:", ":woman-bouncing-ball:", ":woman_bouncing_ball:"}, + "\u26f9\ufe0f\u200d\u2642\ufe0f": {":basketball_man:", ":person_with_ball:", ":bouncing_ball_man:", ":man-bouncing-ball:", ":man_bouncing_ball:"}, + "\u26fa": {":tent:"}, + "\u26fd": {":fuelpump:", ":fuel_pump:"}, + "\u2702\ufe0f": {":scissors:"}, + "\u2705": {":white_check_mark:", ":check_mark_button:"}, + "\u2708\ufe0f": {":airplane:"}, + "\u2709": {":envelope:"}, + "\u2709\ufe0f": {":email:"}, + "\u270a": {":fist:", ":fist_raised:", ":raised_fist:"}, + "\u270a\U0001f3fb": {":fist_tone1:"}, + "\u270a\U0001f3fc": {":fist_tone2:"}, + "\u270a\U0001f3fd": {":fist_tone3:"}, + "\u270a\U0001f3fe": {":fist_tone4:"}, + "\u270a\U0001f3ff": {":fist_tone5:"}, + "\u270b": {":hand:", ":raised_hand:"}, + "\u270b\U0001f3fb": {":raised_hand_tone1:"}, + "\u270b\U0001f3fc": {":raised_hand_tone2:"}, + "\u270b\U0001f3fd": {":raised_hand_tone3:"}, + "\u270b\U0001f3fe": {":raised_hand_tone4:"}, + "\u270b\U0001f3ff": {":raised_hand_tone5:"}, + "\u270c": {":victory_hand:"}, + "\u270c\U0001f3fb": {":v_tone1:"}, + "\u270c\U0001f3fc": {":v_tone2:"}, + "\u270c\U0001f3fd": {":v_tone3:"}, + "\u270c\U0001f3fe": {":v_tone4:"}, + "\u270c\U0001f3ff": {":v_tone5:"}, + "\u270c\ufe0f": {":v:"}, + "\u270d\U0001f3fb": {":writing_hand_tone1:"}, + "\u270d\U0001f3fc": {":writing_hand_tone2:"}, + "\u270d\U0001f3fd": {":writing_hand_tone3:"}, + "\u270d\U0001f3fe": {":writing_hand_tone4:"}, + "\u270d\U0001f3ff": {":writing_hand_tone5:"}, + "\u270d\ufe0f": {":writing_hand:"}, + "\u270f": {":pencil:"}, + "\u270f\ufe0f": {":pencil2:"}, + "\u2712\ufe0f": {":black_nib:"}, + "\u2714": {":check_mark:"}, + "\u2714\ufe0f": {":heavy_check_mark:"}, + "\u2716": {":multiply:"}, + "\u2716\ufe0f": {":heavy_multiplication_x:"}, + "\u271d": {":cross:"}, + "\u271d\ufe0f": {":latin_cross:"}, + "\u2721": {":star_of_David:"}, + "\u2721\ufe0f": {":star_of_david:"}, + "\u2728": {":sparkles:"}, + "\u2733": {":eight-spoked_asterisk:"}, + "\u2733\ufe0f": {":eight_spoked_asterisk:"}, + "\u2734": {":eight-pointed_star:"}, + "\u2734\ufe0f": {":eight_pointed_black_star:"}, + "\u2744\ufe0f": {":snowflake:"}, + "\u2747\ufe0f": {":sparkle:"}, + "\u274c": {":x:", ":cross_mark:"}, + "\u274e": {":cross_mark_button:", ":negative_squared_cross_mark:"}, + "\u2753": {":question:", ":question_mark:"}, + "\u2754": {":grey_question:", ":white_question_mark:"}, + "\u2755": {":grey_exclamation:", ":white_exclamation_mark:"}, + "\u2757": {":exclamation:", ":exclamation_mark:", ":heavy_exclamation_mark:"}, + "\u2763": {":heart_exclamation:"}, + "\u2763\ufe0f": {":heavy_heart_exclamation:", ":heavy_heart_exclamation_mark_ornament:"}, + "\u2764": {":red_heart:"}, + "\u2764\ufe0f": {":heart:"}, + "\u2795": {":plus:", ":heavy_plus_sign:"}, + "\u2796": {":minus:", ":heavy_minus_sign:"}, + "\u2797": {":divide:", ":heavy_division_sign:"}, + "\u27a1": {":right_arrow:"}, + "\u27a1\ufe0f": {":arrow_right:"}, + "\u27b0": {":curly_loop:"}, + "\u27bf": {":loop:", ":double_curly_loop:"}, + "\u2934": {":right_arrow_curving_up:"}, + "\u2934\ufe0f": {":arrow_heading_up:"}, + "\u2935": {":right_arrow_curving_down:"}, + "\u2935\ufe0f": {":arrow_heading_down:"}, + "\u2b05": {":left_arrow:"}, + "\u2b05\ufe0f": {":arrow_left:"}, + "\u2b06": {":up_arrow:"}, + "\u2b06\ufe0f": {":arrow_up:"}, + "\u2b07": {":down_arrow:"}, + "\u2b07\ufe0f": {":arrow_down:"}, + "\u2b1b": {":black_large_square:"}, + "\u2b1c": {":white_large_square:"}, + "\u2b50": {":star:"}, + "\u2b55": {":o:", ":hollow_red_circle:"}, + "\u3030\ufe0f": {":wavy_dash:"}, + "\u303d\ufe0f": {":part_alternation_mark:"}, + "\u3297": {":Japanese_congratulations_button:"}, + "\u3297\ufe0f": {":congratulations:"}, + "\u3299": {":Japanese_secret_button:"}, + "\u3299\ufe0f": {":secret:"}, +} diff --git a/x/faucet/utils/errors.go b/x/faucet/utils/errors.go new file mode 100644 index 0000000..fbfe609 --- /dev/null +++ b/x/faucet/utils/errors.go @@ -0,0 +1,6 @@ +package utils + +import sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + +var ErrParseEmoji = sdkerrors.Register("faucet", 105, "parse emoji failed") + diff --git a/x/faucet/utils/parse_emoji_test.go b/x/faucet/utils/parse_emoji_test.go new file mode 100644 index 0000000..082818f --- /dev/null +++ b/x/faucet/utils/parse_emoji_test.go @@ -0,0 +1,60 @@ +package utils + +import ( + "errors" + "testing" +) + +func Test_parseEmoji(t *testing.T) { + emojis := []string{ + "\U0001f194", + "1\U0001f194", + "\U0001f9d1\u200d\U0001f680", + "1\U0001f9d1\u200d\U0001f680", + } + + for _, v := range emojis[:2] { + emo, err := ParseEmoji(v) + if err != nil { + t.Fatal(err) + } + + if emo != "\U0001f194" { + t.Fatal(emo) + } + } + + for _, v := range emojis[2:] { + emo, err := ParseEmoji(v) + if err != nil { + t.Fatal(err) + } + + if emo != "\U0001f9d1\u200d\U0001f680" { + t.Fatal(emo) + } + } + + emojis = []string{ + "100\U0001f194", + "2\U0001f194", + "1\U0001f194xyz", + "0\U0001f194", + "\U0001f194abc", + "100\U0001f9d1\u200d\U0001f680", + "2\U0001f9d1\u200d\U0001f680", + "1\U0001f9d1\u200d\U0001f680xyz", + "\U0001f9d1\u200d\U0001f680abc", + } + + for _, v := range emojis { + emo, err := ParseEmoji(v) + + if !errors.Is(err, ErrParseEmoji) { + t.Fatal(err) + } + if emo != "" { + t.Fatal(emo) + } + } +} diff --git a/x/faucet/utils/utils.go b/x/faucet/utils/utils.go new file mode 100644 index 0000000..410b209 --- /dev/null +++ b/x/faucet/utils/utils.go @@ -0,0 +1,28 @@ +package utils + +// parse emoji for mintfor, only allows format like "\U0001f630" or "1\U0001f630" +func ParseEmoji(emoji string) (string, error) { + emojiMap := ReverseMapKV(emojiCodeMap) + _, found1 := emojiMap[emoji] + _, found2 := emojiMap[emoji[1:]] + + if found1{ + return emoji, nil + } + + if emoji[0] == '1' && found2 { + return emoji[1:], nil + } + + return "",ErrParseEmoji +} + + +func ReverseMapKV(emojiMap map[string]string)map[string]string{ + reversedMap := map[string]string{} + for k, v := range emojiMap{ + reversedMap[v] = k + } + + return reversedMap +} From 085bafed98e8a93e66dc2cc30128afa569e25212 Mon Sep 17 00:00:00 2001 From: yaruwang Date: Thu, 22 Jul 2021 10:41:15 +0200 Subject: [PATCH 07/22] remove .idea folder --- .idea/.gitignore | 8 -- .idea/encodings.xml | 6 -- .idea/inspectionProfiles/Project_Default.xml | 7 -- .idea/misc.xml | 94 -------------------- .idea/modules.xml | 8 -- .idea/pooltoy.iml | 10 --- .idea/vcs.xml | 6 -- 7 files changed, 139 deletions(-) delete mode 100644 .idea/.gitignore delete mode 100644 .idea/encodings.xml delete mode 100644 .idea/inspectionProfiles/Project_Default.xml delete mode 100644 .idea/misc.xml delete mode 100644 .idea/modules.xml delete mode 100644 .idea/pooltoy.iml delete mode 100644 .idea/vcs.xml diff --git a/.idea/.gitignore b/.idea/.gitignore deleted file mode 100644 index 73f69e0..0000000 --- a/.idea/.gitignore +++ /dev/null @@ -1,8 +0,0 @@ -# Default ignored files -/shelf/ -/workspace.xml -# Datasource local storage ignored files -/dataSources/ -/dataSources.local.xml -# Editor-based HTTP Client requests -/httpRequests/ diff --git a/.idea/encodings.xml b/.idea/encodings.xml deleted file mode 100644 index ada92a5..0000000 --- a/.idea/encodings.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml deleted file mode 100644 index 4aea665..0000000 --- a/.idea/inspectionProfiles/Project_Default.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - - \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml deleted file mode 100644 index 80c5509..0000000 --- a/.idea/misc.xml +++ /dev/null @@ -1,94 +0,0 @@ - - - - IDE - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml deleted file mode 100644 index 7a38906..0000000 --- a/.idea/modules.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/.idea/pooltoy.iml b/.idea/pooltoy.iml deleted file mode 100644 index 25ed3f6..0000000 --- a/.idea/pooltoy.iml +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - - - - \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml deleted file mode 100644 index 35eb1dd..0000000 --- a/.idea/vcs.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file From 1dff52e9144a0c6ba00737aa910406f8b97e7b54 Mon Sep 17 00:00:00 2001 From: yaruwang Date: Fri, 23 Jul 2021 15:18:20 +0200 Subject: [PATCH 08/22] escrow offer --- accounts1.json | 850 +++++++++++++++++++++++++++++ app/app.go | 30 +- proto/escrow/escrow/genesis.proto | 13 + proto/escrow/escrow/query.proto | 15 + proto/escrow/escrow/tx.proto | 32 ++ scripts/init.sh | 2 +- x/escrow/client/cli/query.go | 30 + x/escrow/client/cli/tx.go | 64 +++ x/escrow/genesis.go | 26 + x/escrow/handler.go | 31 ++ x/escrow/keeper/grpc_query.go | 7 + x/escrow/keeper/keeper.go | 72 +++ x/escrow/keeper/keeper_test.go | 18 + x/escrow/keeper/msg_server.go | 37 ++ x/escrow/keeper/msg_server_test.go | 19 + x/escrow/keeper/store.go | 3 + x/escrow/module.go | 168 ++++++ x/escrow/types/codec.go | 29 + x/escrow/types/errors.go | 13 + x/escrow/types/genesis.go | 22 + x/escrow/types/genesis.pb.go | 263 +++++++++ x/escrow/types/keys.go | 27 + x/escrow/types/msgs.go | 52 ++ x/escrow/types/query.pb.go | 84 +++ x/escrow/types/tx.pb.go | 670 +++++++++++++++++++++++ x/escrow/types/types.go | 1 + x/escrow/utils/errors.go | 5 + x/escrow/utils/utils.go | 63 +++ x/escrow/utils/utils_test.go | 97 ++++ x/faucet/keeper/keeper.go | 1 + x/faucet/types/msgs.go | 2 +- x/faucet/utils/emojiCodeMap.go | 2 +- x/faucet/utils/utils.go | 2 +- 33 files changed, 2743 insertions(+), 7 deletions(-) create mode 100644 accounts1.json create mode 100644 proto/escrow/escrow/genesis.proto create mode 100644 proto/escrow/escrow/query.proto create mode 100644 proto/escrow/escrow/tx.proto create mode 100644 x/escrow/client/cli/query.go create mode 100644 x/escrow/client/cli/tx.go create mode 100644 x/escrow/genesis.go create mode 100644 x/escrow/handler.go create mode 100644 x/escrow/keeper/grpc_query.go create mode 100644 x/escrow/keeper/keeper.go create mode 100644 x/escrow/keeper/keeper_test.go create mode 100644 x/escrow/keeper/msg_server.go create mode 100644 x/escrow/keeper/msg_server_test.go create mode 100644 x/escrow/keeper/store.go create mode 100644 x/escrow/module.go create mode 100644 x/escrow/types/codec.go create mode 100644 x/escrow/types/errors.go create mode 100644 x/escrow/types/genesis.go create mode 100644 x/escrow/types/genesis.pb.go create mode 100644 x/escrow/types/keys.go create mode 100644 x/escrow/types/msgs.go create mode 100644 x/escrow/types/query.pb.go create mode 100644 x/escrow/types/tx.pb.go create mode 100644 x/escrow/types/types.go create mode 100644 x/escrow/utils/errors.go create mode 100644 x/escrow/utils/utils.go create mode 100644 x/escrow/utils/utils_test.go diff --git a/accounts1.json b/accounts1.json new file mode 100644 index 0000000..ded87be --- /dev/null +++ b/accounts1.json @@ -0,0 +1,850 @@ +{ + "balances": [ + { + "name": "alice", + "address": "cosmos1qd4gsa4mlnpzmv4zsf9ghdrsgkt5avs8zte65u", + "coins": [ + { + "amount": "1000", + "denom": "token" + }, + { + "amount": "100000000", + "denom": "stake" + } + ] + }, + { + "address": "cosmos1pxjvm30nf0n832sd0u02nsk8d0un0czv67t9f6", + "name": "sean", + "really": "Sean", + "coins": [ + { + "amount": "1", + "denom": "🍣" + }, + { + "amount": "1", + "denom": "🎻" + }, + { + "amount": "1", + "denom": "🛠️" + }, + { + "amount": "1", + "denom": "🧙🏼‍♂️" + }, + { + "amount": "1", + "denom": "🧹" + } + ] + }, + { + "address": "cosmos1zw9p9sppnxawvjqyngn9ce4hy97mu3fjp3tnm9", + "name": "onur", + "really": "Onur", + "coins": [ + { + "amount": "1", + "denom": "🆗" + }, + { + "amount": "2", + "denom": "🍍" + }, + { + "amount": "1", + "denom": "🎙️" + }, + { + "amount": "1", + "denom": "🎬" + }, + { + "amount": "1", + "denom": "🥅" + }, + { + "amount": "1", + "denom": "🥞" + } + ] + }, + { + "address": "cosmos1rp6adqsnwlcqgrjzu8slh0wthx8tx0le2zcp64", + "really": "jessica", + "name": "jessica", + "coins": [ + { + "amount": "1", + "denom": "🎙️" + }, + { + "amount": "1", + "denom": "🎨" + }, + { + "amount": "1", + "denom": "👩‍🎨" + } + ] + }, + { + "address": "cosmos1rcdv738knczcvpnkumfd4w88h5rrlzy9p9d5nc", + "name": "shahan", + "really": "shahan", + "coins": [ + { + "amount": "1", + "denom": "🍎" + }, + { + "amount": "1", + "denom": "🍩" + }, + { + "amount": "1", + "denom": "🐈" + }, + { + "amount": "1", + "denom": "🔒" + }, + { + "amount": "1", + "denom": "🥮" + } + ] + }, + { + "address": "cosmos1rejspc9d2wxwz32py4qxkw2a39egm0t73kwzf5", + "really": "anton", + "name": "anton", + "coins": [ + { + "amount": "1", + "denom": "🌞" + }, + { + "amount": "1", + "denom": "🐊" + }, + { + "amount": "1", + "denom": "🐘" + }, + { + "amount": "1", + "denom": "🧹" + } + ] + }, + { + "address": "cosmos1ztm25wkyfmw5nrth89lnyav3ygcusmsd9wkv84", + "really": "erik", + "name": "erik", + "coins": [ + { + "amount": "1", + "denom": "⚡" + }, + { + "amount": "1", + "denom": "🆒" + }, + { + "amount": "1", + "denom": "🌲" + }, + { + "amount": "1", + "denom": "🌴" + }, + { + "amount": "1", + "denom": "🍎" + }, + { + "amount": "1", + "denom": "🍩" + }, + { + "amount": "1", + "denom": "🐃" + }, + { + "amount": "1", + "denom": "🐋" + }, + { + "amount": "1", + "denom": "🐳" + } + ] + }, + { + "address": "cosmos1yj4z43z7wncfywe49s9aamlprfqqlew6f8qgz6", + "name": "billy", + "really": "billy", + "coins": [ + { + "amount": "1", + "denom": "⌨️" + }, + { + "amount": "1", + "denom": "⚰️" + }, + { + "amount": "1", + "denom": "⛽" + }, + { + "amount": "1", + "denom": "🌚" + }, + { + "amount": "1", + "denom": "🍀" + }, + { + "amount": "1", + "denom": "🎙️" + }, + { + "amount": "1", + "denom": "🎨" + }, + { + "amount": "1", + "denom": "🐑" + }, + { + "amount": "1", + "denom": "👩🏼‍🎨" + }, + { + "amount": "1", + "denom": "📱" + }, + { + "amount": "1", + "denom": "🔦" + }, + { + "amount": "1", + "denom": "🕴️" + }, + { + "amount": "1", + "denom": "🕹️" + }, + { + "amount": "1", + "denom": "🗡️" + }, + { + "amount": "1", + "denom": "🤑" + }, + { + "amount": "1", + "denom": "🤗" + }, + { + "amount": "1", + "denom": "🥑" + }, + { + "amount": "1", + "denom": "🦇" + }, + { + "amount": "1", + "denom": "🧉" + }, + { + "amount": "1", + "denom": "🧑‍🔧" + }, + { + "amount": "1", + "denom": "🧓" + } + ] + }, + { + "address": "cosmos18m8halw40nca9pjh720d5e40s0ea7t6n0wzw90", + "name": "U01QFLFSPNX", + "really": "sam2", + "coins": [ + { + "amount": "1", + "denom": "🍍" + } + ] + }, + { + "address": "cosmos1fjwa0jgtzl8w3zu3w6wel3qevquft7r0g95y3r", + "name": "U015J63Q9QW", + "really": "Daniela", + "coins": [ + { + "amount": "1", + "denom": "💪" + }, + { + "amount": "1", + "denom": "😺" + }, + { + "amount": "1", + "denom": "🥞" + }, + { + "amount": "1", + "denom": "🥳" + } + ] + }, + { + "address": "cosmos12jttgnndlzavecqwneekwrj29w9hxdcketucfr", + "name": "sam", + "really": "sam", + "coins": [ + { + "amount": "2", + "denom": "⛵" + }, + { + "amount": "1", + "denom": "🍩" + }, + + { + "amount": "1", + "denom": "🧀" + }, + { + "amount": "1", + "denom": "🪑" + } + ] + }, + { + "address": "cosmos1vnqyhuuhaxnm2ykfumjszumn988psa576u58sq", + "name": "marko", + "really": "Marko", + "coins": [ + { + "amount": "1", + "denom": "☕" + }, + { + "amount": "1", + "denom": "✉️" + }, + { + "amount": "1", + "denom": "🌯" + }, + { + "amount": "1", + "denom": "🍨" + }, + { + "amount": "1", + "denom": "🏘️" + }, + { + "amount": "1", + "denom": "🐞" + }, + { + "amount": "1", + "denom": "👼" + }, + { + "amount": "1", + "denom": "💌" + }, + { + "amount": "1", + "denom": "💰" + }, + { + "amount": "1", + "denom": "📄" + }, + { + "amount": "1", + "denom": "📍" + }, + { + "amount": "2", + "denom": "🔥" + }, + { + "amount": "1", + "denom": "🕸️" + }, + { + "amount": "1", + "denom": "🛠️" + }, + { + "amount": "1", + "denom": "🛡️" + }, + { + "amount": "1", + "denom": "🥅" + }, + { + "amount": "1", + "denom": "🥞" + }, + { + "amount": "1", + "denom": "🥩" + }, + { + "amount": "1", + "denom": "🦉" + }, + { + "amount": "1", + "denom": "🦾" + } + ] + }, + { + "address": "cosmos106enunsfp2swuwhzfavxgn8x42n0wvrl5030df", + "name": "anna", + "really": "Anna", + "coins": [ + { + "amount": "1", + "denom": "🍊" + }, + { + "amount": "1", + "denom": "🎁" + }, + { + "amount": "2", + "denom": "🎂" + }, + { + "amount": "1", + "denom": "👩‍💼" + }, + { + "amount": "1", + "denom": "💸" + }, + { + "amount": "1", + "denom": "🕳️" + }, + { + "amount": "1", + "denom": "🥂" + } + ] + }, + { + "address": "cosmos1s4razzs8v3ule9wmpmyqcxpw5tz93hjy3vcqwm", + "name": "chris", + "really": "chris", + "coins": [ + { + "amount": "1", + "denom": "🌴" + }, + { + "amount": "1", + "denom": "🍵" + }, + { + "amount": "1", + "denom": "🎂" + }, + { + "amount": "1", + "denom": "🐙" + }, + { + "amount": "1", + "denom": "💰" + }, + { + "amount": "1", + "denom": "💵" + }, + { + "amount": "1", + "denom": "🔤" + }, + { + "amount": "1", + "denom": "🕳️" + }, + { + "amount": "1", + "denom": "🥪" + }, + { + "amount": "1", + "denom": "🪑" + } + ] + }, + { + "address": "cosmos13rwxj6g29kvg46rjqarvdj0cn0zxvw8s5f0zgl", + "name": "U0104B5TMFZ", + "really": "aditya", + "coins": [ + { + "amount": "1", + "denom": "🍕" + }, + { + "amount": "1", + "denom": "💰" + }, + { + "amount": "1", + "denom": "🥑" + }, + { + "amount": "1", + "denom": "🧠" + } + ] + }, + { + "address": "cosmos1jpkhep4jmsuh5xh4sc3aglgs3h0vx5fty8vmfs", + "name": "U012VKXATJ9", + "really": "colin", + "coins": [ + { + "amount": "1", + "denom": "⏳" + }, + { + "amount": "1", + "denom": "🍵" + }, + { + "amount": "1", + "denom": "🐞" + }, + { + "amount": "1", + "denom": "👋" + }, + { + "amount": "1", + "denom": "🙌" + } + ] + }, + { + "address": "cosmos1x8q3e38szadt4x26ez8g4kenueud4hj6vjy2az", + "name": "U01Q1FG1TU1", + "really": "charly", + "coins": [ + { + "amount": "1", + "denom": "🍀" + }, + { + "amount": "1", + "denom": "🍩" + }, + { + "amount": "1", + "denom": "🍻" + }, + { + "amount": "1", + "denom": "🏊‍♀️" + }, + { + "amount": "1", + "denom": "🧗‍♀️" + }, + { + "amount": "1", + "denom": "🪀" + } + ] + }, + { + "address": "cosmos153z2rmmrce3539ng4rtmhsfhwxj4vnmtuhllfa", + "name": "U01P7R8152T", + "really": "Diana_Schallenberg", + "coins": [ + { + "amount": "1", + "denom": "🥂" + } + ] + }, + { + "address": "cosmos15lt2rp7asvtn6pmcnme6ldwdjuzq29y4ege2e8", + "name": "UU71UJJJH", + "really": "tessr", + "coins": [ + { + "amount": "1", + "denom": "☕" + }, + { + "amount": "1", + "denom": "🆒" + }, + { + "amount": "1", + "denom": "🌔" + }, + { + "amount": "1", + "denom": "🍎" + }, + { + "amount": "1", + "denom": "🍧" + }, + { + "amount": "2", + "denom": "🎙️" + }, + { + "amount": "1", + "denom": "🏖️" + }, + { + "amount": "1", + "denom": "🐞" + }, + { + "amount": "1", + "denom": "💎" + }, + { + "amount": "1", + "denom": "💬" + }, + { + "amount": "1", + "denom": "📖" + }, + { + "amount": "1", + "denom": "📚" + }, + { + "amount": "1", + "denom": "🔌" + }, + { + "amount": "1", + "denom": "🔍" + }, + { + "amount": "1", + "denom": "🔜" + }, + { + "amount": "1", + "denom": "🕴🏼" + }, + { + "amount": "1", + "denom": "🚀" + } + ] + }, + { + "address": "cosmos1kky4jglyslvjg300372vn68r0uuxer4pksqav4", + "name": "U0104B5U97Z", + "really": "bez", + "coins": [ + { + "amount": "1", + "denom": "🌵" + }, + { + "amount": "1", + "denom": "🍺" + }, + { + "amount": "1", + "denom": "🎬" + }, + { + "amount": "1", + "denom": "🎽" + }, + { + "amount": "1", + "denom": "🐳" + }, + { + "amount": "1", + "denom": "💰" + }, + { + "amount": "1", + "denom": "🔥" + }, + { + "amount": "1", + "denom": "🙁" + }, + { + "amount": "1", + "denom": "🚢" + }, + { + "amount": "1", + "denom": "🥈" + }, + { + "amount": "1", + "denom": "🧐" + } + ] + }, + { + "address": "cosmos1c4tpu862ryxlsvvkhhs9ftfmcxu52708e3r4hm", + "really": "Federico Kunze", + "name": "UTVGWEEKD", + "coins": [ + { + "amount": "1", + "denom": "🍕" + }, + { + "amount": "1", + "denom": "🎛️" + }, + { + "amount": "1", + "denom": "🎩" + }, + { + "amount": "1", + "denom": "🏹" + }, + { + "amount": "1", + "denom": "🐞" + }, + { + "amount": "1", + "denom": "💯" + }, + { + "amount": "1", + "denom": "💸" + }, + { + "amount": "1", + "denom": "🔍" + }, + { + "amount": "1", + "denom": "🔐" + }, + { + "amount": "1", + "denom": "🔥" + }, + { + "amount": "1", + "denom": "😱" + }, + { + "amount": "2", + "denom": "🚀" + }, + { + "amount": "1", + "denom": "🤝" + }, + { + "amount": "1", + "denom": "🧠" + } + ] + }, + { + "address": "cosmos1730axaje8j3qd8n00p0wtcz6cx8v0n8pcjx7hw", + "name": "UTU7H3GHY", + "really": "Callum", + "coins": [ + { + "amount": "1", + "denom": "🍟" + }, + { + "amount": "1", + "denom": "🍻" + }, + { + "amount": "1", + "denom": "🍽️" + }, + { + "amount": "1", + "denom": "🎲" + }, + { + "amount": "1", + "denom": "🎵" + }, + { + "amount": "1", + "denom": "🏈" + }, + { + "amount": "1", + "denom": "🏎️" + }, + { + "amount": "1", + "denom": "🐐" + }, + { + "amount": "1", + "denom": "📚" + }, + { + "amount": "2", + "denom": "🔑" + }, + { + "amount": "1", + "denom": "🙏" + }, + { + "amount": "1", + "denom": "🚗" + }, + { + "amount": "1", + "denom": "🥝" + }, + { + "amount": "1", + "denom": "🦉" + } + ] + } + ] +} diff --git a/app/app.go b/app/app.go index a87787a..b711394 100644 --- a/app/app.go +++ b/app/app.go @@ -1,6 +1,7 @@ package app import ( + "github.com/interchainberlin/pooltoy/x/escrow" "io" "os" "path/filepath" @@ -74,9 +75,12 @@ import ( stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" appparams "github.com/interchainberlin/pooltoy/app/params" "github.com/interchainberlin/pooltoy/regex" + escrowkeeper "github.com/interchainberlin/pooltoy/x/escrow/keeper" + escrowtypes "github.com/interchainberlin/pooltoy/x/escrow/types" "github.com/interchainberlin/pooltoy/x/faucet" faucetkeeper "github.com/interchainberlin/pooltoy/x/faucet/keeper" faucettypes "github.com/interchainberlin/pooltoy/x/faucet/types" + "github.com/interchainberlin/pooltoy/x/pooltoy" pooltoykeeper "github.com/interchainberlin/pooltoy/x/pooltoy/keeper" pooltoytypes "github.com/interchainberlin/pooltoy/x/pooltoy/types" @@ -138,6 +142,7 @@ var ( transfer.AppModuleBasic{}, pooltoy.AppModuleBasic{}, faucet.AppModule{}, + escrow.AppModule{}, ) // module account permissions @@ -150,6 +155,7 @@ var ( govtypes.ModuleName: {authtypes.Burner}, ibctransfertypes.ModuleName: {authtypes.Minter, authtypes.Burner}, faucettypes.ModuleName: {authtypes.Minter}, + escrowtypes.ModuleName: {authtypes.Staking}, } // module accounts that are allowed to receive tokens @@ -213,12 +219,14 @@ type App struct { PooltoyKeeper pooltoykeeper.Keeper FaucetKeeper faucetkeeper.Keeper // this line is used by starport scaffolding # stargate/app/keeperDeclaration - + EscrowKeeper escrowkeeper.Keeper // the module manager mm *module.Manager sm *module.SimulationManager } +//todo check paramskeeper + // New returns a reference to an initialized Gaia. // NewSimApp returns a reference to an initialized SimApp. func New( @@ -244,6 +252,7 @@ func New( evidencetypes.StoreKey, ibctransfertypes.StoreKey, capabilitytypes.StoreKey, pooltoytypes.StoreKey, faucettypes.StoreKey, + escrowtypes.StoreKey, // this line is used by starport scaffolding # stargate/app/storeKey ) tkeys := sdk.NewTransientStoreKeys(paramstypes.TStoreKey) @@ -329,7 +338,7 @@ func New( transferModule := transfer.NewAppModule(app.TransferKeeper) app.PooltoyKeeper = pooltoykeeper.NewKeeper( - appCodec, + appCodec, // todo why this is not app.appCodec keys[pooltoytypes.StoreKey], app.AccountKeeper, ) @@ -344,6 +353,14 @@ func New( app.appCodec, ) + app.EscrowKeeper = escrowkeeper.NewKeeper( + app.BankKeeper, + app.AccountKeeper, + appCodec, //todo appcodec or app.appcodec? + keys[escrowtypes.StoreKey], + escrowtypes.StartIndex, + ) + // Create static IBC router, add transfer route, then set and seal it ibcRouter := porttypes.NewRouter() ibcRouter.AddRoute(ibctransfertypes.ModuleName, transferModule) @@ -399,6 +416,12 @@ func New( faucet.NewAppModule( app.FaucetKeeper, ), + + escrow.NewAppModule( + app.appCodec, //todo 1 + app.EscrowKeeper, + ), + // this line is used by starport scaffolding # stargate/app/appModule ) @@ -412,7 +435,7 @@ func New( evidencetypes.ModuleName, stakingtypes.ModuleName, minttypes.ModuleName, ibchost.ModuleName, ) - app.mm.SetOrderEndBlockers(crisistypes.ModuleName, govtypes.ModuleName, stakingtypes.ModuleName, pooltoytypes.ModuleName, faucettypes.ModuleName) + app.mm.SetOrderEndBlockers(crisistypes.ModuleName, govtypes.ModuleName, stakingtypes.ModuleName, pooltoytypes.ModuleName, faucettypes.ModuleName, escrowtypes.ModuleName) // NOTE: The genutils module must occur after staking so that pools are // properly initialized with tokens from genesis accounts. @@ -435,6 +458,7 @@ func New( minttypes.ModuleName, pooltoytypes.ModuleName, faucettypes.ModuleName, + escrowtypes.ModuleName, // this line is used by starport scaffolding # stargate/app/initGenesis ) diff --git a/proto/escrow/escrow/genesis.proto b/proto/escrow/escrow/genesis.proto new file mode 100644 index 0000000..9ad45dd --- /dev/null +++ b/proto/escrow/escrow/genesis.proto @@ -0,0 +1,13 @@ +syntax = "proto3"; +package escrow; + +// this line is used by starport scaffolding # genesis/proto/import + +option go_package = "github.com/interchainberlin/pooltoy/x/escrow/types"; + + +// GenesisState defines the escrow module's genesis state. +message GenesisState { + // this line is used by starport scaffolding # genesis/proto/state + // this line is used by starport scaffolding # ibc/genesis/proto +} diff --git a/proto/escrow/escrow/query.proto b/proto/escrow/escrow/query.proto new file mode 100644 index 0000000..9136584 --- /dev/null +++ b/proto/escrow/escrow/query.proto @@ -0,0 +1,15 @@ +syntax = "proto3"; +package escrow; + +import "google/api/annotations.proto"; + +// this line is used by starport scaffolding # 1 + +option go_package = "github.com/interchainberlin/pooltoy/x/escrow/types"; + +// Query defines the gRPC querier service. +service Query { + // this line is used by starport scaffolding # 2 +} + +// this line is used by starport scaffolding # 3 diff --git a/proto/escrow/escrow/tx.proto b/proto/escrow/escrow/tx.proto new file mode 100644 index 0000000..d3c9662 --- /dev/null +++ b/proto/escrow/escrow/tx.proto @@ -0,0 +1,32 @@ +syntax = "proto3"; +package escrow; + +import "gogoproto/gogo.proto"; + +// this line is used by starport scaffolding # proto/tx/import + +option go_package = "github.com/interchainberlin/pooltoy/x/escrow/types"; + +// Msg defines the Msg service. +service Msg { + // this line is used by starport scaffolding # proto/tx/rpc + rpc Offer(OfferRequest) returns (OfferResponse); + +} + +// this line is used by starport scaffolding # proto/tx/message +message OfferRequest { + string sender = 1; + string amount = 2; +// [(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Coins"]; + string request = 3; +// [(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Coins"]; +} + +//message Coin { +// string coin = 1 +// [(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Coin"]; +//} + message OfferResponse { + int64 index =1; + } diff --git a/scripts/init.sh b/scripts/init.sh index aaf905d..2eb1c44 100755 --- a/scripts/init.sh +++ b/scripts/init.sh @@ -8,7 +8,7 @@ pooltoy config pooltoy init mynode --chain-id pooltoy-5 -jq -c '.balances[]' accounts.json | while read i; do +jq -c '.balances[]' accounts1.json | while read i; do echo "y" | pooltoy keys add $(echo "$i" | jq -r ".name") --keyring-backend test pooltoy add-genesis-account $(pooltoy keys show $(echo "$i" | jq -r ".name") --address) $(echo $i | jq -r '.coins | map(.amount+.denom) | join(",")') --keyring-backend test done diff --git a/x/escrow/client/cli/query.go b/x/escrow/client/cli/query.go new file mode 100644 index 0000000..0e56078 --- /dev/null +++ b/x/escrow/client/cli/query.go @@ -0,0 +1,30 @@ +package cli + +import ( + "fmt" + // "strings" + + "github.com/spf13/cobra" + + "github.com/cosmos/cosmos-sdk/client" + // "github.com/cosmos/cosmos-sdk/client/flags" + // sdk "github.com/cosmos/cosmos-sdk/types" + + "github.com/interchainberlin/pooltoy/x/escrow/types" +) + +// GetQueryCmd returns the cli query commands for this module +func GetQueryCmd(queryRoute string) *cobra.Command { + // Group escrow queries under a subcommand + cmd := &cobra.Command{ + Use: types.ModuleName, + Short: fmt.Sprintf("Querying commands for the %s module", types.ModuleName), + DisableFlagParsing: true, + SuggestionsMinimumDistance: 2, + RunE: client.ValidateCmd, + } + + // this line is used by starport scaffolding # 1 + + return cmd +} diff --git a/x/escrow/client/cli/tx.go b/x/escrow/client/cli/tx.go new file mode 100644 index 0000000..e097551 --- /dev/null +++ b/x/escrow/client/cli/tx.go @@ -0,0 +1,64 @@ +package cli + +import ( + "fmt" + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/client/flags" + "github.com/cosmos/cosmos-sdk/client/tx" + //"github.com/cosmos/cosmos-sdk/client/tx" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/spf13/cobra" + // "github.com/cosmos/cosmos-sdk/client/flags" + "github.com/interchainberlin/pooltoy/x/escrow/types" +) + +// GetTxCmd returns the transaction commands for this module +func GetTxCmd() *cobra.Command { + escrowTxCmd := &cobra.Command{ + Use: types.ModuleName, + Short: fmt.Sprintf("%s escrow offer subcommands", types.ModuleName), + DisableFlagParsing: true, + SuggestionsMinimumDistance: 2, + RunE: client.ValidateCmd, + } + + // this line is used by starport scaffolding # 1 + escrowTxCmd.AddCommand(escrowOffer()) + return escrowTxCmd +} + +func escrowOffer() *cobra.Command { + cmd := &cobra.Command{ + Use: "offer [address] [offer] [request] --from [username]", + Short: "send coins to escrow", + Args: cobra.ExactArgs(3), + RunE: func(cmd *cobra.Command, args []string) error { + ctx, err := client.GetClientTxContext(cmd) + if err != nil { + return err + } + + addr, err := sdk.AccAddressFromBech32(args[0]) + if err != nil { + return err + } + offer := types.NewOfferRequest(addr, args[1], args[2]) + + return tx.GenerateOrBroadcastTxCLI(ctx, cmd.Flags(), offer) + + + // method:2 + // msgClient := types.NewMsgClient(ctx) + // offer := &types.OfferRequest{Sender: args[0], Amount: args[1], Request: args[2]} + //res, err := msgClient.Offer(context.Background(), offer) + // if err != nil{ + // return err + //} + // return ctx.PrintProto(res) + + }, + } + flags.AddTxFlagsToCmd(cmd) + return cmd +} + diff --git a/x/escrow/genesis.go b/x/escrow/genesis.go new file mode 100644 index 0000000..9eee323 --- /dev/null +++ b/x/escrow/genesis.go @@ -0,0 +1,26 @@ +package escrow + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/interchainberlin/pooltoy/x/escrow/keeper" + "github.com/interchainberlin/pooltoy/x/escrow/types" +) + +// InitGenesis initializes the capability module's state from a provided genesis +// state. +func InitGenesis(ctx sdk.Context, k keeper.Keeper, genState types.GenesisState) { + // this line is used by starport scaffolding # genesis/module/init + + // this line is used by starport scaffolding # ibc/genesis/init +} + +// ExportGenesis returns the capability module's exported genesis. +func ExportGenesis(ctx sdk.Context, k keeper.Keeper) *types.GenesisState { + genesis := types.DefaultGenesis() + + // this line is used by starport scaffolding # genesis/module/export + + // this line is used by starport scaffolding # ibc/genesis/export + + return genesis +} diff --git a/x/escrow/handler.go b/x/escrow/handler.go new file mode 100644 index 0000000..5178c4a --- /dev/null +++ b/x/escrow/handler.go @@ -0,0 +1,31 @@ +package escrow + +import ( + "fmt" + sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + "github.com/interchainberlin/pooltoy/x/escrow/keeper" + "github.com/interchainberlin/pooltoy/x/escrow/types" +) + +// NewHandler ... +func NewHandler(k keeper.Keeper) sdk.Handler { + // this line is used by starport scaffolding # handler/msgServer + + return func(ctx sdk.Context, msg sdk.Msg) (*sdk.Result, error) { + + ctx = ctx.WithEventManager(sdk.NewEventManager()) + + switch msg := msg.(type) { + // this line is used by starport scaffolding # 1 + case *types.OfferRequest: + res, err := k.Offer(sdk.WrapSDKContext(ctx), msg) + return sdk.WrapServiceResult(ctx, res, err) + + default: + errMsg := fmt.Sprintf("unrecognized %s message type: %v", types.ModuleName, msg.Type()) + return nil, sdkerrors.Wrap(sdkerrors.ErrUnknownRequest, errMsg) + } + } +} + diff --git a/x/escrow/keeper/grpc_query.go b/x/escrow/keeper/grpc_query.go new file mode 100644 index 0000000..0797e6a --- /dev/null +++ b/x/escrow/keeper/grpc_query.go @@ -0,0 +1,7 @@ +package keeper + +import ( + "github.com/interchainberlin/pooltoy/x/escrow/types" +) + +var _ types.QueryServer = Keeper{} diff --git a/x/escrow/keeper/keeper.go b/x/escrow/keeper/keeper.go new file mode 100644 index 0000000..b9859e5 --- /dev/null +++ b/x/escrow/keeper/keeper.go @@ -0,0 +1,72 @@ +package keeper + +import ( + "fmt" + "github.com/cosmos/cosmos-sdk/x/auth/keeper" + "github.com/interchainberlin/pooltoy/x/escrow/utils" + "github.com/tendermint/tendermint/libs/log" + + "github.com/cosmos/cosmos-sdk/codec" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/interchainberlin/pooltoy/x/escrow/types" + // this line is used by starport scaffolding # ibc/keeper/import + bankkeeper "github.com/cosmos/cosmos-sdk/x/bank/keeper" +) + +type Keeper struct { + BankKeeper bankkeeper.Keeper + AccountKeeper keeper.AccountKeeper + cdc codec.Marshaler + storeKey sdk.StoreKey +// memKey sdk.StoreKey + // this line is used by starport scaffolding # ibc/keeper/attribute + index int64 +} + +func NewKeeper( + bankKeeper bankkeeper.Keeper, + accountKeeper keeper.AccountKeeper, + cdc codec.Marshaler, + storeKey sdk.StoreKey, + //memKey sdk.StoreKey, + index int64, +// this line is used by starport scaffolding # ibc/keeper/parameter +) Keeper { + return Keeper{ + BankKeeper: bankKeeper, + AccountKeeper: accountKeeper, + cdc: cdc, + storeKey: storeKey, + index: index, + // this line is used by starport scaffolding # ibc/keeper/return + } +} + +func (k Keeper) Logger(ctx sdk.Context) log.Logger { + return ctx.Logger().With("module", fmt.Sprintf("x/%s", types.ModuleName)) +} + +func (k Keeper) OfferSend(ctx sdk.Context, msg *types.OfferRequest) (*types.OfferResponse, error) { + + addr, err := sdk.AccAddressFromBech32(msg.Sender) + if err != nil { + fmt.Println("addr err!!!!") + return &types.OfferResponse{}, err + } + amount, err := utils.ParseCoins(msg.Amount) + if err != nil { + return &types.OfferResponse{}, err + } + +// moduleAcc:= k.AccountKeeper.GetModuleAddress(types.ModuleName) + + err = k.BankKeeper.SendCoinsFromAccountToModule(ctx, addr,types.ModuleName, amount) + if err != nil { + fmt.Println("sending err!!!!") + return &types.OfferResponse{}, err + } + + //presentIdx := k.index + //k.index +=1 // some checks this index is not re + return &types.OfferResponse{}, nil +} diff --git a/x/escrow/keeper/keeper_test.go b/x/escrow/keeper/keeper_test.go new file mode 100644 index 0000000..81059bc --- /dev/null +++ b/x/escrow/keeper/keeper_test.go @@ -0,0 +1,18 @@ +package keeper + +//func setupKeeper(t testing.TB) (*Keeper, sdk.Context) { +// storeKey := sdk.NewKVStoreKey(types.StoreKey) +// memStoreKey := storetypes.NewMemoryStoreKey(types.MemStoreKey) +// +// db := tmdb.NewMemDB() +// stateStore := store.NewCommitMultiStore(db) +// stateStore.MountStoreWithDB(storeKey, sdk.StoreTypeIAVL, db) +// stateStore.MountStoreWithDB(memStoreKey, sdk.StoreTypeMemory, nil) +// require.NoError(t, stateStore.LoadLatestVersion()) +// +// registry := codectypes.NewInterfaceRegistry() +// keeper := NewKeeper(, codec.NewProtoCodec(registry), storeKey) +// +// ctx := sdk.NewContext(stateStore, tmproto.Header{}, false, log.NewNopLogger()) +// return keeper, ctx +//} diff --git a/x/escrow/keeper/msg_server.go b/x/escrow/keeper/msg_server.go new file mode 100644 index 0000000..1d6e64b --- /dev/null +++ b/x/escrow/keeper/msg_server.go @@ -0,0 +1,37 @@ +package keeper + +import ( + "context" + "fmt" + sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + "github.com/interchainberlin/pooltoy/x/escrow/types" +) + +type msgServer struct { + Keeper +} + +// NewMsgServerImpl returns an implementation of the MsgServer interface +// for the provided Keeper. +func NewMsgServerImpl(keeper Keeper) types.MsgServer { + return &msgServer{Keeper: keeper} +} + +var _ types.MsgServer = Keeper{} + +func (k Keeper) Offer(c context.Context, msg *types.OfferRequest) (*types.OfferResponse, error) { + ctx := sdk.UnwrapSDKContext(c) + res, err := k.OfferSend(ctx, msg) + if err != nil { + return nil, sdkerrors.Wrap(err, fmt.Sprintf("unable to offer")) + } + + return res, nil +} + +//func (k Keeper) getIndex(ctx sdk.Context) int64{ +// //store := ctx.KVStore(k.storeKey) +// //if k.isPresent(ctx, ) +// return 1 +//} diff --git a/x/escrow/keeper/msg_server_test.go b/x/escrow/keeper/msg_server_test.go new file mode 100644 index 0000000..3a9fbf7 --- /dev/null +++ b/x/escrow/keeper/msg_server_test.go @@ -0,0 +1,19 @@ +package keeper +// +//import ( +// sdk "github.com/cosmos/cosmos-sdk/types" +// "testing" +//) + +//import ( +// "context" +// "testing" +// +// sdk "github.com/cosmos/cosmos-sdk/types" +// "github.com/interchainberlin/pooltoy/x/escrow/types" +//) +//// +//func setupMsgServer(t testing.TB) (types.MsgServer, context.Context) { +// keeper, ctx := setupKeeper(t) +// return NewMsgServerImpl(*keeper), sdk.WrapSDKContext(ctx) +//} diff --git a/x/escrow/keeper/store.go b/x/escrow/keeper/store.go new file mode 100644 index 0000000..749412a --- /dev/null +++ b/x/escrow/keeper/store.go @@ -0,0 +1,3 @@ +package keeper + + diff --git a/x/escrow/module.go b/x/escrow/module.go new file mode 100644 index 0000000..df4801e --- /dev/null +++ b/x/escrow/module.go @@ -0,0 +1,168 @@ +package escrow + +import ( + "encoding/json" + "fmt" + // this line is used by starport scaffolding # 1 + + "github.com/gorilla/mux" + "github.com/grpc-ecosystem/grpc-gateway/runtime" + "github.com/spf13/cobra" + + abci "github.com/tendermint/tendermint/abci/types" + + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/codec" + cdctypes "github.com/cosmos/cosmos-sdk/codec/types" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/types/module" + "github.com/interchainberlin/pooltoy/x/escrow/client/cli" + "github.com/interchainberlin/pooltoy/x/escrow/keeper" + "github.com/interchainberlin/pooltoy/x/escrow/types" + // this line is used by starport scaffolding # ibc/module/import +) + +var ( + _ module.AppModule = AppModule{} + _ module.AppModuleBasic = AppModuleBasic{} + // this line is used by starport scaffolding # ibc/module/interface +) + +// ---------------------------------------------------------------------------- +// AppModuleBasic +// ---------------------------------------------------------------------------- + +// AppModuleBasic implements the AppModuleBasic interface for the capability module. +type AppModuleBasic struct { + //cdc codec.Marshaler +} + +//todo: check here +func NewAppModuleBasic(cdc codec.Marshaler) AppModuleBasic { + return AppModuleBasic{} +} + +// Name returns the capability module's name. +func (AppModuleBasic) Name() string { + return types.ModuleName +} + +func (AppModuleBasic) RegisterCodec(cdc *codec.LegacyAmino) { + types.RegisterCodec(cdc) +} + +func (AppModuleBasic) RegisterLegacyAminoCodec(cdc *codec.LegacyAmino) { + types.RegisterCodec(cdc) +} + +// RegisterInterfaces registers the module's interface types +func (a AppModuleBasic) RegisterInterfaces(reg cdctypes.InterfaceRegistry) { + types.RegisterInterfaces(reg) +} + +// DefaultGenesis returns the capability module's default genesis state. +func (AppModuleBasic) DefaultGenesis(cdc codec.JSONMarshaler) json.RawMessage { + return cdc.MustMarshalJSON(types.DefaultGenesis()) +} + +// ValidateGenesis performs genesis state validation for the capability module. +func (AppModuleBasic) ValidateGenesis(cdc codec.JSONMarshaler, config client.TxEncodingConfig, bz json.RawMessage) error { + var genState types.GenesisState + if err := cdc.UnmarshalJSON(bz, &genState); err != nil { + return fmt.Errorf("failed to unmarshal %s genesis state: %w", types.ModuleName, err) + } + return genState.Validate() +} + +// RegisterRESTRoutes registers the capability module's REST service handlers. +func (AppModuleBasic) RegisterRESTRoutes(clientCtx client.Context, rtr *mux.Router) { +} + +// RegisterGRPCGatewayRoutes registers the gRPC Gateway routes for the module. +func (AppModuleBasic) RegisterGRPCGatewayRoutes(clientCtx client.Context, mux *runtime.ServeMux) { + // this line is used by starport scaffolding # 2 +} + +// GetTxCmd returns the capability module's root tx command. +func (a AppModuleBasic) GetTxCmd() *cobra.Command { + return cli.GetTxCmd() +} + +// GetQueryCmd returns the capability module's root query command. +func (AppModuleBasic) GetQueryCmd() *cobra.Command { + return cli.GetQueryCmd(types.StoreKey) +} + +// ---------------------------------------------------------------------------- +// AppModule +// ---------------------------------------------------------------------------- + +// AppModule implements the AppModule interface for the capability module. +type AppModule struct { + AppModuleBasic + + keeper keeper.Keeper +} + +func NewAppModule(cdc codec.Marshaler, keeper keeper.Keeper) AppModule { + return AppModule{ + AppModuleBasic: NewAppModuleBasic(cdc), + 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 (am AppModule) Route() sdk.Route { + return sdk.NewRoute(types.RouterKey, NewHandler(am.keeper)) +} + +// QuerierRoute returns the capability module's query routing key. +func (AppModule) QuerierRoute() string { return types.QuerierRoute } + +// LegacyQuerierHandler returns the capability module's Querier. +func (am AppModule) LegacyQuerierHandler(legacyQuerierCdc *codec.LegacyAmino) sdk.Querier { + return nil +} + +// RegisterServices registers a GRPC query service to respond to the +// module-specific GRPC queries. +func (am AppModule) RegisterServices(cfg module.Configurator) { + types.RegisterQueryServer(cfg.QueryServer(), am.keeper) + types.RegisterMsgServer(cfg.MsgServer(), am.keeper) + +} + +// RegisterInvariants registers the capability module's invariants. +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, cdc codec.JSONMarshaler, gs json.RawMessage) []abci.ValidatorUpdate { + var genState types.GenesisState + // Initialize global index to index in genesis state + cdc.MustUnmarshalJSON(gs, &genState) + + InitGenesis(ctx, am.keeper, genState) + + return []abci.ValidatorUpdate{} +} + +// ExportGenesis returns the capability module's exported genesis state as raw JSON bytes. +func (am AppModule) ExportGenesis(ctx sdk.Context, cdc codec.JSONMarshaler) json.RawMessage { + genState := ExportGenesis(ctx, am.keeper) + return cdc.MustMarshalJSON(genState) +} + +// BeginBlock executes all ABCI BeginBlock logic respective to the capability module. +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(_ sdk.Context, _ abci.RequestEndBlock) []abci.ValidatorUpdate { + return []abci.ValidatorUpdate{} +} diff --git a/x/escrow/types/codec.go b/x/escrow/types/codec.go new file mode 100644 index 0000000..43a6647 --- /dev/null +++ b/x/escrow/types/codec.go @@ -0,0 +1,29 @@ +package types + +import ( + "github.com/cosmos/cosmos-sdk/codec" + cdctypes "github.com/cosmos/cosmos-sdk/codec/types" + sdk "github.com/cosmos/cosmos-sdk/types" + + // this line is used by starport scaffolding # 1 + "github.com/cosmos/cosmos-sdk/types/msgservice" +) + +func RegisterCodec(cdc *codec.LegacyAmino) { + // this line is used by starport scaffolding # 2 +} + +func RegisterInterfaces(registry cdctypes.InterfaceRegistry) { + // this line is used by starport scaffolding # 3 + + registry.RegisterImplementations((*sdk.Msg)(nil), &OfferRequest{}) + + msgservice.RegisterMsgServiceDesc(registry, &_Msg_serviceDesc) + + +} + +var ( + amino = codec.NewLegacyAmino() + ModuleCdc = codec.NewProtoCodec(cdctypes.NewInterfaceRegistry()) +) diff --git a/x/escrow/types/errors.go b/x/escrow/types/errors.go new file mode 100644 index 0000000..c82999c --- /dev/null +++ b/x/escrow/types/errors.go @@ -0,0 +1,13 @@ +package types + +// DONTCOVER + +import ( + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" +) + +// x/escrow module sentinel errors +var ( + ErrSample = sdkerrors.Register(ModuleName, 1100, "sample error") + // this line is used by starport scaffolding # ibc/errors +) diff --git a/x/escrow/types/genesis.go b/x/escrow/types/genesis.go new file mode 100644 index 0000000..7096753 --- /dev/null +++ b/x/escrow/types/genesis.go @@ -0,0 +1,22 @@ +package types + +// DefaultIndex is the default capability global index +const DefaultIndex uint64 = 1 + +// DefaultGenesis returns the default Capability genesis state +func DefaultGenesis() *GenesisState { + return &GenesisState{ + // this line is used by starport scaffolding # ibc/genesistype/default + // this line is used by starport scaffolding # genesis/types/default + } +} + +// Validate performs basic genesis state validation returning an error upon any +// failure. +func (gs GenesisState) Validate() error { + // this line is used by starport scaffolding # ibc/genesistype/validate + + // this line is used by starport scaffolding # genesis/types/validate + + return nil +} diff --git a/x/escrow/types/genesis.pb.go b/x/escrow/types/genesis.pb.go new file mode 100644 index 0000000..c72328d --- /dev/null +++ b/x/escrow/types/genesis.pb.go @@ -0,0 +1,263 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: escrow/escrow/genesis.proto + +package types + +import ( + fmt "fmt" + 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 + +// GenesisState defines the escrow module's genesis state. +type GenesisState struct { +} + +func (m *GenesisState) Reset() { *m = GenesisState{} } +func (m *GenesisState) String() string { return proto.CompactTextString(m) } +func (*GenesisState) ProtoMessage() {} +func (*GenesisState) Descriptor() ([]byte, []int) { + return fileDescriptor_a2ef36a6ca65f517, []int{0} +} +func (m *GenesisState) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *GenesisState) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_GenesisState.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 *GenesisState) XXX_Merge(src proto.Message) { + xxx_messageInfo_GenesisState.Merge(m, src) +} +func (m *GenesisState) XXX_Size() int { + return m.Size() +} +func (m *GenesisState) XXX_DiscardUnknown() { + xxx_messageInfo_GenesisState.DiscardUnknown(m) +} + +var xxx_messageInfo_GenesisState proto.InternalMessageInfo + +func init() { + proto.RegisterType((*GenesisState)(nil), "escrow.GenesisState") +} + +func init() { proto.RegisterFile("escrow/escrow/genesis.proto", fileDescriptor_a2ef36a6ca65f517) } + +var fileDescriptor_a2ef36a6ca65f517 = []byte{ + // 142 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x92, 0x4e, 0x2d, 0x4e, 0x2e, + 0xca, 0x2f, 0xd7, 0x87, 0x52, 0xe9, 0xa9, 0x79, 0xa9, 0xc5, 0x99, 0xc5, 0x7a, 0x05, 0x45, 0xf9, + 0x25, 0xf9, 0x42, 0x6c, 0x10, 0x51, 0x25, 0x3e, 0x2e, 0x1e, 0x77, 0x88, 0x44, 0x70, 0x49, 0x62, + 0x49, 0xaa, 0x93, 0xcf, 0x89, 0x47, 0x72, 0x8c, 0x17, 0x1e, 0xc9, 0x31, 0x3e, 0x78, 0x24, 0xc7, + 0x38, 0xe1, 0xb1, 0x1c, 0xc3, 0x85, 0xc7, 0x72, 0x0c, 0x37, 0x1e, 0xcb, 0x31, 0x44, 0x19, 0xa5, + 0x67, 0x96, 0x64, 0x94, 0x26, 0xe9, 0x25, 0xe7, 0xe7, 0xea, 0x67, 0xe6, 0x95, 0xa4, 0x16, 0x25, + 0x67, 0x24, 0x66, 0xe6, 0x25, 0xa5, 0x16, 0xe5, 0x64, 0xe6, 0xe9, 0x17, 0xe4, 0xe7, 0xe7, 0x94, + 0xe4, 0x57, 0xea, 0x57, 0xc0, 0x6c, 0x2b, 0xa9, 0x2c, 0x48, 0x2d, 0x4e, 0x62, 0x03, 0x5b, 0x66, + 0x0c, 0x08, 0x00, 0x00, 0xff, 0xff, 0xfb, 0x6f, 0x05, 0xd0, 0x8b, 0x00, 0x00, 0x00, +} + +func (m *GenesisState) 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 *GenesisState) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *GenesisState) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + return len(dAtA) - i, nil +} + +func encodeVarintGenesis(dAtA []byte, offset int, v uint64) int { + offset -= sovGenesis(v) + base := offset + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return base +} +func (m *GenesisState) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + return n +} + +func sovGenesis(x uint64) (n int) { + return (math_bits.Len64(x|1) + 6) / 7 +} +func sozGenesis(x uint64) (n int) { + return sovGenesis(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (m *GenesisState) 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 ErrIntOverflowGenesis + } + 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: GenesisState: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: GenesisState: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + default: + iNdEx = preIndex + skippy, err := skipGenesis(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenesis + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func skipGenesis(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, ErrIntOverflowGenesis + } + 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, ErrIntOverflowGenesis + } + 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, ErrIntOverflowGenesis + } + 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, ErrInvalidLengthGenesis + } + iNdEx += length + case 3: + depth++ + case 4: + if depth == 0 { + return 0, ErrUnexpectedEndOfGroupGenesis + } + depth-- + case 5: + iNdEx += 4 + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + if iNdEx < 0 { + return 0, ErrInvalidLengthGenesis + } + if depth == 0 { + return iNdEx, nil + } + } + return 0, io.ErrUnexpectedEOF +} + +var ( + ErrInvalidLengthGenesis = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowGenesis = fmt.Errorf("proto: integer overflow") + ErrUnexpectedEndOfGroupGenesis = fmt.Errorf("proto: unexpected end of group") +) diff --git a/x/escrow/types/keys.go b/x/escrow/types/keys.go new file mode 100644 index 0000000..65eca0b --- /dev/null +++ b/x/escrow/types/keys.go @@ -0,0 +1,27 @@ +package types + +const ( + // ModuleName defines the module name + ModuleName = "escrow" + + // StoreKey defines the primary module store key + StoreKey = ModuleName + + // RouterKey is the message route for slashing + RouterKey = ModuleName + + // QuerierRoute defines the module's query routing key + QuerierRoute = ModuleName + + // MemStoreKey defines the in-memory store key + //MemStoreKey = "mem_escrow" + + // this line is used by starport scaffolding # ibc/keys/name + StartIndex = int64(0) +) + +// this line is used by starport scaffolding # ibc/keys/port + +func KeyPrefix(p string) []byte { + return []byte(p) +} diff --git a/x/escrow/types/msgs.go b/x/escrow/types/msgs.go new file mode 100644 index 0000000..575992a --- /dev/null +++ b/x/escrow/types/msgs.go @@ -0,0 +1,52 @@ +package types + +import ( + fmt "fmt" + sdk "github.com/cosmos/cosmos-sdk/types" +) + +var ( + _ sdk.Msg = &OfferRequest{} +) + +const ( + TypeOffer = "offer" +) + +// NewMsgMint is a constructor function for NewMsgMint +func NewOfferRequest(sender sdk.AccAddress, amount string, request string) *OfferRequest { + return &OfferRequest{Sender: sender.String(), Amount: amount, Request: request} +} + +// Route should return the name of the module +func (msg *OfferRequest) Route() string { return RouterKey } + +// Type should return the action +func (msg *OfferRequest) Type() string { return TypeOffer} + +// ValidateBasic runs stateless checks on the message +func (msg *OfferRequest) ValidateBasic() error { + //addr, err := sdk.AccAddressFromBech32(msg.Sender) + //fmt.Println("validation basic!!!!", addr) + //if err != nil { + // return sdkerrors.Wrap(sdkerrors.ErrInvalidAddress, msg.Sender) + //} + //// todo add more validation + + return nil +} + +// GetSignBytes encodes the message for signing +func (msg *OfferRequest) GetSignBytes() []byte { + panic("amino support disabled") +} + +// GetSigners defines whose signature is required +func (msg *OfferRequest) GetSigners() []sdk.AccAddress { + sender, err := sdk.AccAddressFromBech32(msg.Sender) + if err != nil { + fmt.Println(err) + // panic(err) + } + return []sdk.AccAddress{sdk.AccAddress(sender)} +} diff --git a/x/escrow/types/query.pb.go b/x/escrow/types/query.pb.go new file mode 100644 index 0000000..427de65 --- /dev/null +++ b/x/escrow/types/query.pb.go @@ -0,0 +1,84 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: escrow/escrow/query.proto + +package types + +import ( + context "context" + fmt "fmt" + grpc1 "github.com/gogo/protobuf/grpc" + proto "github.com/gogo/protobuf/proto" + _ "google.golang.org/genproto/googleapis/api/annotations" + grpc "google.golang.org/grpc" + math "math" +) + +// 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 + +func init() { proto.RegisterFile("escrow/escrow/query.proto", fileDescriptor_cf6961269d90321b) } + +var fileDescriptor_cf6961269d90321b = []byte{ + // 161 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x92, 0x4c, 0x2d, 0x4e, 0x2e, + 0xca, 0x2f, 0xd7, 0x87, 0x52, 0x85, 0xa5, 0xa9, 0x45, 0x95, 0x7a, 0x05, 0x45, 0xf9, 0x25, 0xf9, + 0x42, 0x6c, 0x10, 0x31, 0x29, 0x99, 0xf4, 0xfc, 0xfc, 0xf4, 0x9c, 0x54, 0xfd, 0xc4, 0x82, 0x4c, + 0xfd, 0xc4, 0xbc, 0xbc, 0xfc, 0x92, 0xc4, 0x92, 0xcc, 0xfc, 0xbc, 0x62, 0x88, 0x2a, 0x23, 0x76, + 0x2e, 0xd6, 0x40, 0x90, 0x26, 0x27, 0x9f, 0x13, 0x8f, 0xe4, 0x18, 0x2f, 0x3c, 0x92, 0x63, 0x7c, + 0xf0, 0x48, 0x8e, 0x71, 0xc2, 0x63, 0x39, 0x86, 0x0b, 0x8f, 0xe5, 0x18, 0x6e, 0x3c, 0x96, 0x63, + 0x88, 0x32, 0x4a, 0xcf, 0x2c, 0xc9, 0x28, 0x4d, 0xd2, 0x4b, 0xce, 0xcf, 0xd5, 0xcf, 0xcc, 0x2b, + 0x49, 0x2d, 0x4a, 0xce, 0x48, 0xcc, 0xcc, 0x4b, 0x4a, 0x2d, 0xca, 0xc9, 0xcc, 0xd3, 0x2f, 0xc8, + 0xcf, 0xcf, 0x29, 0xc9, 0xaf, 0xd4, 0xaf, 0x80, 0x39, 0xa1, 0xa4, 0xb2, 0x20, 0xb5, 0x38, 0x89, + 0x0d, 0x6c, 0xba, 0x31, 0x20, 0x00, 0x00, 0xff, 0xff, 0x0b, 0xf3, 0xbb, 0x07, 0xa0, 0x00, 0x00, + 0x00, +} + +// Reference imports to suppress errors if they are not otherwise used. +var _ context.Context +var _ grpc.ClientConn + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +const _ = grpc.SupportPackageIsVersion4 + +// QueryClient is the client API for Query service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. +type QueryClient interface { +} + +type queryClient struct { + cc grpc1.ClientConn +} + +func NewQueryClient(cc grpc1.ClientConn) QueryClient { + return &queryClient{cc} +} + +// QueryServer is the server API for Query service. +type QueryServer interface { +} + +// UnimplementedQueryServer can be embedded to have forward compatible implementations. +type UnimplementedQueryServer struct { +} + +func RegisterQueryServer(s grpc1.Server, srv QueryServer) { + s.RegisterService(&_Query_serviceDesc, srv) +} + +var _Query_serviceDesc = grpc.ServiceDesc{ + ServiceName: "escrow.Query", + HandlerType: (*QueryServer)(nil), + Methods: []grpc.MethodDesc{}, + Streams: []grpc.StreamDesc{}, + Metadata: "escrow/escrow/query.proto", +} diff --git a/x/escrow/types/tx.pb.go b/x/escrow/types/tx.pb.go new file mode 100644 index 0000000..5a3c53a --- /dev/null +++ b/x/escrow/types/tx.pb.go @@ -0,0 +1,670 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: escrow/escrow/tx.proto + +package types + +import ( + context "context" + fmt "fmt" + _ "github.com/gogo/protobuf/gogoproto" + grpc1 "github.com/gogo/protobuf/grpc" + proto "github.com/gogo/protobuf/proto" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" + 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 + +// this line is used by starport scaffolding # proto/tx/message +type OfferRequest struct { + Sender string `protobuf:"bytes,1,opt,name=sender,proto3" json:"sender,omitempty"` + Amount string `protobuf:"bytes,2,opt,name=amount,proto3" json:"amount,omitempty"` + // [(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Coins"]; + Request string `protobuf:"bytes,3,opt,name=request,proto3" json:"request,omitempty"` +} + +func (m *OfferRequest) Reset() { *m = OfferRequest{} } +func (m *OfferRequest) String() string { return proto.CompactTextString(m) } +func (*OfferRequest) ProtoMessage() {} +func (*OfferRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_f5eef200b34c62c8, []int{0} +} +func (m *OfferRequest) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *OfferRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_OfferRequest.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 *OfferRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_OfferRequest.Merge(m, src) +} +func (m *OfferRequest) XXX_Size() int { + return m.Size() +} +func (m *OfferRequest) XXX_DiscardUnknown() { + xxx_messageInfo_OfferRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_OfferRequest proto.InternalMessageInfo + +func (m *OfferRequest) GetSender() string { + if m != nil { + return m.Sender + } + return "" +} + +func (m *OfferRequest) GetAmount() string { + if m != nil { + return m.Amount + } + return "" +} + +func (m *OfferRequest) GetRequest() string { + if m != nil { + return m.Request + } + return "" +} + +//message Coin { +// string coin = 1 +// [(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Coin"]; +//} +type OfferResponse struct { + Index int64 `protobuf:"varint,1,opt,name=index,proto3" json:"index,omitempty"` +} + +func (m *OfferResponse) Reset() { *m = OfferResponse{} } +func (m *OfferResponse) String() string { return proto.CompactTextString(m) } +func (*OfferResponse) ProtoMessage() {} +func (*OfferResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_f5eef200b34c62c8, []int{1} +} +func (m *OfferResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *OfferResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_OfferResponse.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 *OfferResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_OfferResponse.Merge(m, src) +} +func (m *OfferResponse) XXX_Size() int { + return m.Size() +} +func (m *OfferResponse) XXX_DiscardUnknown() { + xxx_messageInfo_OfferResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_OfferResponse proto.InternalMessageInfo + +func (m *OfferResponse) GetIndex() int64 { + if m != nil { + return m.Index + } + return 0 +} + +func init() { + proto.RegisterType((*OfferRequest)(nil), "escrow.OfferRequest") + proto.RegisterType((*OfferResponse)(nil), "escrow.OfferResponse") +} + +func init() { proto.RegisterFile("escrow/escrow/tx.proto", fileDescriptor_f5eef200b34c62c8) } + +var fileDescriptor_f5eef200b34c62c8 = []byte{ + // 253 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x5c, 0x90, 0x41, 0x4b, 0xc3, 0x30, + 0x14, 0xc7, 0x1b, 0xcb, 0x2a, 0x06, 0xbd, 0x84, 0x3a, 0xca, 0x0e, 0x41, 0x06, 0x82, 0xa7, 0x06, + 0xa6, 0x37, 0x6f, 0x9e, 0x15, 0xa1, 0x27, 0xf1, 0xb6, 0x76, 0x6f, 0x5d, 0x60, 0xcb, 0x8b, 0x49, + 0x8a, 0xdd, 0xb7, 0xf0, 0x63, 0x79, 0xdc, 0xd1, 0xa3, 0xb4, 0x5f, 0x44, 0x9a, 0x54, 0x91, 0x9d, + 0x92, 0xdf, 0xef, 0x25, 0x7f, 0x1e, 0x7f, 0x3a, 0x05, 0x5b, 0x19, 0x7c, 0x17, 0xe3, 0xe1, 0xda, + 0x5c, 0x1b, 0x74, 0xc8, 0x92, 0x20, 0x66, 0x69, 0x8d, 0x35, 0x7a, 0x25, 0x86, 0x5b, 0x98, 0xce, + 0x5f, 0xe8, 0xf9, 0xf3, 0x7a, 0x0d, 0xa6, 0x80, 0xb7, 0x06, 0xac, 0x63, 0x53, 0x9a, 0x58, 0x50, + 0x2b, 0x30, 0x19, 0xb9, 0x22, 0x37, 0x67, 0xc5, 0x48, 0x83, 0x5f, 0xee, 0xb0, 0x51, 0x2e, 0x3b, + 0x09, 0x3e, 0x10, 0xcb, 0xe8, 0xa9, 0x09, 0x5f, 0xb3, 0xd8, 0x0f, 0x7e, 0x71, 0x7e, 0x4d, 0x2f, + 0xc6, 0x64, 0xab, 0x51, 0x59, 0x60, 0x29, 0x9d, 0x48, 0xb5, 0x82, 0xd6, 0x27, 0xc7, 0x45, 0x80, + 0xc5, 0x3d, 0x8d, 0x9f, 0x6c, 0xcd, 0xee, 0xe8, 0xc4, 0xbf, 0x66, 0x69, 0x1e, 0xf6, 0xcd, 0xff, + 0xaf, 0x35, 0xbb, 0x3c, 0xb2, 0x21, 0xf2, 0xe1, 0xf1, 0xb3, 0xe3, 0xe4, 0xd0, 0x71, 0xf2, 0xdd, + 0x71, 0xf2, 0xd1, 0xf3, 0xe8, 0xd0, 0xf3, 0xe8, 0xab, 0xe7, 0xd1, 0xeb, 0xa2, 0x96, 0x6e, 0xd3, + 0x94, 0x79, 0x85, 0x3b, 0x21, 0x95, 0x03, 0x53, 0x6d, 0x96, 0x52, 0x95, 0x60, 0xb6, 0x52, 0x09, + 0x8d, 0xb8, 0x75, 0xb8, 0x17, 0xed, 0x5f, 0x59, 0x7b, 0x0d, 0xb6, 0x4c, 0x7c, 0x25, 0xb7, 0x3f, + 0x01, 0x00, 0x00, 0xff, 0xff, 0xdf, 0xeb, 0x7f, 0x8b, 0x4a, 0x01, 0x00, 0x00, +} + +// Reference imports to suppress errors if they are not otherwise used. +var _ context.Context +var _ grpc.ClientConn + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +const _ = grpc.SupportPackageIsVersion4 + +// MsgClient is the client API for Msg service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. +type MsgClient interface { + // this line is used by starport scaffolding # proto/tx/rpc + Offer(ctx context.Context, in *OfferRequest, opts ...grpc.CallOption) (*OfferResponse, error) +} + +type msgClient struct { + cc grpc1.ClientConn +} + +func NewMsgClient(cc grpc1.ClientConn) MsgClient { + return &msgClient{cc} +} + +func (c *msgClient) Offer(ctx context.Context, in *OfferRequest, opts ...grpc.CallOption) (*OfferResponse, error) { + out := new(OfferResponse) + err := c.cc.Invoke(ctx, "/escrow.Msg/Offer", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// MsgServer is the server API for Msg service. +type MsgServer interface { + // this line is used by starport scaffolding # proto/tx/rpc + Offer(context.Context, *OfferRequest) (*OfferResponse, error) +} + +// UnimplementedMsgServer can be embedded to have forward compatible implementations. +type UnimplementedMsgServer struct { +} + +func (*UnimplementedMsgServer) Offer(ctx context.Context, req *OfferRequest) (*OfferResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method Offer not implemented") +} + +func RegisterMsgServer(s grpc1.Server, srv MsgServer) { + s.RegisterService(&_Msg_serviceDesc, srv) +} + +func _Msg_Offer_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(OfferRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(MsgServer).Offer(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/escrow.Msg/Offer", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MsgServer).Offer(ctx, req.(*OfferRequest)) + } + return interceptor(ctx, in, info, handler) +} + +var _Msg_serviceDesc = grpc.ServiceDesc{ + ServiceName: "escrow.Msg", + HandlerType: (*MsgServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "Offer", + Handler: _Msg_Offer_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "escrow/escrow/tx.proto", +} + +func (m *OfferRequest) 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 *OfferRequest) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *OfferRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Request) > 0 { + i -= len(m.Request) + copy(dAtA[i:], m.Request) + i = encodeVarintTx(dAtA, i, uint64(len(m.Request))) + i-- + dAtA[i] = 0x1a + } + if len(m.Amount) > 0 { + i -= len(m.Amount) + copy(dAtA[i:], m.Amount) + i = encodeVarintTx(dAtA, i, uint64(len(m.Amount))) + i-- + dAtA[i] = 0x12 + } + if len(m.Sender) > 0 { + i -= len(m.Sender) + copy(dAtA[i:], m.Sender) + i = encodeVarintTx(dAtA, i, uint64(len(m.Sender))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *OfferResponse) 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 *OfferResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *OfferResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.Index != 0 { + i = encodeVarintTx(dAtA, i, uint64(m.Index)) + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + +func encodeVarintTx(dAtA []byte, offset int, v uint64) int { + offset -= sovTx(v) + base := offset + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return base +} +func (m *OfferRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Sender) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + l = len(m.Amount) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + l = len(m.Request) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + return n +} + +func (m *OfferResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Index != 0 { + n += 1 + sovTx(uint64(m.Index)) + } + return n +} + +func sovTx(x uint64) (n int) { + return (math_bits.Len64(x|1) + 6) / 7 +} +func sozTx(x uint64) (n int) { + return sovTx(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (m *OfferRequest) 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 ErrIntOverflowTx + } + 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: OfferRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: OfferRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Sender", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + 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 ErrInvalidLengthTx + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Sender = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Amount", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + 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 ErrInvalidLengthTx + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Amount = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Request", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + 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 ErrInvalidLengthTx + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Request = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipTx(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthTx + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *OfferResponse) 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 ErrIntOverflowTx + } + 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: OfferResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: OfferResponse: 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 ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Index |= int64(b&0x7F) << shift + if b < 0x80 { + break + } + } + default: + iNdEx = preIndex + skippy, err := skipTx(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthTx + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func skipTx(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, ErrIntOverflowTx + } + 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, ErrIntOverflowTx + } + 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, ErrIntOverflowTx + } + 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, ErrInvalidLengthTx + } + iNdEx += length + case 3: + depth++ + case 4: + if depth == 0 { + return 0, ErrUnexpectedEndOfGroupTx + } + depth-- + case 5: + iNdEx += 4 + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + if iNdEx < 0 { + return 0, ErrInvalidLengthTx + } + if depth == 0 { + return iNdEx, nil + } + } + return 0, io.ErrUnexpectedEOF +} + +var ( + ErrInvalidLengthTx = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowTx = fmt.Errorf("proto: integer overflow") + ErrUnexpectedEndOfGroupTx = fmt.Errorf("proto: unexpected end of group") +) diff --git a/x/escrow/types/types.go b/x/escrow/types/types.go new file mode 100644 index 0000000..ab1254f --- /dev/null +++ b/x/escrow/types/types.go @@ -0,0 +1 @@ +package types diff --git a/x/escrow/utils/errors.go b/x/escrow/utils/errors.go new file mode 100644 index 0000000..86c9364 --- /dev/null +++ b/x/escrow/utils/errors.go @@ -0,0 +1,5 @@ +package utils + +import sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + +var ErrParsEscrowEmoji = sdkerrors.Register("escrow", 106, "parse emoji failed") diff --git a/x/escrow/utils/utils.go b/x/escrow/utils/utils.go new file mode 100644 index 0000000..de6ecb2 --- /dev/null +++ b/x/escrow/utils/utils.go @@ -0,0 +1,63 @@ +package utils + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/interchainberlin/pooltoy/x/faucet/utils" + "strconv" +) + +func ParseCoins(coins string) (sdk.Coins, error) { + sdkcoins := sdk.Coins{} + coin := sdk.Coin{} + emojiMap := utils.ReverseMapKV(utils.EmojiCodeMap) + num := "" + + // cannot be all num + _, err := strconv.Atoi(coins) + if err == nil { + return sdk.Coins{}, ErrParsEscrowEmoji + } + + for _, v := range coins { + _, err := strconv.Atoi(string(v)) + _, found := emojiMap[string(v)] + + // not emoji, not number + if err != nil && !found { + return sdk.Coins{}, ErrParsEscrowEmoji + } + + // is num + if err == nil { + num += string(v) + } + + // is emoji + if found { + + var bigAmt sdk.Int + if num == "" { + bigAmt = sdk.NewInt(1) + } else { + amt, err := strconv.Atoi(num) + if err == nil && amt != 0 { + bigAmt = sdk.NewInt(int64(amt)) + } else { + return sdk.Coins{}, ErrParsEscrowEmoji + + } + } + + coin.Amount = bigAmt + coin.Denom = string(v) + + sdkcoins = append(sdkcoins, coin) + coin = sdk.Coin{} + num = "" + } + + } + + return sdkcoins, nil + +} diff --git a/x/escrow/utils/utils_test.go b/x/escrow/utils/utils_test.go new file mode 100644 index 0000000..0e9cec1 --- /dev/null +++ b/x/escrow/utils/utils_test.go @@ -0,0 +1,97 @@ +package utils + +import ( + "errors" + "fmt" + sdk "github.com/cosmos/cosmos-sdk/types" + "testing" + +) + +func TestParseCoins_0(t *testing.T) { + coins := "1🆗200🍍" + res, err := ParseCoins(coins) + if err != nil { + t.Fatal(err) + } + + if r :=res[0].Amount.BigInt().Cmp(sdk.NewInt(1).BigInt()); r!=0{ + t.Fatal(res[1].Amount.BigInt()) + } + if res[0].Denom != "🆗"{ + t.Fatal(res[0].Denom) + } + + if r :=res[1].Amount.BigInt().Cmp(sdk.NewInt(200).BigInt()); r!=0{ + t.Fatal(res[1].Amount.BigInt()) + } + if res[1].Denom != "🍍"{ + t.Fatal(res[1].Denom) + } +} + + +func TestParseCoins_1(t *testing.T) { + coins := "🆗200🍍" + res, err := ParseCoins(coins) + if err != nil { + t.Fatal(err) + } + fmt.Println(res.String()) + + if r :=res[0].Amount.BigInt().Cmp(sdk.NewInt(1).BigInt()); r!=0{ + t.Fatal(res[1].Amount.BigInt()) + } + if res[0].Denom != "🆗"{ + t.Fatal(res[0].Denom) + } + + if r :=res[1].Amount.BigInt().Cmp(sdk.NewInt(200).BigInt()); r!=0{ + t.Fatal(res[1].Amount.BigInt()) + } + if res[1].Denom != "🍍"{ + t.Fatal(res[1].Denom) + } +} + +func TestParseCoins_2(t *testing.T) { + coins := "🆗🍍" + res, err := ParseCoins(coins) + if err != nil { + t.Fatal(err) + } + + if r :=res[0].Amount.BigInt().Cmp(sdk.NewInt(1).BigInt()); r!=0{ + t.Fatal(res[1].Amount.BigInt()) + } + if res[0].Denom != "🆗"{ + t.Fatal(res[0].Denom) + } + + if r :=res[1].Amount.BigInt().Cmp(sdk.NewInt(1).BigInt()); r!=0{ + t.Fatal(res[1].Amount.BigInt()) + } + if res[1].Denom != "🍍"{ + t.Fatal(res[1].Denom) + } +} + +// ----------------------------------------------------------------------------- +//fail cases +// ----------------------------------------------------------------------------- +func TestParseCoins_3(t *testing.T) { + coins := "1🆗0🍍" + _, err := ParseCoins(coins) + if !errors.Is(err, ErrParsEscrowEmoji) { + t.Fatal(err) + } +} + +func TestParseCoins_4(t *testing.T) { + coins := "0🆗0🍍" + _, err := ParseCoins(coins) + if !errors.Is(err, ErrParsEscrowEmoji) { + t.Fatal(err) + } +} + diff --git a/x/faucet/keeper/keeper.go b/x/faucet/keeper/keeper.go index 34dd72f..1635f87 100644 --- a/x/faucet/keeper/keeper.go +++ b/x/faucet/keeper/keeper.go @@ -57,6 +57,7 @@ func (k Keeper) Logger(ctx sdk.Context) log.Logger { func (k Keeper) MintAndSend(ctx sdk.Context, msg *types.MsgMint) error { // TODO: should most of this logic be in the msg_server? + mintTime := ctx.BlockTime().Unix() if msg.Denom == k.StakingKeeper.BondDenom(ctx) { return types.ErrCantWithdrawStake diff --git a/x/faucet/types/msgs.go b/x/faucet/types/msgs.go index 02a2186..5bae03a 100644 --- a/x/faucet/types/msgs.go +++ b/x/faucet/types/msgs.go @@ -17,7 +17,7 @@ const ( // NewMsgMint is a constructor function for NewMsgMint func NewMsgMint(sender sdk.AccAddress, minter sdk.AccAddress, denom string) *MsgMint { return &MsgMint{Sender: sender.String(), Minter: minter.String(), Denom: denom} -} +} //todo no need to be addr, string as arg is fine // Route should return the name of the module func (msg *MsgMint) Route() string { return RouterKey } diff --git a/x/faucet/utils/emojiCodeMap.go b/x/faucet/utils/emojiCodeMap.go index 692dfa4..9d351d8 100644 --- a/x/faucet/utils/emojiCodeMap.go +++ b/x/faucet/utils/emojiCodeMap.go @@ -5,7 +5,7 @@ package utils // DO NOT EDIT // Mapping from character to concrete escape code. -var emojiCodeMap = map[string]string{ +var EmojiCodeMap = map[string]string{ ":+1:": "\U0001f44d", ":-1:": "\U0001f44e", ":100:": "\U0001f4af", diff --git a/x/faucet/utils/utils.go b/x/faucet/utils/utils.go index 410b209..1311d76 100644 --- a/x/faucet/utils/utils.go +++ b/x/faucet/utils/utils.go @@ -2,7 +2,7 @@ package utils // parse emoji for mintfor, only allows format like "\U0001f630" or "1\U0001f630" func ParseEmoji(emoji string) (string, error) { - emojiMap := ReverseMapKV(emojiCodeMap) + emojiMap := ReverseMapKV(EmojiCodeMap) _, found1 := emojiMap[emoji] _, found2 := emojiMap[emoji[1:]] From e0a42c479a4fe1ed09a5071a25e15117e179f522 Mon Sep 17 00:00:00 2001 From: yaruwang Date: Tue, 27 Jul 2021 18:31:14 +0200 Subject: [PATCH 09/22] parse emojiStr into coins --- x/escrow/utils/errors.go | 7 +- x/escrow/utils/utils.go | 198 ++++++++++++++++++++++++++++------- x/escrow/utils/utils_test.go | 145 ++++++++++++------------- 3 files changed, 237 insertions(+), 113 deletions(-) diff --git a/x/escrow/utils/errors.go b/x/escrow/utils/errors.go index 86c9364..699d334 100644 --- a/x/escrow/utils/errors.go +++ b/x/escrow/utils/errors.go @@ -2,4 +2,9 @@ package utils import sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" -var ErrParsEscrowEmoji = sdkerrors.Register("escrow", 106, "parse emoji failed") +var ErrParseEmojiandNum = sdkerrors.Register("escrow", 106, "parse emoji string into numbers and emojis failed") +var ErrParseEmojiToCoins = sdkerrors.Register("escrow", 107, "parse emoji string into coins failed") + +var ErrEmojiCoinsCheck = sdkerrors.Register("escrow", 108, "emoji coins check failed") + +var ErrEmojiStr = sdkerrors.Register("escrow", 109, "parse emoji string into emoji failed") diff --git a/x/escrow/utils/utils.go b/x/escrow/utils/utils.go index de6ecb2..048adce 100644 --- a/x/escrow/utils/utils.go +++ b/x/escrow/utils/utils.go @@ -4,60 +4,188 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" "github.com/interchainberlin/pooltoy/x/faucet/utils" "strconv" + "strings" + "unicode" ) -func ParseCoins(coins string) (sdk.Coins, error) { - sdkcoins := sdk.Coins{} - coin := sdk.Coin{} - emojiMap := utils.ReverseMapKV(utils.EmojiCodeMap) - num := "" +// ----------------------------------------------------------------------------- +// +// ----------------------------------------------------------------------------- + +// find the max mactch, e.g. str = "\U0001f1e6\U0001f1fd\U0001f6e9", \U0001f1e6\U0001f1fd\" is an emoji, "\U0001f1e6" is also an emoji, it should find "\U0001f1e6\U0001f1fd". +// maxlen is the max length of a single emoji's runes, here is 5 according to the emojiCodeMap. +// ----------------------------------------------------------------------------- - // cannot be all num - _, err := strconv.Atoi(coins) - if err == nil { - return sdk.Coins{}, ErrParsEscrowEmoji +func GetCoinsWithCheck(emostr string) (coins sdk.Coins, err error) { + nums, emos, err := ParseEmojiandNum(emostr) + if err != nil { + return sdk.Coins{}, err } - for _, v := range coins { - _, err := strconv.Atoi(string(v)) - _, found := emojiMap[string(v)] + coins, err = GetCoins(nums, emos) + if err != nil { + return sdk.Coins{}, err + } + emptyCoins := sdk.Coins{} + if coins.IsEqual(emptyCoins) { // todo do we allow empty coins? + return coins, nil + } + if !coins.IsAllPositive() { + return sdk.Coins{}, ErrEmojiCoinsCheck + } + //if err := coins.Validate(); err != nil { + // fmt.Println("validation failed", err) + // return sdk.Coins{}, err + //} - // not emoji, not number - if err != nil && !found { - return sdk.Coins{}, ErrParsEscrowEmoji + //not allow the same emoji appear twice ⭐⭐, one should write 2⭐, this is for distinguish accidental input + memo := map[string]bool{} + for _, coin := range coins { + _, found := memo[coin.Denom] + if found { + return sdk.Coins{}, ErrEmojiCoinsCheck + } else { + memo[coin.Denom] = true } + } + + return coins, nil +} - // is num - if err == nil { - num += string(v) +func GetCoins(nums, emos []string) (coins sdk.Coins, err error) { + if len(nums) != len(emos) { + return sdk.Coins{}, ErrParseEmojiToCoins + } + coin := sdk.Coin{} + j := 0 + for _, emo := range emos { + emolist, err := ParseEmo(emo, 5) + if err != nil { + return sdk.Coins{}, ErrParseEmojiToCoins } - // is emoji - if found { + for i := range emolist { + if i == 0 { + n, err := strconv.Atoi(nums[j]) + if err != nil { + return sdk.Coins{}, ErrParseEmojiToCoins + } + coin.Amount = sdk.NewInt(int64(n)) + j++ + } else { + coin.Amount = sdk.NewInt(1) + } + + coin.Denom = emolist[i] + coins = append(coins, coin) + } + } - var bigAmt sdk.Int - if num == "" { - bigAmt = sdk.NewInt(1) + return coins, nil +} + +// parse the string, to get list of nums and emojis +func ParseEmojiandNum(str string) (nums []string, emos []string, err error) { + numBuf := strings.Builder{} + emojiBuf := strings.Builder{} + writebuf := true + + for _, r := range []rune(str) { + + ok := unicode.IsDigit(r) + + switch writebuf { + case true: + if ok { + numBuf.WriteRune(r) } else { - amt, err := strconv.Atoi(num) - if err == nil && amt != 0 { - bigAmt = sdk.NewInt(int64(amt)) - } else { - return sdk.Coins{}, ErrParsEscrowEmoji + emojiBuf.WriteRune(r) + writebuf = false + } + case false: + if ok { + num, emo, ok := FlushBuf(&numBuf, &emojiBuf) + if !ok { + return nil, nil, ErrParseEmojiandNum } + nums = append(nums, num) + emos = append(emos, emo) + numBuf.WriteRune(r) + writebuf = true + } else { + emojiBuf.WriteRune(r) } + } + } - coin.Amount = bigAmt - coin.Denom = string(v) + num, emo, ok := FlushBuf(&numBuf, &emojiBuf) + if !ok { + return nil, nil, ErrParseEmojiandNum + } + nums = append(nums, num) + emos = append(emos, emo) - sdkcoins = append(sdkcoins, coin) - coin = sdk.Coin{} - num = "" - } + return nums, emos, nil +} + +func FlushBuf(numBuf, emojiBuf *strings.Builder) (num string, emo string, ok bool) { + + if numBuf.String() == "" && emojiBuf.String() == "" { + return "", "", false + } + + if numBuf.String() != "" && emojiBuf.String() == "" { + return "", "", false + } + + if numBuf.String() == "" && emojiBuf.String() != "" { + emo = emojiBuf.String() + num = "1" + numBuf.Reset() + emojiBuf.Reset() + } + if numBuf.String() != "" && emojiBuf.String() != "" { + num = numBuf.String() + emo = emojiBuf.String() + numBuf.Reset() + emojiBuf.Reset() } - return sdkcoins, nil + return num, emo, true +} + +// parse emojis string which does not contain numbers +func ParseEmo(emo string, emojiMaxLen int) (emolist []string, err error) { + // use rune rather than string to avoid index jumping + r := []rune(emo) + emojimap := utils.ReverseMapKV(utils.EmojiCodeMap) + + i := 0 + for i < len(r) { + maxLen := emojiMaxLen + if i+emojiMaxLen >= len(r) { + maxLen = len(r) - i + } + + hasEmoji := true + + for j := maxLen; j > 0; j-- { + _, found := emojimap[string(r[i:i+j])] + if found { + emolist = append(emolist, string(r[i:i+j])) + i += j + hasEmoji = true + break + } + hasEmoji = false + } + + if hasEmoji == false { + return []string{}, ErrEmojiStr + } + } + return emolist, nil } diff --git a/x/escrow/utils/utils_test.go b/x/escrow/utils/utils_test.go index 0e9cec1..772ab9c 100644 --- a/x/escrow/utils/utils_test.go +++ b/x/escrow/utils/utils_test.go @@ -1,97 +1,88 @@ package utils import ( - "errors" - "fmt" sdk "github.com/cosmos/cosmos-sdk/types" "testing" - ) -func TestParseCoins_0(t *testing.T) { - coins := "1🆗200🍍" - res, err := ParseCoins(coins) - if err != nil { - t.Fatal(err) - } - - if r :=res[0].Amount.BigInt().Cmp(sdk.NewInt(1).BigInt()); r!=0{ - t.Fatal(res[1].Amount.BigInt()) - } - if res[0].Denom != "🆗"{ - t.Fatal(res[0].Denom) - } - - if r :=res[1].Amount.BigInt().Cmp(sdk.NewInt(200).BigInt()); r!=0{ - t.Fatal(res[1].Amount.BigInt()) - } - if res[1].Denom != "🍍"{ - t.Fatal(res[1].Denom) - } -} - - -func TestParseCoins_1(t *testing.T) { - coins := "🆗200🍍" - res, err := ParseCoins(coins) - if err != nil { - t.Fatal(err) +func TestParseCoins_Cases_Pass(t *testing.T) { + type ParseCase struct { + EmoStr string + Coins sdk.Coins } - fmt.Println(res.String()) - if r :=res[0].Amount.BigInt().Cmp(sdk.NewInt(1).BigInt()); r!=0{ - t.Fatal(res[1].Amount.BigInt()) - } - if res[0].Denom != "🆗"{ - t.Fatal(res[0].Denom) - } + samples := []ParseCase{ + { + EmoStr: "1🆗", + Coins: []sdk.Coin{ + {Denom: "🆗", Amount: sdk.NewInt(1)}, + }, + }, + { + EmoStr: "🆗🍍", + Coins: []sdk.Coin{ + {Denom: "🆗", Amount: sdk.NewInt(1)}, + {Denom: "🍍", Amount: sdk.NewInt(1)}, + }, + }, + { + EmoStr: "12🆗🍍", + Coins: []sdk.Coin{ + {Denom: "🆗", Amount: sdk.NewInt(12)}, + {Denom: "🍍", Amount: sdk.NewInt(1)}, + }, + }, + { + EmoStr: "12" + "\U0001f1e6\U0001f1f2", + Coins: []sdk.Coin{ + {Denom: "\U0001f1e6\U0001f1f2", Amount: sdk.NewInt(12)}, + }, + }, - if r :=res[1].Amount.BigInt().Cmp(sdk.NewInt(200).BigInt()); r!=0{ - t.Fatal(res[1].Amount.BigInt()) - } - if res[1].Denom != "🍍"{ - t.Fatal(res[1].Denom) + { + EmoStr: "10\U0001f9d1\u200d\U0001f3a8" + + "40\U0001f632" + "\U0001f1e6\U0001f1fa" + "\U0001f3a8" + "2\U0001f9d6\U0001f3fb\u200d\u2640\ufe0f", + Coins: []sdk.Coin{ + {Denom: "\U0001f9d1\u200d\U0001f3a8", Amount: sdk.NewInt(10)}, + {Denom: "\U0001f632", Amount: sdk.NewInt(40)}, + {Denom: "\U0001f1e6\U0001f1fa", Amount: sdk.NewInt(1)}, + {Denom: "\U0001f3a8", Amount: sdk.NewInt(1)}, + {Denom: "\U0001f9d6\U0001f3fb\u200d\u2640\ufe0f", Amount: sdk.NewInt(2)}, + }, + }, } -} -func TestParseCoins_2(t *testing.T) { - coins := "🆗🍍" - res, err := ParseCoins(coins) - if err != nil { - t.Fatal(err) - } + for i, sample := range samples { + coins, err := GetCoinsWithCheck(sample.EmoStr) + if err != nil { + t.Fatalf("failed case %d", i) + } - if r :=res[0].Amount.BigInt().Cmp(sdk.NewInt(1).BigInt()); r!=0{ - t.Fatal(res[1].Amount.BigInt()) - } - if res[0].Denom != "🆗"{ - t.Fatal(res[0].Denom) - } - - if r :=res[1].Amount.BigInt().Cmp(sdk.NewInt(1).BigInt()); r!=0{ - t.Fatal(res[1].Amount.BigInt()) - } - if res[1].Denom != "🍍"{ - t.Fatal(res[1].Denom) + if !coins.IsEqual(sample.Coins) { + t.Fatalf("failed case %d: %s", i, coins.String()) + } } } -// ----------------------------------------------------------------------------- -//fail cases -// ----------------------------------------------------------------------------- -func TestParseCoins_3(t *testing.T) { - coins := "1🆗0🍍" - _, err := ParseCoins(coins) - if !errors.Is(err, ErrParsEscrowEmoji) { - t.Fatal(err) +func TestParseCoins_Cases_Fail(t *testing.T) { + str := []string{ + "", + "-123🆗", // negative + "0🆗", // zero + "1e10🆗", // scientific notation + "1.2🆗", // decimal + "1,223🆗", // formatted + "1,223", // no emoji + "1🆗🆗", // duplicate emoji + "1🆗2🍍3🆗", // duplicate emoji + // "00002🆗⭐", // leading zero //todo if allow ??? + "01 🆗", //space } -} -func TestParseCoins_4(t *testing.T) { - coins := "0🆗0🍍" - _, err := ParseCoins(coins) - if !errors.Is(err, ErrParsEscrowEmoji) { - t.Fatal(err) + for i, s := range str { + _, err := GetCoinsWithCheck(s) + if err == nil { + t.Fatalf("failed case %d", i) + } } } - From 21acc916e1d9631f01f7968129e477fc9b874090 Mon Sep 17 00:00:00 2001 From: yaruwang Date: Wed, 28 Jul 2021 10:42:05 +0200 Subject: [PATCH 10/22] escrow query offer --- accounts1.json | 2 +- app/app.go | 2 +- proto/escrow/escrow/query.proto | 34 +- proto/escrow/escrow/tx.proto | 11 +- x/escrow/client/cli/query.go | 53 +- x/escrow/keeper/grpc_query.go | 7 - x/escrow/keeper/keeper.go | 39 +- x/escrow/keeper/msg_server.go | 37 +- x/escrow/keeper/query_server.go | 38 + x/escrow/keeper/store.go | 89 +++ x/escrow/types/keys.go | 6 +- x/escrow/types/query.pb.go | 1263 +++++++++++++++++++++++++++++- x/escrow/types/tx.pb.go | 89 ++- x/faucet/utils/utils.go | 8 +- x/pooltoy/keeper/query_server.go | 2 + 15 files changed, 1587 insertions(+), 93 deletions(-) delete mode 100644 x/escrow/keeper/grpc_query.go create mode 100644 x/escrow/keeper/query_server.go diff --git a/accounts1.json b/accounts1.json index ded87be..0d6aa91 100644 --- a/accounts1.json +++ b/accounts1.json @@ -37,7 +37,7 @@ }, { "amount": "1", - "denom": "🧹" + "denom": "\uD83E\uDDF9" } ] }, diff --git a/app/app.go b/app/app.go index b711394..bed7fd1 100644 --- a/app/app.go +++ b/app/app.go @@ -358,7 +358,7 @@ func New( app.AccountKeeper, appCodec, //todo appcodec or app.appcodec? keys[escrowtypes.StoreKey], - escrowtypes.StartIndex, + &escrowtypes.StartIndex, ) // Create static IBC router, add transfer route, then set and seal it diff --git a/proto/escrow/escrow/query.proto b/proto/escrow/escrow/query.proto index 9136584..d4bfb46 100644 --- a/proto/escrow/escrow/query.proto +++ b/proto/escrow/escrow/query.proto @@ -9,7 +9,37 @@ option go_package = "github.com/interchainberlin/pooltoy/x/escrow/types"; // Query defines the gRPC querier service. service Query { - // this line is used by starport scaffolding # 2 + // this line is used by starport scaffolding # 2 + rpc QueryOfferListAll (OfferListAllRequest) returns (OfferListResponse); + rpc QueryOfferByID (QueryOfferByIDRequest) returns (Offer); + rpc QueryOfferByAddr (QueryOfferByAddrRequest) returns (OfferListResponse); + + +} + +message OfferListAllRequest {} + +message QueryOfferByIDRequest{ + string querier = 1; + int64 id = 2; +} + +message QueryOfferByAddrRequest { + string querier = 1; + string offerer = 2; } -// this line is used by starport scaffolding # 3 +message Offer { + string sender = 1; + string amount = 2; + // [(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Coins"]; + string request = 3; + // [(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Coins"]; +} + +message OfferListResponse { + repeated Offer offerList = 1; +} + + + diff --git a/proto/escrow/escrow/tx.proto b/proto/escrow/escrow/tx.proto index d3c9662..056d948 100644 --- a/proto/escrow/escrow/tx.proto +++ b/proto/escrow/escrow/tx.proto @@ -18,15 +18,16 @@ service Msg { message OfferRequest { string sender = 1; string amount = 2; -// [(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Coins"]; + // [(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Coins"]; string request = 3; -// [(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Coins"]; + // [(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Coins"]; } //message Coin { // string coin = 1 // [(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Coin"]; //} - message OfferResponse { - int64 index =1; - } +message OfferResponse { + string sender = 1; + int64 index = 2; +} diff --git a/x/escrow/client/cli/query.go b/x/escrow/client/cli/query.go index 0e56078..0418f09 100644 --- a/x/escrow/client/cli/query.go +++ b/x/escrow/client/cli/query.go @@ -1,7 +1,9 @@ package cli import ( + "context" "fmt" + "github.com/cosmos/cosmos-sdk/client/flags" // "strings" "github.com/spf13/cobra" @@ -16,7 +18,7 @@ import ( // GetQueryCmd returns the cli query commands for this module func GetQueryCmd(queryRoute string) *cobra.Command { // Group escrow queries under a subcommand - cmd := &cobra.Command{ + escrowQuerycmd := &cobra.Command{ Use: types.ModuleName, Short: fmt.Sprintf("Querying commands for the %s module", types.ModuleName), DisableFlagParsing: true, @@ -25,6 +27,55 @@ func GetQueryCmd(queryRoute string) *cobra.Command { } // this line is used by starport scaffolding # 1 + escrowQuerycmd.AddCommand(escrowOfferListAll(), escrowOfferByAddr()) + return escrowQuerycmd +} + +func escrowOfferListAll() *cobra.Command { + cmd := &cobra.Command{ + Use: "offer-list-all", + Short: "show all the offers", + Args: cobra.NoArgs, + RunE: func(cmd *cobra.Command, args []string) error { + ctx, err := client.GetClientTxContext(cmd) + if err != nil { + return err + } + + queryClient := types.NewQueryClient(ctx) + offerList, err := queryClient.QueryOfferListAll(context.Background(), &types.OfferListAllRequest{}) + if err != nil { + return err + } + + return ctx.PrintProto(offerList) + }, + } + flags.AddTxFlagsToCmd(cmd) + return cmd +} + +func escrowOfferByAddr() *cobra.Command { + cmd := &cobra.Command{ + Use: "offer-by-addr [querier] [offerer]", + Short: "show all the offers of an address", + Args: cobra.ExactArgs(2), + RunE: func(cmd *cobra.Command, args []string) error { + ctx, err := client.GetClientTxContext(cmd) + if err != nil { + return err + } + + queryClient := types.NewQueryClient(ctx) + offerList, err := queryClient.QueryOfferByAddr(context.Background(), &types.QueryOfferByAddrRequest{Querier:args[0], Offerer: args[1]}) + if err != nil { + return err + } + + return ctx.PrintProto(offerList) + }, + } + flags.AddTxFlagsToCmd(cmd) return cmd } diff --git a/x/escrow/keeper/grpc_query.go b/x/escrow/keeper/grpc_query.go deleted file mode 100644 index 0797e6a..0000000 --- a/x/escrow/keeper/grpc_query.go +++ /dev/null @@ -1,7 +0,0 @@ -package keeper - -import ( - "github.com/interchainberlin/pooltoy/x/escrow/types" -) - -var _ types.QueryServer = Keeper{} diff --git a/x/escrow/keeper/keeper.go b/x/escrow/keeper/keeper.go index b9859e5..34669ee 100644 --- a/x/escrow/keeper/keeper.go +++ b/x/escrow/keeper/keeper.go @@ -2,15 +2,15 @@ package keeper import ( "fmt" - "github.com/cosmos/cosmos-sdk/x/auth/keeper" - "github.com/interchainberlin/pooltoy/x/escrow/utils" - "github.com/tendermint/tendermint/libs/log" - "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/interchainberlin/pooltoy/x/escrow/types" + "github.com/cosmos/cosmos-sdk/x/auth/keeper" // this line is used by starport scaffolding # ibc/keeper/import bankkeeper "github.com/cosmos/cosmos-sdk/x/bank/keeper" + + "github.com/interchainberlin/pooltoy/x/escrow/types" + "github.com/tendermint/tendermint/libs/log" + ) type Keeper struct { @@ -20,7 +20,7 @@ type Keeper struct { storeKey sdk.StoreKey // memKey sdk.StoreKey // this line is used by starport scaffolding # ibc/keeper/attribute - index int64 + index *int64 } func NewKeeper( @@ -29,7 +29,7 @@ func NewKeeper( cdc codec.Marshaler, storeKey sdk.StoreKey, //memKey sdk.StoreKey, - index int64, + index *int64, // this line is used by starport scaffolding # ibc/keeper/parameter ) Keeper { return Keeper{ @@ -45,28 +45,3 @@ func NewKeeper( func (k Keeper) Logger(ctx sdk.Context) log.Logger { return ctx.Logger().With("module", fmt.Sprintf("x/%s", types.ModuleName)) } - -func (k Keeper) OfferSend(ctx sdk.Context, msg *types.OfferRequest) (*types.OfferResponse, error) { - - addr, err := sdk.AccAddressFromBech32(msg.Sender) - if err != nil { - fmt.Println("addr err!!!!") - return &types.OfferResponse{}, err - } - amount, err := utils.ParseCoins(msg.Amount) - if err != nil { - return &types.OfferResponse{}, err - } - -// moduleAcc:= k.AccountKeeper.GetModuleAddress(types.ModuleName) - - err = k.BankKeeper.SendCoinsFromAccountToModule(ctx, addr,types.ModuleName, amount) - if err != nil { - fmt.Println("sending err!!!!") - return &types.OfferResponse{}, err - } - - //presentIdx := k.index - //k.index +=1 // some checks this index is not re - return &types.OfferResponse{}, nil -} diff --git a/x/escrow/keeper/msg_server.go b/x/escrow/keeper/msg_server.go index 1d6e64b..50dfe59 100644 --- a/x/escrow/keeper/msg_server.go +++ b/x/escrow/keeper/msg_server.go @@ -6,6 +6,7 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" "github.com/interchainberlin/pooltoy/x/escrow/types" + "github.com/interchainberlin/pooltoy/x/escrow/utils" ) type msgServer struct { @@ -27,11 +28,37 @@ func (k Keeper) Offer(c context.Context, msg *types.OfferRequest) (*types.OfferR return nil, sdkerrors.Wrap(err, fmt.Sprintf("unable to offer")) } + + _, err = k.InsertOffer(ctx, *msg) + if err != nil { + return nil, err + } + return res, nil } -//func (k Keeper) getIndex(ctx sdk.Context) int64{ -// //store := ctx.KVStore(k.storeKey) -// //if k.isPresent(ctx, ) -// return 1 -//} +func (k Keeper) OfferSend(ctx sdk.Context, msg *types.OfferRequest) (*types.OfferResponse, error) { + + addr, err := sdk.AccAddressFromBech32(msg.Sender) + if err != nil { + fmt.Println("addr err!!!!") + return &types.OfferResponse{}, err + } + amount, err := utils.ParseCoins(msg.Amount) + if err != nil { + return &types.OfferResponse{}, err + } + + // moduleAcc:= k.AccountKeeper.GetModuleAddress(types.ModuleName) + + err = k.BankKeeper.SendCoinsFromAccountToModule(ctx, addr,types.ModuleName, amount) + if err != nil { + fmt.Println("sending err!!!!") + return &types.OfferResponse{}, err + } + + presentIdx := k.index + *k.index +=1 // some checks this index is not re + return &types.OfferResponse{Sender: msg.Sender, Index: *presentIdx}, nil +} + diff --git a/x/escrow/keeper/query_server.go b/x/escrow/keeper/query_server.go new file mode 100644 index 0000000..07fd114 --- /dev/null +++ b/x/escrow/keeper/query_server.go @@ -0,0 +1,38 @@ +package keeper + +import ( + "context" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/interchainberlin/pooltoy/x/escrow/types" +) + +var _ types.QueryServer = Keeper{} + +func (k Keeper) QueryOfferListAll(c context.Context, req *types.OfferListAllRequest) (*types.OfferListResponse, error){ + //if req != nil{ + // return nil, status.Error(codes.InvalidArgument, "non-empty request") + //} + + ctx := sdk.UnwrapSDKContext(c) + offers, err :=k.ListOffer(ctx, *req) + if err != nil { + return nil, err + } + + return &offers, nil + +} + +func (k Keeper)QueryOfferByAddr(c context.Context, req *types.QueryOfferByAddrRequest) (*types.OfferListResponse, error){ + ctx := sdk.UnwrapSDKContext(c) + offers, err :=k.ListOfferByAddr(ctx, *req) + if err != nil { + return nil, err + } + + return &offers, nil +} + +func (k Keeper) QueryOfferByID(c context.Context, req *types.QueryOfferByIDRequest) (*types.Offer, error){ + return nil, nil +} diff --git a/x/escrow/keeper/store.go b/x/escrow/keeper/store.go index 749412a..bb595a0 100644 --- a/x/escrow/keeper/store.go +++ b/x/escrow/keeper/store.go @@ -1,3 +1,92 @@ package keeper +import ( + "fmt" + "github.com/cosmos/cosmos-sdk/store/prefix" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/interchainberlin/pooltoy/x/escrow/types" + "strconv" +) +func (k Keeper) InsertOffer(ctx sdk.Context, offer types.OfferRequest) ([]byte, error) { + store := ctx.KVStore(k.storeKey) + addr, err := sdk.AccAddressFromBech32(offer.Sender) + if err != nil { + return []byte{}, err + } + storeK := []byte{} + storeK = append(storeK, addr...) + storeK = append(storeK, []byte(strconv.FormatInt(*k.index, 10))...) + // todo maybe we do not need int64 for index + storeV, err := offer.Marshal() + if err != nil { + return nil, err + } + fmt.Println("store key is", storeK) + store.Set([]byte(storeK), storeV) + + return storeV, nil +} + +func (k Keeper) ListOffer(ctx sdk.Context, offer types.OfferListAllRequest) (types.OfferListResponse, error) { + store := ctx.KVStore(k.storeKey) + offers := []*types.Offer{} + + iterator := sdk.KVStorePrefixIterator(store, []byte(types.OfferPrefix)) + for ; iterator.Valid(); iterator.Next() { + var offer types.Offer + fmt.Println("key is!!!!", string(iterator.Key())) + k.cdc.MustUnmarshalBinaryBare(store.Get(iterator.Key()), &offer) + offers = append(offers, &offer) + } + + return types.OfferListResponse{OfferList: offers}, nil +} + +func (k Keeper) ListOfferByAddr(ctx sdk.Context, offer types.QueryOfferByAddrRequest) (types.OfferListResponse, error) { + + addr, err := sdk.AccAddressFromBech32(offer.Offerer) + fmt.Println("addr is!!!!", addr.String()) + if err != nil { + return types.OfferListResponse{}, err + } + addrStore := k.getAddressPrefixStore(ctx, addr) + fmt.Println("does the store has the addr!!!!", addrStore.Has(addr)) + iterator := addrStore.Iterator(nil, nil) + defer iterator.Close() + + offers := []*types.Offer{} + i :=0 + fmt.Println("valid iterator!!!!", iterator.Valid()) + for ; iterator.Valid(); iterator.Next() { + fmt.Println("i is!!!!", i) + i ++ + fmt.Println("substore key is!!!!", string(iterator.Key())) + var offer types.Offer + k.cdc.MustUnmarshalBinaryBare(iterator.Value(), &offer) + fmt.Println("offer unmarshal is!!!!", offer.Sender, offer.Amount, offer.Request) + offers = append(offers, &offer) + } + + return types.OfferListResponse{offers}, nil +} + +func (k Keeper) getAddressPrefixStore(ctx sdk.Context, addr sdk.AccAddress) prefix.Store { + store := ctx.KVStore(k.storeKey) + ref :="offer-" + b := []byte(ref) + fmt.Println("ref b is!!!!",b) + addr, _ = sdk.AccAddressFromBech32("cosmos126c2ak7k5qw8rhhha60kgksjrjf5jvkgtzlklw") + fmt.Println("ref addr !!!!", addr) + fmt.Println("the new prefix is!!!!", CreateAddrPrefix(addr)) + addrStore := prefix.NewStore(store, CreateAddrPrefix(addr)) + + return addrStore +} + + +func CreateAddrPrefix(addr []byte) []byte { + return append([]byte(types.OfferPrefix), addr...) +} + +// todo cannot find the pakcage: address.MustLengthPrefix(addr)... diff --git a/x/escrow/types/keys.go b/x/escrow/types/keys.go index 65eca0b..870e866 100644 --- a/x/escrow/types/keys.go +++ b/x/escrow/types/keys.go @@ -17,11 +17,15 @@ const ( //MemStoreKey = "mem_escrow" // this line is used by starport scaffolding # ibc/keys/name - StartIndex = int64(0) + + + OfferPrefix ="offer-" ) // this line is used by starport scaffolding # ibc/keys/port +var StartIndex = int64(0) + func KeyPrefix(p string) []byte { return []byte(p) } diff --git a/x/escrow/types/query.pb.go b/x/escrow/types/query.pb.go index 427de65..3a5480f 100644 --- a/x/escrow/types/query.pb.go +++ b/x/escrow/types/query.pb.go @@ -10,7 +10,11 @@ import ( proto "github.com/gogo/protobuf/proto" _ "google.golang.org/genproto/googleapis/api/annotations" grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" + io "io" math "math" + math_bits "math/bits" ) // Reference imports to suppress errors if they are not otherwise used. @@ -24,21 +28,287 @@ var _ = math.Inf // proto package needs to be updated. const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package +type OfferListAllRequest struct { +} + +func (m *OfferListAllRequest) Reset() { *m = OfferListAllRequest{} } +func (m *OfferListAllRequest) String() string { return proto.CompactTextString(m) } +func (*OfferListAllRequest) ProtoMessage() {} +func (*OfferListAllRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_cf6961269d90321b, []int{0} +} +func (m *OfferListAllRequest) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *OfferListAllRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_OfferListAllRequest.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 *OfferListAllRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_OfferListAllRequest.Merge(m, src) +} +func (m *OfferListAllRequest) XXX_Size() int { + return m.Size() +} +func (m *OfferListAllRequest) XXX_DiscardUnknown() { + xxx_messageInfo_OfferListAllRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_OfferListAllRequest proto.InternalMessageInfo + +type QueryOfferByIDRequest struct { + Querier string `protobuf:"bytes,1,opt,name=querier,proto3" json:"querier,omitempty"` + Id int64 `protobuf:"varint,2,opt,name=id,proto3" json:"id,omitempty"` +} + +func (m *QueryOfferByIDRequest) Reset() { *m = QueryOfferByIDRequest{} } +func (m *QueryOfferByIDRequest) String() string { return proto.CompactTextString(m) } +func (*QueryOfferByIDRequest) ProtoMessage() {} +func (*QueryOfferByIDRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_cf6961269d90321b, []int{1} +} +func (m *QueryOfferByIDRequest) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryOfferByIDRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryOfferByIDRequest.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 *QueryOfferByIDRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryOfferByIDRequest.Merge(m, src) +} +func (m *QueryOfferByIDRequest) XXX_Size() int { + return m.Size() +} +func (m *QueryOfferByIDRequest) XXX_DiscardUnknown() { + xxx_messageInfo_QueryOfferByIDRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryOfferByIDRequest proto.InternalMessageInfo + +func (m *QueryOfferByIDRequest) GetQuerier() string { + if m != nil { + return m.Querier + } + return "" +} + +func (m *QueryOfferByIDRequest) GetId() int64 { + if m != nil { + return m.Id + } + return 0 +} + +type QueryOfferByAddrRequest struct { + Querier string `protobuf:"bytes,1,opt,name=querier,proto3" json:"querier,omitempty"` + Offerer string `protobuf:"bytes,2,opt,name=offerer,proto3" json:"offerer,omitempty"` +} + +func (m *QueryOfferByAddrRequest) Reset() { *m = QueryOfferByAddrRequest{} } +func (m *QueryOfferByAddrRequest) String() string { return proto.CompactTextString(m) } +func (*QueryOfferByAddrRequest) ProtoMessage() {} +func (*QueryOfferByAddrRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_cf6961269d90321b, []int{2} +} +func (m *QueryOfferByAddrRequest) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryOfferByAddrRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryOfferByAddrRequest.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 *QueryOfferByAddrRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryOfferByAddrRequest.Merge(m, src) +} +func (m *QueryOfferByAddrRequest) XXX_Size() int { + return m.Size() +} +func (m *QueryOfferByAddrRequest) XXX_DiscardUnknown() { + xxx_messageInfo_QueryOfferByAddrRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryOfferByAddrRequest proto.InternalMessageInfo + +func (m *QueryOfferByAddrRequest) GetQuerier() string { + if m != nil { + return m.Querier + } + return "" +} + +func (m *QueryOfferByAddrRequest) GetOfferer() string { + if m != nil { + return m.Offerer + } + return "" +} + +type Offer struct { + Sender string `protobuf:"bytes,1,opt,name=sender,proto3" json:"sender,omitempty"` + Amount string `protobuf:"bytes,2,opt,name=amount,proto3" json:"amount,omitempty"` + // [(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Coins"]; + Request string `protobuf:"bytes,3,opt,name=request,proto3" json:"request,omitempty"` +} + +func (m *Offer) Reset() { *m = Offer{} } +func (m *Offer) String() string { return proto.CompactTextString(m) } +func (*Offer) ProtoMessage() {} +func (*Offer) Descriptor() ([]byte, []int) { + return fileDescriptor_cf6961269d90321b, []int{3} +} +func (m *Offer) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *Offer) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_Offer.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 *Offer) XXX_Merge(src proto.Message) { + xxx_messageInfo_Offer.Merge(m, src) +} +func (m *Offer) XXX_Size() int { + return m.Size() +} +func (m *Offer) XXX_DiscardUnknown() { + xxx_messageInfo_Offer.DiscardUnknown(m) +} + +var xxx_messageInfo_Offer proto.InternalMessageInfo + +func (m *Offer) GetSender() string { + if m != nil { + return m.Sender + } + return "" +} + +func (m *Offer) GetAmount() string { + if m != nil { + return m.Amount + } + return "" +} + +func (m *Offer) GetRequest() string { + if m != nil { + return m.Request + } + return "" +} + +type OfferListResponse struct { + OfferList []*Offer `protobuf:"bytes,1,rep,name=offerList,proto3" json:"offerList,omitempty"` +} + +func (m *OfferListResponse) Reset() { *m = OfferListResponse{} } +func (m *OfferListResponse) String() string { return proto.CompactTextString(m) } +func (*OfferListResponse) ProtoMessage() {} +func (*OfferListResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_cf6961269d90321b, []int{4} +} +func (m *OfferListResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *OfferListResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_OfferListResponse.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 *OfferListResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_OfferListResponse.Merge(m, src) +} +func (m *OfferListResponse) XXX_Size() int { + return m.Size() +} +func (m *OfferListResponse) XXX_DiscardUnknown() { + xxx_messageInfo_OfferListResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_OfferListResponse proto.InternalMessageInfo + +func (m *OfferListResponse) GetOfferList() []*Offer { + if m != nil { + return m.OfferList + } + return nil +} + +func init() { + proto.RegisterType((*OfferListAllRequest)(nil), "escrow.OfferListAllRequest") + proto.RegisterType((*QueryOfferByIDRequest)(nil), "escrow.QueryOfferByIDRequest") + proto.RegisterType((*QueryOfferByAddrRequest)(nil), "escrow.QueryOfferByAddrRequest") + proto.RegisterType((*Offer)(nil), "escrow.Offer") + proto.RegisterType((*OfferListResponse)(nil), "escrow.OfferListResponse") +} + func init() { proto.RegisterFile("escrow/escrow/query.proto", fileDescriptor_cf6961269d90321b) } var fileDescriptor_cf6961269d90321b = []byte{ - // 161 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x92, 0x4c, 0x2d, 0x4e, 0x2e, - 0xca, 0x2f, 0xd7, 0x87, 0x52, 0x85, 0xa5, 0xa9, 0x45, 0x95, 0x7a, 0x05, 0x45, 0xf9, 0x25, 0xf9, - 0x42, 0x6c, 0x10, 0x31, 0x29, 0x99, 0xf4, 0xfc, 0xfc, 0xf4, 0x9c, 0x54, 0xfd, 0xc4, 0x82, 0x4c, - 0xfd, 0xc4, 0xbc, 0xbc, 0xfc, 0x92, 0xc4, 0x92, 0xcc, 0xfc, 0xbc, 0x62, 0x88, 0x2a, 0x23, 0x76, - 0x2e, 0xd6, 0x40, 0x90, 0x26, 0x27, 0x9f, 0x13, 0x8f, 0xe4, 0x18, 0x2f, 0x3c, 0x92, 0x63, 0x7c, - 0xf0, 0x48, 0x8e, 0x71, 0xc2, 0x63, 0x39, 0x86, 0x0b, 0x8f, 0xe5, 0x18, 0x6e, 0x3c, 0x96, 0x63, - 0x88, 0x32, 0x4a, 0xcf, 0x2c, 0xc9, 0x28, 0x4d, 0xd2, 0x4b, 0xce, 0xcf, 0xd5, 0xcf, 0xcc, 0x2b, - 0x49, 0x2d, 0x4a, 0xce, 0x48, 0xcc, 0xcc, 0x4b, 0x4a, 0x2d, 0xca, 0xc9, 0xcc, 0xd3, 0x2f, 0xc8, - 0xcf, 0xcf, 0x29, 0xc9, 0xaf, 0xd4, 0xaf, 0x80, 0x39, 0xa1, 0xa4, 0xb2, 0x20, 0xb5, 0x38, 0x89, - 0x0d, 0x6c, 0xba, 0x31, 0x20, 0x00, 0x00, 0xff, 0xff, 0x0b, 0xf3, 0xbb, 0x07, 0xa0, 0x00, 0x00, - 0x00, + // 380 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x84, 0x92, 0xcd, 0x4e, 0xea, 0x40, + 0x14, 0xc7, 0x19, 0x08, 0x10, 0xe6, 0xe6, 0x92, 0xcb, 0xdc, 0x70, 0x6f, 0x41, 0xad, 0xa4, 0x2b, + 0x12, 0x93, 0x36, 0xc1, 0xbd, 0x11, 0xe2, 0xc6, 0x88, 0x1a, 0xba, 0x74, 0x57, 0xe8, 0x00, 0x93, + 0x94, 0x39, 0x65, 0x66, 0x1a, 0xed, 0x5b, 0xf8, 0x58, 0x2e, 0x59, 0xba, 0x34, 0xe0, 0x83, 0x98, + 0x7e, 0x01, 0x55, 0xa2, 0xab, 0xc9, 0xff, 0x7c, 0xfc, 0xe6, 0x9c, 0xff, 0x0c, 0x6e, 0x51, 0x39, + 0x11, 0xf0, 0x68, 0xa5, 0xc7, 0x32, 0xa0, 0x22, 0x34, 0x7d, 0x01, 0x0a, 0x48, 0x25, 0x89, 0xb5, + 0x8f, 0x67, 0x00, 0x33, 0x8f, 0x5a, 0x8e, 0xcf, 0x2c, 0x87, 0x73, 0x50, 0x8e, 0x62, 0xc0, 0x65, + 0x52, 0x65, 0x34, 0xf1, 0xdf, 0xfb, 0xe9, 0x94, 0x8a, 0x21, 0x93, 0xaa, 0xef, 0x79, 0x36, 0x5d, + 0x06, 0x54, 0x2a, 0xa3, 0x8f, 0x9b, 0xa3, 0x88, 0x15, 0xe7, 0x06, 0xe1, 0xf5, 0x55, 0x9a, 0x20, + 0x1a, 0xae, 0x46, 0x97, 0x30, 0x2a, 0x34, 0xd4, 0x41, 0xdd, 0x9a, 0x9d, 0x49, 0x52, 0xc7, 0x45, + 0xe6, 0x6a, 0xc5, 0x0e, 0xea, 0x96, 0xec, 0x22, 0x73, 0x8d, 0x5b, 0xfc, 0x7f, 0x1f, 0xd1, 0x77, + 0x5d, 0xf1, 0x33, 0x44, 0xc3, 0x55, 0x88, 0xea, 0xa9, 0x88, 0x49, 0x35, 0x3b, 0x93, 0xc6, 0x08, + 0x97, 0x63, 0x12, 0xf9, 0x87, 0x2b, 0x92, 0x72, 0x77, 0xdb, 0x9b, 0xaa, 0x28, 0xee, 0x2c, 0x20, + 0xe0, 0x2a, 0xed, 0x4c, 0x55, 0x84, 0x14, 0xc9, 0xbd, 0x5a, 0x29, 0x41, 0xa6, 0xd2, 0xb8, 0xc4, + 0x8d, 0xed, 0xee, 0x36, 0x95, 0x3e, 0x70, 0x49, 0xc9, 0x19, 0xae, 0x41, 0x16, 0xd4, 0x50, 0xa7, + 0xd4, 0xfd, 0xd5, 0xfb, 0x6d, 0x26, 0x56, 0x9a, 0x71, 0xb5, 0xbd, 0xcb, 0xf7, 0xde, 0x11, 0x2e, + 0xc7, 0x4b, 0x92, 0x1b, 0xdc, 0xd8, 0x6d, 0x9b, 0x9a, 0x49, 0x8e, 0x72, 0x8d, 0x79, 0x8b, 0xdb, + 0xad, 0x2f, 0xc9, 0xed, 0x0c, 0x17, 0xb8, 0x9e, 0x77, 0x9f, 0x9c, 0x64, 0xc5, 0x07, 0x5f, 0xa5, + 0x9d, 0x9f, 0x90, 0xdc, 0xe1, 0x3f, 0x9f, 0xad, 0x27, 0xa7, 0x87, 0x08, 0x7b, 0x8f, 0xf2, 0xcd, + 0x3c, 0x83, 0xe1, 0xcb, 0x5a, 0x47, 0xab, 0xb5, 0x8e, 0xde, 0xd6, 0x3a, 0x7a, 0xde, 0xe8, 0x85, + 0xd5, 0x46, 0x2f, 0xbc, 0x6e, 0xf4, 0xc2, 0x43, 0x6f, 0xc6, 0xd4, 0x3c, 0x18, 0x9b, 0x13, 0x58, + 0x58, 0x8c, 0x2b, 0x2a, 0x26, 0x73, 0x87, 0xf1, 0x31, 0x15, 0x1e, 0xe3, 0x96, 0x0f, 0xe0, 0x29, + 0x08, 0xad, 0xa7, 0xec, 0x7b, 0xaa, 0xd0, 0xa7, 0x72, 0x5c, 0x89, 0x7f, 0xde, 0xf9, 0x47, 0x00, + 0x00, 0x00, 0xff, 0xff, 0xe2, 0xbd, 0xb7, 0xa8, 0xbc, 0x02, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -53,6 +323,10 @@ const _ = grpc.SupportPackageIsVersion4 // // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. type QueryClient interface { + // this line is used by starport scaffolding # 2 + QueryOfferListAll(ctx context.Context, in *OfferListAllRequest, opts ...grpc.CallOption) (*OfferListResponse, error) + QueryOfferByID(ctx context.Context, in *QueryOfferByIDRequest, opts ...grpc.CallOption) (*Offer, error) + QueryOfferByAddr(ctx context.Context, in *QueryOfferByAddrRequest, opts ...grpc.CallOption) (*OfferListResponse, error) } type queryClient struct { @@ -63,22 +337,981 @@ func NewQueryClient(cc grpc1.ClientConn) QueryClient { return &queryClient{cc} } +func (c *queryClient) QueryOfferListAll(ctx context.Context, in *OfferListAllRequest, opts ...grpc.CallOption) (*OfferListResponse, error) { + out := new(OfferListResponse) + err := c.cc.Invoke(ctx, "/escrow.Query/QueryOfferListAll", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *queryClient) QueryOfferByID(ctx context.Context, in *QueryOfferByIDRequest, opts ...grpc.CallOption) (*Offer, error) { + out := new(Offer) + err := c.cc.Invoke(ctx, "/escrow.Query/QueryOfferByID", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *queryClient) QueryOfferByAddr(ctx context.Context, in *QueryOfferByAddrRequest, opts ...grpc.CallOption) (*OfferListResponse, error) { + out := new(OfferListResponse) + err := c.cc.Invoke(ctx, "/escrow.Query/QueryOfferByAddr", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + // QueryServer is the server API for Query service. type QueryServer interface { + // this line is used by starport scaffolding # 2 + QueryOfferListAll(context.Context, *OfferListAllRequest) (*OfferListResponse, error) + QueryOfferByID(context.Context, *QueryOfferByIDRequest) (*Offer, error) + QueryOfferByAddr(context.Context, *QueryOfferByAddrRequest) (*OfferListResponse, error) } // UnimplementedQueryServer can be embedded to have forward compatible implementations. type UnimplementedQueryServer struct { } +func (*UnimplementedQueryServer) QueryOfferListAll(ctx context.Context, req *OfferListAllRequest) (*OfferListResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method QueryOfferListAll not implemented") +} +func (*UnimplementedQueryServer) QueryOfferByID(ctx context.Context, req *QueryOfferByIDRequest) (*Offer, error) { + return nil, status.Errorf(codes.Unimplemented, "method QueryOfferByID not implemented") +} +func (*UnimplementedQueryServer) QueryOfferByAddr(ctx context.Context, req *QueryOfferByAddrRequest) (*OfferListResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method QueryOfferByAddr not implemented") +} + func RegisterQueryServer(s grpc1.Server, srv QueryServer) { s.RegisterService(&_Query_serviceDesc, srv) } +func _Query_QueryOfferListAll_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(OfferListAllRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(QueryServer).QueryOfferListAll(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/escrow.Query/QueryOfferListAll", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(QueryServer).QueryOfferListAll(ctx, req.(*OfferListAllRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Query_QueryOfferByID_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(QueryOfferByIDRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(QueryServer).QueryOfferByID(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/escrow.Query/QueryOfferByID", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(QueryServer).QueryOfferByID(ctx, req.(*QueryOfferByIDRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Query_QueryOfferByAddr_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(QueryOfferByAddrRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(QueryServer).QueryOfferByAddr(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/escrow.Query/QueryOfferByAddr", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(QueryServer).QueryOfferByAddr(ctx, req.(*QueryOfferByAddrRequest)) + } + return interceptor(ctx, in, info, handler) +} + var _Query_serviceDesc = grpc.ServiceDesc{ ServiceName: "escrow.Query", HandlerType: (*QueryServer)(nil), - Methods: []grpc.MethodDesc{}, - Streams: []grpc.StreamDesc{}, - Metadata: "escrow/escrow/query.proto", + Methods: []grpc.MethodDesc{ + { + MethodName: "QueryOfferListAll", + Handler: _Query_QueryOfferListAll_Handler, + }, + { + MethodName: "QueryOfferByID", + Handler: _Query_QueryOfferByID_Handler, + }, + { + MethodName: "QueryOfferByAddr", + Handler: _Query_QueryOfferByAddr_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "escrow/escrow/query.proto", +} + +func (m *OfferListAllRequest) 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 *OfferListAllRequest) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *OfferListAllRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + return len(dAtA) - i, nil +} + +func (m *QueryOfferByIDRequest) 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 *QueryOfferByIDRequest) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryOfferByIDRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.Id != 0 { + i = encodeVarintQuery(dAtA, i, uint64(m.Id)) + i-- + dAtA[i] = 0x10 + } + if len(m.Querier) > 0 { + i -= len(m.Querier) + copy(dAtA[i:], m.Querier) + i = encodeVarintQuery(dAtA, i, uint64(len(m.Querier))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *QueryOfferByAddrRequest) 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 *QueryOfferByAddrRequest) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryOfferByAddrRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Offerer) > 0 { + i -= len(m.Offerer) + copy(dAtA[i:], m.Offerer) + i = encodeVarintQuery(dAtA, i, uint64(len(m.Offerer))) + i-- + dAtA[i] = 0x12 + } + if len(m.Querier) > 0 { + i -= len(m.Querier) + copy(dAtA[i:], m.Querier) + i = encodeVarintQuery(dAtA, i, uint64(len(m.Querier))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *Offer) 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 *Offer) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) } + +func (m *Offer) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Request) > 0 { + i -= len(m.Request) + copy(dAtA[i:], m.Request) + i = encodeVarintQuery(dAtA, i, uint64(len(m.Request))) + i-- + dAtA[i] = 0x1a + } + if len(m.Amount) > 0 { + i -= len(m.Amount) + copy(dAtA[i:], m.Amount) + i = encodeVarintQuery(dAtA, i, uint64(len(m.Amount))) + i-- + dAtA[i] = 0x12 + } + if len(m.Sender) > 0 { + i -= len(m.Sender) + copy(dAtA[i:], m.Sender) + i = encodeVarintQuery(dAtA, i, uint64(len(m.Sender))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *OfferListResponse) 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 *OfferListResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *OfferListResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.OfferList) > 0 { + for iNdEx := len(m.OfferList) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.OfferList[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintQuery(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + } + return len(dAtA) - i, nil +} + +func encodeVarintQuery(dAtA []byte, offset int, v uint64) int { + offset -= sovQuery(v) + base := offset + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return base +} +func (m *OfferListAllRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + return n +} + +func (m *QueryOfferByIDRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Querier) + if l > 0 { + n += 1 + l + sovQuery(uint64(l)) + } + if m.Id != 0 { + n += 1 + sovQuery(uint64(m.Id)) + } + return n +} + +func (m *QueryOfferByAddrRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Querier) + if l > 0 { + n += 1 + l + sovQuery(uint64(l)) + } + l = len(m.Offerer) + if l > 0 { + n += 1 + l + sovQuery(uint64(l)) + } + return n +} + +func (m *Offer) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Sender) + if l > 0 { + n += 1 + l + sovQuery(uint64(l)) + } + l = len(m.Amount) + if l > 0 { + n += 1 + l + sovQuery(uint64(l)) + } + l = len(m.Request) + if l > 0 { + n += 1 + l + sovQuery(uint64(l)) + } + return n +} + +func (m *OfferListResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.OfferList) > 0 { + for _, e := range m.OfferList { + l = e.Size() + n += 1 + l + sovQuery(uint64(l)) + } + } + return n +} + +func sovQuery(x uint64) (n int) { + return (math_bits.Len64(x|1) + 6) / 7 +} +func sozQuery(x uint64) (n int) { + return sovQuery(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (m *OfferListAllRequest) 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 ErrIntOverflowQuery + } + 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: OfferListAllRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: OfferListAllRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *QueryOfferByIDRequest) 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 ErrIntOverflowQuery + } + 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: QueryOfferByIDRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryOfferByIDRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Querier", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + 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 ErrInvalidLengthQuery + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Querier = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Id", wireType) + } + m.Id = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Id |= int64(b&0x7F) << shift + if b < 0x80 { + break + } + } + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *QueryOfferByAddrRequest) 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 ErrIntOverflowQuery + } + 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: QueryOfferByAddrRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryOfferByAddrRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Querier", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + 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 ErrInvalidLengthQuery + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Querier = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Offerer", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + 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 ErrInvalidLengthQuery + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Offerer = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *Offer) 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 ErrIntOverflowQuery + } + 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: Offer: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Offer: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Sender", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + 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 ErrInvalidLengthQuery + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Sender = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Amount", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + 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 ErrInvalidLengthQuery + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Amount = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Request", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + 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 ErrInvalidLengthQuery + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Request = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *OfferListResponse) 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 ErrIntOverflowQuery + } + 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: OfferListResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: OfferListResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field OfferList", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.OfferList = append(m.OfferList, &Offer{}) + if err := m.OfferList[len(m.OfferList)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func skipQuery(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, ErrIntOverflowQuery + } + 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, ErrIntOverflowQuery + } + 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, ErrIntOverflowQuery + } + 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, ErrInvalidLengthQuery + } + iNdEx += length + case 3: + depth++ + case 4: + if depth == 0 { + return 0, ErrUnexpectedEndOfGroupQuery + } + depth-- + case 5: + iNdEx += 4 + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + if iNdEx < 0 { + return 0, ErrInvalidLengthQuery + } + if depth == 0 { + return iNdEx, nil + } + } + return 0, io.ErrUnexpectedEOF +} + +var ( + ErrInvalidLengthQuery = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowQuery = fmt.Errorf("proto: integer overflow") + ErrUnexpectedEndOfGroupQuery = fmt.Errorf("proto: unexpected end of group") +) diff --git a/x/escrow/types/tx.pb.go b/x/escrow/types/tx.pb.go index 5a3c53a..0646783 100644 --- a/x/escrow/types/tx.pb.go +++ b/x/escrow/types/tx.pb.go @@ -95,7 +95,8 @@ func (m *OfferRequest) GetRequest() string { // [(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Coin"]; //} type OfferResponse struct { - Index int64 `protobuf:"varint,1,opt,name=index,proto3" json:"index,omitempty"` + Sender string `protobuf:"bytes,1,opt,name=sender,proto3" json:"sender,omitempty"` + Index int64 `protobuf:"varint,2,opt,name=index,proto3" json:"index,omitempty"` } func (m *OfferResponse) Reset() { *m = OfferResponse{} } @@ -131,6 +132,13 @@ func (m *OfferResponse) XXX_DiscardUnknown() { var xxx_messageInfo_OfferResponse proto.InternalMessageInfo +func (m *OfferResponse) GetSender() string { + if m != nil { + return m.Sender + } + return "" +} + func (m *OfferResponse) GetIndex() int64 { if m != nil { return m.Index @@ -146,23 +154,23 @@ func init() { func init() { proto.RegisterFile("escrow/escrow/tx.proto", fileDescriptor_f5eef200b34c62c8) } var fileDescriptor_f5eef200b34c62c8 = []byte{ - // 253 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x5c, 0x90, 0x41, 0x4b, 0xc3, 0x30, - 0x14, 0xc7, 0x1b, 0xcb, 0x2a, 0x06, 0xbd, 0x84, 0x3a, 0xca, 0x0e, 0x41, 0x06, 0x82, 0xa7, 0x06, - 0xa6, 0x37, 0x6f, 0x9e, 0x15, 0xa1, 0x27, 0xf1, 0xb6, 0x76, 0x6f, 0x5d, 0x60, 0xcb, 0x8b, 0x49, - 0x8a, 0xdd, 0xb7, 0xf0, 0x63, 0x79, 0xdc, 0xd1, 0xa3, 0xb4, 0x5f, 0x44, 0x9a, 0x54, 0x91, 0x9d, - 0x92, 0xdf, 0xef, 0x25, 0x7f, 0x1e, 0x7f, 0x3a, 0x05, 0x5b, 0x19, 0x7c, 0x17, 0xe3, 0xe1, 0xda, - 0x5c, 0x1b, 0x74, 0xc8, 0x92, 0x20, 0x66, 0x69, 0x8d, 0x35, 0x7a, 0x25, 0x86, 0x5b, 0x98, 0xce, - 0x5f, 0xe8, 0xf9, 0xf3, 0x7a, 0x0d, 0xa6, 0x80, 0xb7, 0x06, 0xac, 0x63, 0x53, 0x9a, 0x58, 0x50, - 0x2b, 0x30, 0x19, 0xb9, 0x22, 0x37, 0x67, 0xc5, 0x48, 0x83, 0x5f, 0xee, 0xb0, 0x51, 0x2e, 0x3b, - 0x09, 0x3e, 0x10, 0xcb, 0xe8, 0xa9, 0x09, 0x5f, 0xb3, 0xd8, 0x0f, 0x7e, 0x71, 0x7e, 0x4d, 0x2f, - 0xc6, 0x64, 0xab, 0x51, 0x59, 0x60, 0x29, 0x9d, 0x48, 0xb5, 0x82, 0xd6, 0x27, 0xc7, 0x45, 0x80, - 0xc5, 0x3d, 0x8d, 0x9f, 0x6c, 0xcd, 0xee, 0xe8, 0xc4, 0xbf, 0x66, 0x69, 0x1e, 0xf6, 0xcd, 0xff, - 0xaf, 0x35, 0xbb, 0x3c, 0xb2, 0x21, 0xf2, 0xe1, 0xf1, 0xb3, 0xe3, 0xe4, 0xd0, 0x71, 0xf2, 0xdd, - 0x71, 0xf2, 0xd1, 0xf3, 0xe8, 0xd0, 0xf3, 0xe8, 0xab, 0xe7, 0xd1, 0xeb, 0xa2, 0x96, 0x6e, 0xd3, - 0x94, 0x79, 0x85, 0x3b, 0x21, 0x95, 0x03, 0x53, 0x6d, 0x96, 0x52, 0x95, 0x60, 0xb6, 0x52, 0x09, - 0x8d, 0xb8, 0x75, 0xb8, 0x17, 0xed, 0x5f, 0x59, 0x7b, 0x0d, 0xb6, 0x4c, 0x7c, 0x25, 0xb7, 0x3f, - 0x01, 0x00, 0x00, 0xff, 0xff, 0xdf, 0xeb, 0x7f, 0x8b, 0x4a, 0x01, 0x00, 0x00, + // 254 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x12, 0x4b, 0x2d, 0x4e, 0x2e, + 0xca, 0x2f, 0xd7, 0x87, 0x52, 0x25, 0x15, 0x7a, 0x05, 0x45, 0xf9, 0x25, 0xf9, 0x42, 0x6c, 0x10, + 0x01, 0x29, 0x91, 0xf4, 0xfc, 0xf4, 0x7c, 0xb0, 0x90, 0x3e, 0x88, 0x05, 0x91, 0x55, 0x8a, 0xe0, + 0xe2, 0xf1, 0x4f, 0x4b, 0x4b, 0x2d, 0x0a, 0x4a, 0x2d, 0x2c, 0x4d, 0x2d, 0x2e, 0x11, 0x12, 0xe3, + 0x62, 0x2b, 0x4e, 0xcd, 0x4b, 0x49, 0x2d, 0x92, 0x60, 0x54, 0x60, 0xd4, 0xe0, 0x0c, 0x82, 0xf2, + 0x40, 0xe2, 0x89, 0xb9, 0xf9, 0xa5, 0x79, 0x25, 0x12, 0x4c, 0x10, 0x71, 0x08, 0x4f, 0x48, 0x82, + 0x8b, 0xbd, 0x08, 0xa2, 0x55, 0x82, 0x19, 0x2c, 0x01, 0xe3, 0x2a, 0xd9, 0x72, 0xf1, 0x42, 0x4d, + 0x2e, 0x2e, 0xc8, 0xcf, 0x2b, 0x4e, 0xc5, 0x69, 0xb4, 0x08, 0x17, 0x6b, 0x66, 0x5e, 0x4a, 0x6a, + 0x05, 0xd8, 0x64, 0xe6, 0x20, 0x08, 0xc7, 0xc8, 0x9a, 0x8b, 0xd9, 0xb7, 0x38, 0x5d, 0xc8, 0x84, + 0x8b, 0x15, 0x6c, 0x8a, 0x90, 0x88, 0x1e, 0xc4, 0x1f, 0x7a, 0xc8, 0xce, 0x95, 0x12, 0x45, 0x13, + 0x85, 0x58, 0xe5, 0xe4, 0x73, 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, 0x46, + 0xe9, 0x99, 0x25, 0x19, 0xa5, 0x49, 0x7a, 0xc9, 0xf9, 0xb9, 0xfa, 0x99, 0x79, 0x25, 0xa9, 0x45, + 0xc9, 0x19, 0x89, 0x99, 0x79, 0x49, 0xa9, 0x45, 0x39, 0x99, 0x79, 0xfa, 0x05, 0xf9, 0xf9, 0x39, + 0x25, 0xf9, 0x95, 0xfa, 0x15, 0xf0, 0x40, 0xac, 0x2c, 0x48, 0x2d, 0x4e, 0x62, 0x03, 0x07, 0x95, + 0x31, 0x20, 0x00, 0x00, 0xff, 0xff, 0x6c, 0xed, 0x8e, 0x31, 0x62, 0x01, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -314,7 +322,14 @@ func (m *OfferResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { if m.Index != 0 { i = encodeVarintTx(dAtA, i, uint64(m.Index)) i-- - dAtA[i] = 0x8 + dAtA[i] = 0x10 + } + if len(m.Sender) > 0 { + i -= len(m.Sender) + copy(dAtA[i:], m.Sender) + i = encodeVarintTx(dAtA, i, uint64(len(m.Sender))) + i-- + dAtA[i] = 0xa } return len(dAtA) - i, nil } @@ -357,6 +372,10 @@ func (m *OfferResponse) Size() (n int) { } var l int _ = l + l = len(m.Sender) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } if m.Index != 0 { n += 1 + sovTx(uint64(m.Index)) } @@ -545,6 +564,38 @@ func (m *OfferResponse) Unmarshal(dAtA []byte) error { } switch fieldNum { case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Sender", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + 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 ErrInvalidLengthTx + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Sender = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: if wireType != 0 { return fmt.Errorf("proto: wrong wireType = %d for field Index", wireType) } diff --git a/x/faucet/utils/utils.go b/x/faucet/utils/utils.go index 1311d76..235b2bb 100644 --- a/x/faucet/utils/utils.go +++ b/x/faucet/utils/utils.go @@ -18,10 +18,10 @@ func ParseEmoji(emoji string) (string, error) { } -func ReverseMapKV(emojiMap map[string]string)map[string]string{ - reversedMap := map[string]string{} - for k, v := range emojiMap{ - reversedMap[v] = k +func ReverseMapKV(emojiMap map[string]string)map[string]bool{ + reversedMap := map[string]bool{} + for _, v := range emojiMap{ + reversedMap[v] = true } return reversedMap diff --git a/x/pooltoy/keeper/query_server.go b/x/pooltoy/keeper/query_server.go index 54d2acb..9952ed1 100644 --- a/x/pooltoy/keeper/query_server.go +++ b/x/pooltoy/keeper/query_server.go @@ -33,3 +33,5 @@ func (k Keeper) QueryListUsers(c context.Context, req *types.QueryListUsersReque // todo move query most emoji to faucet module // todo return a emoji rank list + + From 6d5a9687efb83486b0528e9bf4d6995f78184f61 Mon Sep 17 00:00:00 2001 From: yaruwang Date: Wed, 28 Jul 2021 18:02:09 +0200 Subject: [PATCH 11/22] change proto --- accounts1.json | 2 +- go.sum | 1 + proto/escrow/escrow/tx.proto | 33 -- proto/escrow/{escrow => }/genesis.proto | 0 proto/escrow/{escrow => }/query.proto | 14 +- proto/escrow/tx.proto | 42 +++ .../proto/cosmos/auth/v1beta1/auth.proto | 50 +++ .../proto/cosmos/auth/v1beta1/genesis.proto | 17 + .../proto/cosmos/auth/v1beta1/query.proto | 47 +++ .../proto/cosmos/bank/v1beta1/bank.proto | 85 +++++ .../proto/cosmos/bank/v1beta1/genesis.proto | 38 ++ .../proto/cosmos/bank/v1beta1/query.proto | 150 ++++++++ .../proto/cosmos/bank/v1beta1/tx.proto | 42 +++ .../proto/cosmos/base/abci/v1beta1/abci.proto | 137 +++++++ .../proto/cosmos/base/kv/v1beta1/kv.proto | 17 + .../base/query/v1beta1/pagination.proto | 50 +++ .../base/reflection/v1beta1/reflection.proto | 44 +++ .../base/snapshots/v1beta1/snapshot.proto | 20 + .../base/store/v1beta1/commit_info.proto | 29 ++ .../cosmos/base/store/v1beta1/snapshot.proto | 28 ++ .../base/tendermint/v1beta1/query.proto | 137 +++++++ .../proto/cosmos/base/v1beta1/coin.proto | 40 ++ .../capability/v1beta1/capability.proto | 30 ++ .../cosmos/capability/v1beta1/genesis.proto | 26 ++ .../proto/cosmos/crisis/v1beta1/genesis.proto | 15 + .../proto/cosmos/crisis/v1beta1/tx.proto | 25 ++ .../proto/cosmos/crypto/ed25519/keys.proto | 22 ++ .../proto/cosmos/crypto/multisig/keys.proto | 18 + .../crypto/multisig/v1beta1/multisig.proto | 25 ++ .../proto/cosmos/crypto/secp256k1/keys.proto | 22 ++ .../distribution/v1beta1/distribution.proto | 157 ++++++++ .../cosmos/distribution/v1beta1/genesis.proto | 155 ++++++++ .../cosmos/distribution/v1beta1/query.proto | 218 +++++++++++ .../cosmos/distribution/v1beta1/tx.proto | 79 ++++ .../cosmos/evidence/v1beta1/evidence.proto | 21 ++ .../cosmos/evidence/v1beta1/genesis.proto | 12 + .../proto/cosmos/evidence/v1beta1/query.proto | 51 +++ .../proto/cosmos/evidence/v1beta1/tx.proto | 32 ++ .../cosmos/genutil/v1beta1/genesis.proto | 16 + .../proto/cosmos/gov/v1beta1/genesis.proto | 26 ++ .../proto/cosmos/gov/v1beta1/gov.proto | 183 +++++++++ .../proto/cosmos/gov/v1beta1/query.proto | 190 ++++++++++ third_party/proto/cosmos/gov/v1beta1/tx.proto | 75 ++++ .../proto/cosmos/mint/v1beta1/genesis.proto | 16 + .../proto/cosmos/mint/v1beta1/mint.proto | 53 +++ .../proto/cosmos/mint/v1beta1/query.proto | 57 +++ .../proto/cosmos/params/v1beta1/params.proto | 27 ++ .../proto/cosmos/params/v1beta1/query.proto | 32 ++ .../cosmos/slashing/v1beta1/genesis.proto | 50 +++ .../proto/cosmos/slashing/v1beta1/query.proto | 63 ++++ .../cosmos/slashing/v1beta1/slashing.proto | 55 +++ .../proto/cosmos/slashing/v1beta1/tx.proto | 26 ++ .../cosmos/staking/v1beta1/genesis.proto | 53 +++ .../proto/cosmos/staking/v1beta1/query.proto | 348 ++++++++++++++++++ .../cosmos/staking/v1beta1/staking.proto | 334 +++++++++++++++++ .../proto/cosmos/staking/v1beta1/tx.proto | 126 +++++++ .../cosmos/tx/signing/v1beta1/signing.proto | 79 ++++ .../proto/cosmos/tx/v1beta1/service.proto | 129 +++++++ third_party/proto/cosmos/tx/v1beta1/tx.proto | 181 +++++++++ .../proto/cosmos/upgrade/v1beta1/query.proto | 68 ++++ .../cosmos/upgrade/v1beta1/upgrade.proto | 62 ++++ .../proto/cosmos/vesting/v1beta1/tx.proto | 31 ++ .../cosmos/vesting/v1beta1/vesting.proto | 73 ++++ x/escrow/client/cli/tx.go | 1 + x/escrow/handler.go | 2 +- x/escrow/keeper/msg_server.go | 15 +- x/escrow/keeper/store.go | 34 +- x/escrow/types/codec.go | 2 +- x/escrow/types/genesis.pb.go | 26 +- x/escrow/types/msgs.go | 18 +- x/escrow/types/query.pb.go | 339 ++--------------- x/escrow/types/tx.pb.go | 206 ++++++----- 72 files changed, 4440 insertions(+), 487 deletions(-) delete mode 100644 proto/escrow/escrow/tx.proto rename proto/escrow/{escrow => }/genesis.proto (100%) rename proto/escrow/{escrow => }/query.proto (76%) create mode 100644 proto/escrow/tx.proto create mode 100644 third_party/proto/cosmos/auth/v1beta1/auth.proto create mode 100644 third_party/proto/cosmos/auth/v1beta1/genesis.proto create mode 100644 third_party/proto/cosmos/auth/v1beta1/query.proto create mode 100644 third_party/proto/cosmos/bank/v1beta1/bank.proto create mode 100644 third_party/proto/cosmos/bank/v1beta1/genesis.proto create mode 100644 third_party/proto/cosmos/bank/v1beta1/query.proto create mode 100644 third_party/proto/cosmos/bank/v1beta1/tx.proto create mode 100644 third_party/proto/cosmos/base/abci/v1beta1/abci.proto create mode 100644 third_party/proto/cosmos/base/kv/v1beta1/kv.proto create mode 100644 third_party/proto/cosmos/base/query/v1beta1/pagination.proto create mode 100644 third_party/proto/cosmos/base/reflection/v1beta1/reflection.proto create mode 100644 third_party/proto/cosmos/base/snapshots/v1beta1/snapshot.proto create mode 100644 third_party/proto/cosmos/base/store/v1beta1/commit_info.proto create mode 100644 third_party/proto/cosmos/base/store/v1beta1/snapshot.proto create mode 100644 third_party/proto/cosmos/base/tendermint/v1beta1/query.proto create mode 100644 third_party/proto/cosmos/base/v1beta1/coin.proto create mode 100644 third_party/proto/cosmos/capability/v1beta1/capability.proto create mode 100644 third_party/proto/cosmos/capability/v1beta1/genesis.proto create mode 100644 third_party/proto/cosmos/crisis/v1beta1/genesis.proto create mode 100644 third_party/proto/cosmos/crisis/v1beta1/tx.proto create mode 100644 third_party/proto/cosmos/crypto/ed25519/keys.proto create mode 100644 third_party/proto/cosmos/crypto/multisig/keys.proto create mode 100644 third_party/proto/cosmos/crypto/multisig/v1beta1/multisig.proto create mode 100644 third_party/proto/cosmos/crypto/secp256k1/keys.proto create mode 100644 third_party/proto/cosmos/distribution/v1beta1/distribution.proto create mode 100644 third_party/proto/cosmos/distribution/v1beta1/genesis.proto create mode 100644 third_party/proto/cosmos/distribution/v1beta1/query.proto create mode 100644 third_party/proto/cosmos/distribution/v1beta1/tx.proto create mode 100644 third_party/proto/cosmos/evidence/v1beta1/evidence.proto create mode 100644 third_party/proto/cosmos/evidence/v1beta1/genesis.proto create mode 100644 third_party/proto/cosmos/evidence/v1beta1/query.proto create mode 100644 third_party/proto/cosmos/evidence/v1beta1/tx.proto create mode 100644 third_party/proto/cosmos/genutil/v1beta1/genesis.proto create mode 100644 third_party/proto/cosmos/gov/v1beta1/genesis.proto create mode 100644 third_party/proto/cosmos/gov/v1beta1/gov.proto create mode 100644 third_party/proto/cosmos/gov/v1beta1/query.proto create mode 100644 third_party/proto/cosmos/gov/v1beta1/tx.proto create mode 100644 third_party/proto/cosmos/mint/v1beta1/genesis.proto create mode 100644 third_party/proto/cosmos/mint/v1beta1/mint.proto create mode 100644 third_party/proto/cosmos/mint/v1beta1/query.proto create mode 100644 third_party/proto/cosmos/params/v1beta1/params.proto create mode 100644 third_party/proto/cosmos/params/v1beta1/query.proto create mode 100644 third_party/proto/cosmos/slashing/v1beta1/genesis.proto create mode 100644 third_party/proto/cosmos/slashing/v1beta1/query.proto create mode 100644 third_party/proto/cosmos/slashing/v1beta1/slashing.proto create mode 100644 third_party/proto/cosmos/slashing/v1beta1/tx.proto create mode 100644 third_party/proto/cosmos/staking/v1beta1/genesis.proto create mode 100644 third_party/proto/cosmos/staking/v1beta1/query.proto create mode 100644 third_party/proto/cosmos/staking/v1beta1/staking.proto create mode 100644 third_party/proto/cosmos/staking/v1beta1/tx.proto create mode 100644 third_party/proto/cosmos/tx/signing/v1beta1/signing.proto create mode 100644 third_party/proto/cosmos/tx/v1beta1/service.proto create mode 100644 third_party/proto/cosmos/tx/v1beta1/tx.proto create mode 100644 third_party/proto/cosmos/upgrade/v1beta1/query.proto create mode 100644 third_party/proto/cosmos/upgrade/v1beta1/upgrade.proto create mode 100644 third_party/proto/cosmos/vesting/v1beta1/tx.proto create mode 100644 third_party/proto/cosmos/vesting/v1beta1/vesting.proto diff --git a/accounts1.json b/accounts1.json index 0d6aa91..d7a434c 100644 --- a/accounts1.json +++ b/accounts1.json @@ -147,7 +147,7 @@ "name": "erik", "coins": [ { - "amount": "1", + "amount": "100", "denom": "⚡" }, { diff --git a/go.sum b/go.sum index 69748e1..e39aa51 100644 --- a/go.sum +++ b/go.sum @@ -101,6 +101,7 @@ github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfc github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= github.com/cosmos/cosmos-sdk v0.42.6 h1:ps1QWfvaX6VLNcykA7wzfii/5IwBfYgTIik6NOVDq/c= github.com/cosmos/cosmos-sdk v0.42.6/go.mod h1:kh37gwYQoWdgR7N/9zeqW2rJ7cnP2W4A7nqIaf6m3zg= +github.com/cosmos/cosmos-sdk v0.42.7/go.mod h1:SrclJP9lMXxz2fCbngxb0brsPNuZXqoQQ9VHuQ3Tpf4= github.com/cosmos/go-bip39 v0.0.0-20180819234021-555e2067c45d/go.mod h1:tSxLoYXyBmiFeKpvmq4dzayMdCjCnu8uqmCysIGBT2Y= github.com/cosmos/go-bip39 v1.0.0 h1:pcomnQdrdH22njcAatO0yWojsUnCO3y2tNoV1cb6hHY= github.com/cosmos/go-bip39 v1.0.0/go.mod h1:RNJv0H/pOIVgxw6KS7QeX2a0Uo0aKUlfhZ4xuwvCdJw= diff --git a/proto/escrow/escrow/tx.proto b/proto/escrow/escrow/tx.proto deleted file mode 100644 index 056d948..0000000 --- a/proto/escrow/escrow/tx.proto +++ /dev/null @@ -1,33 +0,0 @@ -syntax = "proto3"; -package escrow; - -import "gogoproto/gogo.proto"; - -// this line is used by starport scaffolding # proto/tx/import - -option go_package = "github.com/interchainberlin/pooltoy/x/escrow/types"; - -// Msg defines the Msg service. -service Msg { - // this line is used by starport scaffolding # proto/tx/rpc - rpc Offer(OfferRequest) returns (OfferResponse); - -} - -// this line is used by starport scaffolding # proto/tx/message -message OfferRequest { - string sender = 1; - string amount = 2; - // [(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Coins"]; - string request = 3; - // [(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Coins"]; -} - -//message Coin { -// string coin = 1 -// [(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Coin"]; -//} -message OfferResponse { - string sender = 1; - int64 index = 2; -} diff --git a/proto/escrow/escrow/genesis.proto b/proto/escrow/genesis.proto similarity index 100% rename from proto/escrow/escrow/genesis.proto rename to proto/escrow/genesis.proto diff --git a/proto/escrow/escrow/query.proto b/proto/escrow/query.proto similarity index 76% rename from proto/escrow/escrow/query.proto rename to proto/escrow/query.proto index d4bfb46..4c88a51 100644 --- a/proto/escrow/escrow/query.proto +++ b/proto/escrow/query.proto @@ -2,7 +2,7 @@ syntax = "proto3"; package escrow; import "google/api/annotations.proto"; - +import "escrow/tx.proto"; // this line is used by starport scaffolding # 1 option go_package = "github.com/interchainberlin/pooltoy/x/escrow/types"; @@ -13,8 +13,6 @@ service Query { rpc QueryOfferListAll (OfferListAllRequest) returns (OfferListResponse); rpc QueryOfferByID (QueryOfferByIDRequest) returns (Offer); rpc QueryOfferByAddr (QueryOfferByAddrRequest) returns (OfferListResponse); - - } message OfferListAllRequest {} @@ -29,17 +27,7 @@ message QueryOfferByAddrRequest { string offerer = 2; } -message Offer { - string sender = 1; - string amount = 2; - // [(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Coins"]; - string request = 3; - // [(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Coins"]; -} - message OfferListResponse { repeated Offer offerList = 1; } - - diff --git a/proto/escrow/tx.proto b/proto/escrow/tx.proto new file mode 100644 index 0000000..f7f8480 --- /dev/null +++ b/proto/escrow/tx.proto @@ -0,0 +1,42 @@ +syntax = "proto3"; +package escrow; + +import "gogoproto/gogo.proto"; +import "cosmos/base/v1beta1/coin.proto"; +// this line is used by starport scaffolding # proto/tx/import +//import "github.com/cosmos/cosmos-sdk/bank/v1beta1/bank.proto"; + +option go_package = "github.com/interchainberlin/pooltoy/x/escrow/types"; + +// Msg defines the Msg service. +service Msg { + // this line is used by starport scaffolding # proto/tx/rpc + rpc Offer(Offer) returns (OfferResponse); + //rpc CancelOffer(CancelOfferRequest) returns(CancelOfferResponse); +} + +// this line is used by starport scaffolding # proto/tx/message +message Offer { + string sender = 1; + repeated cosmos.base.v1beta1.Coin amount = 2 + [(gogoproto.nullable) = false, (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins"]; + repeated cosmos.base.v1beta1.Coin request = 3 + [(gogoproto.nullable) = false, (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins"]; +} + +//message Coin { +// string coin = 1 +// [(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Coin"]; +//} +message OfferResponse { + string sender = 1; + int64 index = 2; +} + +// +//message CancelOfferRequest { +// string sender = 1; +// int64 ID = 2; +//} +// +//message CancelOfferResponse{} diff --git a/third_party/proto/cosmos/auth/v1beta1/auth.proto b/third_party/proto/cosmos/auth/v1beta1/auth.proto new file mode 100644 index 0000000..72e1d9e --- /dev/null +++ b/third_party/proto/cosmos/auth/v1beta1/auth.proto @@ -0,0 +1,50 @@ +syntax = "proto3"; +package cosmos.auth.v1beta1; + +import "cosmos_proto/cosmos.proto"; +import "gogoproto/gogo.proto"; +import "google/protobuf/any.proto"; + +option go_package = "github.com/cosmos/cosmos-sdk/x/auth/types"; + +// BaseAccount defines a base account type. It contains all the necessary fields +// for basic account functionality. Any custom account type should extend this +// type for additional functionality (e.g. vesting). +message BaseAccount { + option (gogoproto.goproto_getters) = false; + option (gogoproto.goproto_stringer) = false; + option (gogoproto.equal) = false; + + option (cosmos_proto.implements_interface) = "AccountI"; + + string address = 1; + google.protobuf.Any pub_key = 2 + [(gogoproto.jsontag) = "public_key,omitempty", (gogoproto.moretags) = "yaml:\"public_key\""]; + uint64 account_number = 3 [(gogoproto.moretags) = "yaml:\"account_number\""]; + uint64 sequence = 4; +} + +// ModuleAccount defines an account for modules that holds coins on a pool. +message ModuleAccount { + option (gogoproto.goproto_getters) = false; + option (gogoproto.goproto_stringer) = false; + option (cosmos_proto.implements_interface) = "ModuleAccountI"; + + BaseAccount base_account = 1 [(gogoproto.embed) = true, (gogoproto.moretags) = "yaml:\"base_account\""]; + string name = 2; + repeated string permissions = 3; +} + +// Params defines the parameters for the auth module. +message Params { + option (gogoproto.equal) = true; + option (gogoproto.goproto_stringer) = false; + + uint64 max_memo_characters = 1 [(gogoproto.moretags) = "yaml:\"max_memo_characters\""]; + uint64 tx_sig_limit = 2 [(gogoproto.moretags) = "yaml:\"tx_sig_limit\""]; + uint64 tx_size_cost_per_byte = 3 [(gogoproto.moretags) = "yaml:\"tx_size_cost_per_byte\""]; + uint64 sig_verify_cost_ed25519 = 4 + [(gogoproto.customname) = "SigVerifyCostED25519", (gogoproto.moretags) = "yaml:\"sig_verify_cost_ed25519\""]; + uint64 sig_verify_cost_secp256k1 = 5 + [(gogoproto.customname) = "SigVerifyCostSecp256k1", (gogoproto.moretags) = "yaml:\"sig_verify_cost_secp256k1\""]; +} diff --git a/third_party/proto/cosmos/auth/v1beta1/genesis.proto b/third_party/proto/cosmos/auth/v1beta1/genesis.proto new file mode 100644 index 0000000..c88b94e --- /dev/null +++ b/third_party/proto/cosmos/auth/v1beta1/genesis.proto @@ -0,0 +1,17 @@ +syntax = "proto3"; +package cosmos.auth.v1beta1; + +import "google/protobuf/any.proto"; +import "gogoproto/gogo.proto"; +import "cosmos/auth/v1beta1/auth.proto"; + +option go_package = "github.com/cosmos/cosmos-sdk/x/auth/types"; + +// GenesisState defines the auth module's genesis state. +message GenesisState { + // params defines all the paramaters of the module. + Params params = 1 [(gogoproto.nullable) = false]; + + // accounts are the accounts present at genesis. + repeated google.protobuf.Any accounts = 2; +} diff --git a/third_party/proto/cosmos/auth/v1beta1/query.proto b/third_party/proto/cosmos/auth/v1beta1/query.proto new file mode 100644 index 0000000..a885792 --- /dev/null +++ b/third_party/proto/cosmos/auth/v1beta1/query.proto @@ -0,0 +1,47 @@ +syntax = "proto3"; +package cosmos.auth.v1beta1; + +import "gogoproto/gogo.proto"; +import "google/protobuf/any.proto"; +import "google/api/annotations.proto"; +import "cosmos/auth/v1beta1/auth.proto"; +import "cosmos_proto/cosmos.proto"; + +option go_package = "github.com/cosmos/cosmos-sdk/x/auth/types"; + +// Query defines the gRPC querier service. +service Query { + // Account returns account details based on address. + rpc Account(QueryAccountRequest) returns (QueryAccountResponse) { + option (google.api.http).get = "/cosmos/auth/v1beta1/accounts/{address}"; + } + + // Params queries all parameters. + rpc Params(QueryParamsRequest) returns (QueryParamsResponse) { + option (google.api.http).get = "/cosmos/auth/v1beta1/params"; + } +} + +// QueryAccountRequest is the request type for the Query/Account RPC method. +message QueryAccountRequest { + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + + // address defines the address to query for. + string address = 1; +} + +// QueryAccountResponse is the response type for the Query/Account RPC method. +message QueryAccountResponse { + // account defines the account of the corresponding address. + google.protobuf.Any account = 1 [(cosmos_proto.accepts_interface) = "AccountI"]; +} + +// QueryParamsRequest is the request type for the Query/Params RPC method. +message QueryParamsRequest {} + +// QueryParamsResponse is the response type for the Query/Params RPC method. +message QueryParamsResponse { + // params defines the parameters of the module. + Params params = 1 [(gogoproto.nullable) = false]; +} diff --git a/third_party/proto/cosmos/bank/v1beta1/bank.proto b/third_party/proto/cosmos/bank/v1beta1/bank.proto new file mode 100644 index 0000000..5a93833 --- /dev/null +++ b/third_party/proto/cosmos/bank/v1beta1/bank.proto @@ -0,0 +1,85 @@ +syntax = "proto3"; +package cosmos.bank.v1beta1; + +import "gogoproto/gogo.proto"; +import "cosmos_proto/cosmos.proto"; +import "cosmos/base/v1beta1/coin.proto"; + +option go_package = "github.com/cosmos/cosmos-sdk/x/bank/types"; + +// Params defines the parameters for the bank module. +message Params { + option (gogoproto.goproto_stringer) = false; + repeated SendEnabled send_enabled = 1 [(gogoproto.moretags) = "yaml:\"send_enabled,omitempty\""]; + bool default_send_enabled = 2 [(gogoproto.moretags) = "yaml:\"default_send_enabled,omitempty\""]; +} + +// SendEnabled maps coin denom to a send_enabled status (whether a denom is +// sendable). +message SendEnabled { + option (gogoproto.equal) = true; + option (gogoproto.goproto_stringer) = false; + string denom = 1; + bool enabled = 2; +} + +// Input models transaction input. +message Input { + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + + string address = 1; + repeated cosmos.base.v1beta1.Coin coins = 2 + [(gogoproto.nullable) = false, (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins"]; +} + +// Output models transaction outputs. +message Output { + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + + string address = 1; + repeated cosmos.base.v1beta1.Coin coins = 2 + [(gogoproto.nullable) = false, (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins"]; +} + +// Supply represents a struct that passively keeps track of the total supply +// amounts in the network. +message Supply { + option (gogoproto.equal) = true; + option (gogoproto.goproto_getters) = false; + option (gogoproto.goproto_stringer) = false; + + option (cosmos_proto.implements_interface) = "*github.com/cosmos/cosmos-sdk/x/bank/exported.SupplyI"; + + repeated cosmos.base.v1beta1.Coin total = 1 + [(gogoproto.nullable) = false, (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins"]; +} + +// DenomUnit represents a struct that describes a given +// denomination unit of the basic token. +message DenomUnit { + // denom represents the string name of the given denom unit (e.g uatom). + string denom = 1; + // exponent represents power of 10 exponent that one must + // raise the base_denom to in order to equal the given DenomUnit's denom + // 1 denom = 1^exponent base_denom + // (e.g. with a base_denom of uatom, one can create a DenomUnit of 'atom' with + // exponent = 6, thus: 1 atom = 10^6 uatom). + uint32 exponent = 2; + // aliases is a list of string aliases for the given denom + repeated string aliases = 3; +} + +// Metadata represents a struct that describes +// a basic token. +message Metadata { + string description = 1; + // denom_units represents the list of DenomUnit's for a given coin + repeated DenomUnit denom_units = 2; + // base represents the base denom (should be the DenomUnit with exponent = 0). + string base = 3; + // display indicates the suggested denom that should be + // displayed in clients. + string display = 4; +} diff --git a/third_party/proto/cosmos/bank/v1beta1/genesis.proto b/third_party/proto/cosmos/bank/v1beta1/genesis.proto new file mode 100644 index 0000000..25c80a3 --- /dev/null +++ b/third_party/proto/cosmos/bank/v1beta1/genesis.proto @@ -0,0 +1,38 @@ +syntax = "proto3"; +package cosmos.bank.v1beta1; + +import "gogoproto/gogo.proto"; +import "cosmos/base/v1beta1/coin.proto"; +import "cosmos/bank/v1beta1/bank.proto"; + +option go_package = "github.com/cosmos/cosmos-sdk/x/bank/types"; + +// GenesisState defines the bank module's genesis state. +message GenesisState { + // params defines all the paramaters of the module. + Params params = 1 [(gogoproto.nullable) = false]; + + // balances is an array containing the balances of all the accounts. + repeated Balance balances = 2 [(gogoproto.nullable) = false]; + + // supply represents the total supply. + repeated cosmos.base.v1beta1.Coin supply = 3 + [(gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins", (gogoproto.nullable) = false]; + + // denom_metadata defines the metadata of the differents coins. + repeated Metadata denom_metadata = 4 [(gogoproto.moretags) = "yaml:\"denom_metadata\"", (gogoproto.nullable) = false]; +} + +// Balance defines an account address and balance pair used in the bank module's +// genesis state. +message Balance { + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + + // address is the address of the balance holder. + string address = 1; + + // coins defines the different coins this balance holds. + repeated cosmos.base.v1beta1.Coin coins = 2 + [(gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins", (gogoproto.nullable) = false]; +} diff --git a/third_party/proto/cosmos/bank/v1beta1/query.proto b/third_party/proto/cosmos/bank/v1beta1/query.proto new file mode 100644 index 0000000..bc5e291 --- /dev/null +++ b/third_party/proto/cosmos/bank/v1beta1/query.proto @@ -0,0 +1,150 @@ +syntax = "proto3"; +package cosmos.bank.v1beta1; + +import "cosmos/base/query/v1beta1/pagination.proto"; +import "gogoproto/gogo.proto"; +import "google/api/annotations.proto"; +import "cosmos/base/v1beta1/coin.proto"; +import "cosmos/bank/v1beta1/bank.proto"; + +option go_package = "github.com/cosmos/cosmos-sdk/x/bank/types"; + +// Query defines the gRPC querier service. +service Query { + // Balance queries the balance of a single coin for a single account. + rpc Balance(QueryBalanceRequest) returns (QueryBalanceResponse) { + option (google.api.http).get = "/cosmos/bank/v1beta1/balances/{address}/{denom}"; + } + + // AllBalances queries the balance of all coins for a single account. + rpc AllBalances(QueryAllBalancesRequest) returns (QueryAllBalancesResponse) { + option (google.api.http).get = "/cosmos/bank/v1beta1/balances/{address}"; + } + + // TotalSupply queries the total supply of all coins. + rpc TotalSupply(QueryTotalSupplyRequest) returns (QueryTotalSupplyResponse) { + option (google.api.http).get = "/cosmos/bank/v1beta1/supply"; + } + + // SupplyOf queries the supply of a single coin. + rpc SupplyOf(QuerySupplyOfRequest) returns (QuerySupplyOfResponse) { + option (google.api.http).get = "/cosmos/bank/v1beta1/supply/{denom}"; + } + + // Params queries the parameters of x/bank module. + rpc Params(QueryParamsRequest) returns (QueryParamsResponse) { + option (google.api.http).get = "/cosmos/bank/v1beta1/params"; + } + + // DenomsMetadata queries the client metadata of a given coin denomination. + rpc DenomMetadata(QueryDenomMetadataRequest) returns (QueryDenomMetadataResponse) { + option (google.api.http).get = "/cosmos/bank/v1beta1/denoms_metadata/{denom}"; + } + + // DenomsMetadata queries the client metadata for all registered coin denominations. + rpc DenomsMetadata(QueryDenomsMetadataRequest) returns (QueryDenomsMetadataResponse) { + option (google.api.http).get = "/cosmos/bank/v1beta1/denoms_metadata"; + } +} + +// QueryBalanceRequest is the request type for the Query/Balance RPC method. +message QueryBalanceRequest { + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + + // address is the address to query balances for. + string address = 1; + + // denom is the coin denom to query balances for. + string denom = 2; +} + +// QueryBalanceResponse is the response type for the Query/Balance RPC method. +message QueryBalanceResponse { + // balance is the balance of the coin. + cosmos.base.v1beta1.Coin balance = 1; +} + +// QueryBalanceRequest is the request type for the Query/AllBalances RPC method. +message QueryAllBalancesRequest { + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + + // address is the address to query balances for. + string address = 1; + + // pagination defines an optional pagination for the request. + cosmos.base.query.v1beta1.PageRequest pagination = 2; +} + +// QueryAllBalancesResponse is the response type for the Query/AllBalances RPC +// method. +message QueryAllBalancesResponse { + // balances is the balances of all the coins. + repeated cosmos.base.v1beta1.Coin balances = 1 + [(gogoproto.nullable) = false, (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins"]; + + // pagination defines the pagination in the response. + cosmos.base.query.v1beta1.PageResponse pagination = 2; +} + +// QueryTotalSupplyRequest is the request type for the Query/TotalSupply RPC +// method. +message QueryTotalSupplyRequest {} + +// QueryTotalSupplyResponse is the response type for the Query/TotalSupply RPC +// method +message QueryTotalSupplyResponse { + // supply is the supply of the coins + repeated cosmos.base.v1beta1.Coin supply = 1 + [(gogoproto.nullable) = false, (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins"]; +} + +// QuerySupplyOfRequest is the request type for the Query/SupplyOf RPC method. +message QuerySupplyOfRequest { + // denom is the coin denom to query balances for. + string denom = 1; +} + +// QuerySupplyOfResponse is the response type for the Query/SupplyOf RPC method. +message QuerySupplyOfResponse { + // amount is the supply of the coin. + cosmos.base.v1beta1.Coin amount = 1 [(gogoproto.nullable) = false]; +} + +// QueryParamsRequest defines the request type for querying x/bank parameters. +message QueryParamsRequest {} + +// QueryParamsResponse defines the response type for querying x/bank parameters. +message QueryParamsResponse { + Params params = 1 [(gogoproto.nullable) = false]; +} + +// QueryDenomsMetadataRequest is the request type for the Query/DenomsMetadata RPC method. +message QueryDenomsMetadataRequest { + // pagination defines an optional pagination for the request. + cosmos.base.query.v1beta1.PageRequest pagination = 1; +} + +// QueryDenomsMetadataResponse is the response type for the Query/DenomsMetadata RPC +// method. +message QueryDenomsMetadataResponse { + // metadata provides the client information for all the registered tokens. + repeated Metadata metadatas = 1 [(gogoproto.nullable) = false]; + + // pagination defines the pagination in the response. + cosmos.base.query.v1beta1.PageResponse pagination = 2; +} + +// QueryDenomMetadataRequest is the request type for the Query/DenomMetadata RPC method. +message QueryDenomMetadataRequest { + // denom is the coin denom to query the metadata for. + string denom = 1; +} + +// QueryDenomMetadataResponse is the response type for the Query/DenomMetadata RPC +// method. +message QueryDenomMetadataResponse { + // metadata describes and provides all the client information for the requested token. + Metadata metadata = 1 [(gogoproto.nullable) = false]; +} diff --git a/third_party/proto/cosmos/bank/v1beta1/tx.proto b/third_party/proto/cosmos/bank/v1beta1/tx.proto new file mode 100644 index 0000000..26b2ab4 --- /dev/null +++ b/third_party/proto/cosmos/bank/v1beta1/tx.proto @@ -0,0 +1,42 @@ +syntax = "proto3"; +package cosmos.bank.v1beta1; + +import "gogoproto/gogo.proto"; +import "cosmos/base/v1beta1/coin.proto"; +import "cosmos/bank/v1beta1/bank.proto"; + +option go_package = "github.com/cosmos/cosmos-sdk/x/bank/types"; + +// Msg defines the bank Msg service. +service Msg { + // Send defines a method for sending coins from one account to another account. + rpc Send(MsgSend) returns (MsgSendResponse); + + // MultiSend defines a method for sending coins from some accounts to other accounts. + rpc MultiSend(MsgMultiSend) returns (MsgMultiSendResponse); +} + +// MsgSend represents a message to send coins from one account to another. +message MsgSend { + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + + string from_address = 1 [(gogoproto.moretags) = "yaml:\"from_address\""]; + string to_address = 2 [(gogoproto.moretags) = "yaml:\"to_address\""]; + repeated cosmos.base.v1beta1.Coin amount = 3 + [(gogoproto.nullable) = false, (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins"]; +} + +// MsgSendResponse defines the Msg/Send response type. +message MsgSendResponse {} + +// MsgMultiSend represents an arbitrary multi-in, multi-out send message. +message MsgMultiSend { + option (gogoproto.equal) = false; + + repeated Input inputs = 1 [(gogoproto.nullable) = false]; + repeated Output outputs = 2 [(gogoproto.nullable) = false]; +} + +// MsgMultiSendResponse defines the Msg/MultiSend response type. +message MsgMultiSendResponse {} diff --git a/third_party/proto/cosmos/base/abci/v1beta1/abci.proto b/third_party/proto/cosmos/base/abci/v1beta1/abci.proto new file mode 100644 index 0000000..72da2aa --- /dev/null +++ b/third_party/proto/cosmos/base/abci/v1beta1/abci.proto @@ -0,0 +1,137 @@ +syntax = "proto3"; +package cosmos.base.abci.v1beta1; + +import "gogoproto/gogo.proto"; +import "tendermint/abci/types.proto"; +import "google/protobuf/any.proto"; + +option go_package = "github.com/cosmos/cosmos-sdk/types"; +option (gogoproto.goproto_stringer_all) = false; + +// TxResponse defines a structure containing relevant tx data and metadata. The +// tags are stringified and the log is JSON decoded. +message TxResponse { + option (gogoproto.goproto_getters) = false; + // The block height + int64 height = 1; + // The transaction hash. + string txhash = 2 [(gogoproto.customname) = "TxHash"]; + // Namespace for the Code + string codespace = 3; + // Response code. + uint32 code = 4; + // Result bytes, if any. + string data = 5; + // The output of the application's logger (raw string). May be + // non-deterministic. + string raw_log = 6; + // The output of the application's logger (typed). May be non-deterministic. + repeated ABCIMessageLog logs = 7 [(gogoproto.castrepeated) = "ABCIMessageLogs", (gogoproto.nullable) = false]; + // Additional information. May be non-deterministic. + string info = 8; + // Amount of gas requested for transaction. + int64 gas_wanted = 9; + // Amount of gas consumed by transaction. + int64 gas_used = 10; + // The request transaction bytes. + google.protobuf.Any tx = 11; + // Time of the previous block. For heights > 1, it's the weighted median of + // the timestamps of the valid votes in the block.LastCommit. For height == 1, + // it's genesis time. + string timestamp = 12; +} + +// ABCIMessageLog defines a structure containing an indexed tx ABCI message log. +message ABCIMessageLog { + option (gogoproto.stringer) = true; + + uint32 msg_index = 1; + string log = 2; + + // Events contains a slice of Event objects that were emitted during some + // execution. + repeated StringEvent events = 3 [(gogoproto.castrepeated) = "StringEvents", (gogoproto.nullable) = false]; +} + +// StringEvent defines en Event object wrapper where all the attributes +// contain key/value pairs that are strings instead of raw bytes. +message StringEvent { + option (gogoproto.stringer) = true; + + string type = 1; + repeated Attribute attributes = 2 [(gogoproto.nullable) = false]; +} + +// Attribute defines an attribute wrapper where the key and value are +// strings instead of raw bytes. +message Attribute { + string key = 1; + string value = 2; +} + +// GasInfo defines tx execution gas context. +message GasInfo { + // GasWanted is the maximum units of work we allow this tx to perform. + uint64 gas_wanted = 1 [(gogoproto.moretags) = "yaml:\"gas_wanted\""]; + + // GasUsed is the amount of gas actually consumed. + uint64 gas_used = 2 [(gogoproto.moretags) = "yaml:\"gas_used\""]; +} + +// Result is the union of ResponseFormat and ResponseCheckTx. +message Result { + option (gogoproto.goproto_getters) = false; + + // Data is any data returned from message or handler execution. It MUST be + // length prefixed in order to separate data from multiple message executions. + bytes data = 1; + + // Log contains the log information from message or handler execution. + string log = 2; + + // Events contains a slice of Event objects that were emitted during message + // or handler execution. + repeated tendermint.abci.Event events = 3 [(gogoproto.nullable) = false]; +} + +// SimulationResponse defines the response generated when a transaction is +// successfully simulated. +message SimulationResponse { + GasInfo gas_info = 1 [(gogoproto.embed) = true, (gogoproto.nullable) = false]; + Result result = 2; +} + +// MsgData defines the data returned in a Result object during message +// execution. +message MsgData { + option (gogoproto.stringer) = true; + + string msg_type = 1; + bytes data = 2; +} + +// TxMsgData defines a list of MsgData. A transaction will have a MsgData object +// for each message. +message TxMsgData { + option (gogoproto.stringer) = true; + + repeated MsgData data = 1; +} + +// SearchTxsResult defines a structure for querying txs pageable +message SearchTxsResult { + option (gogoproto.stringer) = true; + + // Count of all txs + uint64 total_count = 1 [(gogoproto.moretags) = "yaml:\"total_count\"", (gogoproto.jsontag) = "total_count"]; + // Count of txs in current page + uint64 count = 2; + // Index of current page, start from 1 + uint64 page_number = 3 [(gogoproto.moretags) = "yaml:\"page_number\"", (gogoproto.jsontag) = "page_number"]; + // Count of total pages + uint64 page_total = 4 [(gogoproto.moretags) = "yaml:\"page_total\"", (gogoproto.jsontag) = "page_total"]; + // Max count txs per page + uint64 limit = 5; + // List of txs in current page + repeated TxResponse txs = 6; +} diff --git a/third_party/proto/cosmos/base/kv/v1beta1/kv.proto b/third_party/proto/cosmos/base/kv/v1beta1/kv.proto new file mode 100644 index 0000000..4e9b8d2 --- /dev/null +++ b/third_party/proto/cosmos/base/kv/v1beta1/kv.proto @@ -0,0 +1,17 @@ +syntax = "proto3"; +package cosmos.base.kv.v1beta1; + +import "gogoproto/gogo.proto"; + +option go_package = "github.com/cosmos/cosmos-sdk/types/kv"; + +// Pairs defines a repeated slice of Pair objects. +message Pairs { + repeated Pair pairs = 1 [(gogoproto.nullable) = false]; +} + +// Pair defines a key/value bytes tuple. +message Pair { + bytes key = 1; + bytes value = 2; +} diff --git a/third_party/proto/cosmos/base/query/v1beta1/pagination.proto b/third_party/proto/cosmos/base/query/v1beta1/pagination.proto new file mode 100644 index 0000000..2a8cbcc --- /dev/null +++ b/third_party/proto/cosmos/base/query/v1beta1/pagination.proto @@ -0,0 +1,50 @@ +syntax = "proto3"; +package cosmos.base.query.v1beta1; + +option go_package = "github.com/cosmos/cosmos-sdk/types/query"; + +// PageRequest is to be embedded in gRPC request messages for efficient +// pagination. Ex: +// +// message SomeRequest { +// Foo some_parameter = 1; +// PageRequest pagination = 2; +// } +message PageRequest { + // key is a value returned in PageResponse.next_key to begin + // querying the next page most efficiently. Only one of offset or key + // should be set. + bytes key = 1; + + // offset is a numeric offset that can be used when key is unavailable. + // It is less efficient than using key. Only one of offset or key should + // be set. + uint64 offset = 2; + + // limit is the total number of results to be returned in the result page. + // If left empty it will default to a value to be set by each app. + uint64 limit = 3; + + // count_total is set to true to indicate that the result set should include + // a count of the total number of items available for pagination in UIs. + // count_total is only respected when offset is used. It is ignored when key + // is set. + bool count_total = 4; +} + +// PageResponse is to be embedded in gRPC response messages where the +// corresponding request message has used PageRequest. +// +// message SomeResponse { +// repeated Bar results = 1; +// PageResponse page = 2; +// } +message PageResponse { + // next_key is the key to be passed to PageRequest.key to + // query the next page most efficiently + bytes next_key = 1; + + // total is total number of results available if PageRequest.count_total + // was set, its value is undefined otherwise + uint64 total = 2; +} diff --git a/third_party/proto/cosmos/base/reflection/v1beta1/reflection.proto b/third_party/proto/cosmos/base/reflection/v1beta1/reflection.proto new file mode 100644 index 0000000..22670e7 --- /dev/null +++ b/third_party/proto/cosmos/base/reflection/v1beta1/reflection.proto @@ -0,0 +1,44 @@ +syntax = "proto3"; +package cosmos.base.reflection.v1beta1; + +import "google/api/annotations.proto"; + +option go_package = "github.com/cosmos/cosmos-sdk/client/grpc/reflection"; + +// ReflectionService defines a service for interface reflection. +service ReflectionService { + // ListAllInterfaces lists all the interfaces registered in the interface + // registry. + rpc ListAllInterfaces(ListAllInterfacesRequest) returns (ListAllInterfacesResponse) { + option (google.api.http).get = "/cosmos/base/reflection/v1beta1/interfaces"; + }; + + // ListImplementations list all the concrete types that implement a given + // interface. + rpc ListImplementations(ListImplementationsRequest) returns (ListImplementationsResponse) { + option (google.api.http).get = "/cosmos/base/reflection/v1beta1/interfaces/" + "{interface_name}/implementations"; + }; +} + +// ListAllInterfacesRequest is the request type of the ListAllInterfaces RPC. +message ListAllInterfacesRequest {} + +// ListAllInterfacesResponse is the response type of the ListAllInterfaces RPC. +message ListAllInterfacesResponse { + // interface_names is an array of all the registered interfaces. + repeated string interface_names = 1; +} + +// ListImplementationsRequest is the request type of the ListImplementations +// RPC. +message ListImplementationsRequest { + // interface_name defines the interface to query the implementations for. + string interface_name = 1; +} + +// ListImplementationsResponse is the response type of the ListImplementations +// RPC. +message ListImplementationsResponse { + repeated string implementation_message_names = 1; +} diff --git a/third_party/proto/cosmos/base/snapshots/v1beta1/snapshot.proto b/third_party/proto/cosmos/base/snapshots/v1beta1/snapshot.proto new file mode 100644 index 0000000..9ac5a7c --- /dev/null +++ b/third_party/proto/cosmos/base/snapshots/v1beta1/snapshot.proto @@ -0,0 +1,20 @@ +syntax = "proto3"; +package cosmos.base.snapshots.v1beta1; + +import "gogoproto/gogo.proto"; + +option go_package = "github.com/cosmos/cosmos-sdk/snapshots/types"; + +// Snapshot contains Tendermint state sync snapshot info. +message Snapshot { + uint64 height = 1; + uint32 format = 2; + uint32 chunks = 3; + bytes hash = 4; + Metadata metadata = 5 [(gogoproto.nullable) = false]; +} + +// Metadata contains SDK-specific snapshot metadata. +message Metadata { + repeated bytes chunk_hashes = 1; // SHA-256 chunk hashes +} \ No newline at end of file diff --git a/third_party/proto/cosmos/base/store/v1beta1/commit_info.proto b/third_party/proto/cosmos/base/store/v1beta1/commit_info.proto new file mode 100644 index 0000000..98a33d3 --- /dev/null +++ b/third_party/proto/cosmos/base/store/v1beta1/commit_info.proto @@ -0,0 +1,29 @@ +syntax = "proto3"; +package cosmos.base.store.v1beta1; + +import "gogoproto/gogo.proto"; + +option go_package = "github.com/cosmos/cosmos-sdk/store/types"; + +// CommitInfo defines commit information used by the multi-store when committing +// a version/height. +message CommitInfo { + int64 version = 1; + repeated StoreInfo store_infos = 2 [(gogoproto.nullable) = false]; +} + +// StoreInfo defines store-specific commit information. It contains a reference +// between a store name and the commit ID. +message StoreInfo { + string name = 1; + CommitID commit_id = 2 [(gogoproto.nullable) = false]; +} + +// CommitID defines the committment information when a specific store is +// committed. +message CommitID { + option (gogoproto.goproto_stringer) = false; + + int64 version = 1; + bytes hash = 2; +} diff --git a/third_party/proto/cosmos/base/store/v1beta1/snapshot.proto b/third_party/proto/cosmos/base/store/v1beta1/snapshot.proto new file mode 100644 index 0000000..8348550 --- /dev/null +++ b/third_party/proto/cosmos/base/store/v1beta1/snapshot.proto @@ -0,0 +1,28 @@ +syntax = "proto3"; +package cosmos.base.store.v1beta1; + +import "gogoproto/gogo.proto"; + +option go_package = "github.com/cosmos/cosmos-sdk/store/types"; + +// SnapshotItem is an item contained in a rootmulti.Store snapshot. +message SnapshotItem { + // item is the specific type of snapshot item. + oneof item { + SnapshotStoreItem store = 1; + SnapshotIAVLItem iavl = 2 [(gogoproto.customname) = "IAVL"]; + } +} + +// SnapshotStoreItem contains metadata about a snapshotted store. +message SnapshotStoreItem { + string name = 1; +} + +// SnapshotIAVLItem is an exported IAVL node. +message SnapshotIAVLItem { + bytes key = 1; + bytes value = 2; + int64 version = 3; + int32 height = 4; +} \ No newline at end of file diff --git a/third_party/proto/cosmos/base/tendermint/v1beta1/query.proto b/third_party/proto/cosmos/base/tendermint/v1beta1/query.proto new file mode 100644 index 0000000..505d413 --- /dev/null +++ b/third_party/proto/cosmos/base/tendermint/v1beta1/query.proto @@ -0,0 +1,137 @@ +syntax = "proto3"; +package cosmos.base.tendermint.v1beta1; + +import "gogoproto/gogo.proto"; +import "google/protobuf/any.proto"; +import "google/api/annotations.proto"; +import "tendermint/p2p/types.proto"; +import "tendermint/types/block.proto"; +import "tendermint/types/types.proto"; +import "cosmos/base/query/v1beta1/pagination.proto"; + +option go_package = "github.com/cosmos/cosmos-sdk/client/grpc/tmservice"; + +// Service defines the gRPC querier service for tendermint queries. +service Service { + // GetNodeInfo queries the current node info. + rpc GetNodeInfo(GetNodeInfoRequest) returns (GetNodeInfoResponse) { + option (google.api.http).get = "/cosmos/base/tendermint/v1beta1/node_info"; + } + // GetSyncing queries node syncing. + rpc GetSyncing(GetSyncingRequest) returns (GetSyncingResponse) { + option (google.api.http).get = "/cosmos/base/tendermint/v1beta1/syncing"; + } + // GetLatestBlock returns the latest block. + rpc GetLatestBlock(GetLatestBlockRequest) returns (GetLatestBlockResponse) { + option (google.api.http).get = "/cosmos/base/tendermint/v1beta1/blocks/latest"; + } + // GetBlockByHeight queries block for given height. + rpc GetBlockByHeight(GetBlockByHeightRequest) returns (GetBlockByHeightResponse) { + option (google.api.http).get = "/cosmos/base/tendermint/v1beta1/blocks/{height}"; + } + + // GetLatestValidatorSet queries latest validator-set. + rpc GetLatestValidatorSet(GetLatestValidatorSetRequest) returns (GetLatestValidatorSetResponse) { + option (google.api.http).get = "/cosmos/base/tendermint/v1beta1/validatorsets/latest"; + } + // GetValidatorSetByHeight queries validator-set at a given height. + rpc GetValidatorSetByHeight(GetValidatorSetByHeightRequest) returns (GetValidatorSetByHeightResponse) { + option (google.api.http).get = "/cosmos/base/tendermint/v1beta1/validatorsets/{height}"; + } +} + +// GetValidatorSetByHeightRequest is the request type for the Query/GetValidatorSetByHeight RPC method. +message GetValidatorSetByHeightRequest { + int64 height = 1; + // pagination defines an pagination for the request. + cosmos.base.query.v1beta1.PageRequest pagination = 2; +} + +// GetValidatorSetByHeightResponse is the response type for the Query/GetValidatorSetByHeight RPC method. +message GetValidatorSetByHeightResponse { + int64 block_height = 1; + repeated Validator validators = 2; + // pagination defines an pagination for the response. + cosmos.base.query.v1beta1.PageResponse pagination = 3; +} + +// GetLatestValidatorSetRequest is the request type for the Query/GetValidatorSetByHeight RPC method. +message GetLatestValidatorSetRequest { + // pagination defines an pagination for the request. + cosmos.base.query.v1beta1.PageRequest pagination = 1; +} + +// GetLatestValidatorSetResponse is the response type for the Query/GetValidatorSetByHeight RPC method. +message GetLatestValidatorSetResponse { + int64 block_height = 1; + repeated Validator validators = 2; + // pagination defines an pagination for the response. + cosmos.base.query.v1beta1.PageResponse pagination = 3; +} + +// Validator is the type for the validator-set. +message Validator { + string address = 1; + google.protobuf.Any pub_key = 2; + int64 voting_power = 3; + int64 proposer_priority = 4; +} + +// GetBlockByHeightRequest is the request type for the Query/GetBlockByHeight RPC method. +message GetBlockByHeightRequest { + int64 height = 1; +} + +// GetBlockByHeightResponse is the response type for the Query/GetBlockByHeight RPC method. +message GetBlockByHeightResponse { + .tendermint.types.BlockID block_id = 1; + .tendermint.types.Block block = 2; +} + +// GetLatestBlockRequest is the request type for the Query/GetLatestBlock RPC method. +message GetLatestBlockRequest {} + +// GetLatestBlockResponse is the response type for the Query/GetLatestBlock RPC method. +message GetLatestBlockResponse { + .tendermint.types.BlockID block_id = 1; + .tendermint.types.Block block = 2; +} + +// GetSyncingRequest is the request type for the Query/GetSyncing RPC method. +message GetSyncingRequest {} + +// GetSyncingResponse is the response type for the Query/GetSyncing RPC method. +message GetSyncingResponse { + bool syncing = 1; +} + +// GetNodeInfoRequest is the request type for the Query/GetNodeInfo RPC method. +message GetNodeInfoRequest {} + +// GetNodeInfoResponse is the request type for the Query/GetNodeInfo RPC method. +message GetNodeInfoResponse { + .tendermint.p2p.DefaultNodeInfo default_node_info = 1; + VersionInfo application_version = 2; +} + +// VersionInfo is the type for the GetNodeInfoResponse message. +message VersionInfo { + string name = 1; + string app_name = 2; + string version = 3; + string git_commit = 4; + string build_tags = 5; + string go_version = 6; + repeated Module build_deps = 7; + string cosmos_sdk_version = 8; +} + +// Module is the type for VersionInfo +message Module { + // module path + string path = 1; + // module version + string version = 2; + // checksum + string sum = 3; +} diff --git a/third_party/proto/cosmos/base/v1beta1/coin.proto b/third_party/proto/cosmos/base/v1beta1/coin.proto new file mode 100644 index 0000000..fab7528 --- /dev/null +++ b/third_party/proto/cosmos/base/v1beta1/coin.proto @@ -0,0 +1,40 @@ +syntax = "proto3"; +package cosmos.base.v1beta1; + +import "gogoproto/gogo.proto"; + +option go_package = "github.com/cosmos/cosmos-sdk/types"; +option (gogoproto.goproto_stringer_all) = false; +option (gogoproto.stringer_all) = false; + +// Coin defines a token with a denomination and an amount. +// +// NOTE: The amount field is an Int which implements the custom method +// signatures required by gogoproto. +message Coin { + option (gogoproto.equal) = true; + + string denom = 1; + string amount = 2 [(gogoproto.customtype) = "Int", (gogoproto.nullable) = false]; +} + +// DecCoin defines a token with a denomination and a decimal amount. +// +// NOTE: The amount field is an Dec which implements the custom method +// signatures required by gogoproto. +message DecCoin { + option (gogoproto.equal) = true; + + string denom = 1; + string amount = 2 [(gogoproto.customtype) = "Dec", (gogoproto.nullable) = false]; +} + +// IntProto defines a Protobuf wrapper around an Int object. +message IntProto { + string int = 1 [(gogoproto.customtype) = "Int", (gogoproto.nullable) = false]; +} + +// DecProto defines a Protobuf wrapper around a Dec object. +message DecProto { + string dec = 1 [(gogoproto.customtype) = "Dec", (gogoproto.nullable) = false]; +} diff --git a/third_party/proto/cosmos/capability/v1beta1/capability.proto b/third_party/proto/cosmos/capability/v1beta1/capability.proto new file mode 100644 index 0000000..1c8332f --- /dev/null +++ b/third_party/proto/cosmos/capability/v1beta1/capability.proto @@ -0,0 +1,30 @@ +syntax = "proto3"; +package cosmos.capability.v1beta1; + +option go_package = "github.com/cosmos/cosmos-sdk/x/capability/types"; + +import "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/third_party/proto/cosmos/capability/v1beta1/genesis.proto b/third_party/proto/cosmos/capability/v1beta1/genesis.proto new file mode 100644 index 0000000..05bb0af --- /dev/null +++ b/third_party/proto/cosmos/capability/v1beta1/genesis.proto @@ -0,0 +1,26 @@ +syntax = "proto3"; +package cosmos.capability.v1beta1; + +import "gogoproto/gogo.proto"; +import "cosmos/capability/v1beta1/capability.proto"; + +option go_package = "github.com/cosmos/cosmos-sdk/x/capability/types"; + +// GenesisOwners defines the capability owners with their corresponding index. +message GenesisOwners { + // index is the index of the capability owner. + uint64 index = 1; + + // index_owners are the owners at the given index. + CapabilityOwners index_owners = 2 [(gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"index_owners\""]; +} + +// GenesisState defines the capability module's genesis state. +message GenesisState { + // index is the capability global index. + uint64 index = 1; + + // owners represents a map from index to owners of the capability index + // index key is string to allow amino marshalling. + repeated GenesisOwners owners = 2 [(gogoproto.nullable) = false]; +} diff --git a/third_party/proto/cosmos/crisis/v1beta1/genesis.proto b/third_party/proto/cosmos/crisis/v1beta1/genesis.proto new file mode 100644 index 0000000..5b0ff7e --- /dev/null +++ b/third_party/proto/cosmos/crisis/v1beta1/genesis.proto @@ -0,0 +1,15 @@ +syntax = "proto3"; +package cosmos.crisis.v1beta1; + +option go_package = "github.com/cosmos/cosmos-sdk/x/crisis/types"; + +import "gogoproto/gogo.proto"; +import "cosmos/base/v1beta1/coin.proto"; + +// GenesisState defines the crisis module's genesis state. +message GenesisState { + // constant_fee is the fee used to verify the invariant in the crisis + // module. + cosmos.base.v1beta1.Coin constant_fee = 3 + [(gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"constant_fee\""]; +} diff --git a/third_party/proto/cosmos/crisis/v1beta1/tx.proto b/third_party/proto/cosmos/crisis/v1beta1/tx.proto new file mode 100644 index 0000000..26457ad --- /dev/null +++ b/third_party/proto/cosmos/crisis/v1beta1/tx.proto @@ -0,0 +1,25 @@ +syntax = "proto3"; +package cosmos.crisis.v1beta1; + +option go_package = "github.com/cosmos/cosmos-sdk/x/crisis/types"; + +import "gogoproto/gogo.proto"; + +// Msg defines the bank Msg service. +service Msg { + // VerifyInvariant defines a method to verify a particular invariance. + rpc VerifyInvariant(MsgVerifyInvariant) returns (MsgVerifyInvariantResponse); +} + +// MsgVerifyInvariant represents a message to verify a particular invariance. +message MsgVerifyInvariant { + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + + string sender = 1; + string invariant_module_name = 2 [(gogoproto.moretags) = "yaml:\"invariant_module_name\""]; + string invariant_route = 3 [(gogoproto.moretags) = "yaml:\"invariant_route\""]; +} + +// MsgVerifyInvariantResponse defines the Msg/VerifyInvariant response type. +message MsgVerifyInvariantResponse {} diff --git a/third_party/proto/cosmos/crypto/ed25519/keys.proto b/third_party/proto/cosmos/crypto/ed25519/keys.proto new file mode 100644 index 0000000..bed9c29 --- /dev/null +++ b/third_party/proto/cosmos/crypto/ed25519/keys.proto @@ -0,0 +1,22 @@ +syntax = "proto3"; +package cosmos.crypto.ed25519; + +import "gogoproto/gogo.proto"; + +option go_package = "github.com/cosmos/cosmos-sdk/crypto/keys/ed25519"; + +// PubKey defines a ed25519 public key +// Key is the compressed form of the pubkey. The first byte depends is a 0x02 byte +// if the y-coordinate is the lexicographically largest of the two associated with +// the x-coordinate. Otherwise the first byte is a 0x03. +// This prefix is followed with the x-coordinate. +message PubKey { + option (gogoproto.goproto_stringer) = false; + + bytes key = 1 [(gogoproto.casttype) = "crypto/ed25519.PublicKey"]; +} + +// PrivKey defines a ed25519 private key. +message PrivKey { + bytes key = 1 [(gogoproto.casttype) = "crypto/ed25519.PrivateKey"]; +} diff --git a/third_party/proto/cosmos/crypto/multisig/keys.proto b/third_party/proto/cosmos/crypto/multisig/keys.proto new file mode 100644 index 0000000..f8398e8 --- /dev/null +++ b/third_party/proto/cosmos/crypto/multisig/keys.proto @@ -0,0 +1,18 @@ +syntax = "proto3"; +package cosmos.crypto.multisig; + +import "gogoproto/gogo.proto"; +import "google/protobuf/any.proto"; + +option go_package = "github.com/cosmos/cosmos-sdk/crypto/keys/multisig"; + +// LegacyAminoPubKey specifies a public key type +// which nests multiple public keys and a threshold, +// it uses legacy amino address rules. +message LegacyAminoPubKey { + option (gogoproto.goproto_getters) = false; + + uint32 threshold = 1 [(gogoproto.moretags) = "yaml:\"threshold\""]; + repeated google.protobuf.Any public_keys = 2 + [(gogoproto.customname) = "PubKeys", (gogoproto.moretags) = "yaml:\"pubkeys\""]; +} diff --git a/third_party/proto/cosmos/crypto/multisig/v1beta1/multisig.proto b/third_party/proto/cosmos/crypto/multisig/v1beta1/multisig.proto new file mode 100644 index 0000000..bf671f1 --- /dev/null +++ b/third_party/proto/cosmos/crypto/multisig/v1beta1/multisig.proto @@ -0,0 +1,25 @@ +syntax = "proto3"; +package cosmos.crypto.multisig.v1beta1; + +import "gogoproto/gogo.proto"; + +option go_package = "github.com/cosmos/cosmos-sdk/crypto/types"; + +// MultiSignature wraps the signatures from a multisig.LegacyAminoPubKey. +// See cosmos.tx.v1betata1.ModeInfo.Multi for how to specify which signers +// signed and with which modes. +message MultiSignature { + option (gogoproto.goproto_unrecognized) = true; + repeated bytes signatures = 1; +} + +// CompactBitArray is an implementation of a space efficient bit array. +// This is used to ensure that the encoded data takes up a minimal amount of +// space after proto encoding. +// This is not thread safe, and is not intended for concurrent usage. +message CompactBitArray { + option (gogoproto.goproto_stringer) = false; + + uint32 extra_bits_stored = 1; + bytes elems = 2; +} diff --git a/third_party/proto/cosmos/crypto/secp256k1/keys.proto b/third_party/proto/cosmos/crypto/secp256k1/keys.proto new file mode 100644 index 0000000..a227257 --- /dev/null +++ b/third_party/proto/cosmos/crypto/secp256k1/keys.proto @@ -0,0 +1,22 @@ +syntax = "proto3"; +package cosmos.crypto.secp256k1; + +import "gogoproto/gogo.proto"; + +option go_package = "github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1"; + +// PubKey defines a secp256k1 public key +// Key is the compressed form of the pubkey. The first byte depends is a 0x02 byte +// if the y-coordinate is the lexicographically largest of the two associated with +// the x-coordinate. Otherwise the first byte is a 0x03. +// This prefix is followed with the x-coordinate. +message PubKey { + option (gogoproto.goproto_stringer) = false; + + bytes key = 1; +} + +// PrivKey defines a secp256k1 private key. +message PrivKey { + bytes key = 1; +} diff --git a/third_party/proto/cosmos/distribution/v1beta1/distribution.proto b/third_party/proto/cosmos/distribution/v1beta1/distribution.proto new file mode 100644 index 0000000..ae98ec0 --- /dev/null +++ b/third_party/proto/cosmos/distribution/v1beta1/distribution.proto @@ -0,0 +1,157 @@ +syntax = "proto3"; +package cosmos.distribution.v1beta1; + +option go_package = "github.com/cosmos/cosmos-sdk/x/distribution/types"; +option (gogoproto.equal_all) = true; + +import "gogoproto/gogo.proto"; +import "cosmos/base/v1beta1/coin.proto"; + +// Params defines the set of params for the distribution module. +message Params { + option (gogoproto.goproto_stringer) = false; + string community_tax = 1 [ + (gogoproto.moretags) = "yaml:\"community_tax\"", + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", + (gogoproto.nullable) = false + ]; + string base_proposer_reward = 2 [ + (gogoproto.moretags) = "yaml:\"base_proposer_reward\"", + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", + (gogoproto.nullable) = false + ]; + string bonus_proposer_reward = 3 [ + (gogoproto.moretags) = "yaml:\"bonus_proposer_reward\"", + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", + (gogoproto.nullable) = false + ]; + bool withdraw_addr_enabled = 4 [(gogoproto.moretags) = "yaml:\"withdraw_addr_enabled\""]; +} + +// ValidatorHistoricalRewards represents historical rewards for a validator. +// Height is implicit within the store key. +// Cumulative reward ratio is the sum from the zeroeth period +// until this period of rewards / tokens, per the spec. +// The reference count indicates the number of objects +// which might need to reference this historical entry at any point. +// ReferenceCount = +// number of outstanding delegations which ended the associated period (and +// might need to read that record) +// + number of slashes which ended the associated period (and might need to +// read that record) +// + one per validator for the zeroeth period, set on initialization +message ValidatorHistoricalRewards { + repeated cosmos.base.v1beta1.DecCoin cumulative_reward_ratio = 1 [ + (gogoproto.moretags) = "yaml:\"cumulative_reward_ratio\"", + (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.DecCoins", + (gogoproto.nullable) = false + ]; + uint32 reference_count = 2 [(gogoproto.moretags) = "yaml:\"reference_count\""]; +} + +// ValidatorCurrentRewards represents current rewards and current +// period for a validator kept as a running counter and incremented +// each block as long as the validator's tokens remain constant. +message ValidatorCurrentRewards { + repeated cosmos.base.v1beta1.DecCoin rewards = 1 + [(gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.DecCoins", (gogoproto.nullable) = false]; + uint64 period = 2; +} + +// ValidatorAccumulatedCommission represents accumulated commission +// for a validator kept as a running counter, can be withdrawn at any time. +message ValidatorAccumulatedCommission { + repeated cosmos.base.v1beta1.DecCoin commission = 1 + [(gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.DecCoins", (gogoproto.nullable) = false]; +} + +// ValidatorOutstandingRewards represents outstanding (un-withdrawn) rewards +// for a validator inexpensive to track, allows simple sanity checks. +message ValidatorOutstandingRewards { + repeated cosmos.base.v1beta1.DecCoin rewards = 1 [ + (gogoproto.moretags) = "yaml:\"rewards\"", + (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.DecCoins", + (gogoproto.nullable) = false + ]; +} + +// ValidatorSlashEvent represents a validator slash event. +// Height is implicit within the store key. +// This is needed to calculate appropriate amount of staking tokens +// for delegations which are withdrawn after a slash has occurred. +message ValidatorSlashEvent { + uint64 validator_period = 1 [(gogoproto.moretags) = "yaml:\"validator_period\""]; + string fraction = 2 [(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", (gogoproto.nullable) = false]; +} + +// ValidatorSlashEvents is a collection of ValidatorSlashEvent messages. +message ValidatorSlashEvents { + option (gogoproto.goproto_stringer) = false; + repeated ValidatorSlashEvent validator_slash_events = 1 + [(gogoproto.moretags) = "yaml:\"validator_slash_events\"", (gogoproto.nullable) = false]; +} + +// FeePool is the global fee pool for distribution. +message FeePool { + repeated cosmos.base.v1beta1.DecCoin community_pool = 1 [ + (gogoproto.nullable) = false, + (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.DecCoins", + (gogoproto.moretags) = "yaml:\"community_pool\"" + ]; +} + +// CommunityPoolSpendProposal details a proposal for use of community funds, +// together with how many coins are proposed to be spent, and to which +// recipient account. +message CommunityPoolSpendProposal { + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + option (gogoproto.goproto_stringer) = false; + + string title = 1; + string description = 2; + string recipient = 3; + repeated cosmos.base.v1beta1.Coin amount = 4 + [(gogoproto.nullable) = false, (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins"]; +} + +// DelegatorStartingInfo represents the starting info for a delegator reward +// period. It tracks the previous validator period, the delegation's amount of +// staking token, and the creation height (to check later on if any slashes have +// occurred). NOTE: Even though validators are slashed to whole staking tokens, +// the delegators within the validator may be left with less than a full token, +// thus sdk.Dec is used. +message DelegatorStartingInfo { + uint64 previous_period = 1 [(gogoproto.moretags) = "yaml:\"previous_period\""]; + string stake = 2 [ + (gogoproto.moretags) = "yaml:\"stake\"", + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", + (gogoproto.nullable) = false + ]; + uint64 height = 3 [(gogoproto.moretags) = "yaml:\"creation_height\"", (gogoproto.jsontag) = "creation_height"]; +} + +// DelegationDelegatorReward represents the properties +// of a delegator's delegation reward. +message DelegationDelegatorReward { + option (gogoproto.goproto_getters) = false; + option (gogoproto.goproto_stringer) = true; + + string validator_address = 1 [(gogoproto.moretags) = "yaml:\"validator_address\""]; + + repeated cosmos.base.v1beta1.DecCoin reward = 2 + [(gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.DecCoins", (gogoproto.nullable) = false]; +} + +// CommunityPoolSpendProposalWithDeposit defines a CommunityPoolSpendProposal +// with a deposit +message CommunityPoolSpendProposalWithDeposit { + option (gogoproto.goproto_getters) = false; + option (gogoproto.goproto_stringer) = true; + + string title = 1 [(gogoproto.moretags) = "yaml:\"title\""]; + string description = 2 [(gogoproto.moretags) = "yaml:\"description\""]; + string recipient = 3 [(gogoproto.moretags) = "yaml:\"recipient\""]; + string amount = 4 [(gogoproto.moretags) = "yaml:\"amount\""]; + string deposit = 5 [(gogoproto.moretags) = "yaml:\"deposit\""]; +} diff --git a/third_party/proto/cosmos/distribution/v1beta1/genesis.proto b/third_party/proto/cosmos/distribution/v1beta1/genesis.proto new file mode 100644 index 0000000..c0b17cd --- /dev/null +++ b/third_party/proto/cosmos/distribution/v1beta1/genesis.proto @@ -0,0 +1,155 @@ +syntax = "proto3"; +package cosmos.distribution.v1beta1; + +option go_package = "github.com/cosmos/cosmos-sdk/x/distribution/types"; +option (gogoproto.equal_all) = true; + +import "gogoproto/gogo.proto"; +import "cosmos/base/v1beta1/coin.proto"; +import "cosmos/distribution/v1beta1/distribution.proto"; + +// DelegatorWithdrawInfo is the address for where distributions rewards are +// withdrawn to by default this struct is only used at genesis to feed in +// default withdraw addresses. +message DelegatorWithdrawInfo { + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + + // delegator_address is the address of the delegator. + string delegator_address = 1 [(gogoproto.moretags) = "yaml:\"delegator_address\""]; + + // withdraw_address is the address to withdraw the delegation rewards to. + string withdraw_address = 2 [(gogoproto.moretags) = "yaml:\"withdraw_address\""]; +} + +// ValidatorOutstandingRewardsRecord is used for import/export via genesis json. +message ValidatorOutstandingRewardsRecord { + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + + // validator_address is the address of the validator. + string validator_address = 1 [(gogoproto.moretags) = "yaml:\"validator_address\""]; + + // outstanding_rewards represents the oustanding rewards of a validator. + repeated cosmos.base.v1beta1.DecCoin outstanding_rewards = 2 [ + (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.DecCoins", + (gogoproto.nullable) = false, + (gogoproto.moretags) = "yaml:\"outstanding_rewards\"" + ]; +} + +// ValidatorAccumulatedCommissionRecord is used for import / export via genesis +// json. +message ValidatorAccumulatedCommissionRecord { + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + + // validator_address is the address of the validator. + string validator_address = 1 [(gogoproto.moretags) = "yaml:\"validator_address\""]; + + // accumulated is the accumulated commission of a validator. + ValidatorAccumulatedCommission accumulated = 2 + [(gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"accumulated\""]; +} + +// ValidatorHistoricalRewardsRecord is used for import / export via genesis +// json. +message ValidatorHistoricalRewardsRecord { + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + + // validator_address is the address of the validator. + string validator_address = 1 [(gogoproto.moretags) = "yaml:\"validator_address\""]; + + // period defines the period the historical rewards apply to. + uint64 period = 2; + + // rewards defines the historical rewards of a validator. + ValidatorHistoricalRewards rewards = 3 [(gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"rewards\""]; +} + +// ValidatorCurrentRewardsRecord is used for import / export via genesis json. +message ValidatorCurrentRewardsRecord { + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + + // validator_address is the address of the validator. + string validator_address = 1 [(gogoproto.moretags) = "yaml:\"validator_address\""]; + + // rewards defines the current rewards of a validator. + ValidatorCurrentRewards rewards = 2 [(gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"rewards\""]; +} + +// DelegatorStartingInfoRecord used for import / export via genesis json. +message DelegatorStartingInfoRecord { + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + + // delegator_address is the address of the delegator. + string delegator_address = 1 [(gogoproto.moretags) = "yaml:\"delegator_address\""]; + + // validator_address is the address of the validator. + string validator_address = 2 [(gogoproto.moretags) = "yaml:\"validator_address\""]; + + // starting_info defines the starting info of a delegator. + DelegatorStartingInfo starting_info = 3 + [(gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"starting_info\""]; +} + +// ValidatorSlashEventRecord is used for import / export via genesis json. +message ValidatorSlashEventRecord { + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + + // validator_address is the address of the validator. + string validator_address = 1 [(gogoproto.moretags) = "yaml:\"validator_address\""]; + // height defines the block height at which the slash event occured. + uint64 height = 2; + // period is the period of the slash event. + uint64 period = 3; + // validator_slash_event describes the slash event. + ValidatorSlashEvent validator_slash_event = 4 [(gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"event\""]; +} + +// GenesisState defines the distribution module's genesis state. +message GenesisState { + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + + // params defines all the paramaters of the module. + Params params = 1 [(gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"params\""]; + + // fee_pool defines the fee pool at genesis. + FeePool fee_pool = 2 [(gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"fee_pool\""]; + + // fee_pool defines the delegator withdraw infos at genesis. + repeated DelegatorWithdrawInfo delegator_withdraw_infos = 3 + [(gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"delegator_withdraw_infos\""]; + + // fee_pool defines the previous proposer at genesis. + string previous_proposer = 4 [(gogoproto.moretags) = "yaml:\"previous_proposer\""]; + + // fee_pool defines the outstanding rewards of all validators at genesis. + repeated ValidatorOutstandingRewardsRecord outstanding_rewards = 5 + [(gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"outstanding_rewards\""]; + + // fee_pool defines the accumulated commisions of all validators at genesis. + repeated ValidatorAccumulatedCommissionRecord validator_accumulated_commissions = 6 + [(gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"validator_accumulated_commissions\""]; + + // fee_pool defines the historical rewards of all validators at genesis. + repeated ValidatorHistoricalRewardsRecord validator_historical_rewards = 7 + [(gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"validator_historical_rewards\""]; + + // fee_pool defines the current rewards of all validators at genesis. + repeated ValidatorCurrentRewardsRecord validator_current_rewards = 8 + [(gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"validator_current_rewards\""]; + + // fee_pool defines the delegator starting infos at genesis. + repeated DelegatorStartingInfoRecord delegator_starting_infos = 9 + [(gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"delegator_starting_infos\""]; + + // fee_pool defines the validator slash events at genesis. + repeated ValidatorSlashEventRecord validator_slash_events = 10 + [(gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"validator_slash_events\""]; +} diff --git a/third_party/proto/cosmos/distribution/v1beta1/query.proto b/third_party/proto/cosmos/distribution/v1beta1/query.proto new file mode 100644 index 0000000..2991218 --- /dev/null +++ b/third_party/proto/cosmos/distribution/v1beta1/query.proto @@ -0,0 +1,218 @@ +syntax = "proto3"; +package cosmos.distribution.v1beta1; + +import "cosmos/base/query/v1beta1/pagination.proto"; +import "gogoproto/gogo.proto"; +import "google/api/annotations.proto"; +import "cosmos/base/v1beta1/coin.proto"; +import "cosmos/distribution/v1beta1/distribution.proto"; + +option go_package = "github.com/cosmos/cosmos-sdk/x/distribution/types"; + +// Query defines the gRPC querier service for distribution module. +service Query { + // Params queries params of the distribution module. + rpc Params(QueryParamsRequest) returns (QueryParamsResponse) { + option (google.api.http).get = "/cosmos/distribution/v1beta1/params"; + } + + // ValidatorOutstandingRewards queries rewards of a validator address. + rpc ValidatorOutstandingRewards(QueryValidatorOutstandingRewardsRequest) + returns (QueryValidatorOutstandingRewardsResponse) { + option (google.api.http).get = "/cosmos/distribution/v1beta1/validators/" + "{validator_address}/outstanding_rewards"; + } + + // ValidatorCommission queries accumulated commission for a validator. + rpc ValidatorCommission(QueryValidatorCommissionRequest) returns (QueryValidatorCommissionResponse) { + option (google.api.http).get = "/cosmos/distribution/v1beta1/validators/" + "{validator_address}/commission"; + } + + // ValidatorSlashes queries slash events of a validator. + rpc ValidatorSlashes(QueryValidatorSlashesRequest) returns (QueryValidatorSlashesResponse) { + option (google.api.http).get = "/cosmos/distribution/v1beta1/validators/{validator_address}/slashes"; + } + + // DelegationRewards queries the total rewards accrued by a delegation. + rpc DelegationRewards(QueryDelegationRewardsRequest) returns (QueryDelegationRewardsResponse) { + option (google.api.http).get = "/cosmos/distribution/v1beta1/delegators/{delegator_address}/rewards/" + "{validator_address}"; + } + + // DelegationTotalRewards queries the total rewards accrued by a each + // validator. + rpc DelegationTotalRewards(QueryDelegationTotalRewardsRequest) returns (QueryDelegationTotalRewardsResponse) { + option (google.api.http).get = "/cosmos/distribution/v1beta1/delegators/{delegator_address}/rewards"; + } + + // DelegatorValidators queries the validators of a delegator. + rpc DelegatorValidators(QueryDelegatorValidatorsRequest) returns (QueryDelegatorValidatorsResponse) { + option (google.api.http).get = "/cosmos/distribution/v1beta1/delegators/" + "{delegator_address}/validators"; + } + + // DelegatorWithdrawAddress queries withdraw address of a delegator. + rpc DelegatorWithdrawAddress(QueryDelegatorWithdrawAddressRequest) returns (QueryDelegatorWithdrawAddressResponse) { + option (google.api.http).get = "/cosmos/distribution/v1beta1/delegators/" + "{delegator_address}/withdraw_address"; + } + + // CommunityPool queries the community pool coins. + rpc CommunityPool(QueryCommunityPoolRequest) returns (QueryCommunityPoolResponse) { + option (google.api.http).get = "/cosmos/distribution/v1beta1/community_pool"; + } +} + +// QueryParamsRequest is the request type for the Query/Params RPC method. +message QueryParamsRequest {} + +// QueryParamsResponse is the response type for the Query/Params RPC method. +message QueryParamsResponse { + // params defines the parameters of the module. + Params params = 1 [(gogoproto.nullable) = false]; +} + +// QueryValidatorOutstandingRewardsRequest is the request type for the +// Query/ValidatorOutstandingRewards RPC method. +message QueryValidatorOutstandingRewardsRequest { + // validator_address defines the validator address to query for. + string validator_address = 1; +} + +// QueryValidatorOutstandingRewardsResponse is the response type for the +// Query/ValidatorOutstandingRewards RPC method. +message QueryValidatorOutstandingRewardsResponse { + ValidatorOutstandingRewards rewards = 1 [(gogoproto.nullable) = false]; +} + +// QueryValidatorCommissionRequest is the request type for the +// Query/ValidatorCommission RPC method +message QueryValidatorCommissionRequest { + // validator_address defines the validator address to query for. + string validator_address = 1; +} + +// QueryValidatorCommissionResponse is the response type for the +// Query/ValidatorCommission RPC method +message QueryValidatorCommissionResponse { + // commission defines the commision the validator received. + ValidatorAccumulatedCommission commission = 1 [(gogoproto.nullable) = false]; +} + +// QueryValidatorSlashesRequest is the request type for the +// Query/ValidatorSlashes RPC method +message QueryValidatorSlashesRequest { + option (gogoproto.goproto_getters) = false; + option (gogoproto.goproto_stringer) = true; + + // validator_address defines the validator address to query for. + string validator_address = 1; + // starting_height defines the optional starting height to query the slashes. + uint64 starting_height = 2; + // starting_height defines the optional ending height to query the slashes. + uint64 ending_height = 3; + // pagination defines an optional pagination for the request. + cosmos.base.query.v1beta1.PageRequest pagination = 4; +} + +// QueryValidatorSlashesResponse is the response type for the +// Query/ValidatorSlashes RPC method. +message QueryValidatorSlashesResponse { + // slashes defines the slashes the validator received. + repeated ValidatorSlashEvent slashes = 1 [(gogoproto.nullable) = false]; + + // pagination defines the pagination in the response. + cosmos.base.query.v1beta1.PageResponse pagination = 2; +} + +// QueryDelegationRewardsRequest is the request type for the +// Query/DelegationRewards RPC method. +message QueryDelegationRewardsRequest { + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + + // delegator_address defines the delegator address to query for. + string delegator_address = 1; + // validator_address defines the validator address to query for. + string validator_address = 2; +} + +// QueryDelegationRewardsResponse is the response type for the +// Query/DelegationRewards RPC method. +message QueryDelegationRewardsResponse { + // rewards defines the rewards accrued by a delegation. + repeated cosmos.base.v1beta1.DecCoin rewards = 1 + [(gogoproto.nullable) = false, (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.DecCoins"]; +} + +// QueryDelegationTotalRewardsRequest is the request type for the +// Query/DelegationTotalRewards RPC method. +message QueryDelegationTotalRewardsRequest { + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + // delegator_address defines the delegator address to query for. + string delegator_address = 1; +} + +// QueryDelegationTotalRewardsResponse is the response type for the +// Query/DelegationTotalRewards RPC method. +message QueryDelegationTotalRewardsResponse { + // rewards defines all the rewards accrued by a delegator. + repeated DelegationDelegatorReward rewards = 1 [(gogoproto.nullable) = false]; + // total defines the sum of all the rewards. + repeated cosmos.base.v1beta1.DecCoin total = 2 + [(gogoproto.nullable) = false, (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.DecCoins"]; +} + +// QueryDelegatorValidatorsRequest is the request type for the +// Query/DelegatorValidators RPC method. +message QueryDelegatorValidatorsRequest { + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + + // delegator_address defines the delegator address to query for. + string delegator_address = 1; +} + +// QueryDelegatorValidatorsResponse is the response type for the +// Query/DelegatorValidators RPC method. +message QueryDelegatorValidatorsResponse { + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + + // validators defines the validators a delegator is delegating for. + repeated string validators = 1; +} + +// QueryDelegatorWithdrawAddressRequest is the request type for the +// Query/DelegatorWithdrawAddress RPC method. +message QueryDelegatorWithdrawAddressRequest { + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + + // delegator_address defines the delegator address to query for. + string delegator_address = 1; +} + +// QueryDelegatorWithdrawAddressResponse is the response type for the +// Query/DelegatorWithdrawAddress RPC method. +message QueryDelegatorWithdrawAddressResponse { + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + + // withdraw_address defines the delegator address to query for. + string withdraw_address = 1; +} + +// QueryCommunityPoolRequest is the request type for the Query/CommunityPool RPC +// method. +message QueryCommunityPoolRequest {} + +// QueryCommunityPoolResponse is the response type for the Query/CommunityPool +// RPC method. +message QueryCommunityPoolResponse { + // pool defines community pool's coins. + repeated cosmos.base.v1beta1.DecCoin pool = 1 + [(gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.DecCoins", (gogoproto.nullable) = false]; +} diff --git a/third_party/proto/cosmos/distribution/v1beta1/tx.proto b/third_party/proto/cosmos/distribution/v1beta1/tx.proto new file mode 100644 index 0000000..e6ce478 --- /dev/null +++ b/third_party/proto/cosmos/distribution/v1beta1/tx.proto @@ -0,0 +1,79 @@ +syntax = "proto3"; +package cosmos.distribution.v1beta1; + +option go_package = "github.com/cosmos/cosmos-sdk/x/distribution/types"; +option (gogoproto.equal_all) = true; + +import "gogoproto/gogo.proto"; +import "cosmos/base/v1beta1/coin.proto"; + +// Msg defines the distribution Msg service. +service Msg { + // SetWithdrawAddress defines a method to change the withdraw address + // for a delegator (or validator self-delegation). + rpc SetWithdrawAddress(MsgSetWithdrawAddress) returns (MsgSetWithdrawAddressResponse); + + // WithdrawDelegatorReward defines a method to withdraw rewards of delegator + // from a single validator. + rpc WithdrawDelegatorReward(MsgWithdrawDelegatorReward) returns (MsgWithdrawDelegatorRewardResponse); + + // WithdrawValidatorCommission defines a method to withdraw the + // full commission to the validator address. + rpc WithdrawValidatorCommission(MsgWithdrawValidatorCommission) returns (MsgWithdrawValidatorCommissionResponse); + + // FundCommunityPool defines a method to allow an account to directly + // fund the community pool. + rpc FundCommunityPool(MsgFundCommunityPool) returns (MsgFundCommunityPoolResponse); +} + +// MsgSetWithdrawAddress sets the withdraw address for +// a delegator (or validator self-delegation). +message MsgSetWithdrawAddress { + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + + string delegator_address = 1 [(gogoproto.moretags) = "yaml:\"delegator_address\""]; + string withdraw_address = 2 [(gogoproto.moretags) = "yaml:\"withdraw_address\""]; +} + +// MsgSetWithdrawAddressResponse defines the Msg/SetWithdrawAddress response type. +message MsgSetWithdrawAddressResponse {} + +// MsgWithdrawDelegatorReward represents delegation withdrawal to a delegator +// from a single validator. +message MsgWithdrawDelegatorReward { + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + + string delegator_address = 1 [(gogoproto.moretags) = "yaml:\"delegator_address\""]; + string validator_address = 2 [(gogoproto.moretags) = "yaml:\"validator_address\""]; +} + +// MsgWithdrawDelegatorRewardResponse defines the Msg/WithdrawDelegatorReward response type. +message MsgWithdrawDelegatorRewardResponse {} + +// MsgWithdrawValidatorCommission withdraws the full commission to the validator +// address. +message MsgWithdrawValidatorCommission { + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + + string validator_address = 1 [(gogoproto.moretags) = "yaml:\"validator_address\""]; +} + +// MsgWithdrawValidatorCommissionResponse defines the Msg/WithdrawValidatorCommission response type. +message MsgWithdrawValidatorCommissionResponse {} + +// MsgFundCommunityPool allows an account to directly +// fund the community pool. +message MsgFundCommunityPool { + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + + repeated cosmos.base.v1beta1.Coin amount = 1 + [(gogoproto.nullable) = false, (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins"]; + string depositor = 2; +} + +// MsgFundCommunityPoolResponse defines the Msg/FundCommunityPool response type. +message MsgFundCommunityPoolResponse {} diff --git a/third_party/proto/cosmos/evidence/v1beta1/evidence.proto b/third_party/proto/cosmos/evidence/v1beta1/evidence.proto new file mode 100644 index 0000000..14612c3 --- /dev/null +++ b/third_party/proto/cosmos/evidence/v1beta1/evidence.proto @@ -0,0 +1,21 @@ +syntax = "proto3"; +package cosmos.evidence.v1beta1; + +option go_package = "github.com/cosmos/cosmos-sdk/x/evidence/types"; +option (gogoproto.equal_all) = true; + +import "gogoproto/gogo.proto"; +import "google/protobuf/timestamp.proto"; + +// Equivocation implements the Evidence interface and defines evidence of double +// signing misbehavior. +message Equivocation { + option (gogoproto.goproto_stringer) = false; + option (gogoproto.goproto_getters) = false; + option (gogoproto.equal) = false; + + int64 height = 1; + google.protobuf.Timestamp time = 2 [(gogoproto.nullable) = false, (gogoproto.stdtime) = true]; + int64 power = 3; + string consensus_address = 4 [(gogoproto.moretags) = "yaml:\"consensus_address\""]; +} \ No newline at end of file diff --git a/third_party/proto/cosmos/evidence/v1beta1/genesis.proto b/third_party/proto/cosmos/evidence/v1beta1/genesis.proto new file mode 100644 index 0000000..199f446 --- /dev/null +++ b/third_party/proto/cosmos/evidence/v1beta1/genesis.proto @@ -0,0 +1,12 @@ +syntax = "proto3"; +package cosmos.evidence.v1beta1; + +option go_package = "github.com/cosmos/cosmos-sdk/x/evidence/types"; + +import "google/protobuf/any.proto"; + +// GenesisState defines the evidence module's genesis state. +message GenesisState { + // evidence defines all the evidence at genesis. + repeated google.protobuf.Any evidence = 1; +} diff --git a/third_party/proto/cosmos/evidence/v1beta1/query.proto b/third_party/proto/cosmos/evidence/v1beta1/query.proto new file mode 100644 index 0000000..eda0054 --- /dev/null +++ b/third_party/proto/cosmos/evidence/v1beta1/query.proto @@ -0,0 +1,51 @@ +syntax = "proto3"; +package cosmos.evidence.v1beta1; + +import "cosmos/base/query/v1beta1/pagination.proto"; +import "gogoproto/gogo.proto"; +import "google/protobuf/any.proto"; +import "google/api/annotations.proto"; + +option go_package = "github.com/cosmos/cosmos-sdk/x/evidence/types"; + +// Query defines the gRPC querier service. +service Query { + // Evidence queries evidence based on evidence hash. + rpc Evidence(QueryEvidenceRequest) returns (QueryEvidenceResponse) { + option (google.api.http).get = "/cosmos/evidence/v1beta1/evidence/{evidence_hash}"; + } + + // AllEvidence queries all evidence. + rpc AllEvidence(QueryAllEvidenceRequest) returns (QueryAllEvidenceResponse) { + option (google.api.http).get = "/cosmos/evidence/v1beta1/evidence"; + } +} + +// QueryEvidenceRequest is the request type for the Query/Evidence RPC method. +message QueryEvidenceRequest { + // evidence_hash defines the hash of the requested evidence. + bytes evidence_hash = 1 [(gogoproto.casttype) = "github.com/tendermint/tendermint/libs/bytes.HexBytes"]; +} + +// QueryEvidenceResponse is the response type for the Query/Evidence RPC method. +message QueryEvidenceResponse { + // evidence returns the requested evidence. + google.protobuf.Any evidence = 1; +} + +// QueryEvidenceRequest is the request type for the Query/AllEvidence RPC +// method. +message QueryAllEvidenceRequest { + // pagination defines an optional pagination for the request. + cosmos.base.query.v1beta1.PageRequest pagination = 1; +} + +// QueryAllEvidenceResponse is the response type for the Query/AllEvidence RPC +// method. +message QueryAllEvidenceResponse { + // evidence returns all evidences. + repeated google.protobuf.Any evidence = 1; + + // pagination defines the pagination in the response. + cosmos.base.query.v1beta1.PageResponse pagination = 2; +} diff --git a/third_party/proto/cosmos/evidence/v1beta1/tx.proto b/third_party/proto/cosmos/evidence/v1beta1/tx.proto new file mode 100644 index 0000000..38795f2 --- /dev/null +++ b/third_party/proto/cosmos/evidence/v1beta1/tx.proto @@ -0,0 +1,32 @@ +syntax = "proto3"; +package cosmos.evidence.v1beta1; + +option go_package = "github.com/cosmos/cosmos-sdk/x/evidence/types"; +option (gogoproto.equal_all) = true; + +import "gogoproto/gogo.proto"; +import "google/protobuf/any.proto"; +import "cosmos_proto/cosmos.proto"; + +// Msg defines the evidence Msg service. +service Msg { + // SubmitEvidence submits an arbitrary Evidence of misbehavior such as equivocation or + // counterfactual signing. + rpc SubmitEvidence(MsgSubmitEvidence) returns (MsgSubmitEvidenceResponse); +} + +// MsgSubmitEvidence represents a message that supports submitting arbitrary +// Evidence of misbehavior such as equivocation or counterfactual signing. +message MsgSubmitEvidence { + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + + string submitter = 1; + google.protobuf.Any evidence = 2 [(cosmos_proto.accepts_interface) = "Evidence"]; +} + +// MsgSubmitEvidenceResponse defines the Msg/SubmitEvidence response type. +message MsgSubmitEvidenceResponse { + // hash defines the hash of the evidence. + bytes hash = 4; +} diff --git a/third_party/proto/cosmos/genutil/v1beta1/genesis.proto b/third_party/proto/cosmos/genutil/v1beta1/genesis.proto new file mode 100644 index 0000000..a020779 --- /dev/null +++ b/third_party/proto/cosmos/genutil/v1beta1/genesis.proto @@ -0,0 +1,16 @@ +syntax = "proto3"; +package cosmos.genutil.v1beta1; + +import "gogoproto/gogo.proto"; + +option go_package = "github.com/cosmos/cosmos-sdk/x/genutil/types"; + +// GenesisState defines the raw genesis transaction in JSON. +message GenesisState { + // gen_txs defines the genesis transactions. + repeated bytes gen_txs = 1 [ + (gogoproto.casttype) = "encoding/json.RawMessage", + (gogoproto.jsontag) = "gentxs", + (gogoproto.moretags) = "yaml:\"gentxs\"" + ]; +} diff --git a/third_party/proto/cosmos/gov/v1beta1/genesis.proto b/third_party/proto/cosmos/gov/v1beta1/genesis.proto new file mode 100644 index 0000000..a999500 --- /dev/null +++ b/third_party/proto/cosmos/gov/v1beta1/genesis.proto @@ -0,0 +1,26 @@ +syntax = "proto3"; + +package cosmos.gov.v1beta1; + +import "gogoproto/gogo.proto"; +import "cosmos/gov/v1beta1/gov.proto"; + +option go_package = "github.com/cosmos/cosmos-sdk/x/gov/types"; + +// GenesisState defines the gov module's genesis state. +message GenesisState { + // starting_proposal_id is the ID of the starting proposal. + uint64 starting_proposal_id = 1 [(gogoproto.moretags) = "yaml:\"starting_proposal_id\""]; + // deposits defines all the deposits present at genesis. + repeated Deposit deposits = 2 [(gogoproto.castrepeated) = "Deposits", (gogoproto.nullable) = false]; + // votes defines all the votes present at genesis. + repeated Vote votes = 3 [(gogoproto.castrepeated) = "Votes", (gogoproto.nullable) = false]; + // proposals defines all the proposals present at genesis. + repeated Proposal proposals = 4 [(gogoproto.castrepeated) = "Proposals", (gogoproto.nullable) = false]; + // params defines all the paramaters of related to deposit. + DepositParams deposit_params = 5 [(gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"deposit_params\""]; + // params defines all the paramaters of related to voting. + VotingParams voting_params = 6 [(gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"voting_params\""]; + // params defines all the paramaters of related to tally. + TallyParams tally_params = 7 [(gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"tally_params\""]; +} diff --git a/third_party/proto/cosmos/gov/v1beta1/gov.proto b/third_party/proto/cosmos/gov/v1beta1/gov.proto new file mode 100644 index 0000000..1d72e64 --- /dev/null +++ b/third_party/proto/cosmos/gov/v1beta1/gov.proto @@ -0,0 +1,183 @@ +syntax = "proto3"; +package cosmos.gov.v1beta1; + +import "cosmos/base/v1beta1/coin.proto"; +import "gogoproto/gogo.proto"; +import "cosmos_proto/cosmos.proto"; +import "google/protobuf/timestamp.proto"; +import "google/protobuf/any.proto"; +import "google/protobuf/duration.proto"; + +option go_package = "github.com/cosmos/cosmos-sdk/x/gov/types"; +option (gogoproto.goproto_stringer_all) = false; +option (gogoproto.stringer_all) = false; +option (gogoproto.goproto_getters_all) = false; + +// VoteOption enumerates the valid vote options for a given governance proposal. +enum VoteOption { + option (gogoproto.goproto_enum_prefix) = false; + + // VOTE_OPTION_UNSPECIFIED defines a no-op vote option. + VOTE_OPTION_UNSPECIFIED = 0 [(gogoproto.enumvalue_customname) = "OptionEmpty"]; + // VOTE_OPTION_YES defines a yes vote option. + VOTE_OPTION_YES = 1 [(gogoproto.enumvalue_customname) = "OptionYes"]; + // VOTE_OPTION_ABSTAIN defines an abstain vote option. + VOTE_OPTION_ABSTAIN = 2 [(gogoproto.enumvalue_customname) = "OptionAbstain"]; + // VOTE_OPTION_NO defines a no vote option. + VOTE_OPTION_NO = 3 [(gogoproto.enumvalue_customname) = "OptionNo"]; + // VOTE_OPTION_NO_WITH_VETO defines a no with veto vote option. + VOTE_OPTION_NO_WITH_VETO = 4 [(gogoproto.enumvalue_customname) = "OptionNoWithVeto"]; +} + +// TextProposal defines a standard text proposal whose changes need to be +// manually updated in case of approval. +message TextProposal { + option (cosmos_proto.implements_interface) = "Content"; + + option (gogoproto.equal) = true; + + string title = 1; + string description = 2; +} + +// Deposit defines an amount deposited by an account address to an active +// proposal. +message Deposit { + option (gogoproto.goproto_getters) = false; + option (gogoproto.equal) = false; + + uint64 proposal_id = 1 [(gogoproto.moretags) = "yaml:\"proposal_id\""]; + string depositor = 2; + repeated cosmos.base.v1beta1.Coin amount = 3 + [(gogoproto.nullable) = false, (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins"]; +} + +// Proposal defines the core field members of a governance proposal. +message Proposal { + option (gogoproto.equal) = true; + + uint64 proposal_id = 1 [(gogoproto.jsontag) = "id", (gogoproto.moretags) = "yaml:\"id\""]; + google.protobuf.Any content = 2 [(cosmos_proto.accepts_interface) = "Content"]; + ProposalStatus status = 3 [(gogoproto.moretags) = "yaml:\"proposal_status\""]; + TallyResult final_tally_result = 4 + [(gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"final_tally_result\""]; + google.protobuf.Timestamp submit_time = 5 + [(gogoproto.stdtime) = true, (gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"submit_time\""]; + google.protobuf.Timestamp deposit_end_time = 6 + [(gogoproto.stdtime) = true, (gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"deposit_end_time\""]; + repeated cosmos.base.v1beta1.Coin total_deposit = 7 [ + (gogoproto.nullable) = false, + (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins", + (gogoproto.moretags) = "yaml:\"total_deposit\"" + ]; + google.protobuf.Timestamp voting_start_time = 8 + [(gogoproto.stdtime) = true, (gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"voting_start_time\""]; + google.protobuf.Timestamp voting_end_time = 9 + [(gogoproto.stdtime) = true, (gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"voting_end_time\""]; +} + +// ProposalStatus enumerates the valid statuses of a proposal. +enum ProposalStatus { + option (gogoproto.goproto_enum_prefix) = false; + + // PROPOSAL_STATUS_UNSPECIFIED defines the default propopsal status. + PROPOSAL_STATUS_UNSPECIFIED = 0 [(gogoproto.enumvalue_customname) = "StatusNil"]; + // PROPOSAL_STATUS_DEPOSIT_PERIOD defines a proposal status during the deposit + // period. + PROPOSAL_STATUS_DEPOSIT_PERIOD = 1 [(gogoproto.enumvalue_customname) = "StatusDepositPeriod"]; + // PROPOSAL_STATUS_VOTING_PERIOD defines a proposal status during the voting + // period. + PROPOSAL_STATUS_VOTING_PERIOD = 2 [(gogoproto.enumvalue_customname) = "StatusVotingPeriod"]; + // PROPOSAL_STATUS_PASSED defines a proposal status of a proposal that has + // passed. + PROPOSAL_STATUS_PASSED = 3 [(gogoproto.enumvalue_customname) = "StatusPassed"]; + // PROPOSAL_STATUS_REJECTED defines a proposal status of a proposal that has + // been rejected. + PROPOSAL_STATUS_REJECTED = 4 [(gogoproto.enumvalue_customname) = "StatusRejected"]; + // PROPOSAL_STATUS_FAILED defines a proposal status of a proposal that has + // failed. + PROPOSAL_STATUS_FAILED = 5 [(gogoproto.enumvalue_customname) = "StatusFailed"]; +} + +// TallyResult defines a standard tally for a governance proposal. +message TallyResult { + option (gogoproto.equal) = true; + + string yes = 1 [(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int", (gogoproto.nullable) = false]; + string abstain = 2 [(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int", (gogoproto.nullable) = false]; + string no = 3 [(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int", (gogoproto.nullable) = false]; + string no_with_veto = 4 [ + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int", + (gogoproto.nullable) = false, + (gogoproto.moretags) = "yaml:\"no_with_veto\"" + ]; +} + +// Vote defines a vote on a governance proposal. +// A Vote consists of a proposal ID, the voter, and the vote option. +message Vote { + option (gogoproto.goproto_stringer) = false; + option (gogoproto.equal) = false; + + uint64 proposal_id = 1 [(gogoproto.moretags) = "yaml:\"proposal_id\""]; + string voter = 2; + VoteOption option = 3; +} + +// DepositParams defines the params for deposits on governance proposals. +message DepositParams { + // Minimum deposit for a proposal to enter voting period. + repeated cosmos.base.v1beta1.Coin min_deposit = 1 [ + (gogoproto.nullable) = false, + (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins", + (gogoproto.moretags) = "yaml:\"min_deposit\"", + (gogoproto.jsontag) = "min_deposit,omitempty" + ]; + + // Maximum period for Atom holders to deposit on a proposal. Initial value: 2 + // months. + google.protobuf.Duration max_deposit_period = 2 [ + (gogoproto.nullable) = false, + (gogoproto.stdduration) = true, + (gogoproto.jsontag) = "max_deposit_period,omitempty", + (gogoproto.moretags) = "yaml:\"max_deposit_period\"" + ]; +} + +// VotingParams defines the params for voting on governance proposals. +message VotingParams { + // Length of the voting period. + google.protobuf.Duration voting_period = 1 [ + (gogoproto.nullable) = false, + (gogoproto.stdduration) = true, + (gogoproto.jsontag) = "voting_period,omitempty", + (gogoproto.moretags) = "yaml:\"voting_period\"" + ]; +} + +// TallyParams defines the params for tallying votes on governance proposals. +message TallyParams { + // Minimum percentage of total stake needed to vote for a result to be + // considered valid. + bytes quorum = 1 [ + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", + (gogoproto.nullable) = false, + (gogoproto.jsontag) = "quorum,omitempty" + ]; + + // Minimum proportion of Yes votes for proposal to pass. Default value: 0.5. + bytes threshold = 2 [ + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", + (gogoproto.nullable) = false, + (gogoproto.jsontag) = "threshold,omitempty" + ]; + + // Minimum value of Veto votes to Total votes ratio for proposal to be + // vetoed. Default value: 1/3. + bytes veto_threshold = 3 [ + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", + (gogoproto.nullable) = false, + (gogoproto.jsontag) = "veto_threshold,omitempty", + (gogoproto.moretags) = "yaml:\"veto_threshold\"" + ]; +} diff --git a/third_party/proto/cosmos/gov/v1beta1/query.proto b/third_party/proto/cosmos/gov/v1beta1/query.proto new file mode 100644 index 0000000..da62bdb --- /dev/null +++ b/third_party/proto/cosmos/gov/v1beta1/query.proto @@ -0,0 +1,190 @@ +syntax = "proto3"; +package cosmos.gov.v1beta1; + +import "cosmos/base/query/v1beta1/pagination.proto"; +import "gogoproto/gogo.proto"; +import "google/api/annotations.proto"; +import "cosmos/gov/v1beta1/gov.proto"; + +option go_package = "github.com/cosmos/cosmos-sdk/x/gov/types"; + +// Query defines the gRPC querier service for gov module +service Query { + // Proposal queries proposal details based on ProposalID. + rpc Proposal(QueryProposalRequest) returns (QueryProposalResponse) { + option (google.api.http).get = "/cosmos/gov/v1beta1/proposals/{proposal_id}"; + } + + // Proposals queries all proposals based on given status. + rpc Proposals(QueryProposalsRequest) returns (QueryProposalsResponse) { + option (google.api.http).get = "/cosmos/gov/v1beta1/proposals"; + } + + // Vote queries voted information based on proposalID, voterAddr. + rpc Vote(QueryVoteRequest) returns (QueryVoteResponse) { + option (google.api.http).get = "/cosmos/gov/v1beta1/proposals/{proposal_id}/votes/{voter}"; + } + + // Votes queries votes of a given proposal. + rpc Votes(QueryVotesRequest) returns (QueryVotesResponse) { + option (google.api.http).get = "/cosmos/gov/v1beta1/proposals/{proposal_id}/votes"; + } + + // Params queries all parameters of the gov module. + rpc Params(QueryParamsRequest) returns (QueryParamsResponse) { + option (google.api.http).get = "/cosmos/gov/v1beta1/params/{params_type}"; + } + + // Deposit queries single deposit information based proposalID, depositAddr. + rpc Deposit(QueryDepositRequest) returns (QueryDepositResponse) { + option (google.api.http).get = "/cosmos/gov/v1beta1/proposals/{proposal_id}/deposits/{depositor}"; + } + + // Deposits queries all deposits of a single proposal. + rpc Deposits(QueryDepositsRequest) returns (QueryDepositsResponse) { + option (google.api.http).get = "/cosmos/gov/v1beta1/proposals/{proposal_id}/deposits"; + } + + // TallyResult queries the tally of a proposal vote. + rpc TallyResult(QueryTallyResultRequest) returns (QueryTallyResultResponse) { + option (google.api.http).get = "/cosmos/gov/v1beta1/proposals/{proposal_id}/tally"; + } +} + +// QueryProposalRequest is the request type for the Query/Proposal RPC method. +message QueryProposalRequest { + // proposal_id defines the unique id of the proposal. + uint64 proposal_id = 1; +} + +// QueryProposalResponse is the response type for the Query/Proposal RPC method. +message QueryProposalResponse { + Proposal proposal = 1 [(gogoproto.nullable) = false]; +} + +// QueryProposalsRequest is the request type for the Query/Proposals RPC method. +message QueryProposalsRequest { + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + + // proposal_status defines the status of the proposals. + ProposalStatus proposal_status = 1; + + // voter defines the voter address for the proposals. + string voter = 2; + + // depositor defines the deposit addresses from the proposals. + string depositor = 3; + + // pagination defines an optional pagination for the request. + cosmos.base.query.v1beta1.PageRequest pagination = 4; +} + +// QueryProposalsResponse is the response type for the Query/Proposals RPC +// method. +message QueryProposalsResponse { + repeated Proposal proposals = 1 [(gogoproto.nullable) = false]; + + // pagination defines the pagination in the response. + cosmos.base.query.v1beta1.PageResponse pagination = 2; +} + +// QueryVoteRequest is the request type for the Query/Vote RPC method. +message QueryVoteRequest { + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + + // proposal_id defines the unique id of the proposal. + uint64 proposal_id = 1; + + // voter defines the oter address for the proposals. + string voter = 2; +} + +// QueryVoteResponse is the response type for the Query/Vote RPC method. +message QueryVoteResponse { + // vote defined the queried vote. + Vote vote = 1 [(gogoproto.nullable) = false]; +} + +// QueryVotesRequest is the request type for the Query/Votes RPC method. +message QueryVotesRequest { + // proposal_id defines the unique id of the proposal. + uint64 proposal_id = 1; + + // pagination defines an optional pagination for the request. + cosmos.base.query.v1beta1.PageRequest pagination = 2; +} + +// QueryVotesResponse is the response type for the Query/Votes RPC method. +message QueryVotesResponse { + // votes defined the queried votes. + repeated Vote votes = 1 [(gogoproto.nullable) = false]; + + // pagination defines the pagination in the response. + cosmos.base.query.v1beta1.PageResponse pagination = 2; +} + +// QueryParamsRequest is the request type for the Query/Params RPC method. +message QueryParamsRequest { + // params_type defines which parameters to query for, can be one of "voting", + // "tallying" or "deposit". + string params_type = 1; +} + +// QueryParamsResponse is the response type for the Query/Params RPC method. +message QueryParamsResponse { + // voting_params defines the parameters related to voting. + VotingParams voting_params = 1 [(gogoproto.nullable) = false]; + // deposit_params defines the parameters related to deposit. + DepositParams deposit_params = 2 [(gogoproto.nullable) = false]; + // tally_params defines the parameters related to tally. + TallyParams tally_params = 3 [(gogoproto.nullable) = false]; +} + +// QueryDepositRequest is the request type for the Query/Deposit RPC method. +message QueryDepositRequest { + option (gogoproto.goproto_getters) = false; + option (gogoproto.equal) = false; + + // proposal_id defines the unique id of the proposal. + uint64 proposal_id = 1; + + // depositor defines the deposit addresses from the proposals. + string depositor = 2; +} + +// QueryDepositResponse is the response type for the Query/Deposit RPC method. +message QueryDepositResponse { + // deposit defines the requested deposit. + Deposit deposit = 1 [(gogoproto.nullable) = false]; +} + +// QueryDepositsRequest is the request type for the Query/Deposits RPC method. +message QueryDepositsRequest { + // proposal_id defines the unique id of the proposal. + uint64 proposal_id = 1; + + // pagination defines an optional pagination for the request. + cosmos.base.query.v1beta1.PageRequest pagination = 2; +} + +// QueryDepositsResponse is the response type for the Query/Deposits RPC method. +message QueryDepositsResponse { + repeated Deposit deposits = 1 [(gogoproto.nullable) = false]; + + // pagination defines the pagination in the response. + cosmos.base.query.v1beta1.PageResponse pagination = 2; +} + +// QueryTallyResultRequest is the request type for the Query/Tally RPC method. +message QueryTallyResultRequest { + // proposal_id defines the unique id of the proposal. + uint64 proposal_id = 1; +} + +// QueryTallyResultResponse is the response type for the Query/Tally RPC method. +message QueryTallyResultResponse { + // tally defines the requested tally. + TallyResult tally = 1 [(gogoproto.nullable) = false]; +} diff --git a/third_party/proto/cosmos/gov/v1beta1/tx.proto b/third_party/proto/cosmos/gov/v1beta1/tx.proto new file mode 100644 index 0000000..d4f0c1f --- /dev/null +++ b/third_party/proto/cosmos/gov/v1beta1/tx.proto @@ -0,0 +1,75 @@ +syntax = "proto3"; +package cosmos.gov.v1beta1; + +import "cosmos/base/v1beta1/coin.proto"; +import "cosmos/gov/v1beta1/gov.proto"; +import "cosmos_proto/cosmos.proto"; +import "gogoproto/gogo.proto"; +import "google/protobuf/any.proto"; + +option go_package = "github.com/cosmos/cosmos-sdk/x/gov/types"; + +// Msg defines the bank Msg service. +service Msg { + // SubmitProposal defines a method to create new proposal given a content. + rpc SubmitProposal(MsgSubmitProposal) returns (MsgSubmitProposalResponse); + + // Vote defines a method to add a vote on a specific proposal. + rpc Vote(MsgVote) returns (MsgVoteResponse); + + // Deposit defines a method to add deposit on a specific proposal. + rpc Deposit(MsgDeposit) returns (MsgDepositResponse); +} + +// MsgSubmitProposal defines an sdk.Msg type that supports submitting arbitrary +// proposal Content. +message MsgSubmitProposal { + option (gogoproto.equal) = false; + option (gogoproto.goproto_stringer) = false; + option (gogoproto.stringer) = false; + option (gogoproto.goproto_getters) = false; + + google.protobuf.Any content = 1 [(cosmos_proto.accepts_interface) = "Content"]; + repeated cosmos.base.v1beta1.Coin initial_deposit = 2 [ + (gogoproto.nullable) = false, + (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins", + (gogoproto.moretags) = "yaml:\"initial_deposit\"" + ]; + string proposer = 3; +} + +// MsgSubmitProposalResponse defines the Msg/SubmitProposal response type. +message MsgSubmitProposalResponse { + uint64 proposal_id = 1 [(gogoproto.jsontag) = "proposal_id", (gogoproto.moretags) = "yaml:\"proposal_id\""]; +} + +// MsgVote defines a message to cast a vote. +message MsgVote { + option (gogoproto.equal) = false; + option (gogoproto.goproto_stringer) = false; + option (gogoproto.stringer) = false; + option (gogoproto.goproto_getters) = false; + + uint64 proposal_id = 1 [(gogoproto.jsontag) = "proposal_id", (gogoproto.moretags) = "yaml:\"proposal_id\""]; + string voter = 2; + VoteOption option = 3; +} + +// MsgVoteResponse defines the Msg/Vote response type. +message MsgVoteResponse {} + +// MsgDeposit defines a message to submit a deposit to an existing proposal. +message MsgDeposit { + option (gogoproto.equal) = false; + option (gogoproto.goproto_stringer) = false; + option (gogoproto.stringer) = false; + option (gogoproto.goproto_getters) = false; + + uint64 proposal_id = 1 [(gogoproto.jsontag) = "proposal_id", (gogoproto.moretags) = "yaml:\"proposal_id\""]; + string depositor = 2; + repeated cosmos.base.v1beta1.Coin amount = 3 + [(gogoproto.nullable) = false, (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins"]; +} + +// MsgDepositResponse defines the Msg/Deposit response type. +message MsgDepositResponse {} diff --git a/third_party/proto/cosmos/mint/v1beta1/genesis.proto b/third_party/proto/cosmos/mint/v1beta1/genesis.proto new file mode 100644 index 0000000..4e783fb --- /dev/null +++ b/third_party/proto/cosmos/mint/v1beta1/genesis.proto @@ -0,0 +1,16 @@ +syntax = "proto3"; +package cosmos.mint.v1beta1; + +import "gogoproto/gogo.proto"; +import "cosmos/mint/v1beta1/mint.proto"; + +option go_package = "github.com/cosmos/cosmos-sdk/x/mint/types"; + +// GenesisState defines the mint module's genesis state. +message GenesisState { + // minter is a space for holding current inflation information. + Minter minter = 1 [(gogoproto.nullable) = false]; + + // params defines all the paramaters of the module. + Params params = 2 [(gogoproto.nullable) = false]; +} diff --git a/third_party/proto/cosmos/mint/v1beta1/mint.proto b/third_party/proto/cosmos/mint/v1beta1/mint.proto new file mode 100644 index 0000000..f94d4ae --- /dev/null +++ b/third_party/proto/cosmos/mint/v1beta1/mint.proto @@ -0,0 +1,53 @@ +syntax = "proto3"; +package cosmos.mint.v1beta1; + +option go_package = "github.com/cosmos/cosmos-sdk/x/mint/types"; + +import "gogoproto/gogo.proto"; + +// Minter represents the minting state. +message Minter { + // current annual inflation rate + string inflation = 1 + [(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", (gogoproto.nullable) = false]; + // current annual expected provisions + string annual_provisions = 2 [ + (gogoproto.moretags) = "yaml:\"annual_provisions\"", + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", + (gogoproto.nullable) = false + ]; +} + +// Params holds parameters for the mint module. +message Params { + option (gogoproto.goproto_stringer) = false; + + // type of coin to mint + string mint_denom = 1; + // maximum annual change in inflation rate + string inflation_rate_change = 2 [ + (gogoproto.moretags) = "yaml:\"inflation_rate_change\"", + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", + (gogoproto.nullable) = false + ]; + // maximum inflation rate + string inflation_max = 3 [ + (gogoproto.moretags) = "yaml:\"inflation_max\"", + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", + (gogoproto.nullable) = false + ]; + // minimum inflation rate + string inflation_min = 4 [ + (gogoproto.moretags) = "yaml:\"inflation_min\"", + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", + (gogoproto.nullable) = false + ]; + // goal of percent bonded atoms + string goal_bonded = 5 [ + (gogoproto.moretags) = "yaml:\"goal_bonded\"", + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", + (gogoproto.nullable) = false + ]; + // expected blocks per year + uint64 blocks_per_year = 6 [(gogoproto.moretags) = "yaml:\"blocks_per_year\""]; +} diff --git a/third_party/proto/cosmos/mint/v1beta1/query.proto b/third_party/proto/cosmos/mint/v1beta1/query.proto new file mode 100644 index 0000000..acd341d --- /dev/null +++ b/third_party/proto/cosmos/mint/v1beta1/query.proto @@ -0,0 +1,57 @@ +syntax = "proto3"; +package cosmos.mint.v1beta1; + +import "gogoproto/gogo.proto"; +import "google/api/annotations.proto"; +import "cosmos/mint/v1beta1/mint.proto"; + +option go_package = "github.com/cosmos/cosmos-sdk/x/mint/types"; + +// Query provides defines the gRPC querier service. +service Query { + // Params returns the total set of minting parameters. + rpc Params(QueryParamsRequest) returns (QueryParamsResponse) { + option (google.api.http).get = "/cosmos/mint/v1beta1/params"; + } + + // Inflation returns the current minting inflation value. + rpc Inflation(QueryInflationRequest) returns (QueryInflationResponse) { + option (google.api.http).get = "/cosmos/mint/v1beta1/inflation"; + } + + // AnnualProvisions current minting annual provisions value. + rpc AnnualProvisions(QueryAnnualProvisionsRequest) returns (QueryAnnualProvisionsResponse) { + option (google.api.http).get = "/cosmos/mint/v1beta1/annual_provisions"; + } +} + +// QueryParamsRequest is the request type for the Query/Params RPC method. +message QueryParamsRequest {} + +// QueryParamsResponse is the response type for the Query/Params RPC method. +message QueryParamsResponse { + // params defines the parameters of the module. + Params params = 1 [(gogoproto.nullable) = false]; +} + +// QueryInflationRequest is the request type for the Query/Inflation RPC method. +message QueryInflationRequest {} + +// QueryInflationResponse is the response type for the Query/Inflation RPC +// method. +message QueryInflationResponse { + // inflation is the current minting inflation value. + bytes inflation = 1 [(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", (gogoproto.nullable) = false]; +} + +// QueryAnnualProvisionsRequest is the request type for the +// Query/AnnualProvisions RPC method. +message QueryAnnualProvisionsRequest {} + +// QueryAnnualProvisionsResponse is the response type for the +// Query/AnnualProvisions RPC method. +message QueryAnnualProvisionsResponse { + // annual_provisions is the current minting annual provisions value. + bytes annual_provisions = 1 + [(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", (gogoproto.nullable) = false]; +} diff --git a/third_party/proto/cosmos/params/v1beta1/params.proto b/third_party/proto/cosmos/params/v1beta1/params.proto new file mode 100644 index 0000000..5382fd7 --- /dev/null +++ b/third_party/proto/cosmos/params/v1beta1/params.proto @@ -0,0 +1,27 @@ +syntax = "proto3"; +package cosmos.params.v1beta1; + +option go_package = "github.com/cosmos/cosmos-sdk/x/params/types/proposal"; +option (gogoproto.equal_all) = true; + +import "gogoproto/gogo.proto"; + +// ParameterChangeProposal defines a proposal to change one or more parameters. +message ParameterChangeProposal { + option (gogoproto.goproto_getters) = false; + option (gogoproto.goproto_stringer) = false; + + string title = 1; + string description = 2; + repeated ParamChange changes = 3 [(gogoproto.nullable) = false]; +} + +// ParamChange defines an individual parameter change, for use in +// ParameterChangeProposal. +message ParamChange { + option (gogoproto.goproto_stringer) = false; + + string subspace = 1; + string key = 2; + string value = 3; +} diff --git a/third_party/proto/cosmos/params/v1beta1/query.proto b/third_party/proto/cosmos/params/v1beta1/query.proto new file mode 100644 index 0000000..1078e02 --- /dev/null +++ b/third_party/proto/cosmos/params/v1beta1/query.proto @@ -0,0 +1,32 @@ +syntax = "proto3"; +package cosmos.params.v1beta1; + +import "gogoproto/gogo.proto"; +import "google/api/annotations.proto"; +import "cosmos/params/v1beta1/params.proto"; + +option go_package = "github.com/cosmos/cosmos-sdk/x/params/types/proposal"; + +// Query defines the gRPC querier service. +service Query { + // Params queries a specific parameter of a module, given its subspace and + // key. + rpc Params(QueryParamsRequest) returns (QueryParamsResponse) { + option (google.api.http).get = "/cosmos/params/v1beta1/params"; + } +} + +// QueryParamsRequest is request type for the Query/Params RPC method. +message QueryParamsRequest { + // subspace defines the module to query the parameter for. + string subspace = 1; + + // key defines the key of the parameter in the subspace. + string key = 2; +} + +// QueryParamsResponse is response type for the Query/Params RPC method. +message QueryParamsResponse { + // param defines the queried parameter. + ParamChange param = 1 [(gogoproto.nullable) = false]; +} diff --git a/third_party/proto/cosmos/slashing/v1beta1/genesis.proto b/third_party/proto/cosmos/slashing/v1beta1/genesis.proto new file mode 100644 index 0000000..c813561 --- /dev/null +++ b/third_party/proto/cosmos/slashing/v1beta1/genesis.proto @@ -0,0 +1,50 @@ +syntax = "proto3"; +package cosmos.slashing.v1beta1; + +option go_package = "github.com/cosmos/cosmos-sdk/x/slashing/types"; + +import "gogoproto/gogo.proto"; +import "cosmos/slashing/v1beta1/slashing.proto"; + +// GenesisState defines the slashing module's genesis state. +message GenesisState { + // params defines all the paramaters of related to deposit. + Params params = 1 [(gogoproto.nullable) = false]; + + // signing_infos represents a map between validator addresses and their + // signing infos. + repeated SigningInfo signing_infos = 2 + [(gogoproto.moretags) = "yaml:\"signing_infos\"", (gogoproto.nullable) = false]; + + // signing_infos represents a map between validator addresses and their + // missed blocks. + repeated ValidatorMissedBlocks missed_blocks = 3 + [(gogoproto.moretags) = "yaml:\"missed_blocks\"", (gogoproto.nullable) = false]; +} + +// SigningInfo stores validator signing info of corresponding address. +message SigningInfo { + // address is the validator address. + string address = 1; + // validator_signing_info represents the signing info of this validator. + ValidatorSigningInfo validator_signing_info = 2 + [(gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"validator_signing_info\""]; +} + +// ValidatorMissedBlocks contains array of missed blocks of corresponding +// address. +message ValidatorMissedBlocks { + // address is the validator address. + string address = 1; + // missed_blocks is an array of missed blocks by the validator. + repeated MissedBlock missed_blocks = 2 + [(gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"missed_blocks\""]; +} + +// MissedBlock contains height and missed status as boolean. +message MissedBlock { + // index is the height at which the block was missed. + int64 index = 1; + // missed is the missed status. + bool missed = 2; +} diff --git a/third_party/proto/cosmos/slashing/v1beta1/query.proto b/third_party/proto/cosmos/slashing/v1beta1/query.proto new file mode 100644 index 0000000..869049a --- /dev/null +++ b/third_party/proto/cosmos/slashing/v1beta1/query.proto @@ -0,0 +1,63 @@ +syntax = "proto3"; +package cosmos.slashing.v1beta1; + +import "cosmos/base/query/v1beta1/pagination.proto"; +import "gogoproto/gogo.proto"; +import "google/api/annotations.proto"; +import "cosmos/slashing/v1beta1/slashing.proto"; + +option go_package = "github.com/cosmos/cosmos-sdk/x/slashing/types"; + +// Query provides defines the gRPC querier service +service Query { + // Params queries the parameters of slashing module + rpc Params(QueryParamsRequest) returns (QueryParamsResponse) { + option (google.api.http).get = "/cosmos/slashing/v1beta1/params"; + } + + // SigningInfo queries the signing info of given cons address + rpc SigningInfo(QuerySigningInfoRequest) returns (QuerySigningInfoResponse) { + option (google.api.http).get = "/cosmos/slashing/v1beta1/signing_infos/{cons_address}"; + } + + // SigningInfos queries signing info of all validators + rpc SigningInfos(QuerySigningInfosRequest) returns (QuerySigningInfosResponse) { + option (google.api.http).get = "/cosmos/slashing/v1beta1/signing_infos"; + } +} + +// QueryParamsRequest is the request type for the Query/Params RPC method +message QueryParamsRequest {} + +// QueryParamsResponse is the response type for the Query/Params RPC method +message QueryParamsResponse { + Params params = 1 [(gogoproto.nullable) = false]; +} + +// QuerySigningInfoRequest is the request type for the Query/SigningInfo RPC +// method +message QuerySigningInfoRequest { + // cons_address is the address to query signing info of + string cons_address = 1; +} + +// QuerySigningInfoResponse is the response type for the Query/SigningInfo RPC +// method +message QuerySigningInfoResponse { + // val_signing_info is the signing info of requested val cons address + ValidatorSigningInfo val_signing_info = 1 [(gogoproto.nullable) = false]; +} + +// QuerySigningInfosRequest is the request type for the Query/SigningInfos RPC +// method +message QuerySigningInfosRequest { + cosmos.base.query.v1beta1.PageRequest pagination = 1; +} + +// QuerySigningInfosResponse is the response type for the Query/SigningInfos RPC +// method +message QuerySigningInfosResponse { + // info is the signing info of all validators + repeated cosmos.slashing.v1beta1.ValidatorSigningInfo info = 1 [(gogoproto.nullable) = false]; + cosmos.base.query.v1beta1.PageResponse pagination = 2; +} diff --git a/third_party/proto/cosmos/slashing/v1beta1/slashing.proto b/third_party/proto/cosmos/slashing/v1beta1/slashing.proto new file mode 100644 index 0000000..657a90f --- /dev/null +++ b/third_party/proto/cosmos/slashing/v1beta1/slashing.proto @@ -0,0 +1,55 @@ +syntax = "proto3"; +package cosmos.slashing.v1beta1; + +option go_package = "github.com/cosmos/cosmos-sdk/x/slashing/types"; +option (gogoproto.equal_all) = true; + +import "gogoproto/gogo.proto"; +import "google/protobuf/duration.proto"; +import "google/protobuf/timestamp.proto"; + +// ValidatorSigningInfo defines a validator's signing info for monitoring their +// liveness activity. +message ValidatorSigningInfo { + option (gogoproto.equal) = true; + option (gogoproto.goproto_stringer) = false; + + string address = 1; + // height at which validator was first a candidate OR was unjailed + int64 start_height = 2 [(gogoproto.moretags) = "yaml:\"start_height\""]; + // index offset into signed block bit array + int64 index_offset = 3 [(gogoproto.moretags) = "yaml:\"index_offset\""]; + // timestamp validator cannot be unjailed until + google.protobuf.Timestamp jailed_until = 4 + [(gogoproto.moretags) = "yaml:\"jailed_until\"", (gogoproto.stdtime) = true, (gogoproto.nullable) = false]; + // whether or not a validator has been tombstoned (killed out of validator + // set) + bool tombstoned = 5; + // missed blocks counter (to avoid scanning the array every time) + int64 missed_blocks_counter = 6 [(gogoproto.moretags) = "yaml:\"missed_blocks_counter\""]; +} + +// Params represents the parameters used for by the slashing module. +message Params { + int64 signed_blocks_window = 1 [(gogoproto.moretags) = "yaml:\"signed_blocks_window\""]; + bytes min_signed_per_window = 2 [ + (gogoproto.moretags) = "yaml:\"min_signed_per_window\"", + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", + (gogoproto.nullable) = false + ]; + google.protobuf.Duration downtime_jail_duration = 3 [ + (gogoproto.nullable) = false, + (gogoproto.stdduration) = true, + (gogoproto.moretags) = "yaml:\"downtime_jail_duration\"" + ]; + bytes slash_fraction_double_sign = 4 [ + (gogoproto.moretags) = "yaml:\"slash_fraction_double_sign\"", + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", + (gogoproto.nullable) = false + ]; + bytes slash_fraction_downtime = 5 [ + (gogoproto.moretags) = "yaml:\"slash_fraction_downtime\"", + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", + (gogoproto.nullable) = false + ]; +} diff --git a/third_party/proto/cosmos/slashing/v1beta1/tx.proto b/third_party/proto/cosmos/slashing/v1beta1/tx.proto new file mode 100644 index 0000000..4d63370 --- /dev/null +++ b/third_party/proto/cosmos/slashing/v1beta1/tx.proto @@ -0,0 +1,26 @@ +syntax = "proto3"; +package cosmos.slashing.v1beta1; + +option go_package = "github.com/cosmos/cosmos-sdk/x/slashing/types"; +option (gogoproto.equal_all) = true; + +import "gogoproto/gogo.proto"; + +// Msg defines the slashing Msg service. +service Msg { + // Unjail defines a method for unjailing a jailed validator, thus returning + // them into the bonded validator set, so they can begin receiving provisions + // and rewards again. + rpc Unjail(MsgUnjail) returns (MsgUnjailResponse); +} + +// MsgUnjail defines the Msg/Unjail request type +message MsgUnjail { + option (gogoproto.goproto_getters) = false; + option (gogoproto.goproto_stringer) = true; + + string validator_addr = 1 [(gogoproto.moretags) = "yaml:\"address\"", (gogoproto.jsontag) = "address"]; +} + +// MsgUnjailResponse defines the Msg/Unjail response type +message MsgUnjailResponse {} \ No newline at end of file diff --git a/third_party/proto/cosmos/staking/v1beta1/genesis.proto b/third_party/proto/cosmos/staking/v1beta1/genesis.proto new file mode 100644 index 0000000..d1563db --- /dev/null +++ b/third_party/proto/cosmos/staking/v1beta1/genesis.proto @@ -0,0 +1,53 @@ +syntax = "proto3"; +package cosmos.staking.v1beta1; + +option go_package = "github.com/cosmos/cosmos-sdk/x/staking/types"; + +import "gogoproto/gogo.proto"; +import "cosmos/staking/v1beta1/staking.proto"; + +// GenesisState defines the staking module's genesis state. +message GenesisState { + // params defines all the paramaters of related to deposit. + Params params = 1 [(gogoproto.nullable) = false]; + + // last_total_power tracks the total amounts of bonded tokens recorded during + // the previous end block. + bytes last_total_power = 2 [ + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int", + (gogoproto.moretags) = "yaml:\"last_total_power\"", + (gogoproto.nullable) = false + ]; + + // last_validator_powers is a special index that provides a historical list + // of the last-block's bonded validators. + repeated LastValidatorPower last_validator_powers = 3 + [(gogoproto.moretags) = "yaml:\"last_validator_powers\"", (gogoproto.nullable) = false]; + + // delegations defines the validator set at genesis. + repeated Validator validators = 4 [(gogoproto.nullable) = false]; + + // delegations defines the delegations active at genesis. + repeated Delegation delegations = 5 [(gogoproto.nullable) = false]; + + // unbonding_delegations defines the unbonding delegations active at genesis. + repeated UnbondingDelegation unbonding_delegations = 6 + [(gogoproto.moretags) = "yaml:\"unbonding_delegations\"", (gogoproto.nullable) = false]; + + // redelegations defines the redelegations active at genesis. + repeated Redelegation redelegations = 7 [(gogoproto.nullable) = false]; + + bool exported = 8; +} + +// LastValidatorPower required for validator set update logic. +message LastValidatorPower { + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + + // address is the address of the validator. + string address = 1; + + // power defines the power of the validator. + int64 power = 2; +} diff --git a/third_party/proto/cosmos/staking/v1beta1/query.proto b/third_party/proto/cosmos/staking/v1beta1/query.proto new file mode 100644 index 0000000..4852c53 --- /dev/null +++ b/third_party/proto/cosmos/staking/v1beta1/query.proto @@ -0,0 +1,348 @@ +syntax = "proto3"; +package cosmos.staking.v1beta1; + +import "cosmos/base/query/v1beta1/pagination.proto"; +import "gogoproto/gogo.proto"; +import "google/api/annotations.proto"; +import "cosmos/staking/v1beta1/staking.proto"; + +option go_package = "github.com/cosmos/cosmos-sdk/x/staking/types"; + +// Query defines the gRPC querier service. +service Query { + // Validators queries all validators that match the given status. + rpc Validators(QueryValidatorsRequest) returns (QueryValidatorsResponse) { + option (google.api.http).get = "/cosmos/staking/v1beta1/validators"; + } + + // Validator queries validator info for given validator address. + rpc Validator(QueryValidatorRequest) returns (QueryValidatorResponse) { + option (google.api.http).get = "/cosmos/staking/v1beta1/validators/{validator_addr}"; + } + + // ValidatorDelegations queries delegate info for given validator. + rpc ValidatorDelegations(QueryValidatorDelegationsRequest) returns (QueryValidatorDelegationsResponse) { + option (google.api.http).get = "/cosmos/staking/v1beta1/validators/{validator_addr}/delegations"; + } + + // ValidatorUnbondingDelegations queries unbonding delegations of a validator. + rpc ValidatorUnbondingDelegations(QueryValidatorUnbondingDelegationsRequest) + returns (QueryValidatorUnbondingDelegationsResponse) { + option (google.api.http).get = "/cosmos/staking/v1beta1/validators/" + "{validator_addr}/unbonding_delegations"; + } + + // Delegation queries delegate info for given validator delegator pair. + rpc Delegation(QueryDelegationRequest) returns (QueryDelegationResponse) { + option (google.api.http).get = "/cosmos/staking/v1beta1/validators/{validator_addr}/delegations/" + "{delegator_addr}"; + } + + // UnbondingDelegation queries unbonding info for given validator delegator + // pair. + rpc UnbondingDelegation(QueryUnbondingDelegationRequest) returns (QueryUnbondingDelegationResponse) { + option (google.api.http).get = "/cosmos/staking/v1beta1/validators/{validator_addr}/delegations/" + "{delegator_addr}/unbonding_delegation"; + } + + // DelegatorDelegations queries all delegations of a given delegator address. + rpc DelegatorDelegations(QueryDelegatorDelegationsRequest) returns (QueryDelegatorDelegationsResponse) { + option (google.api.http).get = "/cosmos/staking/v1beta1/delegations/{delegator_addr}"; + } + + // DelegatorUnbondingDelegations queries all unbonding delegations of a given + // delegator address. + rpc DelegatorUnbondingDelegations(QueryDelegatorUnbondingDelegationsRequest) + returns (QueryDelegatorUnbondingDelegationsResponse) { + option (google.api.http).get = "/cosmos/staking/v1beta1/delegators/" + "{delegator_addr}/unbonding_delegations"; + } + + // Redelegations queries redelegations of given address. + rpc Redelegations(QueryRedelegationsRequest) returns (QueryRedelegationsResponse) { + option (google.api.http).get = "/cosmos/staking/v1beta1/delegators/{delegator_addr}/redelegations"; + } + + // DelegatorValidators queries all validators info for given delegator + // address. + rpc DelegatorValidators(QueryDelegatorValidatorsRequest) returns (QueryDelegatorValidatorsResponse) { + option (google.api.http).get = "/cosmos/staking/v1beta1/delegators/{delegator_addr}/validators"; + } + + // DelegatorValidator queries validator info for given delegator validator + // pair. + rpc DelegatorValidator(QueryDelegatorValidatorRequest) returns (QueryDelegatorValidatorResponse) { + option (google.api.http).get = "/cosmos/staking/v1beta1/delegators/{delegator_addr}/validators/" + "{validator_addr}"; + } + + // HistoricalInfo queries the historical info for given height. + rpc HistoricalInfo(QueryHistoricalInfoRequest) returns (QueryHistoricalInfoResponse) { + option (google.api.http).get = "/cosmos/staking/v1beta1/historical_info/{height}"; + } + + // Pool queries the pool info. + rpc Pool(QueryPoolRequest) returns (QueryPoolResponse) { + option (google.api.http).get = "/cosmos/staking/v1beta1/pool"; + } + + // Parameters queries the staking parameters. + rpc Params(QueryParamsRequest) returns (QueryParamsResponse) { + option (google.api.http).get = "/cosmos/staking/v1beta1/params"; + } +} + +// QueryValidatorsRequest is request type for Query/Validators RPC method. +message QueryValidatorsRequest { + // status enables to query for validators matching a given status. + string status = 1; + + // pagination defines an optional pagination for the request. + cosmos.base.query.v1beta1.PageRequest pagination = 2; +} + +// QueryValidatorsResponse is response type for the Query/Validators RPC method +message QueryValidatorsResponse { + // validators contains all the queried validators. + repeated Validator validators = 1 [(gogoproto.nullable) = false]; + + // pagination defines the pagination in the response. + cosmos.base.query.v1beta1.PageResponse pagination = 2; +} + +// QueryValidatorRequest is response type for the Query/Validator RPC method +message QueryValidatorRequest { + // validator_addr defines the validator address to query for. + string validator_addr = 1; +} + +// QueryValidatorResponse is response type for the Query/Validator RPC method +message QueryValidatorResponse { + // validator defines the the validator info. + Validator validator = 1 [(gogoproto.nullable) = false]; +} + +// QueryValidatorDelegationsRequest is request type for the +// Query/ValidatorDelegations RPC method +message QueryValidatorDelegationsRequest { + // validator_addr defines the validator address to query for. + string validator_addr = 1; + + // pagination defines an optional pagination for the request. + cosmos.base.query.v1beta1.PageRequest pagination = 2; +} + +// QueryValidatorDelegationsResponse is response type for the +// Query/ValidatorDelegations RPC method +message QueryValidatorDelegationsResponse { + repeated DelegationResponse delegation_responses = 1 + [(gogoproto.nullable) = false, (gogoproto.castrepeated) = "DelegationResponses"]; + + // pagination defines the pagination in the response. + cosmos.base.query.v1beta1.PageResponse pagination = 2; +} + +// QueryValidatorUnbondingDelegationsRequest is required type for the +// Query/ValidatorUnbondingDelegations RPC method +message QueryValidatorUnbondingDelegationsRequest { + // validator_addr defines the validator address to query for. + string validator_addr = 1; + + // pagination defines an optional pagination for the request. + cosmos.base.query.v1beta1.PageRequest pagination = 2; +} + +// QueryValidatorUnbondingDelegationsResponse is response type for the +// Query/ValidatorUnbondingDelegations RPC method. +message QueryValidatorUnbondingDelegationsResponse { + repeated UnbondingDelegation unbonding_responses = 1 [(gogoproto.nullable) = false]; + + // pagination defines the pagination in the response. + cosmos.base.query.v1beta1.PageResponse pagination = 2; +} + +// QueryDelegationRequest is request type for the Query/Delegation RPC method. +message QueryDelegationRequest { + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + + // delegator_addr defines the delegator address to query for. + string delegator_addr = 1; + + // validator_addr defines the validator address to query for. + string validator_addr = 2; +} + +// QueryDelegationResponse is response type for the Query/Delegation RPC method. +message QueryDelegationResponse { + // delegation_responses defines the delegation info of a delegation. + DelegationResponse delegation_response = 1; +} + +// QueryUnbondingDelegationRequest is request type for the +// Query/UnbondingDelegation RPC method. +message QueryUnbondingDelegationRequest { + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + + // delegator_addr defines the delegator address to query for. + string delegator_addr = 1; + + // validator_addr defines the validator address to query for. + string validator_addr = 2; +} + +// QueryDelegationResponse is response type for the Query/UnbondingDelegation +// RPC method. +message QueryUnbondingDelegationResponse { + // unbond defines the unbonding information of a delegation. + UnbondingDelegation unbond = 1 [(gogoproto.nullable) = false]; +} + +// QueryDelegatorDelegationsRequest is request type for the +// Query/DelegatorDelegations RPC method. +message QueryDelegatorDelegationsRequest { + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + + // delegator_addr defines the delegator address to query for. + string delegator_addr = 1; + + // pagination defines an optional pagination for the request. + cosmos.base.query.v1beta1.PageRequest pagination = 2; +} + +// QueryDelegatorDelegationsResponse is response type for the +// Query/DelegatorDelegations RPC method. +message QueryDelegatorDelegationsResponse { + // delegation_responses defines all the delegations' info of a delegator. + repeated DelegationResponse delegation_responses = 1 [(gogoproto.nullable) = false]; + + // pagination defines the pagination in the response. + cosmos.base.query.v1beta1.PageResponse pagination = 2; +} + +// QueryDelegatorUnbondingDelegationsRequest is request type for the +// Query/DelegatorUnbondingDelegations RPC method. +message QueryDelegatorUnbondingDelegationsRequest { + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + + // delegator_addr defines the delegator address to query for. + string delegator_addr = 1; + + // pagination defines an optional pagination for the request. + cosmos.base.query.v1beta1.PageRequest pagination = 2; +} + +// QueryUnbondingDelegatorDelegationsResponse is response type for the +// Query/UnbondingDelegatorDelegations RPC method. +message QueryDelegatorUnbondingDelegationsResponse { + repeated UnbondingDelegation unbonding_responses = 1 [(gogoproto.nullable) = false]; + + // pagination defines the pagination in the response. + cosmos.base.query.v1beta1.PageResponse pagination = 2; +} + +// QueryRedelegationsRequest is request type for the Query/Redelegations RPC +// method. +message QueryRedelegationsRequest { + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + + // delegator_addr defines the delegator address to query for. + string delegator_addr = 1; + + // src_validator_addr defines the validator address to redelegate from. + string src_validator_addr = 2; + + // dst_validator_addr defines the validator address to redelegate to. + string dst_validator_addr = 3; + + // pagination defines an optional pagination for the request. + cosmos.base.query.v1beta1.PageRequest pagination = 4; +} + +// QueryRedelegationsResponse is response type for the Query/Redelegations RPC +// method. +message QueryRedelegationsResponse { + repeated RedelegationResponse redelegation_responses = 1 [(gogoproto.nullable) = false]; + + // pagination defines the pagination in the response. + cosmos.base.query.v1beta1.PageResponse pagination = 2; +} + +// QueryDelegatorValidatorsRequest is request type for the +// Query/DelegatorValidators RPC method. +message QueryDelegatorValidatorsRequest { + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + + // delegator_addr defines the delegator address to query for. + string delegator_addr = 1; + + // pagination defines an optional pagination for the request. + cosmos.base.query.v1beta1.PageRequest pagination = 2; +} + +// QueryDelegatorValidatorsResponse is response type for the +// Query/DelegatorValidators RPC method. +message QueryDelegatorValidatorsResponse { + // validators defines the the validators' info of a delegator. + repeated Validator validators = 1 [(gogoproto.nullable) = false]; + + // pagination defines the pagination in the response. + cosmos.base.query.v1beta1.PageResponse pagination = 2; +} + +// QueryDelegatorValidatorRequest is request type for the +// Query/DelegatorValidator RPC method. +message QueryDelegatorValidatorRequest { + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + + // delegator_addr defines the delegator address to query for. + string delegator_addr = 1; + + // validator_addr defines the validator address to query for. + string validator_addr = 2; +} + +// QueryDelegatorValidatorResponse response type for the +// Query/DelegatorValidator RPC method. +message QueryDelegatorValidatorResponse { + // validator defines the the validator info. + Validator validator = 1 [(gogoproto.nullable) = false]; +} + +// QueryHistoricalInfoRequest is request type for the Query/HistoricalInfo RPC +// method. +message QueryHistoricalInfoRequest { + // height defines at which height to query the historical info. + int64 height = 1; +} + +// QueryHistoricalInfoResponse is response type for the Query/HistoricalInfo RPC +// method. +message QueryHistoricalInfoResponse { + // hist defines the historical info at the given height. + HistoricalInfo hist = 1; +} + +// QueryPoolRequest is request type for the Query/Pool RPC method. +message QueryPoolRequest {} + +// QueryPoolResponse is response type for the Query/Pool RPC method. +message QueryPoolResponse { + // pool defines the pool info. + Pool pool = 1 [(gogoproto.nullable) = false]; +} + +// QueryParamsRequest is request type for the Query/Params RPC method. +message QueryParamsRequest {} + +// QueryParamsResponse is response type for the Query/Params RPC method. +message QueryParamsResponse { + // params holds all the parameters of this module. + Params params = 1 [(gogoproto.nullable) = false]; +} diff --git a/third_party/proto/cosmos/staking/v1beta1/staking.proto b/third_party/proto/cosmos/staking/v1beta1/staking.proto new file mode 100644 index 0000000..e37b28b --- /dev/null +++ b/third_party/proto/cosmos/staking/v1beta1/staking.proto @@ -0,0 +1,334 @@ +syntax = "proto3"; +package cosmos.staking.v1beta1; + +import "gogoproto/gogo.proto"; +import "google/protobuf/any.proto"; +import "google/protobuf/duration.proto"; +import "google/protobuf/timestamp.proto"; + +import "cosmos_proto/cosmos.proto"; +import "cosmos/base/v1beta1/coin.proto"; +import "tendermint/types/types.proto"; + +option go_package = "github.com/cosmos/cosmos-sdk/x/staking/types"; + +// HistoricalInfo contains header and validator information for a given block. +// It is stored as part of staking module's state, which persists the `n` most +// recent HistoricalInfo +// (`n` is set by the staking module's `historical_entries` parameter). +message HistoricalInfo { + tendermint.types.Header header = 1 [(gogoproto.nullable) = false]; + repeated Validator valset = 2 [(gogoproto.nullable) = false]; +} + +// CommissionRates defines the initial commission rates to be used for creating +// a validator. +message CommissionRates { + option (gogoproto.equal) = true; + option (gogoproto.goproto_stringer) = false; + + // rate is the commission rate charged to delegators, as a fraction. + string rate = 1 [(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", (gogoproto.nullable) = false]; + // max_rate defines the maximum commission rate which validator can ever charge, as a fraction. + string max_rate = 2 [ + (gogoproto.moretags) = "yaml:\"max_rate\"", + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", + (gogoproto.nullable) = false + ]; + // max_change_rate defines the maximum daily increase of the validator commission, as a fraction. + string max_change_rate = 3 [ + (gogoproto.moretags) = "yaml:\"max_change_rate\"", + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", + (gogoproto.nullable) = false + ]; +} + +// Commission defines commission parameters for a given validator. +message Commission { + option (gogoproto.equal) = true; + option (gogoproto.goproto_stringer) = false; + + // commission_rates defines the initial commission rates to be used for creating a validator. + CommissionRates commission_rates = 1 [(gogoproto.embed) = true, (gogoproto.nullable) = false]; + // update_time is the last time the commission rate was changed. + google.protobuf.Timestamp update_time = 2 + [(gogoproto.nullable) = false, (gogoproto.stdtime) = true, (gogoproto.moretags) = "yaml:\"update_time\""]; +} + +// Description defines a validator description. +message Description { + option (gogoproto.equal) = true; + option (gogoproto.goproto_stringer) = false; + + // moniker defines a human-readable name for the validator. + string moniker = 1; + // identity defines an optional identity signature (ex. UPort or Keybase). + string identity = 2; + // website defines an optional website link. + string website = 3; + // security_contact defines an optional email for security contact. + string security_contact = 4 [(gogoproto.moretags) = "yaml:\"security_contact\""]; + // details define other optional details. + string details = 5; +} + +// Validator defines a validator, together with the total amount of the +// Validator's bond shares and their exchange rate to coins. Slashing results in +// a decrease in the exchange rate, allowing correct calculation of future +// undelegations without iterating over delegators. When coins are delegated to +// this validator, the validator is credited with a delegation whose number of +// bond shares is based on the amount of coins delegated divided by the current +// exchange rate. Voting power can be calculated as total bonded shares +// multiplied by exchange rate. +message Validator { + option (gogoproto.equal) = false; + option (gogoproto.goproto_stringer) = false; + option (gogoproto.goproto_getters) = false; + + // operator_address defines the address of the validator's operator; bech encoded in JSON. + string operator_address = 1 [(gogoproto.moretags) = "yaml:\"operator_address\""]; + // consensus_pubkey is the consensus public key of the validator, as a Protobuf Any. + google.protobuf.Any consensus_pubkey = 2 + [(cosmos_proto.accepts_interface) = "cosmos.crypto.PubKey", (gogoproto.moretags) = "yaml:\"consensus_pubkey\""]; + // jailed defined whether the validator has been jailed from bonded status or not. + bool jailed = 3; + // status is the validator status (bonded/unbonding/unbonded). + BondStatus status = 4; + // tokens define the delegated tokens (incl. self-delegation). + string tokens = 5 [(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int", (gogoproto.nullable) = false]; + // delegator_shares defines total shares issued to a validator's delegators. + string delegator_shares = 6 [ + (gogoproto.moretags) = "yaml:\"delegator_shares\"", + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", + (gogoproto.nullable) = false + ]; + // description defines the description terms for the validator. + Description description = 7 [(gogoproto.nullable) = false]; + // unbonding_height defines, if unbonding, the height at which this validator has begun unbonding. + int64 unbonding_height = 8 [(gogoproto.moretags) = "yaml:\"unbonding_height\""]; + // unbonding_time defines, if unbonding, the min time for the validator to complete unbonding. + google.protobuf.Timestamp unbonding_time = 9 + [(gogoproto.nullable) = false, (gogoproto.stdtime) = true, (gogoproto.moretags) = "yaml:\"unbonding_time\""]; + // commission defines the commission parameters. + Commission commission = 10 [(gogoproto.nullable) = false]; + // min_self_delegation is the validator's self declared minimum self delegation. + string min_self_delegation = 11 [ + (gogoproto.moretags) = "yaml:\"min_self_delegation\"", + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int", + (gogoproto.nullable) = false + ]; +} + +// BondStatus is the status of a validator. +enum BondStatus { + option (gogoproto.goproto_enum_prefix) = false; + + // UNSPECIFIED defines an invalid validator status. + BOND_STATUS_UNSPECIFIED = 0 [(gogoproto.enumvalue_customname) = "Unspecified"]; + // UNBONDED defines a validator that is not bonded. + BOND_STATUS_UNBONDED = 1 [(gogoproto.enumvalue_customname) = "Unbonded"]; + // UNBONDING defines a validator that is unbonding. + BOND_STATUS_UNBONDING = 2 [(gogoproto.enumvalue_customname) = "Unbonding"]; + // BONDED defines a validator that is bonded. + BOND_STATUS_BONDED = 3 [(gogoproto.enumvalue_customname) = "Bonded"]; +} + +// ValAddresses defines a repeated set of validator addresses. +message ValAddresses { + option (gogoproto.goproto_stringer) = false; + option (gogoproto.stringer) = true; + + repeated string addresses = 1; +} + +// DVPair is struct that just has a delegator-validator pair with no other data. +// It is intended to be used as a marshalable pointer. For example, a DVPair can +// be used to construct the key to getting an UnbondingDelegation from state. +message DVPair { + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + option (gogoproto.goproto_stringer) = false; + + string delegator_address = 1 [(gogoproto.moretags) = "yaml:\"delegator_address\""]; + string validator_address = 2 [(gogoproto.moretags) = "yaml:\"validator_address\""]; +} + +// DVPairs defines an array of DVPair objects. +message DVPairs { + repeated DVPair pairs = 1 [(gogoproto.nullable) = false]; +} + +// DVVTriplet is struct that just has a delegator-validator-validator triplet +// with no other data. It is intended to be used as a marshalable pointer. For +// example, a DVVTriplet can be used to construct the key to getting a +// Redelegation from state. +message DVVTriplet { + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + option (gogoproto.goproto_stringer) = false; + + string delegator_address = 1 [(gogoproto.moretags) = "yaml:\"delegator_address\""]; + string validator_src_address = 2 [(gogoproto.moretags) = "yaml:\"validator_src_address\""]; + string validator_dst_address = 3 [(gogoproto.moretags) = "yaml:\"validator_dst_address\""]; +} + +// DVVTriplets defines an array of DVVTriplet objects. +message DVVTriplets { + repeated DVVTriplet triplets = 1 [(gogoproto.nullable) = false]; +} + +// Delegation represents the bond with tokens held by an account. It is +// owned by one delegator, and is associated with the voting power of one +// validator. +message Delegation { + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + option (gogoproto.goproto_stringer) = false; + + // delegator_address is the bech32-encoded address of the delegator. + string delegator_address = 1 [(gogoproto.moretags) = "yaml:\"delegator_address\""]; + // validator_address is the bech32-encoded address of the validator. + string validator_address = 2 [(gogoproto.moretags) = "yaml:\"validator_address\""]; + // shares define the delegation shares received. + string shares = 3 [(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", (gogoproto.nullable) = false]; +} + +// UnbondingDelegation stores all of a single delegator's unbonding bonds +// for a single validator in an time-ordered list. +message UnbondingDelegation { + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + option (gogoproto.goproto_stringer) = false; + + // delegator_address is the bech32-encoded address of the delegator. + string delegator_address = 1 [(gogoproto.moretags) = "yaml:\"delegator_address\""]; + // validator_address is the bech32-encoded address of the validator. + string validator_address = 2 [(gogoproto.moretags) = "yaml:\"validator_address\""]; + // entries are the unbonding delegation entries. + repeated UnbondingDelegationEntry entries = 3 [(gogoproto.nullable) = false]; // unbonding delegation entries +} + +// UnbondingDelegationEntry defines an unbonding object with relevant metadata. +message UnbondingDelegationEntry { + option (gogoproto.equal) = true; + option (gogoproto.goproto_stringer) = false; + + // creation_height is the height which the unbonding took place. + int64 creation_height = 1 [(gogoproto.moretags) = "yaml:\"creation_height\""]; + // completion_time is the unix time for unbonding completion. + google.protobuf.Timestamp completion_time = 2 + [(gogoproto.nullable) = false, (gogoproto.stdtime) = true, (gogoproto.moretags) = "yaml:\"completion_time\""]; + // initial_balance defines the tokens initially scheduled to receive at completion. + string initial_balance = 3 [ + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int", + (gogoproto.nullable) = false, + (gogoproto.moretags) = "yaml:\"initial_balance\"" + ]; + // balance defines the tokens to receive at completion. + string balance = 4 [(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int", (gogoproto.nullable) = false]; +} + +// RedelegationEntry defines a redelegation object with relevant metadata. +message RedelegationEntry { + option (gogoproto.equal) = true; + option (gogoproto.goproto_stringer) = false; + + // creation_height defines the height which the redelegation took place. + int64 creation_height = 1 [(gogoproto.moretags) = "yaml:\"creation_height\""]; + // completion_time defines the unix time for redelegation completion. + google.protobuf.Timestamp completion_time = 2 + [(gogoproto.nullable) = false, (gogoproto.stdtime) = true, (gogoproto.moretags) = "yaml:\"completion_time\""]; + // initial_balance defines the initial balance when redelegation started. + string initial_balance = 3 [ + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int", + (gogoproto.nullable) = false, + (gogoproto.moretags) = "yaml:\"initial_balance\"" + ]; + // shares_dst is the amount of destination-validator shares created by redelegation. + string shares_dst = 4 + [(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", (gogoproto.nullable) = false]; +} + +// Redelegation contains the list of a particular delegator's redelegating bonds +// from a particular source validator to a particular destination validator. +message Redelegation { + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + option (gogoproto.goproto_stringer) = false; + + // delegator_address is the bech32-encoded address of the delegator. + string delegator_address = 1 [(gogoproto.moretags) = "yaml:\"delegator_address\""]; + // validator_src_address is the validator redelegation source operator address. + string validator_src_address = 2 [(gogoproto.moretags) = "yaml:\"validator_src_address\""]; + // validator_dst_address is the validator redelegation destination operator address. + string validator_dst_address = 3 [(gogoproto.moretags) = "yaml:\"validator_dst_address\""]; + // entries are the redelegation entries. + repeated RedelegationEntry entries = 4 [(gogoproto.nullable) = false]; // redelegation entries +} + +// Params defines the parameters for the staking module. +message Params { + option (gogoproto.equal) = true; + option (gogoproto.goproto_stringer) = false; + + // unbonding_time is the time duration of unbonding. + google.protobuf.Duration unbonding_time = 1 + [(gogoproto.nullable) = false, (gogoproto.stdduration) = true, (gogoproto.moretags) = "yaml:\"unbonding_time\""]; + // max_validators is the maximum number of validators. + uint32 max_validators = 2 [(gogoproto.moretags) = "yaml:\"max_validators\""]; + // max_entries is the max entries for either unbonding delegation or redelegation (per pair/trio). + uint32 max_entries = 3 [(gogoproto.moretags) = "yaml:\"max_entries\""]; + // historical_entries is the number of historical entries to persist. + uint32 historical_entries = 4 [(gogoproto.moretags) = "yaml:\"historical_entries\""]; + // bond_denom defines the bondable coin denomination. + string bond_denom = 5 [(gogoproto.moretags) = "yaml:\"bond_denom\""]; +} + +// DelegationResponse is equivalent to Delegation except that it contains a +// balance in addition to shares which is more suitable for client responses. +message DelegationResponse { + option (gogoproto.equal) = false; + option (gogoproto.goproto_stringer) = false; + + Delegation delegation = 1 [(gogoproto.nullable) = false]; + + cosmos.base.v1beta1.Coin balance = 2 [(gogoproto.nullable) = false]; +} + +// RedelegationEntryResponse is equivalent to a RedelegationEntry except that it +// contains a balance in addition to shares which is more suitable for client +// responses. +message RedelegationEntryResponse { + option (gogoproto.equal) = true; + + RedelegationEntry redelegation_entry = 1 [(gogoproto.nullable) = false]; + string balance = 4 [(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int", (gogoproto.nullable) = false]; +} + +// RedelegationResponse is equivalent to a Redelegation except that its entries +// contain a balance in addition to shares which is more suitable for client +// responses. +message RedelegationResponse { + option (gogoproto.equal) = false; + + Redelegation redelegation = 1 [(gogoproto.nullable) = false]; + repeated RedelegationEntryResponse entries = 2 [(gogoproto.nullable) = false]; +} + +// Pool is used for tracking bonded and not-bonded token supply of the bond +// denomination. +message Pool { + option (gogoproto.description) = true; + option (gogoproto.equal) = true; + string not_bonded_tokens = 1 [ + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int", + (gogoproto.jsontag) = "not_bonded_tokens", + (gogoproto.nullable) = false + ]; + string bonded_tokens = 2 [ + (gogoproto.jsontag) = "bonded_tokens", + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int", + (gogoproto.nullable) = false, + (gogoproto.moretags) = "yaml:\"bonded_tokens\"" + ]; +} diff --git a/third_party/proto/cosmos/staking/v1beta1/tx.proto b/third_party/proto/cosmos/staking/v1beta1/tx.proto new file mode 100644 index 0000000..7b05d89 --- /dev/null +++ b/third_party/proto/cosmos/staking/v1beta1/tx.proto @@ -0,0 +1,126 @@ +syntax = "proto3"; +package cosmos.staking.v1beta1; + +import "google/protobuf/any.proto"; +import "google/protobuf/timestamp.proto"; +import "gogoproto/gogo.proto"; + +import "cosmos_proto/cosmos.proto"; +import "cosmos/base/v1beta1/coin.proto"; +import "cosmos/staking/v1beta1/staking.proto"; + +option go_package = "github.com/cosmos/cosmos-sdk/x/staking/types"; + +// Msg defines the staking Msg service. +service Msg { + // CreateValidator defines a method for creating a new validator. + rpc CreateValidator(MsgCreateValidator) returns (MsgCreateValidatorResponse); + + // EditValidator defines a method for editing an existing validator. + rpc EditValidator(MsgEditValidator) returns (MsgEditValidatorResponse); + + // Delegate defines a method for performing a delegation of coins + // from a delegator to a validator. + rpc Delegate(MsgDelegate) returns (MsgDelegateResponse); + + // BeginRedelegate defines a method for performing a redelegation + // of coins from a delegator and source validator to a destination validator. + rpc BeginRedelegate(MsgBeginRedelegate) returns (MsgBeginRedelegateResponse); + + // Undelegate defines a method for performing an undelegation from a + // delegate and a validator. + rpc Undelegate(MsgUndelegate) returns (MsgUndelegateResponse); +} + +// MsgCreateValidator defines a SDK message for creating a new validator. +message MsgCreateValidator { + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + + Description description = 1 [(gogoproto.nullable) = false]; + CommissionRates commission = 2 [(gogoproto.nullable) = false]; + string min_self_delegation = 3 [ + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int", + (gogoproto.moretags) = "yaml:\"min_self_delegation\"", + (gogoproto.nullable) = false + ]; + string delegator_address = 4 [(gogoproto.moretags) = "yaml:\"delegator_address\""]; + string validator_address = 5 [(gogoproto.moretags) = "yaml:\"validator_address\""]; + google.protobuf.Any pubkey = 6 [(cosmos_proto.accepts_interface) = "cosmos.crypto.PubKey"]; + cosmos.base.v1beta1.Coin value = 7 [(gogoproto.nullable) = false]; +} + +// MsgCreateValidatorResponse defines the Msg/CreateValidator response type. +message MsgCreateValidatorResponse {} + +// MsgEditValidator defines a SDK message for editing an existing validator. +message MsgEditValidator { + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + + Description description = 1 [(gogoproto.nullable) = false]; + string validator_address = 2 [(gogoproto.moretags) = "yaml:\"address\""]; + + // We pass a reference to the new commission rate and min self delegation as + // it's not mandatory to update. If not updated, the deserialized rate will be + // zero with no way to distinguish if an update was intended. + // REF: #2373 + string commission_rate = 3 [ + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", + (gogoproto.moretags) = "yaml:\"commission_rate\"" + ]; + string min_self_delegation = 4 [ + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int", + (gogoproto.moretags) = "yaml:\"min_self_delegation\"" + ]; +} + +// MsgEditValidatorResponse defines the Msg/EditValidator response type. +message MsgEditValidatorResponse {} + +// MsgDelegate defines a SDK message for performing a delegation of coins +// from a delegator to a validator. +message MsgDelegate { + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + + string delegator_address = 1 [(gogoproto.moretags) = "yaml:\"delegator_address\""]; + string validator_address = 2 [(gogoproto.moretags) = "yaml:\"validator_address\""]; + cosmos.base.v1beta1.Coin amount = 3 [(gogoproto.nullable) = false]; +} + +// MsgDelegateResponse defines the Msg/Delegate response type. +message MsgDelegateResponse {} + +// MsgBeginRedelegate defines a SDK message for performing a redelegation +// of coins from a delegator and source validator to a destination validator. +message MsgBeginRedelegate { + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + + string delegator_address = 1 [(gogoproto.moretags) = "yaml:\"delegator_address\""]; + string validator_src_address = 2 [(gogoproto.moretags) = "yaml:\"validator_src_address\""]; + string validator_dst_address = 3 [(gogoproto.moretags) = "yaml:\"validator_dst_address\""]; + cosmos.base.v1beta1.Coin amount = 4 [(gogoproto.nullable) = false]; +} + +// MsgBeginRedelegateResponse defines the Msg/BeginRedelegate response type. +message MsgBeginRedelegateResponse { + google.protobuf.Timestamp completion_time = 1 [(gogoproto.nullable) = false, (gogoproto.stdtime) = true]; +} + +// MsgUndelegate defines a SDK message for performing an undelegation from a +// delegate and a validator. +message MsgUndelegate { + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + + string delegator_address = 1 [(gogoproto.moretags) = "yaml:\"delegator_address\""]; + string validator_address = 2 [(gogoproto.moretags) = "yaml:\"validator_address\""]; + cosmos.base.v1beta1.Coin amount = 3 [(gogoproto.nullable) = false]; +} + +// MsgUndelegateResponse defines the Msg/Undelegate response type. +message MsgUndelegateResponse { + google.protobuf.Timestamp completion_time = 1 [(gogoproto.nullable) = false, (gogoproto.stdtime) = true]; +} diff --git a/third_party/proto/cosmos/tx/signing/v1beta1/signing.proto b/third_party/proto/cosmos/tx/signing/v1beta1/signing.proto new file mode 100644 index 0000000..4c1be40 --- /dev/null +++ b/third_party/proto/cosmos/tx/signing/v1beta1/signing.proto @@ -0,0 +1,79 @@ +syntax = "proto3"; +package cosmos.tx.signing.v1beta1; + +import "cosmos/crypto/multisig/v1beta1/multisig.proto"; +import "google/protobuf/any.proto"; + +option go_package = "github.com/cosmos/cosmos-sdk/types/tx/signing"; + +// SignMode represents a signing mode with its own security guarantees. +enum SignMode { + // SIGN_MODE_UNSPECIFIED specifies an unknown signing mode and will be + // rejected + SIGN_MODE_UNSPECIFIED = 0; + + // SIGN_MODE_DIRECT specifies a signing mode which uses SignDoc and is + // verified with raw bytes from Tx + SIGN_MODE_DIRECT = 1; + + // SIGN_MODE_TEXTUAL is a future signing mode that will verify some + // human-readable textual representation on top of the binary representation + // from SIGN_MODE_DIRECT + SIGN_MODE_TEXTUAL = 2; + + // SIGN_MODE_LEGACY_AMINO_JSON is a backwards compatibility mode which uses + // Amino JSON and will be removed in the future + SIGN_MODE_LEGACY_AMINO_JSON = 127; +} + +// SignatureDescriptors wraps multiple SignatureDescriptor's. +message SignatureDescriptors { + // signatures are the signature descriptors + repeated SignatureDescriptor signatures = 1; +} + +// SignatureDescriptor is a convenience type which represents the full data for +// a signature including the public key of the signer, signing modes and the +// signature itself. It is primarily used for coordinating signatures between +// clients. +message SignatureDescriptor { + // public_key is the public key of the signer + google.protobuf.Any public_key = 1; + + Data data = 2; + + // sequence is the sequence of the account, which describes the + // number of committed transactions signed by a given address. It is used to prevent + // replay attacks. + uint64 sequence = 3; + + // Data represents signature data + message Data { + // sum is the oneof that specifies whether this represents single or multi-signature data + oneof sum { + // single represents a single signer + Single single = 1; + + // multi represents a multisig signer + Multi multi = 2; + } + + // Single is the signature data for a single signer + message Single { + // mode is the signing mode of the single signer + SignMode mode = 1; + + // signature is the raw signature bytes + bytes signature = 2; + } + + // Multi is the signature data for a multisig public key + message Multi { + // bitarray specifies which keys within the multisig are signing + cosmos.crypto.multisig.v1beta1.CompactBitArray bitarray = 1; + + // signatures is the signatures of the multi-signature + repeated Data signatures = 2; + } + } +} diff --git a/third_party/proto/cosmos/tx/v1beta1/service.proto b/third_party/proto/cosmos/tx/v1beta1/service.proto new file mode 100644 index 0000000..25214c4 --- /dev/null +++ b/third_party/proto/cosmos/tx/v1beta1/service.proto @@ -0,0 +1,129 @@ +syntax = "proto3"; +package cosmos.tx.v1beta1; + +import "google/api/annotations.proto"; +import "cosmos/base/abci/v1beta1/abci.proto"; +import "cosmos/tx/v1beta1/tx.proto"; +import "gogoproto/gogo.proto"; +import "cosmos/base/query/v1beta1/pagination.proto"; + +option (gogoproto.goproto_registration) = true; +option go_package = "github.com/cosmos/cosmos-sdk/types/tx"; + +// Service defines a gRPC service for interacting with transactions. +service Service { + // Simulate simulates executing a transaction for estimating gas usage. + rpc Simulate(SimulateRequest) returns (SimulateResponse) { + option (google.api.http) = { + post: "/cosmos/tx/v1beta1/simulate" + body: "*" + }; + } + // GetTx fetches a tx by hash. + rpc GetTx(GetTxRequest) returns (GetTxResponse) { + option (google.api.http).get = "/cosmos/tx/v1beta1/txs/{hash}"; + } + // BroadcastTx broadcast transaction. + rpc BroadcastTx(BroadcastTxRequest) returns (BroadcastTxResponse) { + option (google.api.http) = { + post: "/cosmos/tx/v1beta1/txs" + body: "*" + }; + } + // GetTxsEvent fetches txs by event. + rpc GetTxsEvent(GetTxsEventRequest) returns (GetTxsEventResponse) { + option (google.api.http).get = "/cosmos/tx/v1beta1/txs"; + } +} + +// GetTxsEventRequest is the request type for the Service.TxsByEvents +// RPC method. +message GetTxsEventRequest { + // events is the list of transaction event type. + repeated string events = 1; + // pagination defines an pagination for the request. + cosmos.base.query.v1beta1.PageRequest pagination = 2; + OrderBy order_by = 3; +} + +// OrderBy defines the sorting order +enum OrderBy { + // ORDER_BY_UNSPECIFIED specifies an unknown sorting order. OrderBy defaults to ASC in this case. + ORDER_BY_UNSPECIFIED = 0; + // ORDER_BY_ASC defines ascending order + ORDER_BY_ASC = 1; + // ORDER_BY_DESC defines descending order + ORDER_BY_DESC = 2; +} + +// GetTxsEventResponse is the response type for the Service.TxsByEvents +// RPC method. +message GetTxsEventResponse { + // txs is the list of queried transactions. + repeated cosmos.tx.v1beta1.Tx txs = 1; + // tx_responses is the list of queried TxResponses. + repeated cosmos.base.abci.v1beta1.TxResponse tx_responses = 2; + // pagination defines an pagination for the response. + cosmos.base.query.v1beta1.PageResponse pagination = 3; +} + +// BroadcastTxRequest is the request type for the Service.BroadcastTxRequest +// RPC method. +message BroadcastTxRequest { + // tx_bytes is the raw transaction. + bytes tx_bytes = 1; + BroadcastMode mode = 2; +} + +// BroadcastMode specifies the broadcast mode for the TxService.Broadcast RPC method. +enum BroadcastMode { + // zero-value for mode ordering + BROADCAST_MODE_UNSPECIFIED = 0; + // BROADCAST_MODE_BLOCK defines a tx broadcasting mode where the client waits for + // the tx to be committed in a block. + BROADCAST_MODE_BLOCK = 1; + // BROADCAST_MODE_SYNC defines a tx broadcasting mode where the client waits for + // a CheckTx execution response only. + BROADCAST_MODE_SYNC = 2; + // BROADCAST_MODE_ASYNC defines a tx broadcasting mode where the client returns + // immediately. + BROADCAST_MODE_ASYNC = 3; +} + +// BroadcastTxResponse is the response type for the +// Service.BroadcastTx method. +message BroadcastTxResponse { + // tx_response is the queried TxResponses. + cosmos.base.abci.v1beta1.TxResponse tx_response = 1; +} + +// SimulateRequest is the request type for the Service.Simulate +// RPC method. +message SimulateRequest { + // tx is the transaction to simulate. + cosmos.tx.v1beta1.Tx tx = 1; +} + +// SimulateResponse is the response type for the +// Service.SimulateRPC method. +message SimulateResponse { + // gas_info is the information about gas used in the simulation. + cosmos.base.abci.v1beta1.GasInfo gas_info = 1; + // result is the result of the simulation. + cosmos.base.abci.v1beta1.Result result = 2; +} + +// GetTxRequest is the request type for the Service.GetTx +// RPC method. +message GetTxRequest { + // hash is the tx hash to query, encoded as a hex string. + string hash = 1; +} + +// GetTxResponse is the response type for the Service.GetTx method. +message GetTxResponse { + // tx is the queried transaction. + cosmos.tx.v1beta1.Tx tx = 1; + // tx_response is the queried TxResponses. + cosmos.base.abci.v1beta1.TxResponse tx_response = 2; +} \ No newline at end of file diff --git a/third_party/proto/cosmos/tx/v1beta1/tx.proto b/third_party/proto/cosmos/tx/v1beta1/tx.proto new file mode 100644 index 0000000..2b02874 --- /dev/null +++ b/third_party/proto/cosmos/tx/v1beta1/tx.proto @@ -0,0 +1,181 @@ +syntax = "proto3"; +package cosmos.tx.v1beta1; + +import "gogoproto/gogo.proto"; +import "cosmos/crypto/multisig/v1beta1/multisig.proto"; +import "cosmos/base/v1beta1/coin.proto"; +import "cosmos/tx/signing/v1beta1/signing.proto"; +import "google/protobuf/any.proto"; + +option go_package = "github.com/cosmos/cosmos-sdk/types/tx"; + +// Tx is the standard type used for broadcasting transactions. +message Tx { + // body is the processable content of the transaction + TxBody body = 1; + + // auth_info is the authorization related content of the transaction, + // specifically signers, signer modes and fee + AuthInfo auth_info = 2; + + // signatures is a list of signatures that matches the length and order of + // AuthInfo's signer_infos to allow connecting signature meta information like + // public key and signing mode by position. + repeated bytes signatures = 3; +} + +// TxRaw is a variant of Tx that pins the signer's exact binary representation +// of body and auth_info. This is used for signing, broadcasting and +// verification. The binary `serialize(tx: TxRaw)` is stored in Tendermint and +// the hash `sha256(serialize(tx: TxRaw))` becomes the "txhash", commonly used +// as the transaction ID. +message TxRaw { + // body_bytes is a protobuf serialization of a TxBody that matches the + // representation in SignDoc. + bytes body_bytes = 1; + + // auth_info_bytes is a protobuf serialization of an AuthInfo that matches the + // representation in SignDoc. + bytes auth_info_bytes = 2; + + // signatures is a list of signatures that matches the length and order of + // AuthInfo's signer_infos to allow connecting signature meta information like + // public key and signing mode by position. + repeated bytes signatures = 3; +} + +// SignDoc is the type used for generating sign bytes for SIGN_MODE_DIRECT. +message SignDoc { + // body_bytes is protobuf serialization of a TxBody that matches the + // representation in TxRaw. + bytes body_bytes = 1; + + // auth_info_bytes is a protobuf serialization of an AuthInfo that matches the + // representation in TxRaw. + bytes auth_info_bytes = 2; + + // chain_id is the unique identifier of the chain this transaction targets. + // It prevents signed transactions from being used on another chain by an + // attacker + string chain_id = 3; + + // account_number is the account number of the account in state + uint64 account_number = 4; +} + +// TxBody is the body of a transaction that all signers sign over. +message TxBody { + // messages is a list of messages to be executed. The required signers of + // those messages define the number and order of elements in AuthInfo's + // signer_infos and Tx's signatures. Each required signer address is added to + // the list only the first time it occurs. + // By convention, the first required signer (usually from the first message) + // is referred to as the primary signer and pays the fee for the whole + // transaction. + repeated google.protobuf.Any messages = 1; + + // memo is any arbitrary memo to be added to the transaction + string memo = 2; + + // timeout is the block height after which this transaction will not + // be processed by the chain + uint64 timeout_height = 3; + + // extension_options are arbitrary options that can be added by chains + // when the default options are not sufficient. If any of these are present + // and can't be handled, the transaction will be rejected + repeated google.protobuf.Any extension_options = 1023; + + // extension_options are arbitrary options that can be added by chains + // when the default options are not sufficient. If any of these are present + // and can't be handled, they will be ignored + repeated google.protobuf.Any non_critical_extension_options = 2047; +} + +// AuthInfo describes the fee and signer modes that are used to sign a +// transaction. +message AuthInfo { + // signer_infos defines the signing modes for the required signers. The number + // and order of elements must match the required signers from TxBody's + // messages. The first element is the primary signer and the one which pays + // the fee. + repeated SignerInfo signer_infos = 1; + + // Fee is the fee and gas limit for the transaction. The first signer is the + // primary signer and the one which pays the fee. The fee can be calculated + // based on the cost of evaluating the body and doing signature verification + // of the signers. This can be estimated via simulation. + Fee fee = 2; +} + +// SignerInfo describes the public key and signing mode of a single top-level +// signer. +message SignerInfo { + // public_key is the public key of the signer. It is optional for accounts + // that already exist in state. If unset, the verifier can use the required \ + // signer address for this position and lookup the public key. + google.protobuf.Any public_key = 1; + + // mode_info describes the signing mode of the signer and is a nested + // structure to support nested multisig pubkey's + ModeInfo mode_info = 2; + + // sequence is the sequence of the account, which describes the + // number of committed transactions signed by a given address. It is used to + // prevent replay attacks. + uint64 sequence = 3; +} + +// ModeInfo describes the signing mode of a single or nested multisig signer. +message ModeInfo { + // sum is the oneof that specifies whether this represents a single or nested + // multisig signer + oneof sum { + // single represents a single signer + Single single = 1; + + // multi represents a nested multisig signer + Multi multi = 2; + } + + // Single is the mode info for a single signer. It is structured as a message + // to allow for additional fields such as locale for SIGN_MODE_TEXTUAL in the + // future + message Single { + // mode is the signing mode of the single signer + cosmos.tx.signing.v1beta1.SignMode mode = 1; + } + + // Multi is the mode info for a multisig public key + message Multi { + // bitarray specifies which keys within the multisig are signing + cosmos.crypto.multisig.v1beta1.CompactBitArray bitarray = 1; + + // mode_infos is the corresponding modes of the signers of the multisig + // which could include nested multisig public keys + repeated ModeInfo mode_infos = 2; + } +} + +// Fee includes the amount of coins paid in fees and the maximum +// gas to be used by the transaction. The ratio yields an effective "gasprice", +// which must be above some miminum to be accepted into the mempool. +message Fee { + // amount is the amount of coins to be paid as a fee + repeated cosmos.base.v1beta1.Coin amount = 1 + [(gogoproto.nullable) = false, (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins"]; + + // gas_limit is the maximum gas that can be used in transaction processing + // before an out of gas error occurs + uint64 gas_limit = 2; + + // if unset, the first signer is responsible for paying the fees. If set, the specified account must pay the fees. + // the payer must be a tx signer (and thus have signed this field in AuthInfo). + // setting this field does *not* change the ordering of required signers for the transaction. + string payer = 3; + + // if set, the fee payer (either the first signer or the value of the payer field) requests that a fee grant be used + // to pay fees instead of the fee payer's own balance. If an appropriate fee grant does not exist or the chain does + // not support fee grants, this will fail + string granter = 4; +} diff --git a/third_party/proto/cosmos/upgrade/v1beta1/query.proto b/third_party/proto/cosmos/upgrade/v1beta1/query.proto new file mode 100644 index 0000000..9eab27e --- /dev/null +++ b/third_party/proto/cosmos/upgrade/v1beta1/query.proto @@ -0,0 +1,68 @@ +syntax = "proto3"; +package cosmos.upgrade.v1beta1; + +import "google/protobuf/any.proto"; +import "google/api/annotations.proto"; +import "cosmos/upgrade/v1beta1/upgrade.proto"; + +option go_package = "github.com/cosmos/cosmos-sdk/x/upgrade/types"; + +// Query defines the gRPC upgrade querier service. +service Query { + // CurrentPlan queries the current upgrade plan. + rpc CurrentPlan(QueryCurrentPlanRequest) returns (QueryCurrentPlanResponse) { + option (google.api.http).get = "/cosmos/upgrade/v1beta1/current_plan"; + } + + // AppliedPlan queries a previously applied upgrade plan by its name. + rpc AppliedPlan(QueryAppliedPlanRequest) returns (QueryAppliedPlanResponse) { + option (google.api.http).get = "/cosmos/upgrade/v1beta1/applied_plan/{name}"; + } + + // UpgradedConsensusState queries the consensus state that will serve + // as a trusted kernel for the next version of this chain. It will only be + // stored at the last height of this chain. + // UpgradedConsensusState RPC not supported with legacy querier + rpc UpgradedConsensusState(QueryUpgradedConsensusStateRequest) returns (QueryUpgradedConsensusStateResponse) { + option (google.api.http).get = "/cosmos/upgrade/v1beta1/upgraded_consensus_state/{last_height}"; + } +} + +// QueryCurrentPlanRequest is the request type for the Query/CurrentPlan RPC +// method. +message QueryCurrentPlanRequest {} + +// QueryCurrentPlanResponse is the response type for the Query/CurrentPlan RPC +// method. +message QueryCurrentPlanResponse { + // plan is the current upgrade plan. + Plan plan = 1; +} + +// QueryCurrentPlanRequest is the request type for the Query/AppliedPlan RPC +// method. +message QueryAppliedPlanRequest { + // name is the name of the applied plan to query for. + string name = 1; +} + +// QueryAppliedPlanResponse is the response type for the Query/AppliedPlan RPC +// method. +message QueryAppliedPlanResponse { + // height is the block height at which the plan was applied. + int64 height = 1; +} + +// QueryUpgradedConsensusStateRequest is the request type for the Query/UpgradedConsensusState +// RPC method. +message QueryUpgradedConsensusStateRequest { + // last height of the current chain must be sent in request + // as this is the height under which next consensus state is stored + int64 last_height = 1; +} + +// QueryUpgradedConsensusStateResponse is the response type for the Query/UpgradedConsensusState +// RPC method. +message QueryUpgradedConsensusStateResponse { + google.protobuf.Any upgraded_consensus_state = 1; +} diff --git a/third_party/proto/cosmos/upgrade/v1beta1/upgrade.proto b/third_party/proto/cosmos/upgrade/v1beta1/upgrade.proto new file mode 100644 index 0000000..6d6839c --- /dev/null +++ b/third_party/proto/cosmos/upgrade/v1beta1/upgrade.proto @@ -0,0 +1,62 @@ +syntax = "proto3"; +package cosmos.upgrade.v1beta1; + +import "google/protobuf/any.proto"; +import "gogoproto/gogo.proto"; +import "google/protobuf/timestamp.proto"; + +option go_package = "github.com/cosmos/cosmos-sdk/x/upgrade/types"; +option (gogoproto.goproto_stringer_all) = false; +option (gogoproto.goproto_getters_all) = false; + +// Plan specifies information about a planned upgrade and when it should occur. +message Plan { + option (gogoproto.equal) = true; + + // Sets the name for the upgrade. This name will be used by the upgraded + // version of the software to apply any special "on-upgrade" commands during + // the first BeginBlock method after the upgrade is applied. It is also used + // to detect whether a software version can handle a given upgrade. If no + // upgrade handler with this name has been set in the software, it will be + // assumed that the software is out-of-date when the upgrade Time or Height is + // reached and the software will exit. + string name = 1; + + // The time after which the upgrade must be performed. + // Leave set to its zero value to use a pre-defined Height instead. + google.protobuf.Timestamp time = 2 [(gogoproto.stdtime) = true, (gogoproto.nullable) = false]; + + // The height at which the upgrade must be performed. + // Only used if Time is not set. + int64 height = 3; + + // Any application specific upgrade info to be included on-chain + // such as a git commit that validators could automatically upgrade to + string info = 4; + + // IBC-enabled chains can opt-in to including the upgraded client state in its upgrade plan + // This will make the chain commit to the correct upgraded (self) client state before the upgrade occurs, + // so that connecting chains can verify that the new upgraded client is valid by verifying a proof on the + // previous version of the chain. + // This will allow IBC connections to persist smoothly across planned chain upgrades + google.protobuf.Any upgraded_client_state = 5 [(gogoproto.moretags) = "yaml:\"upgraded_client_state\""]; +} + +// SoftwareUpgradeProposal is a gov Content type for initiating a software +// upgrade. +message SoftwareUpgradeProposal { + option (gogoproto.equal) = true; + + string title = 1; + string description = 2; + Plan plan = 3 [(gogoproto.nullable) = false]; +} + +// CancelSoftwareUpgradeProposal is a gov Content type for cancelling a software +// upgrade. +message CancelSoftwareUpgradeProposal { + option (gogoproto.equal) = true; + + string title = 1; + string description = 2; +} diff --git a/third_party/proto/cosmos/vesting/v1beta1/tx.proto b/third_party/proto/cosmos/vesting/v1beta1/tx.proto new file mode 100644 index 0000000..c49be80 --- /dev/null +++ b/third_party/proto/cosmos/vesting/v1beta1/tx.proto @@ -0,0 +1,31 @@ +syntax = "proto3"; +package cosmos.vesting.v1beta1; + +import "gogoproto/gogo.proto"; +import "cosmos/base/v1beta1/coin.proto"; + +option go_package = "github.com/cosmos/cosmos-sdk/x/auth/vesting/types"; + +// Msg defines the bank Msg service. +service Msg { + // CreateVestingAccount defines a method that enables creating a vesting + // account. + rpc CreateVestingAccount(MsgCreateVestingAccount) returns (MsgCreateVestingAccountResponse); +} + +// MsgCreateVestingAccount defines a message that enables creating a vesting +// account. +message MsgCreateVestingAccount { + option (gogoproto.equal) = true; + + string from_address = 1 [(gogoproto.moretags) = "yaml:\"from_address\""]; + string to_address = 2 [(gogoproto.moretags) = "yaml:\"to_address\""]; + repeated cosmos.base.v1beta1.Coin amount = 3 + [(gogoproto.nullable) = false, (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins"]; + + int64 end_time = 4 [(gogoproto.moretags) = "yaml:\"end_time\""]; + bool delayed = 5; +} + +// MsgCreateVestingAccountResponse defines the Msg/CreateVestingAccount response type. +message MsgCreateVestingAccountResponse {} \ No newline at end of file diff --git a/third_party/proto/cosmos/vesting/v1beta1/vesting.proto b/third_party/proto/cosmos/vesting/v1beta1/vesting.proto new file mode 100644 index 0000000..6bdbbf0 --- /dev/null +++ b/third_party/proto/cosmos/vesting/v1beta1/vesting.proto @@ -0,0 +1,73 @@ +syntax = "proto3"; +package cosmos.vesting.v1beta1; + +import "gogoproto/gogo.proto"; +import "cosmos/base/v1beta1/coin.proto"; +import "cosmos/auth/v1beta1/auth.proto"; + +option go_package = "github.com/cosmos/cosmos-sdk/x/auth/vesting/types"; + +// BaseVestingAccount implements the VestingAccount interface. It contains all +// the necessary fields needed for any vesting account implementation. +message BaseVestingAccount { + option (gogoproto.goproto_getters) = false; + option (gogoproto.goproto_stringer) = false; + + cosmos.auth.v1beta1.BaseAccount base_account = 1 [(gogoproto.embed) = true]; + repeated cosmos.base.v1beta1.Coin original_vesting = 2 [ + (gogoproto.nullable) = false, + (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins", + (gogoproto.moretags) = "yaml:\"original_vesting\"" + ]; + repeated cosmos.base.v1beta1.Coin delegated_free = 3 [ + (gogoproto.nullable) = false, + (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins", + (gogoproto.moretags) = "yaml:\"delegated_free\"" + ]; + repeated cosmos.base.v1beta1.Coin delegated_vesting = 4 [ + (gogoproto.nullable) = false, + (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins", + (gogoproto.moretags) = "yaml:\"delegated_vesting\"" + ]; + int64 end_time = 5 [(gogoproto.moretags) = "yaml:\"end_time\""]; +} + +// ContinuousVestingAccount implements the VestingAccount interface. It +// continuously vests by unlocking coins linearly with respect to time. +message ContinuousVestingAccount { + option (gogoproto.goproto_getters) = false; + option (gogoproto.goproto_stringer) = false; + + BaseVestingAccount base_vesting_account = 1 [(gogoproto.embed) = true]; + int64 start_time = 2 [(gogoproto.moretags) = "yaml:\"start_time\""]; +} + +// DelayedVestingAccount implements the VestingAccount interface. It vests all +// coins after a specific time, but non prior. In other words, it keeps them +// locked until a specified time. +message DelayedVestingAccount { + option (gogoproto.goproto_getters) = false; + option (gogoproto.goproto_stringer) = false; + + BaseVestingAccount base_vesting_account = 1 [(gogoproto.embed) = true]; +} + +// Period defines a length of time and amount of coins that will vest. +message Period { + option (gogoproto.goproto_stringer) = false; + + int64 length = 1; + repeated cosmos.base.v1beta1.Coin amount = 2 + [(gogoproto.nullable) = false, (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins"]; +} + +// PeriodicVestingAccount implements the VestingAccount interface. It +// periodically vests by unlocking coins during each specified period. +message PeriodicVestingAccount { + option (gogoproto.goproto_getters) = false; + option (gogoproto.goproto_stringer) = false; + + BaseVestingAccount base_vesting_account = 1 [(gogoproto.embed) = true]; + int64 start_time = 2 [(gogoproto.moretags) = "yaml:\"start_time\""]; + repeated Period vesting_periods = 3 [(gogoproto.moretags) = "yaml:\"vesting_periods\"", (gogoproto.nullable) = false]; +} diff --git a/x/escrow/client/cli/tx.go b/x/escrow/client/cli/tx.go index e097551..3059499 100644 --- a/x/escrow/client/cli/tx.go +++ b/x/escrow/client/cli/tx.go @@ -42,6 +42,7 @@ func escrowOffer() *cobra.Command { if err != nil { return err } + offer := types.NewOfferRequest(addr, args[1], args[2]) return tx.GenerateOrBroadcastTxCLI(ctx, cmd.Flags(), offer) diff --git a/x/escrow/handler.go b/x/escrow/handler.go index 5178c4a..e9f6b9e 100644 --- a/x/escrow/handler.go +++ b/x/escrow/handler.go @@ -18,7 +18,7 @@ func NewHandler(k keeper.Keeper) sdk.Handler { switch msg := msg.(type) { // this line is used by starport scaffolding # 1 - case *types.OfferRequest: + case *types.Offer: res, err := k.Offer(sdk.WrapSDKContext(ctx), msg) return sdk.WrapServiceResult(ctx, res, err) diff --git a/x/escrow/keeper/msg_server.go b/x/escrow/keeper/msg_server.go index 50dfe59..93a0e3d 100644 --- a/x/escrow/keeper/msg_server.go +++ b/x/escrow/keeper/msg_server.go @@ -6,7 +6,6 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" "github.com/interchainberlin/pooltoy/x/escrow/types" - "github.com/interchainberlin/pooltoy/x/escrow/utils" ) type msgServer struct { @@ -21,7 +20,7 @@ func NewMsgServerImpl(keeper Keeper) types.MsgServer { var _ types.MsgServer = Keeper{} -func (k Keeper) Offer(c context.Context, msg *types.OfferRequest) (*types.OfferResponse, error) { +func (k Keeper) Offer(c context.Context, msg *types.Offer) (*types.OfferResponse, error) { ctx := sdk.UnwrapSDKContext(c) res, err := k.OfferSend(ctx, msg) if err != nil { @@ -37,21 +36,21 @@ func (k Keeper) Offer(c context.Context, msg *types.OfferRequest) (*types.OfferR return res, nil } -func (k Keeper) OfferSend(ctx sdk.Context, msg *types.OfferRequest) (*types.OfferResponse, error) { +func (k Keeper) OfferSend(ctx sdk.Context, msg *types.Offer) (*types.OfferResponse, error) { addr, err := sdk.AccAddressFromBech32(msg.Sender) if err != nil { fmt.Println("addr err!!!!") return &types.OfferResponse{}, err } - amount, err := utils.ParseCoins(msg.Amount) - if err != nil { - return &types.OfferResponse{}, err - } +// coins, err := sdk.ParseCoinsNormalized(msg.Amount) +// if err != nil { +// return &types.OfferResponse{}, err +// } // moduleAcc:= k.AccountKeeper.GetModuleAddress(types.ModuleName) - err = k.BankKeeper.SendCoinsFromAccountToModule(ctx, addr,types.ModuleName, amount) + err = k.BankKeeper.SendCoinsFromAccountToModule(ctx, addr,types.ModuleName,msg.Amount) if err != nil { fmt.Println("sending err!!!!") return &types.OfferResponse{}, err diff --git a/x/escrow/keeper/store.go b/x/escrow/keeper/store.go index bb595a0..f3cf3f0 100644 --- a/x/escrow/keeper/store.go +++ b/x/escrow/keeper/store.go @@ -4,18 +4,22 @@ import ( "fmt" "github.com/cosmos/cosmos-sdk/store/prefix" sdk "github.com/cosmos/cosmos-sdk/types" + // types2 "github.com/cosmos/cosmos-sdk/x/auth/types" "github.com/interchainberlin/pooltoy/x/escrow/types" "strconv" + // "github.com/cosmos/cosmos-sdk/types/address" ) -func (k Keeper) InsertOffer(ctx sdk.Context, offer types.OfferRequest) ([]byte, error) { +func (k Keeper) InsertOffer(ctx sdk.Context, offer types.Offer) ([]byte, error) { store := ctx.KVStore(k.storeKey) addr, err := sdk.AccAddressFromBech32(offer.Sender) if err != nil { return []byte{}, err } - storeK := []byte{} + storeK := []byte(types.OfferPrefix) storeK = append(storeK, addr...) + + fmt.Println("storeK is!!!!",storeK) storeK = append(storeK, []byte(strconv.FormatInt(*k.index, 10))...) // todo maybe we do not need int64 for index storeV, err := offer.Marshal() @@ -23,7 +27,7 @@ func (k Keeper) InsertOffer(ctx sdk.Context, offer types.OfferRequest) ([]byte, return nil, err } fmt.Println("store key is", storeK) - store.Set([]byte(storeK), storeV) + store.Set(storeK, storeV) return storeV, nil } @@ -36,7 +40,8 @@ func (k Keeper) ListOffer(ctx sdk.Context, offer types.OfferListAllRequest) (typ for ; iterator.Valid(); iterator.Next() { var offer types.Offer fmt.Println("key is!!!!", string(iterator.Key())) - k.cdc.MustUnmarshalBinaryBare(store.Get(iterator.Key()), &offer) + // k.cdc.MustUnmarshalBinaryBare(store.Get(iterator.Key()), &offer) + offer.Unmarshal(iterator.Value()) offers = append(offers, &offer) } @@ -51,20 +56,19 @@ func (k Keeper) ListOfferByAddr(ctx sdk.Context, offer types.QueryOfferByAddrReq return types.OfferListResponse{}, err } addrStore := k.getAddressPrefixStore(ctx, addr) - fmt.Println("does the store has the addr!!!!", addrStore.Has(addr)) + //fmt.Println("does the store has the addr!!!!", addrStore.Has(addrStore.key())) iterator := addrStore.Iterator(nil, nil) defer iterator.Close() offers := []*types.Offer{} - i :=0 + //i :=0 fmt.Println("valid iterator!!!!", iterator.Valid()) + fmt.Println("valid iterator err!!!!", iterator.Error()) for ; iterator.Valid(); iterator.Next() { - fmt.Println("i is!!!!", i) - i ++ + fmt.Println("start iterate sub store!!!!") fmt.Println("substore key is!!!!", string(iterator.Key())) var offer types.Offer - k.cdc.MustUnmarshalBinaryBare(iterator.Value(), &offer) - fmt.Println("offer unmarshal is!!!!", offer.Sender, offer.Amount, offer.Request) + k.cdc.MustUnmarshalBinaryBare(addrStore.Get(iterator.Key()), &offer) offers = append(offers, &offer) } @@ -73,8 +77,8 @@ func (k Keeper) ListOfferByAddr(ctx sdk.Context, offer types.QueryOfferByAddrReq func (k Keeper) getAddressPrefixStore(ctx sdk.Context, addr sdk.AccAddress) prefix.Store { store := ctx.KVStore(k.storeKey) - ref :="offer-" - b := []byte(ref) +// ref :="offer-" + b := []byte(types.OfferPrefix) fmt.Println("ref b is!!!!",b) addr, _ = sdk.AccAddressFromBech32("cosmos126c2ak7k5qw8rhhha60kgksjrjf5jvkgtzlklw") fmt.Println("ref addr !!!!", addr) @@ -86,7 +90,11 @@ func (k Keeper) getAddressPrefixStore(ctx sdk.Context, addr sdk.AccAddress) pref func CreateAddrPrefix(addr []byte) []byte { - return append([]byte(types.OfferPrefix), addr...) +//todo change to MustLengthPrefix(addr)...) for v0.43.0 release + //prefix := append([]byte(types.OfferPrefix),[]byte{byte(len(addr))}...) + prefix := append([]byte(types.OfferPrefix), addr...) + fmt.Println("the prefix is!!!!", prefix) + return prefix } // todo cannot find the pakcage: address.MustLengthPrefix(addr)... diff --git a/x/escrow/types/codec.go b/x/escrow/types/codec.go index 43a6647..bdb6f1d 100644 --- a/x/escrow/types/codec.go +++ b/x/escrow/types/codec.go @@ -16,7 +16,7 @@ func RegisterCodec(cdc *codec.LegacyAmino) { func RegisterInterfaces(registry cdctypes.InterfaceRegistry) { // this line is used by starport scaffolding # 3 - registry.RegisterImplementations((*sdk.Msg)(nil), &OfferRequest{}) + registry.RegisterImplementations((*sdk.Msg)(nil), &Offer{}) msgservice.RegisterMsgServiceDesc(registry, &_Msg_serviceDesc) diff --git a/x/escrow/types/genesis.pb.go b/x/escrow/types/genesis.pb.go index c72328d..9104b19 100644 --- a/x/escrow/types/genesis.pb.go +++ b/x/escrow/types/genesis.pb.go @@ -1,5 +1,5 @@ // Code generated by protoc-gen-gogo. DO NOT EDIT. -// source: escrow/escrow/genesis.proto +// source: escrow/genesis.proto package types @@ -30,7 +30,7 @@ func (m *GenesisState) Reset() { *m = GenesisState{} } func (m *GenesisState) String() string { return proto.CompactTextString(m) } func (*GenesisState) ProtoMessage() {} func (*GenesisState) Descriptor() ([]byte, []int) { - return fileDescriptor_a2ef36a6ca65f517, []int{0} + return fileDescriptor_291b6ea4c40e3193, []int{0} } func (m *GenesisState) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -63,19 +63,19 @@ func init() { proto.RegisterType((*GenesisState)(nil), "escrow.GenesisState") } -func init() { proto.RegisterFile("escrow/escrow/genesis.proto", fileDescriptor_a2ef36a6ca65f517) } +func init() { proto.RegisterFile("escrow/genesis.proto", fileDescriptor_291b6ea4c40e3193) } -var fileDescriptor_a2ef36a6ca65f517 = []byte{ +var fileDescriptor_291b6ea4c40e3193 = []byte{ // 142 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x92, 0x4e, 0x2d, 0x4e, 0x2e, - 0xca, 0x2f, 0xd7, 0x87, 0x52, 0xe9, 0xa9, 0x79, 0xa9, 0xc5, 0x99, 0xc5, 0x7a, 0x05, 0x45, 0xf9, - 0x25, 0xf9, 0x42, 0x6c, 0x10, 0x51, 0x25, 0x3e, 0x2e, 0x1e, 0x77, 0x88, 0x44, 0x70, 0x49, 0x62, - 0x49, 0xaa, 0x93, 0xcf, 0x89, 0x47, 0x72, 0x8c, 0x17, 0x1e, 0xc9, 0x31, 0x3e, 0x78, 0x24, 0xc7, - 0x38, 0xe1, 0xb1, 0x1c, 0xc3, 0x85, 0xc7, 0x72, 0x0c, 0x37, 0x1e, 0xcb, 0x31, 0x44, 0x19, 0xa5, - 0x67, 0x96, 0x64, 0x94, 0x26, 0xe9, 0x25, 0xe7, 0xe7, 0xea, 0x67, 0xe6, 0x95, 0xa4, 0x16, 0x25, - 0x67, 0x24, 0x66, 0xe6, 0x25, 0xa5, 0x16, 0xe5, 0x64, 0xe6, 0xe9, 0x17, 0xe4, 0xe7, 0xe7, 0x94, - 0xe4, 0x57, 0xea, 0x57, 0xc0, 0x6c, 0x2b, 0xa9, 0x2c, 0x48, 0x2d, 0x4e, 0x62, 0x03, 0x5b, 0x66, - 0x0c, 0x08, 0x00, 0x00, 0xff, 0xff, 0xfb, 0x6f, 0x05, 0xd0, 0x8b, 0x00, 0x00, 0x00, + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x12, 0x49, 0x2d, 0x4e, 0x2e, + 0xca, 0x2f, 0xd7, 0x4f, 0x4f, 0xcd, 0x4b, 0x2d, 0xce, 0x2c, 0xd6, 0x2b, 0x28, 0xca, 0x2f, 0xc9, + 0x17, 0x62, 0x83, 0x88, 0x2a, 0xf1, 0x71, 0xf1, 0xb8, 0x43, 0x24, 0x82, 0x4b, 0x12, 0x4b, 0x52, + 0x9d, 0x7c, 0x4e, 0x3c, 0x92, 0x63, 0xbc, 0xf0, 0x48, 0x8e, 0xf1, 0xc1, 0x23, 0x39, 0xc6, 0x09, + 0x8f, 0xe5, 0x18, 0x2e, 0x3c, 0x96, 0x63, 0xb8, 0xf1, 0x58, 0x8e, 0x21, 0xca, 0x28, 0x3d, 0xb3, + 0x24, 0xa3, 0x34, 0x49, 0x2f, 0x39, 0x3f, 0x57, 0x3f, 0x33, 0xaf, 0x24, 0xb5, 0x28, 0x39, 0x23, + 0x31, 0x33, 0x2f, 0x29, 0xb5, 0x28, 0x27, 0x33, 0x4f, 0xbf, 0x20, 0x3f, 0x3f, 0xa7, 0x24, 0xbf, + 0x52, 0xbf, 0x42, 0x1f, 0x6a, 0x5b, 0x49, 0x65, 0x41, 0x6a, 0x71, 0x12, 0x1b, 0xd8, 0x32, 0x63, + 0x40, 0x00, 0x00, 0x00, 0xff, 0xff, 0x23, 0x27, 0x5a, 0x96, 0x84, 0x00, 0x00, 0x00, } func (m *GenesisState) Marshal() (dAtA []byte, err error) { diff --git a/x/escrow/types/msgs.go b/x/escrow/types/msgs.go index 575992a..481719a 100644 --- a/x/escrow/types/msgs.go +++ b/x/escrow/types/msgs.go @@ -6,7 +6,7 @@ import ( ) var ( - _ sdk.Msg = &OfferRequest{} + _ sdk.Msg = &Offer{} ) const ( @@ -14,18 +14,20 @@ const ( ) // NewMsgMint is a constructor function for NewMsgMint -func NewOfferRequest(sender sdk.AccAddress, amount string, request string) *OfferRequest { - return &OfferRequest{Sender: sender.String(), Amount: amount, Request: request} +func NewOfferRequest(sender sdk.AccAddress, amount string, request string) *Offer { + amt,_ := sdk.ParseCoinsNormalized(amount) + req,_ := sdk.ParseCoinsNormalized(request) + return &Offer{Sender: sender.String(), Amount: amt, Request: req} } // Route should return the name of the module -func (msg *OfferRequest) Route() string { return RouterKey } +func (msg *Offer) Route() string { return RouterKey } // Type should return the action -func (msg *OfferRequest) Type() string { return TypeOffer} +func (msg *Offer) Type() string { return TypeOffer} // ValidateBasic runs stateless checks on the message -func (msg *OfferRequest) ValidateBasic() error { +func (msg *Offer) ValidateBasic() error { //addr, err := sdk.AccAddressFromBech32(msg.Sender) //fmt.Println("validation basic!!!!", addr) //if err != nil { @@ -37,12 +39,12 @@ func (msg *OfferRequest) ValidateBasic() error { } // GetSignBytes encodes the message for signing -func (msg *OfferRequest) GetSignBytes() []byte { +func (msg *Offer) GetSignBytes() []byte { panic("amino support disabled") } // GetSigners defines whose signature is required -func (msg *OfferRequest) GetSigners() []sdk.AccAddress { +func (msg *Offer) GetSigners() []sdk.AccAddress { sender, err := sdk.AccAddressFromBech32(msg.Sender) if err != nil { fmt.Println(err) diff --git a/x/escrow/types/query.pb.go b/x/escrow/types/query.pb.go index 3a5480f..3b7921b 100644 --- a/x/escrow/types/query.pb.go +++ b/x/escrow/types/query.pb.go @@ -1,5 +1,5 @@ // Code generated by protoc-gen-gogo. DO NOT EDIT. -// source: escrow/escrow/query.proto +// source: escrow/query.proto package types @@ -35,7 +35,7 @@ func (m *OfferListAllRequest) Reset() { *m = OfferListAllRequest{} } func (m *OfferListAllRequest) String() string { return proto.CompactTextString(m) } func (*OfferListAllRequest) ProtoMessage() {} func (*OfferListAllRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_cf6961269d90321b, []int{0} + return fileDescriptor_6d37bf65b8b6e159, []int{0} } func (m *OfferListAllRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -73,7 +73,7 @@ func (m *QueryOfferByIDRequest) Reset() { *m = QueryOfferByIDRequest{} } func (m *QueryOfferByIDRequest) String() string { return proto.CompactTextString(m) } func (*QueryOfferByIDRequest) ProtoMessage() {} func (*QueryOfferByIDRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_cf6961269d90321b, []int{1} + return fileDescriptor_6d37bf65b8b6e159, []int{1} } func (m *QueryOfferByIDRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -125,7 +125,7 @@ func (m *QueryOfferByAddrRequest) Reset() { *m = QueryOfferByAddrRequest func (m *QueryOfferByAddrRequest) String() string { return proto.CompactTextString(m) } func (*QueryOfferByAddrRequest) ProtoMessage() {} func (*QueryOfferByAddrRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_cf6961269d90321b, []int{2} + return fileDescriptor_6d37bf65b8b6e159, []int{2} } func (m *QueryOfferByAddrRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -168,67 +168,6 @@ func (m *QueryOfferByAddrRequest) GetOfferer() string { return "" } -type Offer struct { - Sender string `protobuf:"bytes,1,opt,name=sender,proto3" json:"sender,omitempty"` - Amount string `protobuf:"bytes,2,opt,name=amount,proto3" json:"amount,omitempty"` - // [(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Coins"]; - Request string `protobuf:"bytes,3,opt,name=request,proto3" json:"request,omitempty"` -} - -func (m *Offer) Reset() { *m = Offer{} } -func (m *Offer) String() string { return proto.CompactTextString(m) } -func (*Offer) ProtoMessage() {} -func (*Offer) Descriptor() ([]byte, []int) { - return fileDescriptor_cf6961269d90321b, []int{3} -} -func (m *Offer) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *Offer) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - if deterministic { - return xxx_messageInfo_Offer.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 *Offer) XXX_Merge(src proto.Message) { - xxx_messageInfo_Offer.Merge(m, src) -} -func (m *Offer) XXX_Size() int { - return m.Size() -} -func (m *Offer) XXX_DiscardUnknown() { - xxx_messageInfo_Offer.DiscardUnknown(m) -} - -var xxx_messageInfo_Offer proto.InternalMessageInfo - -func (m *Offer) GetSender() string { - if m != nil { - return m.Sender - } - return "" -} - -func (m *Offer) GetAmount() string { - if m != nil { - return m.Amount - } - return "" -} - -func (m *Offer) GetRequest() string { - if m != nil { - return m.Request - } - return "" -} - type OfferListResponse struct { OfferList []*Offer `protobuf:"bytes,1,rep,name=offerList,proto3" json:"offerList,omitempty"` } @@ -237,7 +176,7 @@ func (m *OfferListResponse) Reset() { *m = OfferListResponse{} } func (m *OfferListResponse) String() string { return proto.CompactTextString(m) } func (*OfferListResponse) ProtoMessage() {} func (*OfferListResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_cf6961269d90321b, []int{4} + return fileDescriptor_6d37bf65b8b6e159, []int{3} } func (m *OfferListResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -277,38 +216,35 @@ func init() { proto.RegisterType((*OfferListAllRequest)(nil), "escrow.OfferListAllRequest") proto.RegisterType((*QueryOfferByIDRequest)(nil), "escrow.QueryOfferByIDRequest") proto.RegisterType((*QueryOfferByAddrRequest)(nil), "escrow.QueryOfferByAddrRequest") - proto.RegisterType((*Offer)(nil), "escrow.Offer") proto.RegisterType((*OfferListResponse)(nil), "escrow.OfferListResponse") } -func init() { proto.RegisterFile("escrow/escrow/query.proto", fileDescriptor_cf6961269d90321b) } - -var fileDescriptor_cf6961269d90321b = []byte{ - // 380 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x84, 0x92, 0xcd, 0x4e, 0xea, 0x40, - 0x14, 0xc7, 0x19, 0x08, 0x10, 0xe6, 0xe6, 0x92, 0xcb, 0xdc, 0x70, 0x6f, 0x41, 0xad, 0xa4, 0x2b, - 0x12, 0x93, 0x36, 0xc1, 0xbd, 0x11, 0xe2, 0xc6, 0x88, 0x1a, 0xba, 0x74, 0x57, 0xe8, 0x00, 0x93, - 0x94, 0x39, 0x65, 0x66, 0x1a, 0xed, 0x5b, 0xf8, 0x58, 0x2e, 0x59, 0xba, 0x34, 0xe0, 0x83, 0x98, - 0x7e, 0x01, 0x55, 0xa2, 0xab, 0xc9, 0xff, 0x7c, 0xfc, 0xe6, 0x9c, 0xff, 0x0c, 0x6e, 0x51, 0x39, - 0x11, 0xf0, 0x68, 0xa5, 0xc7, 0x32, 0xa0, 0x22, 0x34, 0x7d, 0x01, 0x0a, 0x48, 0x25, 0x89, 0xb5, - 0x8f, 0x67, 0x00, 0x33, 0x8f, 0x5a, 0x8e, 0xcf, 0x2c, 0x87, 0x73, 0x50, 0x8e, 0x62, 0xc0, 0x65, - 0x52, 0x65, 0x34, 0xf1, 0xdf, 0xfb, 0xe9, 0x94, 0x8a, 0x21, 0x93, 0xaa, 0xef, 0x79, 0x36, 0x5d, - 0x06, 0x54, 0x2a, 0xa3, 0x8f, 0x9b, 0xa3, 0x88, 0x15, 0xe7, 0x06, 0xe1, 0xf5, 0x55, 0x9a, 0x20, - 0x1a, 0xae, 0x46, 0x97, 0x30, 0x2a, 0x34, 0xd4, 0x41, 0xdd, 0x9a, 0x9d, 0x49, 0x52, 0xc7, 0x45, - 0xe6, 0x6a, 0xc5, 0x0e, 0xea, 0x96, 0xec, 0x22, 0x73, 0x8d, 0x5b, 0xfc, 0x7f, 0x1f, 0xd1, 0x77, - 0x5d, 0xf1, 0x33, 0x44, 0xc3, 0x55, 0x88, 0xea, 0xa9, 0x88, 0x49, 0x35, 0x3b, 0x93, 0xc6, 0x08, - 0x97, 0x63, 0x12, 0xf9, 0x87, 0x2b, 0x92, 0x72, 0x77, 0xdb, 0x9b, 0xaa, 0x28, 0xee, 0x2c, 0x20, - 0xe0, 0x2a, 0xed, 0x4c, 0x55, 0x84, 0x14, 0xc9, 0xbd, 0x5a, 0x29, 0x41, 0xa6, 0xd2, 0xb8, 0xc4, - 0x8d, 0xed, 0xee, 0x36, 0x95, 0x3e, 0x70, 0x49, 0xc9, 0x19, 0xae, 0x41, 0x16, 0xd4, 0x50, 0xa7, - 0xd4, 0xfd, 0xd5, 0xfb, 0x6d, 0x26, 0x56, 0x9a, 0x71, 0xb5, 0xbd, 0xcb, 0xf7, 0xde, 0x11, 0x2e, - 0xc7, 0x4b, 0x92, 0x1b, 0xdc, 0xd8, 0x6d, 0x9b, 0x9a, 0x49, 0x8e, 0x72, 0x8d, 0x79, 0x8b, 0xdb, - 0xad, 0x2f, 0xc9, 0xed, 0x0c, 0x17, 0xb8, 0x9e, 0x77, 0x9f, 0x9c, 0x64, 0xc5, 0x07, 0x5f, 0xa5, - 0x9d, 0x9f, 0x90, 0xdc, 0xe1, 0x3f, 0x9f, 0xad, 0x27, 0xa7, 0x87, 0x08, 0x7b, 0x8f, 0xf2, 0xcd, - 0x3c, 0x83, 0xe1, 0xcb, 0x5a, 0x47, 0xab, 0xb5, 0x8e, 0xde, 0xd6, 0x3a, 0x7a, 0xde, 0xe8, 0x85, - 0xd5, 0x46, 0x2f, 0xbc, 0x6e, 0xf4, 0xc2, 0x43, 0x6f, 0xc6, 0xd4, 0x3c, 0x18, 0x9b, 0x13, 0x58, - 0x58, 0x8c, 0x2b, 0x2a, 0x26, 0x73, 0x87, 0xf1, 0x31, 0x15, 0x1e, 0xe3, 0x96, 0x0f, 0xe0, 0x29, - 0x08, 0xad, 0xa7, 0xec, 0x7b, 0xaa, 0xd0, 0xa7, 0x72, 0x5c, 0x89, 0x7f, 0xde, 0xf9, 0x47, 0x00, - 0x00, 0x00, 0xff, 0xff, 0xe2, 0xbd, 0xb7, 0xa8, 0xbc, 0x02, 0x00, 0x00, +func init() { proto.RegisterFile("escrow/query.proto", fileDescriptor_6d37bf65b8b6e159) } + +var fileDescriptor_6d37bf65b8b6e159 = []byte{ + // 347 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x84, 0x52, 0xc1, 0x4e, 0xc2, 0x40, + 0x14, 0x64, 0x21, 0x42, 0x58, 0x23, 0xca, 0x1a, 0x62, 0xad, 0x5a, 0x49, 0x4f, 0x24, 0x26, 0xdd, + 0x04, 0xef, 0x46, 0x88, 0x17, 0x23, 0x6a, 0xec, 0xd1, 0x5b, 0xa1, 0x0b, 0x6c, 0x52, 0xf7, 0x95, + 0xdd, 0x25, 0xd2, 0xbf, 0xf0, 0xb3, 0x3c, 0x72, 0xf4, 0x68, 0xc0, 0x0f, 0x31, 0xb4, 0x14, 0xa8, + 0x12, 0x3d, 0xee, 0xcc, 0xbc, 0xd9, 0x79, 0x93, 0x87, 0x09, 0x53, 0x3d, 0x09, 0xaf, 0x74, 0x34, + 0x66, 0x32, 0x72, 0x42, 0x09, 0x1a, 0x48, 0x31, 0xc1, 0xcc, 0xd3, 0x01, 0xc0, 0x20, 0x60, 0xd4, + 0x0b, 0x39, 0xf5, 0x84, 0x00, 0xed, 0x69, 0x0e, 0x42, 0x25, 0x2a, 0x73, 0x7f, 0x39, 0xa9, 0x27, + 0x09, 0x60, 0xd7, 0xf0, 0xe1, 0x63, 0xbf, 0xcf, 0x64, 0x87, 0x2b, 0xdd, 0x0a, 0x02, 0x97, 0x8d, + 0xc6, 0x4c, 0x69, 0xbb, 0x85, 0x6b, 0x4f, 0x0b, 0xf3, 0x98, 0x6b, 0x47, 0xb7, 0x37, 0x4b, 0x82, + 0x18, 0xb8, 0xb4, 0xf8, 0x95, 0x33, 0x69, 0xa0, 0x3a, 0x6a, 0x94, 0xdd, 0xf4, 0x49, 0x2a, 0x38, + 0xcf, 0x7d, 0x23, 0x5f, 0x47, 0x8d, 0x82, 0x9b, 0xe7, 0xbe, 0x7d, 0x8f, 0x8f, 0x36, 0x2d, 0x5a, + 0xbe, 0x2f, 0xff, 0x37, 0x31, 0x70, 0x09, 0x16, 0x7a, 0x26, 0x63, 0xa7, 0xb2, 0x9b, 0x3e, 0xed, + 0x6b, 0x5c, 0x5d, 0x05, 0x75, 0x99, 0x0a, 0x41, 0x28, 0x46, 0x2e, 0x70, 0x19, 0x52, 0xd0, 0x40, + 0xf5, 0x42, 0x63, 0xb7, 0xb9, 0xe7, 0x24, 0x2b, 0x3a, 0xb1, 0xda, 0x5d, 0xf3, 0xcd, 0x2f, 0x84, + 0x77, 0xe2, 0x44, 0xe4, 0x0e, 0x57, 0xd7, 0xd1, 0x96, 0x9b, 0x93, 0x93, 0xcc, 0x60, 0xb6, 0x0f, + 0xf3, 0xf8, 0x17, 0xb9, 0xca, 0x70, 0x85, 0x2b, 0xd9, 0xaa, 0xc8, 0x59, 0x2a, 0xde, 0x5a, 0xa1, + 0x99, 0x4d, 0x48, 0x1e, 0xf0, 0xc1, 0xcf, 0x9e, 0xc8, 0xf9, 0x36, 0x87, 0x8d, 0x06, 0xff, 0xc8, + 0xd3, 0xee, 0xbc, 0xcf, 0x2c, 0x34, 0x9d, 0x59, 0xe8, 0x73, 0x66, 0xa1, 0xb7, 0xb9, 0x95, 0x9b, + 0xce, 0xad, 0xdc, 0xc7, 0xdc, 0xca, 0x3d, 0x37, 0x07, 0x5c, 0x0f, 0xc7, 0x5d, 0xa7, 0x07, 0x2f, + 0x94, 0x0b, 0xcd, 0x64, 0x6f, 0xe8, 0x71, 0xd1, 0x65, 0x32, 0xe0, 0x82, 0x86, 0x00, 0x81, 0x86, + 0x88, 0x4e, 0x68, 0x7a, 0x22, 0x51, 0xc8, 0x54, 0xb7, 0x18, 0x9f, 0xc9, 0xe5, 0x77, 0x00, 0x00, + 0x00, 0xff, 0xff, 0x41, 0xef, 0xda, 0xca, 0x73, 0x02, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -462,7 +398,7 @@ var _Query_serviceDesc = grpc.ServiceDesc{ }, }, Streams: []grpc.StreamDesc{}, - Metadata: "escrow/escrow/query.proto", + Metadata: "escrow/query.proto", } func (m *OfferListAllRequest) Marshal() (dAtA []byte, err error) { @@ -560,50 +496,6 @@ func (m *QueryOfferByAddrRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) return len(dAtA) - i, nil } -func (m *Offer) 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 *Offer) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *Offer) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if len(m.Request) > 0 { - i -= len(m.Request) - copy(dAtA[i:], m.Request) - i = encodeVarintQuery(dAtA, i, uint64(len(m.Request))) - i-- - dAtA[i] = 0x1a - } - if len(m.Amount) > 0 { - i -= len(m.Amount) - copy(dAtA[i:], m.Amount) - i = encodeVarintQuery(dAtA, i, uint64(len(m.Amount))) - i-- - dAtA[i] = 0x12 - } - if len(m.Sender) > 0 { - i -= len(m.Sender) - copy(dAtA[i:], m.Sender) - i = encodeVarintQuery(dAtA, i, uint64(len(m.Sender))) - i-- - dAtA[i] = 0xa - } - return len(dAtA) - i, nil -} - func (m *OfferListResponse) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -694,27 +586,6 @@ func (m *QueryOfferByAddrRequest) Size() (n int) { return n } -func (m *Offer) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - l = len(m.Sender) - if l > 0 { - n += 1 + l + sovQuery(uint64(l)) - } - l = len(m.Amount) - if l > 0 { - n += 1 + l + sovQuery(uint64(l)) - } - l = len(m.Request) - if l > 0 { - n += 1 + l + sovQuery(uint64(l)) - } - return n -} - func (m *OfferListResponse) Size() (n int) { if m == nil { return 0 @@ -1001,152 +872,6 @@ func (m *QueryOfferByAddrRequest) Unmarshal(dAtA []byte) error { } return nil } -func (m *Offer) 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 ErrIntOverflowQuery - } - 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: Offer: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: Offer: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Sender", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowQuery - } - 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 ErrInvalidLengthQuery - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthQuery - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Sender = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Amount", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowQuery - } - 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 ErrInvalidLengthQuery - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthQuery - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Amount = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 3: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Request", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowQuery - } - 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 ErrInvalidLengthQuery - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthQuery - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Request = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipQuery(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthQuery - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} func (m *OfferListResponse) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 diff --git a/x/escrow/types/tx.pb.go b/x/escrow/types/tx.pb.go index 0646783..0f2ced2 100644 --- a/x/escrow/types/tx.pb.go +++ b/x/escrow/types/tx.pb.go @@ -1,11 +1,13 @@ // Code generated by protoc-gen-gogo. DO NOT EDIT. -// source: escrow/escrow/tx.proto +// source: escrow/tx.proto package types import ( context "context" fmt "fmt" + github_com_cosmos_cosmos_sdk_types "github.com/cosmos/cosmos-sdk/types" + types "github.com/cosmos/cosmos-sdk/types" _ "github.com/gogo/protobuf/gogoproto" grpc1 "github.com/gogo/protobuf/grpc" proto "github.com/gogo/protobuf/proto" @@ -29,25 +31,24 @@ var _ = math.Inf const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package // this line is used by starport scaffolding # proto/tx/message -type OfferRequest struct { - Sender string `protobuf:"bytes,1,opt,name=sender,proto3" json:"sender,omitempty"` - Amount string `protobuf:"bytes,2,opt,name=amount,proto3" json:"amount,omitempty"` - // [(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Coins"]; - Request string `protobuf:"bytes,3,opt,name=request,proto3" json:"request,omitempty"` +type Offer struct { + Sender string `protobuf:"bytes,1,opt,name=sender,proto3" json:"sender,omitempty"` + Amount github_com_cosmos_cosmos_sdk_types.Coins `protobuf:"bytes,2,rep,name=amount,proto3,castrepeated=github.com/cosmos/cosmos-sdk/types.Coins" json:"amount"` + Request github_com_cosmos_cosmos_sdk_types.Coins `protobuf:"bytes,3,rep,name=request,proto3,castrepeated=github.com/cosmos/cosmos-sdk/types.Coins" json:"request"` } -func (m *OfferRequest) Reset() { *m = OfferRequest{} } -func (m *OfferRequest) String() string { return proto.CompactTextString(m) } -func (*OfferRequest) ProtoMessage() {} -func (*OfferRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_f5eef200b34c62c8, []int{0} +func (m *Offer) Reset() { *m = Offer{} } +func (m *Offer) String() string { return proto.CompactTextString(m) } +func (*Offer) ProtoMessage() {} +func (*Offer) Descriptor() ([]byte, []int) { + return fileDescriptor_8e01f3e45c7c056c, []int{0} } -func (m *OfferRequest) XXX_Unmarshal(b []byte) error { +func (m *Offer) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) } -func (m *OfferRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { +func (m *Offer) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { if deterministic { - return xxx_messageInfo_OfferRequest.Marshal(b, m, deterministic) + return xxx_messageInfo_Offer.Marshal(b, m, deterministic) } else { b = b[:cap(b)] n, err := m.MarshalToSizedBuffer(b) @@ -57,37 +58,37 @@ func (m *OfferRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) return b[:n], nil } } -func (m *OfferRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_OfferRequest.Merge(m, src) +func (m *Offer) XXX_Merge(src proto.Message) { + xxx_messageInfo_Offer.Merge(m, src) } -func (m *OfferRequest) XXX_Size() int { +func (m *Offer) XXX_Size() int { return m.Size() } -func (m *OfferRequest) XXX_DiscardUnknown() { - xxx_messageInfo_OfferRequest.DiscardUnknown(m) +func (m *Offer) XXX_DiscardUnknown() { + xxx_messageInfo_Offer.DiscardUnknown(m) } -var xxx_messageInfo_OfferRequest proto.InternalMessageInfo +var xxx_messageInfo_Offer proto.InternalMessageInfo -func (m *OfferRequest) GetSender() string { +func (m *Offer) GetSender() string { if m != nil { return m.Sender } return "" } -func (m *OfferRequest) GetAmount() string { +func (m *Offer) GetAmount() github_com_cosmos_cosmos_sdk_types.Coins { if m != nil { return m.Amount } - return "" + return nil } -func (m *OfferRequest) GetRequest() string { +func (m *Offer) GetRequest() github_com_cosmos_cosmos_sdk_types.Coins { if m != nil { return m.Request } - return "" + return nil } //message Coin { @@ -103,7 +104,7 @@ func (m *OfferResponse) Reset() { *m = OfferResponse{} } func (m *OfferResponse) String() string { return proto.CompactTextString(m) } func (*OfferResponse) ProtoMessage() {} func (*OfferResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_f5eef200b34c62c8, []int{1} + return fileDescriptor_8e01f3e45c7c056c, []int{1} } func (m *OfferResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -147,30 +148,35 @@ func (m *OfferResponse) GetIndex() int64 { } func init() { - proto.RegisterType((*OfferRequest)(nil), "escrow.OfferRequest") + proto.RegisterType((*Offer)(nil), "escrow.Offer") proto.RegisterType((*OfferResponse)(nil), "escrow.OfferResponse") } -func init() { proto.RegisterFile("escrow/escrow/tx.proto", fileDescriptor_f5eef200b34c62c8) } - -var fileDescriptor_f5eef200b34c62c8 = []byte{ - // 254 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x12, 0x4b, 0x2d, 0x4e, 0x2e, - 0xca, 0x2f, 0xd7, 0x87, 0x52, 0x25, 0x15, 0x7a, 0x05, 0x45, 0xf9, 0x25, 0xf9, 0x42, 0x6c, 0x10, - 0x01, 0x29, 0x91, 0xf4, 0xfc, 0xf4, 0x7c, 0xb0, 0x90, 0x3e, 0x88, 0x05, 0x91, 0x55, 0x8a, 0xe0, - 0xe2, 0xf1, 0x4f, 0x4b, 0x4b, 0x2d, 0x0a, 0x4a, 0x2d, 0x2c, 0x4d, 0x2d, 0x2e, 0x11, 0x12, 0xe3, - 0x62, 0x2b, 0x4e, 0xcd, 0x4b, 0x49, 0x2d, 0x92, 0x60, 0x54, 0x60, 0xd4, 0xe0, 0x0c, 0x82, 0xf2, - 0x40, 0xe2, 0x89, 0xb9, 0xf9, 0xa5, 0x79, 0x25, 0x12, 0x4c, 0x10, 0x71, 0x08, 0x4f, 0x48, 0x82, - 0x8b, 0xbd, 0x08, 0xa2, 0x55, 0x82, 0x19, 0x2c, 0x01, 0xe3, 0x2a, 0xd9, 0x72, 0xf1, 0x42, 0x4d, - 0x2e, 0x2e, 0xc8, 0xcf, 0x2b, 0x4e, 0xc5, 0x69, 0xb4, 0x08, 0x17, 0x6b, 0x66, 0x5e, 0x4a, 0x6a, - 0x05, 0xd8, 0x64, 0xe6, 0x20, 0x08, 0xc7, 0xc8, 0x9a, 0x8b, 0xd9, 0xb7, 0x38, 0x5d, 0xc8, 0x84, - 0x8b, 0x15, 0x6c, 0x8a, 0x90, 0x88, 0x1e, 0xc4, 0x1f, 0x7a, 0xc8, 0xce, 0x95, 0x12, 0x45, 0x13, - 0x85, 0x58, 0xe5, 0xe4, 0x73, 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, 0x46, - 0xe9, 0x99, 0x25, 0x19, 0xa5, 0x49, 0x7a, 0xc9, 0xf9, 0xb9, 0xfa, 0x99, 0x79, 0x25, 0xa9, 0x45, - 0xc9, 0x19, 0x89, 0x99, 0x79, 0x49, 0xa9, 0x45, 0x39, 0x99, 0x79, 0xfa, 0x05, 0xf9, 0xf9, 0x39, - 0x25, 0xf9, 0x95, 0xfa, 0x15, 0xf0, 0x40, 0xac, 0x2c, 0x48, 0x2d, 0x4e, 0x62, 0x03, 0x07, 0x95, - 0x31, 0x20, 0x00, 0x00, 0xff, 0xff, 0x6c, 0xed, 0x8e, 0x31, 0x62, 0x01, 0x00, 0x00, +func init() { proto.RegisterFile("escrow/tx.proto", fileDescriptor_8e01f3e45c7c056c) } + +var fileDescriptor_8e01f3e45c7c056c = []byte{ + // 326 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x91, 0xb1, 0x4e, 0xeb, 0x30, + 0x14, 0x86, 0x93, 0x46, 0xcd, 0xd5, 0xf5, 0x55, 0x75, 0xa5, 0xa8, 0xa0, 0xd0, 0xc1, 0xad, 0x3a, + 0x65, 0xa9, 0x4d, 0x0b, 0x2b, 0x4b, 0x59, 0x41, 0x48, 0x19, 0xd9, 0x92, 0xf4, 0x34, 0xb5, 0x68, + 0x7d, 0x82, 0xed, 0x42, 0xfb, 0x16, 0x3c, 0x07, 0x4f, 0xd2, 0xb1, 0x23, 0x13, 0xa0, 0x76, 0xe4, + 0x25, 0x50, 0xe3, 0x44, 0x82, 0x81, 0x8d, 0xc9, 0xfe, 0xcf, 0xd1, 0xf9, 0x7e, 0xfd, 0xe7, 0x90, + 0xff, 0xa0, 0x33, 0x85, 0x8f, 0xdc, 0xac, 0x58, 0xa1, 0xd0, 0x60, 0xe0, 0xdb, 0x42, 0xa7, 0x9d, + 0x63, 0x8e, 0x65, 0x89, 0x1f, 0x7e, 0xb6, 0xdb, 0xa1, 0x19, 0xea, 0x05, 0x6a, 0x9e, 0x26, 0x1a, + 0xf8, 0xc3, 0x30, 0x05, 0x93, 0x0c, 0x79, 0x86, 0x42, 0xda, 0x7e, 0xff, 0xc3, 0x25, 0xcd, 0x9b, + 0xe9, 0x14, 0x54, 0x70, 0x4c, 0x7c, 0x0d, 0x72, 0x02, 0x2a, 0x74, 0x7b, 0x6e, 0xf4, 0x37, 0xae, + 0x54, 0x90, 0x11, 0x3f, 0x59, 0xe0, 0x52, 0x9a, 0xb0, 0xd1, 0xf3, 0xa2, 0x7f, 0xa3, 0x13, 0x66, + 0x91, 0xec, 0x80, 0x64, 0x15, 0x92, 0x5d, 0xa2, 0x90, 0xe3, 0xd3, 0xcd, 0x6b, 0xd7, 0x79, 0x7e, + 0xeb, 0x46, 0xb9, 0x30, 0xb3, 0x65, 0xca, 0x32, 0x5c, 0xf0, 0xca, 0xdf, 0x3e, 0x03, 0x3d, 0xb9, + 0xe3, 0x66, 0x5d, 0x80, 0x2e, 0x07, 0x74, 0x5c, 0xa1, 0x03, 0x20, 0x7f, 0x14, 0xdc, 0x2f, 0x41, + 0x9b, 0xd0, 0xfb, 0x7d, 0x97, 0x9a, 0xdd, 0xbf, 0x20, 0xad, 0x32, 0x6c, 0x0c, 0xba, 0x40, 0xa9, + 0xe1, 0xc7, 0xd0, 0x6d, 0xd2, 0x14, 0x72, 0x02, 0xab, 0xb0, 0xd1, 0x73, 0x23, 0x2f, 0xb6, 0x62, + 0x74, 0x4e, 0xbc, 0x6b, 0x9d, 0x07, 0x83, 0x7a, 0x65, 0x2d, 0x66, 0x77, 0xcf, 0x4a, 0xd9, 0x39, + 0xfa, 0x26, 0x6b, 0x8f, 0xf1, 0xd5, 0x66, 0x47, 0xdd, 0xed, 0x8e, 0xba, 0xef, 0x3b, 0xea, 0x3e, + 0xed, 0xa9, 0xb3, 0xdd, 0x53, 0xe7, 0x65, 0x4f, 0x9d, 0xdb, 0xd1, 0x97, 0x04, 0x42, 0x1a, 0x50, + 0xd9, 0x2c, 0x11, 0x32, 0x05, 0x35, 0x17, 0x92, 0x17, 0x88, 0x73, 0x83, 0x6b, 0xbe, 0xe2, 0xf5, + 0xc5, 0x0f, 0x89, 0x52, 0xbf, 0xbc, 0xdb, 0xd9, 0x67, 0x00, 0x00, 0x00, 0xff, 0xff, 0x52, 0xb9, + 0x44, 0x4a, 0x08, 0x02, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -186,7 +192,7 @@ const _ = grpc.SupportPackageIsVersion4 // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. type MsgClient interface { // this line is used by starport scaffolding # proto/tx/rpc - Offer(ctx context.Context, in *OfferRequest, opts ...grpc.CallOption) (*OfferResponse, error) + Offer(ctx context.Context, in *Offer, opts ...grpc.CallOption) (*OfferResponse, error) } type msgClient struct { @@ -197,7 +203,7 @@ func NewMsgClient(cc grpc1.ClientConn) MsgClient { return &msgClient{cc} } -func (c *msgClient) Offer(ctx context.Context, in *OfferRequest, opts ...grpc.CallOption) (*OfferResponse, error) { +func (c *msgClient) Offer(ctx context.Context, in *Offer, opts ...grpc.CallOption) (*OfferResponse, error) { out := new(OfferResponse) err := c.cc.Invoke(ctx, "/escrow.Msg/Offer", in, out, opts...) if err != nil { @@ -209,14 +215,14 @@ func (c *msgClient) Offer(ctx context.Context, in *OfferRequest, opts ...grpc.Ca // MsgServer is the server API for Msg service. type MsgServer interface { // this line is used by starport scaffolding # proto/tx/rpc - Offer(context.Context, *OfferRequest) (*OfferResponse, error) + Offer(context.Context, *Offer) (*OfferResponse, error) } // UnimplementedMsgServer can be embedded to have forward compatible implementations. type UnimplementedMsgServer struct { } -func (*UnimplementedMsgServer) Offer(ctx context.Context, req *OfferRequest) (*OfferResponse, error) { +func (*UnimplementedMsgServer) Offer(ctx context.Context, req *Offer) (*OfferResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method Offer not implemented") } @@ -225,7 +231,7 @@ func RegisterMsgServer(s grpc1.Server, srv MsgServer) { } func _Msg_Offer_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(OfferRequest) + in := new(Offer) if err := dec(in); err != nil { return nil, err } @@ -237,7 +243,7 @@ func _Msg_Offer_Handler(srv interface{}, ctx context.Context, dec func(interface FullMethod: "/escrow.Msg/Offer", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(MsgServer).Offer(ctx, req.(*OfferRequest)) + return srv.(MsgServer).Offer(ctx, req.(*Offer)) } return interceptor(ctx, in, info, handler) } @@ -252,10 +258,10 @@ var _Msg_serviceDesc = grpc.ServiceDesc{ }, }, Streams: []grpc.StreamDesc{}, - Metadata: "escrow/escrow/tx.proto", + Metadata: "escrow/tx.proto", } -func (m *OfferRequest) Marshal() (dAtA []byte, err error) { +func (m *Offer) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) n, err := m.MarshalToSizedBuffer(dAtA[:size]) @@ -265,29 +271,43 @@ func (m *OfferRequest) Marshal() (dAtA []byte, err error) { return dAtA[:n], nil } -func (m *OfferRequest) MarshalTo(dAtA []byte) (int, error) { +func (m *Offer) MarshalTo(dAtA []byte) (int, error) { size := m.Size() return m.MarshalToSizedBuffer(dAtA[:size]) } -func (m *OfferRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { +func (m *Offer) MarshalToSizedBuffer(dAtA []byte) (int, error) { i := len(dAtA) _ = i var l int _ = l if len(m.Request) > 0 { - i -= len(m.Request) - copy(dAtA[i:], m.Request) - i = encodeVarintTx(dAtA, i, uint64(len(m.Request))) - i-- - dAtA[i] = 0x1a + for iNdEx := len(m.Request) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Request[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintTx(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x1a + } } if len(m.Amount) > 0 { - i -= len(m.Amount) - copy(dAtA[i:], m.Amount) - i = encodeVarintTx(dAtA, i, uint64(len(m.Amount))) - i-- - dAtA[i] = 0x12 + for iNdEx := len(m.Amount) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Amount[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintTx(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } } if len(m.Sender) > 0 { i -= len(m.Sender) @@ -345,7 +365,7 @@ func encodeVarintTx(dAtA []byte, offset int, v uint64) int { dAtA[offset] = uint8(v) return base } -func (m *OfferRequest) Size() (n int) { +func (m *Offer) Size() (n int) { if m == nil { return 0 } @@ -355,13 +375,17 @@ func (m *OfferRequest) Size() (n int) { if l > 0 { n += 1 + l + sovTx(uint64(l)) } - l = len(m.Amount) - if l > 0 { - n += 1 + l + sovTx(uint64(l)) + if len(m.Amount) > 0 { + for _, e := range m.Amount { + l = e.Size() + n += 1 + l + sovTx(uint64(l)) + } } - l = len(m.Request) - if l > 0 { - n += 1 + l + sovTx(uint64(l)) + if len(m.Request) > 0 { + for _, e := range m.Request { + l = e.Size() + n += 1 + l + sovTx(uint64(l)) + } } return n } @@ -388,7 +412,7 @@ func sovTx(x uint64) (n int) { func sozTx(x uint64) (n int) { return sovTx(uint64((x << 1) ^ uint64((int64(x) >> 63)))) } -func (m *OfferRequest) Unmarshal(dAtA []byte) error { +func (m *Offer) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -411,10 +435,10 @@ func (m *OfferRequest) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: OfferRequest: wiretype end group for non-group") + return fmt.Errorf("proto: Offer: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: OfferRequest: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: Offer: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: @@ -453,7 +477,7 @@ func (m *OfferRequest) Unmarshal(dAtA []byte) error { if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field Amount", wireType) } - var stringLen uint64 + var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowTx @@ -463,29 +487,31 @@ func (m *OfferRequest) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + msglen |= int(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { + if msglen < 0 { return ErrInvalidLengthTx } - postIndex := iNdEx + intStringLen + postIndex := iNdEx + msglen if postIndex < 0 { return ErrInvalidLengthTx } if postIndex > l { return io.ErrUnexpectedEOF } - m.Amount = string(dAtA[iNdEx:postIndex]) + m.Amount = append(m.Amount, types.Coin{}) + if err := m.Amount[len(m.Amount)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } iNdEx = postIndex case 3: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field Request", wireType) } - var stringLen uint64 + var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowTx @@ -495,23 +521,25 @@ func (m *OfferRequest) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + msglen |= int(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { + if msglen < 0 { return ErrInvalidLengthTx } - postIndex := iNdEx + intStringLen + postIndex := iNdEx + msglen if postIndex < 0 { return ErrInvalidLengthTx } if postIndex > l { return io.ErrUnexpectedEOF } - m.Request = string(dAtA[iNdEx:postIndex]) + m.Request = append(m.Request, types.Coin{}) + if err := m.Request[len(m.Request)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } iNdEx = postIndex default: iNdEx = preIndex From 6db4e8321b6787149113e5dd2c89c8e211e230df Mon Sep 17 00:00:00 2001 From: yaruwang Date: Wed, 4 Aug 2021 15:38:39 +0200 Subject: [PATCH 12/22] add upgrade --- app/app.go | 58 ++++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 50 insertions(+), 8 deletions(-) diff --git a/app/app.go b/app/app.go index bed7fd1..c32be98 100644 --- a/app/app.go +++ b/app/app.go @@ -1,6 +1,10 @@ package app import ( + store "github.com/cosmos/cosmos-sdk/store/types" + "github.com/cosmos/cosmos-sdk/x/upgrade" + upgradekeeper "github.com/cosmos/cosmos-sdk/x/upgrade/keeper" + upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types" "github.com/interchainberlin/pooltoy/x/escrow" "io" "os" @@ -51,7 +55,7 @@ import ( govclient "github.com/cosmos/cosmos-sdk/x/gov/client" govkeeper "github.com/cosmos/cosmos-sdk/x/gov/keeper" govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" - transfer "github.com/cosmos/cosmos-sdk/x/ibc/applications/transfer" + "github.com/cosmos/cosmos-sdk/x/ibc/applications/transfer" ibctransferkeeper "github.com/cosmos/cosmos-sdk/x/ibc/applications/transfer/keeper" ibctransfertypes "github.com/cosmos/cosmos-sdk/x/ibc/applications/transfer/types" ibc "github.com/cosmos/cosmos-sdk/x/ibc/core" @@ -96,6 +100,7 @@ import ( upgradeclient "github.com/cosmos/cosmos-sdk/x/upgrade/client" upgradekeeper "github.com/cosmos/cosmos-sdk/x/upgrade/keeper" upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types" + ) const Name = "pooltoy" @@ -112,6 +117,8 @@ func getGovProposalHandlers() []govclient.ProposalHandler { upgradeclient.ProposalHandler, upgradeclient.CancelProposalHandler, // this line is used by starport scaffolding # stargate/app/govProposalHandler + upgradeclient.ProposalHandler, + upgradeclient.CancelProposalHandler, ) return govProposalHandlers @@ -133,6 +140,7 @@ var ( mint.AppModuleBasic{}, distr.AppModuleBasic{}, gov.NewAppModuleBasic(getGovProposalHandlers()...), + upgrade.AppModuleBasic{}, params.AppModuleBasic{}, crisis.AppModuleBasic{}, slashing.AppModuleBasic{}, @@ -155,7 +163,7 @@ var ( govtypes.ModuleName: {authtypes.Burner}, ibctransfertypes.ModuleName: {authtypes.Minter, authtypes.Burner}, faucettypes.ModuleName: {authtypes.Minter}, - escrowtypes.ModuleName: {authtypes.Staking}, + escrowtypes.ModuleName: {authtypes.Staking}, } // module accounts that are allowed to receive tokens @@ -204,6 +212,7 @@ type App struct { MintKeeper mintkeeper.Keeper // todo check if needed DistrKeeper distrkeeper.Keeper GovKeeper govkeeper.Keeper + UpgradeKeeper upgradekeeper.Keeper CrisisKeeper crisiskeeper.Keeper UpgradeKeeper upgradekeeper.Keeper ParamsKeeper paramskeeper.Keeper @@ -253,6 +262,8 @@ func New( pooltoytypes.StoreKey, faucettypes.StoreKey, escrowtypes.StoreKey, + upgradetypes.StoreKey, + // this line is used by starport scaffolding # stargate/app/storeKey ) tkeys := sdk.NewTransientStoreKeys(paramstypes.TStoreKey) @@ -280,7 +291,10 @@ func New( // grant capabilities for the ibc and ibc-transfer modules scopedIBCKeeper := app.CapabilityKeeper.ScopeToModule(ibchost.ModuleName) scopedTransferKeeper := app.CapabilityKeeper.ScopeToModule(ibctransfertypes.ModuleName) - + //StakingKeeper := stakingkeeper.NewKeeper( + // appCodec, keys[stakingtypes.StoreKey], app.AccountKeeper, app.BankKeeper, app.GetSubspace(stakingtypes.ModuleName), + //) + app.UpgradeKeeper = upgradekeeper.NewKeeper(skipUpgradeHeights, keys[upgradetypes.StoreKey], appCodec, homePath) // add keepers app.AccountKeeper = authkeeper.NewAccountKeeper( appCodec, keys[authtypes.StoreKey], app.GetSubspace(authtypes.ModuleName), authtypes.ProtoBaseAccount, maccPerms, @@ -325,9 +339,14 @@ func New( govRouter := govtypes.NewRouter() govRouter.AddRoute(govtypes.RouterKey, govtypes.ProposalHandler). AddRoute(paramproposal.RouterKey, params.NewParamChangeProposalHandler(app.ParamsKeeper)). + AddRoute(upgradetypes.RouterKey, upgrade.NewSoftwareUpgradeProposalHandler(app.UpgradeKeeper)). AddRoute(distrtypes.RouterKey, distr.NewCommunityPoolSpendProposalHandler(app.DistrKeeper)). AddRoute(upgradetypes.RouterKey, upgrade.NewSoftwareUpgradeProposalHandler(app.UpgradeKeeper)). AddRoute(ibchost.RouterKey, ibcclient.NewClientUpdateProposalHandler(app.IBCKeeper.ClientKeeper)) + app.GovKeeper = govkeeper.NewKeeper( + appCodec, keys[govtypes.StoreKey], app.GetSubspace(govtypes.ModuleName), app.AccountKeeper, app.BankKeeper, + &stakingKeeper, govRouter, + ) // Create Transfer Keepers app.TransferKeeper = ibctransferkeeper.NewKeeper( @@ -353,6 +372,7 @@ func New( app.appCodec, ) + app.EscrowKeeper = escrowkeeper.NewKeeper( app.BankKeeper, app.AccountKeeper, @@ -375,10 +395,10 @@ func New( // this line is used by starport scaffolding # stargate/app/keeperDefinition - app.GovKeeper = govkeeper.NewKeeper( - appCodec, keys[govtypes.StoreKey], app.GetSubspace(govtypes.ModuleName), app.AccountKeeper, app.BankKeeper, - &stakingKeeper, govRouter, - ) + //app.GovKeeper = govkeeper.NewKeeper( + // appCodec, keys[govtypes.StoreKey], app.GetSubspace(govtypes.ModuleName), app.AccountKeeper, app.BankKeeper, + // &stakingKeeper, govRouter, + //) /**** Module Options ****/ @@ -432,11 +452,33 @@ func New( app.mm.SetOrderBeginBlockers( upgradetypes.ModuleName, distrtypes.ModuleName, slashingtypes.ModuleName, - evidencetypes.ModuleName, stakingtypes.ModuleName, minttypes.ModuleName, ibchost.ModuleName, + evidencetypes.ModuleName, stakingtypes.ModuleName, minttypes.ModuleName,pooltoytypes.ModuleName, faucettypes.ModuleName, escrowtypes.ModuleName, ibchost.ModuleName, ) app.mm.SetOrderEndBlockers(crisistypes.ModuleName, govtypes.ModuleName, stakingtypes.ModuleName, pooltoytypes.ModuleName, faucettypes.ModuleName, escrowtypes.ModuleName) + app.UpgradeKeeper.SetUpgradeHandler("pooltoy-upgrade-0", + func(ctx sdk.Context, plan upgradetypes.Plan) { + // a place to run genesis initialization logic for new modules that were just added as part of the upgrade... + + // var genState escrowtypes.GenesisState + // genState.Params = escrowtypes.DefaultParams() + // genState.Params.PoolCreationFee = sdk.NewCoins(sdk.NewCoin("uatom", sdk.NewInt(40000000))) + // app.Escrow.InitGenesis(ctx, genState) + }) + + upgradeInfo, err := app.UpgradeKeeper.ReadUpgradeInfoFromDisk() + if err != nil { + panic(err) + } + + if upgradeInfo.Name == "pooltoy-upgrade-0" && !app.UpgradeKeeper.IsSkipHeight(upgradeInfo.Height) { + storeUpgrades := store.StoreUpgrades{ + // Added: []string{liquiditytypes.ModuleName}, + } + // configure store loader that checks if version == upgradeHeight and applies store upgrades + app.SetStoreLoader(upgradetypes.UpgradeStoreLoader(upgradeInfo.Height, &storeUpgrades)) + } // NOTE: The genutils module must occur after staking so that pools are // properly initialized with tokens from genesis accounts. // NOTE: Capability module must occur first so that it can initialize any capabilities From 4cefe70d1cc2985fe206585ce39aa9dcf4037ac7 Mon Sep 17 00:00:00 2001 From: yaruwang Date: Thu, 5 Aug 2021 10:32:35 +0200 Subject: [PATCH 13/22] escrow offer query debug --- proto/escrow/query.proto | 8 +- x/escrow/client/cli/query.go | 4 +- x/escrow/keeper/query_server.go | 2 +- x/escrow/keeper/store.go | 33 ++----- x/escrow/types/query.pb.go | 163 ++++++-------------------------- 5 files changed, 42 insertions(+), 168 deletions(-) diff --git a/proto/escrow/query.proto b/proto/escrow/query.proto index 4c88a51..66c7fe9 100644 --- a/proto/escrow/query.proto +++ b/proto/escrow/query.proto @@ -11,20 +11,18 @@ option go_package = "github.com/interchainberlin/pooltoy/x/escrow/types"; service Query { // this line is used by starport scaffolding # 2 rpc QueryOfferListAll (OfferListAllRequest) returns (OfferListResponse); - rpc QueryOfferByID (QueryOfferByIDRequest) returns (Offer); + rpc QueryOfferByID (QueryOfferByIDRequest) returns (OfferListResponse); rpc QueryOfferByAddr (QueryOfferByAddrRequest) returns (OfferListResponse); } message OfferListAllRequest {} message QueryOfferByIDRequest{ - string querier = 1; - int64 id = 2; + int64 id = 1; } message QueryOfferByAddrRequest { - string querier = 1; - string offerer = 2; + string offerer = 1; } message OfferListResponse { diff --git a/x/escrow/client/cli/query.go b/x/escrow/client/cli/query.go index 0418f09..f34e312 100644 --- a/x/escrow/client/cli/query.go +++ b/x/escrow/client/cli/query.go @@ -60,7 +60,7 @@ func escrowOfferByAddr() *cobra.Command { cmd := &cobra.Command{ Use: "offer-by-addr [querier] [offerer]", Short: "show all the offers of an address", - Args: cobra.ExactArgs(2), + Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { ctx, err := client.GetClientTxContext(cmd) if err != nil { @@ -68,7 +68,7 @@ func escrowOfferByAddr() *cobra.Command { } queryClient := types.NewQueryClient(ctx) - offerList, err := queryClient.QueryOfferByAddr(context.Background(), &types.QueryOfferByAddrRequest{Querier:args[0], Offerer: args[1]}) + offerList, err := queryClient.QueryOfferByAddr(context.Background(), &types.QueryOfferByAddrRequest{Offerer: args[0]}) if err != nil { return err } diff --git a/x/escrow/keeper/query_server.go b/x/escrow/keeper/query_server.go index 07fd114..c6038bd 100644 --- a/x/escrow/keeper/query_server.go +++ b/x/escrow/keeper/query_server.go @@ -33,6 +33,6 @@ func (k Keeper)QueryOfferByAddr(c context.Context, req *types.QueryOfferByAddrRe return &offers, nil } -func (k Keeper) QueryOfferByID(c context.Context, req *types.QueryOfferByIDRequest) (*types.Offer, error){ +func (k Keeper) QueryOfferByID(c context.Context, req *types.QueryOfferByIDRequest) (*types.OfferListResponse, error){ return nil, nil } diff --git a/x/escrow/keeper/store.go b/x/escrow/keeper/store.go index f3cf3f0..7ea6ded 100644 --- a/x/escrow/keeper/store.go +++ b/x/escrow/keeper/store.go @@ -18,15 +18,13 @@ func (k Keeper) InsertOffer(ctx sdk.Context, offer types.Offer) ([]byte, error) } storeK := []byte(types.OfferPrefix) storeK = append(storeK, addr...) - - fmt.Println("storeK is!!!!",storeK) storeK = append(storeK, []byte(strconv.FormatInt(*k.index, 10))...) - // todo maybe we do not need int64 for index + // todo maybe we do not need int64 for index storeV, err := offer.Marshal() if err != nil { return nil, err } - fmt.Println("store key is", storeK) + store.Set(storeK, storeV) return storeV, nil @@ -39,9 +37,7 @@ func (k Keeper) ListOffer(ctx sdk.Context, offer types.OfferListAllRequest) (typ iterator := sdk.KVStorePrefixIterator(store, []byte(types.OfferPrefix)) for ; iterator.Valid(); iterator.Next() { var offer types.Offer - fmt.Println("key is!!!!", string(iterator.Key())) - // k.cdc.MustUnmarshalBinaryBare(store.Get(iterator.Key()), &offer) - offer.Unmarshal(iterator.Value()) + offer.Unmarshal(iterator.Value()) offers = append(offers, &offer) } @@ -51,22 +47,15 @@ func (k Keeper) ListOffer(ctx sdk.Context, offer types.OfferListAllRequest) (typ func (k Keeper) ListOfferByAddr(ctx sdk.Context, offer types.QueryOfferByAddrRequest) (types.OfferListResponse, error) { addr, err := sdk.AccAddressFromBech32(offer.Offerer) - fmt.Println("addr is!!!!", addr.String()) if err != nil { return types.OfferListResponse{}, err } addrStore := k.getAddressPrefixStore(ctx, addr) - //fmt.Println("does the store has the addr!!!!", addrStore.Has(addrStore.key())) + iterator := addrStore.Iterator(nil, nil) defer iterator.Close() - offers := []*types.Offer{} - //i :=0 - fmt.Println("valid iterator!!!!", iterator.Valid()) - fmt.Println("valid iterator err!!!!", iterator.Error()) for ; iterator.Valid(); iterator.Next() { - fmt.Println("start iterate sub store!!!!") - fmt.Println("substore key is!!!!", string(iterator.Key())) var offer types.Offer k.cdc.MustUnmarshalBinaryBare(addrStore.Get(iterator.Key()), &offer) offers = append(offers, &offer) @@ -77,24 +66,14 @@ func (k Keeper) ListOfferByAddr(ctx sdk.Context, offer types.QueryOfferByAddrReq func (k Keeper) getAddressPrefixStore(ctx sdk.Context, addr sdk.AccAddress) prefix.Store { store := ctx.KVStore(k.storeKey) -// ref :="offer-" - b := []byte(types.OfferPrefix) - fmt.Println("ref b is!!!!",b) - addr, _ = sdk.AccAddressFromBech32("cosmos126c2ak7k5qw8rhhha60kgksjrjf5jvkgtzlklw") - fmt.Println("ref addr !!!!", addr) - fmt.Println("the new prefix is!!!!", CreateAddrPrefix(addr)) addrStore := prefix.NewStore(store, CreateAddrPrefix(addr)) return addrStore } - func CreateAddrPrefix(addr []byte) []byte { -//todo change to MustLengthPrefix(addr)...) for v0.43.0 release - //prefix := append([]byte(types.OfferPrefix),[]byte{byte(len(addr))}...) + //todo change to MustLengthPrefix(addr)...) for v0.43.0 release prefix := append([]byte(types.OfferPrefix), addr...) - fmt.Println("the prefix is!!!!", prefix) + fmt.Println("the prefix len is!!!!", len(prefix)) return prefix } - -// todo cannot find the pakcage: address.MustLengthPrefix(addr)... diff --git a/x/escrow/types/query.pb.go b/x/escrow/types/query.pb.go index 3b7921b..3ec6b51 100644 --- a/x/escrow/types/query.pb.go +++ b/x/escrow/types/query.pb.go @@ -65,8 +65,7 @@ func (m *OfferListAllRequest) XXX_DiscardUnknown() { var xxx_messageInfo_OfferListAllRequest proto.InternalMessageInfo type QueryOfferByIDRequest struct { - Querier string `protobuf:"bytes,1,opt,name=querier,proto3" json:"querier,omitempty"` - Id int64 `protobuf:"varint,2,opt,name=id,proto3" json:"id,omitempty"` + Id int64 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"` } func (m *QueryOfferByIDRequest) Reset() { *m = QueryOfferByIDRequest{} } @@ -102,13 +101,6 @@ func (m *QueryOfferByIDRequest) XXX_DiscardUnknown() { var xxx_messageInfo_QueryOfferByIDRequest proto.InternalMessageInfo -func (m *QueryOfferByIDRequest) GetQuerier() string { - if m != nil { - return m.Querier - } - return "" -} - func (m *QueryOfferByIDRequest) GetId() int64 { if m != nil { return m.Id @@ -117,8 +109,7 @@ func (m *QueryOfferByIDRequest) GetId() int64 { } type QueryOfferByAddrRequest struct { - Querier string `protobuf:"bytes,1,opt,name=querier,proto3" json:"querier,omitempty"` - Offerer string `protobuf:"bytes,2,opt,name=offerer,proto3" json:"offerer,omitempty"` + Offerer string `protobuf:"bytes,1,opt,name=offerer,proto3" json:"offerer,omitempty"` } func (m *QueryOfferByAddrRequest) Reset() { *m = QueryOfferByAddrRequest{} } @@ -154,13 +145,6 @@ func (m *QueryOfferByAddrRequest) XXX_DiscardUnknown() { var xxx_messageInfo_QueryOfferByAddrRequest proto.InternalMessageInfo -func (m *QueryOfferByAddrRequest) GetQuerier() string { - if m != nil { - return m.Querier - } - return "" -} - func (m *QueryOfferByAddrRequest) GetOfferer() string { if m != nil { return m.Offerer @@ -222,29 +206,28 @@ func init() { func init() { proto.RegisterFile("escrow/query.proto", fileDescriptor_6d37bf65b8b6e159) } var fileDescriptor_6d37bf65b8b6e159 = []byte{ - // 347 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x84, 0x52, 0xc1, 0x4e, 0xc2, 0x40, - 0x14, 0x64, 0x21, 0x42, 0x58, 0x23, 0xca, 0x1a, 0x62, 0xad, 0x5a, 0x49, 0x4f, 0x24, 0x26, 0xdd, - 0x04, 0xef, 0x46, 0x88, 0x17, 0x23, 0x6a, 0xec, 0xd1, 0x5b, 0xa1, 0x0b, 0x6c, 0x52, 0xf7, 0x95, - 0xdd, 0x25, 0xd2, 0xbf, 0xf0, 0xb3, 0x3c, 0x72, 0xf4, 0x68, 0xc0, 0x0f, 0x31, 0xb4, 0x14, 0xa8, - 0x12, 0x3d, 0xee, 0xcc, 0xbc, 0xd9, 0x79, 0x93, 0x87, 0x09, 0x53, 0x3d, 0x09, 0xaf, 0x74, 0x34, - 0x66, 0x32, 0x72, 0x42, 0x09, 0x1a, 0x48, 0x31, 0xc1, 0xcc, 0xd3, 0x01, 0xc0, 0x20, 0x60, 0xd4, - 0x0b, 0x39, 0xf5, 0x84, 0x00, 0xed, 0x69, 0x0e, 0x42, 0x25, 0x2a, 0x73, 0x7f, 0x39, 0xa9, 0x27, - 0x09, 0x60, 0xd7, 0xf0, 0xe1, 0x63, 0xbf, 0xcf, 0x64, 0x87, 0x2b, 0xdd, 0x0a, 0x02, 0x97, 0x8d, - 0xc6, 0x4c, 0x69, 0xbb, 0x85, 0x6b, 0x4f, 0x0b, 0xf3, 0x98, 0x6b, 0x47, 0xb7, 0x37, 0x4b, 0x82, - 0x18, 0xb8, 0xb4, 0xf8, 0x95, 0x33, 0x69, 0xa0, 0x3a, 0x6a, 0x94, 0xdd, 0xf4, 0x49, 0x2a, 0x38, - 0xcf, 0x7d, 0x23, 0x5f, 0x47, 0x8d, 0x82, 0x9b, 0xe7, 0xbe, 0x7d, 0x8f, 0x8f, 0x36, 0x2d, 0x5a, - 0xbe, 0x2f, 0xff, 0x37, 0x31, 0x70, 0x09, 0x16, 0x7a, 0x26, 0x63, 0xa7, 0xb2, 0x9b, 0x3e, 0xed, - 0x6b, 0x5c, 0x5d, 0x05, 0x75, 0x99, 0x0a, 0x41, 0x28, 0x46, 0x2e, 0x70, 0x19, 0x52, 0xd0, 0x40, - 0xf5, 0x42, 0x63, 0xb7, 0xb9, 0xe7, 0x24, 0x2b, 0x3a, 0xb1, 0xda, 0x5d, 0xf3, 0xcd, 0x2f, 0x84, - 0x77, 0xe2, 0x44, 0xe4, 0x0e, 0x57, 0xd7, 0xd1, 0x96, 0x9b, 0x93, 0x93, 0xcc, 0x60, 0xb6, 0x0f, - 0xf3, 0xf8, 0x17, 0xb9, 0xca, 0x70, 0x85, 0x2b, 0xd9, 0xaa, 0xc8, 0x59, 0x2a, 0xde, 0x5a, 0xa1, - 0x99, 0x4d, 0x48, 0x1e, 0xf0, 0xc1, 0xcf, 0x9e, 0xc8, 0xf9, 0x36, 0x87, 0x8d, 0x06, 0xff, 0xc8, - 0xd3, 0xee, 0xbc, 0xcf, 0x2c, 0x34, 0x9d, 0x59, 0xe8, 0x73, 0x66, 0xa1, 0xb7, 0xb9, 0x95, 0x9b, - 0xce, 0xad, 0xdc, 0xc7, 0xdc, 0xca, 0x3d, 0x37, 0x07, 0x5c, 0x0f, 0xc7, 0x5d, 0xa7, 0x07, 0x2f, - 0x94, 0x0b, 0xcd, 0x64, 0x6f, 0xe8, 0x71, 0xd1, 0x65, 0x32, 0xe0, 0x82, 0x86, 0x00, 0x81, 0x86, - 0x88, 0x4e, 0x68, 0x7a, 0x22, 0x51, 0xc8, 0x54, 0xb7, 0x18, 0x9f, 0xc9, 0xe5, 0x77, 0x00, 0x00, - 0x00, 0xff, 0xff, 0x41, 0xef, 0xda, 0xca, 0x73, 0x02, 0x00, 0x00, + // 331 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x7c, 0x91, 0x4f, 0x4e, 0x02, 0x31, + 0x18, 0xc5, 0x29, 0x44, 0x0c, 0x35, 0xa2, 0xd4, 0x10, 0x11, 0xb5, 0x92, 0xd9, 0x48, 0x62, 0x32, + 0x4d, 0xe0, 0x02, 0x42, 0xdc, 0xa8, 0x44, 0xe3, 0x2c, 0xdd, 0x0d, 0x4c, 0x81, 0x26, 0x63, 0xbf, + 0xa1, 0x2d, 0x91, 0xb9, 0x85, 0xc7, 0x72, 0xc9, 0xd2, 0xa5, 0x81, 0x0b, 0x78, 0x04, 0xc3, 0x0c, + 0x03, 0x8c, 0x12, 0x96, 0x7d, 0xef, 0xd7, 0xf7, 0xfd, 0xc3, 0x84, 0xeb, 0x9e, 0x82, 0x77, 0x36, + 0x1a, 0x73, 0x15, 0xda, 0x81, 0x02, 0x03, 0x24, 0x1f, 0x6b, 0xd5, 0x8b, 0x01, 0xc0, 0xc0, 0xe7, + 0xcc, 0x0d, 0x04, 0x73, 0xa5, 0x04, 0xe3, 0x1a, 0x01, 0x52, 0xc7, 0x54, 0xf5, 0x68, 0xf9, 0xd3, + 0x4c, 0x62, 0xc1, 0x2a, 0xe3, 0x93, 0xe7, 0x7e, 0x9f, 0xab, 0x8e, 0xd0, 0xa6, 0xe5, 0xfb, 0x0e, + 0x1f, 0x8d, 0xb9, 0x36, 0xd6, 0x35, 0x2e, 0xbf, 0x2c, 0xc2, 0x23, 0xaf, 0x1d, 0xde, 0xdf, 0x2d, + 0x0d, 0x52, 0xc4, 0x59, 0xe1, 0x55, 0x50, 0x0d, 0xd5, 0x73, 0x4e, 0x56, 0x78, 0x56, 0x13, 0x9f, + 0x6e, 0x82, 0x2d, 0xcf, 0x53, 0x09, 0x5a, 0xc1, 0xfb, 0xb0, 0x50, 0xb9, 0x8a, 0xf8, 0x82, 0x93, + 0x3c, 0xad, 0x5b, 0x5c, 0x5a, 0x15, 0x75, 0xb8, 0x0e, 0x40, 0x6a, 0x4e, 0x6e, 0x70, 0x01, 0x12, + 0xb1, 0x82, 0x6a, 0xb9, 0xfa, 0x41, 0xe3, 0xd0, 0x8e, 0xdb, 0xb5, 0x23, 0xda, 0x59, 0xfb, 0x8d, + 0x1f, 0x84, 0xf7, 0xa2, 0xba, 0xe4, 0x11, 0x97, 0xd6, 0x0d, 0x2c, 0xa7, 0x20, 0xe7, 0xa9, 0x8f, + 0xe9, 0xd9, 0xaa, 0x67, 0xff, 0xcc, 0x55, 0x0f, 0x0f, 0xb8, 0x98, 0x1e, 0x9b, 0x5c, 0x26, 0xf0, + 0xd6, 0x75, 0xec, 0xca, 0x7a, 0xc2, 0xc7, 0x7f, 0x37, 0x43, 0xae, 0xb6, 0xa5, 0x6d, 0xec, 0x6c, + 0x47, 0x5e, 0xbb, 0xf3, 0x39, 0xa3, 0x68, 0x3a, 0xa3, 0xe8, 0x7b, 0x46, 0xd1, 0xc7, 0x9c, 0x66, + 0xa6, 0x73, 0x9a, 0xf9, 0x9a, 0xd3, 0xcc, 0x6b, 0x63, 0x20, 0xcc, 0x70, 0xdc, 0xb5, 0x7b, 0xf0, + 0xc6, 0x84, 0x34, 0x5c, 0xf5, 0x86, 0xae, 0x90, 0x5d, 0xae, 0x7c, 0x21, 0x59, 0x00, 0xe0, 0x1b, + 0x08, 0xd9, 0x84, 0x25, 0xa7, 0x0f, 0x03, 0xae, 0xbb, 0xf9, 0xe8, 0xfc, 0xcd, 0xdf, 0x00, 0x00, + 0x00, 0xff, 0xff, 0x12, 0x03, 0x73, 0x9f, 0x4b, 0x02, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -261,7 +244,7 @@ const _ = grpc.SupportPackageIsVersion4 type QueryClient interface { // this line is used by starport scaffolding # 2 QueryOfferListAll(ctx context.Context, in *OfferListAllRequest, opts ...grpc.CallOption) (*OfferListResponse, error) - QueryOfferByID(ctx context.Context, in *QueryOfferByIDRequest, opts ...grpc.CallOption) (*Offer, error) + QueryOfferByID(ctx context.Context, in *QueryOfferByIDRequest, opts ...grpc.CallOption) (*OfferListResponse, error) QueryOfferByAddr(ctx context.Context, in *QueryOfferByAddrRequest, opts ...grpc.CallOption) (*OfferListResponse, error) } @@ -282,8 +265,8 @@ func (c *queryClient) QueryOfferListAll(ctx context.Context, in *OfferListAllReq return out, nil } -func (c *queryClient) QueryOfferByID(ctx context.Context, in *QueryOfferByIDRequest, opts ...grpc.CallOption) (*Offer, error) { - out := new(Offer) +func (c *queryClient) QueryOfferByID(ctx context.Context, in *QueryOfferByIDRequest, opts ...grpc.CallOption) (*OfferListResponse, error) { + out := new(OfferListResponse) err := c.cc.Invoke(ctx, "/escrow.Query/QueryOfferByID", in, out, opts...) if err != nil { return nil, err @@ -304,7 +287,7 @@ func (c *queryClient) QueryOfferByAddr(ctx context.Context, in *QueryOfferByAddr type QueryServer interface { // this line is used by starport scaffolding # 2 QueryOfferListAll(context.Context, *OfferListAllRequest) (*OfferListResponse, error) - QueryOfferByID(context.Context, *QueryOfferByIDRequest) (*Offer, error) + QueryOfferByID(context.Context, *QueryOfferByIDRequest) (*OfferListResponse, error) QueryOfferByAddr(context.Context, *QueryOfferByAddrRequest) (*OfferListResponse, error) } @@ -315,7 +298,7 @@ type UnimplementedQueryServer struct { func (*UnimplementedQueryServer) QueryOfferListAll(ctx context.Context, req *OfferListAllRequest) (*OfferListResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method QueryOfferListAll not implemented") } -func (*UnimplementedQueryServer) QueryOfferByID(ctx context.Context, req *QueryOfferByIDRequest) (*Offer, error) { +func (*UnimplementedQueryServer) QueryOfferByID(ctx context.Context, req *QueryOfferByIDRequest) (*OfferListResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method QueryOfferByID not implemented") } func (*UnimplementedQueryServer) QueryOfferByAddr(ctx context.Context, req *QueryOfferByAddrRequest) (*OfferListResponse, error) { @@ -447,14 +430,7 @@ func (m *QueryOfferByIDRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { if m.Id != 0 { i = encodeVarintQuery(dAtA, i, uint64(m.Id)) i-- - dAtA[i] = 0x10 - } - if len(m.Querier) > 0 { - i -= len(m.Querier) - copy(dAtA[i:], m.Querier) - i = encodeVarintQuery(dAtA, i, uint64(len(m.Querier))) - i-- - dAtA[i] = 0xa + dAtA[i] = 0x8 } return len(dAtA) - i, nil } @@ -484,13 +460,6 @@ func (m *QueryOfferByAddrRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) copy(dAtA[i:], m.Offerer) i = encodeVarintQuery(dAtA, i, uint64(len(m.Offerer))) i-- - dAtA[i] = 0x12 - } - if len(m.Querier) > 0 { - i -= len(m.Querier) - copy(dAtA[i:], m.Querier) - i = encodeVarintQuery(dAtA, i, uint64(len(m.Querier))) - i-- dAtA[i] = 0xa } return len(dAtA) - i, nil @@ -559,10 +528,6 @@ func (m *QueryOfferByIDRequest) Size() (n int) { } var l int _ = l - l = len(m.Querier) - if l > 0 { - n += 1 + l + sovQuery(uint64(l)) - } if m.Id != 0 { n += 1 + sovQuery(uint64(m.Id)) } @@ -575,10 +540,6 @@ func (m *QueryOfferByAddrRequest) Size() (n int) { } var l int _ = l - l = len(m.Querier) - if l > 0 { - n += 1 + l + sovQuery(uint64(l)) - } l = len(m.Offerer) if l > 0 { n += 1 + l + sovQuery(uint64(l)) @@ -687,38 +648,6 @@ func (m *QueryOfferByIDRequest) Unmarshal(dAtA []byte) error { } switch fieldNum { case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Querier", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowQuery - } - 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 ErrInvalidLengthQuery - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthQuery - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Querier = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 2: if wireType != 0 { return fmt.Errorf("proto: wrong wireType = %d for field Id", wireType) } @@ -788,38 +717,6 @@ func (m *QueryOfferByAddrRequest) Unmarshal(dAtA []byte) error { } switch fieldNum { case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Querier", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowQuery - } - 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 ErrInvalidLengthQuery - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthQuery - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Querier = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 2: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field Offerer", wireType) } From 917c6d724af9201c747f28e7eb31071e8f13bdd1 Mon Sep 17 00:00:00 2001 From: yaruwang Date: Thu, 5 Aug 2021 16:34:56 +0200 Subject: [PATCH 14/22] query offer by id --- app/app.go | 3 +- go.mod | 1 + go.sum | 1 - proto/escrow/query.proto | 2 +- x/escrow/client/cli/query.go | 37 +++++++++++++++++-- x/escrow/keeper/keeper.go | 9 ++--- x/escrow/keeper/msg_server.go | 10 ++--- x/escrow/keeper/query_server.go | 10 ++++- x/escrow/keeper/store.go | 65 +++++++++++++++++++++++++++++++-- x/escrow/module.go | 2 +- x/escrow/types/keys.go | 8 ++-- x/escrow/types/query.pb.go | 54 +++++++++++++-------------- 12 files changed, 145 insertions(+), 57 deletions(-) diff --git a/app/app.go b/app/app.go index c32be98..5412a98 100644 --- a/app/app.go +++ b/app/app.go @@ -262,6 +262,7 @@ func New( pooltoytypes.StoreKey, faucettypes.StoreKey, escrowtypes.StoreKey, + escrowtypes.IDStoreKey, upgradetypes.StoreKey, // this line is used by starport scaffolding # stargate/app/storeKey @@ -378,7 +379,7 @@ func New( app.AccountKeeper, appCodec, //todo appcodec or app.appcodec? keys[escrowtypes.StoreKey], - &escrowtypes.StartIndex, + keys[escrowtypes.IDStoreKey], ) // Create static IBC router, add transfer route, then set and seal it diff --git a/go.mod b/go.mod index e56757b..cd54111 100644 --- a/go.mod +++ b/go.mod @@ -9,6 +9,7 @@ require ( github.com/gorilla/mux v1.8.0 github.com/grpc-ecosystem/grpc-gateway v1.16.0 github.com/kr/text v0.2.0 // indirect + github.com/pkg/errors v0.9.1 github.com/regen-network/cosmos-proto v0.3.1 github.com/spf13/cast v1.3.1 github.com/spf13/cobra v1.1.3 diff --git a/go.sum b/go.sum index e39aa51..69748e1 100644 --- a/go.sum +++ b/go.sum @@ -101,7 +101,6 @@ github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfc github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= github.com/cosmos/cosmos-sdk v0.42.6 h1:ps1QWfvaX6VLNcykA7wzfii/5IwBfYgTIik6NOVDq/c= github.com/cosmos/cosmos-sdk v0.42.6/go.mod h1:kh37gwYQoWdgR7N/9zeqW2rJ7cnP2W4A7nqIaf6m3zg= -github.com/cosmos/cosmos-sdk v0.42.7/go.mod h1:SrclJP9lMXxz2fCbngxb0brsPNuZXqoQQ9VHuQ3Tpf4= github.com/cosmos/go-bip39 v0.0.0-20180819234021-555e2067c45d/go.mod h1:tSxLoYXyBmiFeKpvmq4dzayMdCjCnu8uqmCysIGBT2Y= github.com/cosmos/go-bip39 v1.0.0 h1:pcomnQdrdH22njcAatO0yWojsUnCO3y2tNoV1cb6hHY= github.com/cosmos/go-bip39 v1.0.0/go.mod h1:RNJv0H/pOIVgxw6KS7QeX2a0Uo0aKUlfhZ4xuwvCdJw= diff --git a/proto/escrow/query.proto b/proto/escrow/query.proto index 66c7fe9..13cde94 100644 --- a/proto/escrow/query.proto +++ b/proto/escrow/query.proto @@ -11,7 +11,7 @@ option go_package = "github.com/interchainberlin/pooltoy/x/escrow/types"; service Query { // this line is used by starport scaffolding # 2 rpc QueryOfferListAll (OfferListAllRequest) returns (OfferListResponse); - rpc QueryOfferByID (QueryOfferByIDRequest) returns (OfferListResponse); + rpc QueryOfferByID (QueryOfferByIDRequest) returns (Offer); rpc QueryOfferByAddr (QueryOfferByAddrRequest) returns (OfferListResponse); } diff --git a/x/escrow/client/cli/query.go b/x/escrow/client/cli/query.go index f34e312..a1c5e79 100644 --- a/x/escrow/client/cli/query.go +++ b/x/escrow/client/cli/query.go @@ -4,6 +4,8 @@ import ( "context" "fmt" "github.com/cosmos/cosmos-sdk/client/flags" + "strconv" + // "strings" "github.com/spf13/cobra" @@ -16,7 +18,7 @@ import ( ) // GetQueryCmd returns the cli query commands for this module -func GetQueryCmd(queryRoute string) *cobra.Command { +func GetQueryCmd() *cobra.Command { // Group escrow queries under a subcommand escrowQuerycmd := &cobra.Command{ Use: types.ModuleName, @@ -27,7 +29,7 @@ func GetQueryCmd(queryRoute string) *cobra.Command { } // this line is used by starport scaffolding # 1 - escrowQuerycmd.AddCommand(escrowOfferListAll(), escrowOfferByAddr()) + escrowQuerycmd.AddCommand(escrowOfferListAll(), escrowOfferByAddr(), escrowOfferByID()) return escrowQuerycmd } @@ -58,7 +60,7 @@ func escrowOfferListAll() *cobra.Command { func escrowOfferByAddr() *cobra.Command { cmd := &cobra.Command{ - Use: "offer-by-addr [querier] [offerer]", + Use: "offer-by-addr [offerer]", Short: "show all the offers of an address", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { @@ -79,3 +81,32 @@ func escrowOfferByAddr() *cobra.Command { flags.AddTxFlagsToCmd(cmd) return cmd } + +func escrowOfferByID() *cobra.Command { + cmd := &cobra.Command{ + Use: "offer-by-id [ID]", + Short: "show all the offer of an ID", + Args: cobra.ExactArgs(1), + RunE: func(cmd *cobra.Command, args []string) error { + ctx, err := client.GetClientTxContext(cmd) + if err != nil { + return err + } + queryClient := types.NewQueryClient(ctx) + + i, err := strconv.ParseInt(args[0], 10, 64) + if err != nil { + return err + } + + offer, err := queryClient.QueryOfferByID(context.Background(), &types.QueryOfferByIDRequest{Id: i}) + if err != nil { + return err + } + + return ctx.PrintProto(offer) + }, + } + flags.AddTxFlagsToCmd(cmd) + return cmd +} diff --git a/x/escrow/keeper/keeper.go b/x/escrow/keeper/keeper.go index 34669ee..b3fcd4b 100644 --- a/x/escrow/keeper/keeper.go +++ b/x/escrow/keeper/keeper.go @@ -18,9 +18,7 @@ type Keeper struct { AccountKeeper keeper.AccountKeeper cdc codec.Marshaler storeKey sdk.StoreKey -// memKey sdk.StoreKey - // this line is used by starport scaffolding # ibc/keeper/attribute - index *int64 + idStoreKey sdk.StoreKey } func NewKeeper( @@ -28,8 +26,7 @@ func NewKeeper( accountKeeper keeper.AccountKeeper, cdc codec.Marshaler, storeKey sdk.StoreKey, - //memKey sdk.StoreKey, - index *int64, + idStoreKey sdk.StoreKey, // this line is used by starport scaffolding # ibc/keeper/parameter ) Keeper { return Keeper{ @@ -37,7 +34,7 @@ func NewKeeper( AccountKeeper: accountKeeper, cdc: cdc, storeKey: storeKey, - index: index, + idStoreKey: idStoreKey, // this line is used by starport scaffolding # ibc/keeper/return } } diff --git a/x/escrow/keeper/msg_server.go b/x/escrow/keeper/msg_server.go index 93a0e3d..7c4d0d5 100644 --- a/x/escrow/keeper/msg_server.go +++ b/x/escrow/keeper/msg_server.go @@ -20,6 +20,7 @@ func NewMsgServerImpl(keeper Keeper) types.MsgServer { var _ types.MsgServer = Keeper{} +// todo: merge OfferSend and Offer into 1 func (k Keeper) Offer(c context.Context, msg *types.Offer) (*types.OfferResponse, error) { ctx := sdk.UnwrapSDKContext(c) res, err := k.OfferSend(ctx, msg) @@ -27,7 +28,6 @@ func (k Keeper) Offer(c context.Context, msg *types.Offer) (*types.OfferResponse return nil, sdkerrors.Wrap(err, fmt.Sprintf("unable to offer")) } - _, err = k.InsertOffer(ctx, *msg) if err != nil { return nil, err @@ -40,7 +40,6 @@ func (k Keeper) OfferSend(ctx sdk.Context, msg *types.Offer) (*types.OfferRespon addr, err := sdk.AccAddressFromBech32(msg.Sender) if err != nil { - fmt.Println("addr err!!!!") return &types.OfferResponse{}, err } // coins, err := sdk.ParseCoinsNormalized(msg.Amount) @@ -52,12 +51,11 @@ func (k Keeper) OfferSend(ctx sdk.Context, msg *types.Offer) (*types.OfferRespon err = k.BankKeeper.SendCoinsFromAccountToModule(ctx, addr,types.ModuleName,msg.Amount) if err != nil { - fmt.Println("sending err!!!!") return &types.OfferResponse{}, err } - presentIdx := k.index - *k.index +=1 // some checks this index is not re - return &types.OfferResponse{Sender: msg.Sender, Index: *presentIdx}, nil + + //*k.index +=1 // some checks this index is not in store + return &types.OfferResponse{Sender: msg.Sender, Index: k.GetLatestID(ctx)}, nil } diff --git a/x/escrow/keeper/query_server.go b/x/escrow/keeper/query_server.go index c6038bd..49a2625 100644 --- a/x/escrow/keeper/query_server.go +++ b/x/escrow/keeper/query_server.go @@ -33,6 +33,12 @@ func (k Keeper)QueryOfferByAddr(c context.Context, req *types.QueryOfferByAddrRe return &offers, nil } -func (k Keeper) QueryOfferByID(c context.Context, req *types.QueryOfferByIDRequest) (*types.OfferListResponse, error){ - return nil, nil +func (k Keeper) QueryOfferByID(c context.Context, req *types.QueryOfferByIDRequest) (*types.Offer, error){ + ctx := sdk.UnwrapSDKContext(c) + offer, err :=k.ListOfferByID(ctx, *req) + if err != nil { + return nil, err + } + + return &offer, nil } diff --git a/x/escrow/keeper/store.go b/x/escrow/keeper/store.go index 7ea6ded..79b2452 100644 --- a/x/escrow/keeper/store.go +++ b/x/escrow/keeper/store.go @@ -1,9 +1,10 @@ package keeper import ( - "fmt" "github.com/cosmos/cosmos-sdk/store/prefix" sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/pkg/errors" + // types2 "github.com/cosmos/cosmos-sdk/x/auth/types" "github.com/interchainberlin/pooltoy/x/escrow/types" "strconv" @@ -18,7 +19,9 @@ func (k Keeper) InsertOffer(ctx sdk.Context, offer types.Offer) ([]byte, error) } storeK := []byte(types.OfferPrefix) storeK = append(storeK, addr...) - storeK = append(storeK, []byte(strconv.FormatInt(*k.index, 10))...) + id := k.GetUpdatedID(ctx) + storeK = append(storeK, []byte(strconv.FormatInt(id, 10))...) + // todo maybe we do not need int64 for index storeV, err := offer.Marshal() if err != nil { @@ -26,7 +29,6 @@ func (k Keeper) InsertOffer(ctx sdk.Context, offer types.Offer) ([]byte, error) } store.Set(storeK, storeV) - return storeV, nil } @@ -35,6 +37,7 @@ func (k Keeper) ListOffer(ctx sdk.Context, offer types.OfferListAllRequest) (typ offers := []*types.Offer{} iterator := sdk.KVStorePrefixIterator(store, []byte(types.OfferPrefix)) + defer iterator.Close() for ; iterator.Valid(); iterator.Next() { var offer types.Offer offer.Unmarshal(iterator.Value()) @@ -74,6 +77,60 @@ func (k Keeper) getAddressPrefixStore(ctx sdk.Context, addr sdk.AccAddress) pref func CreateAddrPrefix(addr []byte) []byte { //todo change to MustLengthPrefix(addr)...) for v0.43.0 release prefix := append([]byte(types.OfferPrefix), addr...) - fmt.Println("the prefix len is!!!!", len(prefix)) + return prefix } + +func (k Keeper) ListOfferByID(ctx sdk.Context, offerReq types.QueryOfferByIDRequest) (types.Offer, error) { + store := ctx.KVStore(k.storeKey) + iterator := sdk.KVStorePrefixIterator(store, []byte(types.OfferPrefix)) + defer iterator.Close() + + var offer types.Offer + for ; iterator.Valid(); iterator.Next() { + idBytes := iterator.Key()[types.AddrPrefixLen:] + + i, err := BytesToInt64(idBytes) + if err != nil { + return offer, errors.New("convert ID failed") + } + if i == offerReq.Id { + k.cdc.MustUnmarshalBinaryBare(store.Get(iterator.Key()), &offer) + } + } + // the ID not found + if offer.Sender == "" { + return offer, errors.New("ID not found") + } + return offer, nil +} + +func BytesToInt64(b []byte) (int64, error) { + i, err := strconv.Atoi(string(b)) + if err != nil { + return 0, err + } + return int64(i), nil +} + +// store for record latest ID +func (k Keeper) GetLatestID(ctx sdk.Context) int64{ + idStore := ctx.KVStore(k.idStoreKey) + if !idStore.Has([]byte(types.IDStoreKey)){ + // store is empty + return int64(-1) + } + + b := idStore.Get([]byte(types.IDStoreKey)) + i, _ := BytesToInt64(b) + return i +} + +// store id + 1 +func (k Keeper) GetUpdatedID(ctx sdk.Context) int64{ + id := k.GetLatestID(ctx) + idStore := ctx.KVStore(k.idStoreKey) + idStore.Set([]byte(types.IDStoreKey), []byte(strconv.FormatInt(id+1, 10))) + + return id+1 +} diff --git a/x/escrow/module.go b/x/escrow/module.go index df4801e..eb38ff3 100644 --- a/x/escrow/module.go +++ b/x/escrow/module.go @@ -90,7 +90,7 @@ func (a AppModuleBasic) GetTxCmd() *cobra.Command { // GetQueryCmd returns the capability module's root query command. func (AppModuleBasic) GetQueryCmd() *cobra.Command { - return cli.GetQueryCmd(types.StoreKey) + return cli.GetQueryCmd() } // ---------------------------------------------------------------------------- diff --git a/x/escrow/types/keys.go b/x/escrow/types/keys.go index 870e866..3cc3ea8 100644 --- a/x/escrow/types/keys.go +++ b/x/escrow/types/keys.go @@ -6,7 +6,7 @@ const ( // StoreKey defines the primary module store key StoreKey = ModuleName - + IDStoreKey = "id" // RouterKey is the message route for slashing RouterKey = ModuleName @@ -17,15 +17,13 @@ const ( //MemStoreKey = "mem_escrow" // this line is used by starport scaffolding # ibc/keys/name - - + // 26 is the byte len of escrow store prefix + address + AddrPrefixLen = 26 OfferPrefix ="offer-" ) // this line is used by starport scaffolding # ibc/keys/port -var StartIndex = int64(0) - func KeyPrefix(p string) []byte { return []byte(p) } diff --git a/x/escrow/types/query.pb.go b/x/escrow/types/query.pb.go index 3ec6b51..f00b684 100644 --- a/x/escrow/types/query.pb.go +++ b/x/escrow/types/query.pb.go @@ -206,28 +206,28 @@ func init() { func init() { proto.RegisterFile("escrow/query.proto", fileDescriptor_6d37bf65b8b6e159) } var fileDescriptor_6d37bf65b8b6e159 = []byte{ - // 331 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x7c, 0x91, 0x4f, 0x4e, 0x02, 0x31, - 0x18, 0xc5, 0x29, 0x44, 0x0c, 0x35, 0xa2, 0xd4, 0x10, 0x11, 0xb5, 0x92, 0xd9, 0x48, 0x62, 0x32, - 0x4d, 0xe0, 0x02, 0x42, 0xdc, 0xa8, 0x44, 0xe3, 0x2c, 0xdd, 0x0d, 0x4c, 0x81, 0x26, 0x63, 0xbf, - 0xa1, 0x2d, 0x91, 0xb9, 0x85, 0xc7, 0x72, 0xc9, 0xd2, 0xa5, 0x81, 0x0b, 0x78, 0x04, 0xc3, 0x0c, - 0x03, 0x8c, 0x12, 0x96, 0x7d, 0xef, 0xd7, 0xf7, 0xfd, 0xc3, 0x84, 0xeb, 0x9e, 0x82, 0x77, 0x36, - 0x1a, 0x73, 0x15, 0xda, 0x81, 0x02, 0x03, 0x24, 0x1f, 0x6b, 0xd5, 0x8b, 0x01, 0xc0, 0xc0, 0xe7, - 0xcc, 0x0d, 0x04, 0x73, 0xa5, 0x04, 0xe3, 0x1a, 0x01, 0x52, 0xc7, 0x54, 0xf5, 0x68, 0xf9, 0xd3, - 0x4c, 0x62, 0xc1, 0x2a, 0xe3, 0x93, 0xe7, 0x7e, 0x9f, 0xab, 0x8e, 0xd0, 0xa6, 0xe5, 0xfb, 0x0e, - 0x1f, 0x8d, 0xb9, 0x36, 0xd6, 0x35, 0x2e, 0xbf, 0x2c, 0xc2, 0x23, 0xaf, 0x1d, 0xde, 0xdf, 0x2d, - 0x0d, 0x52, 0xc4, 0x59, 0xe1, 0x55, 0x50, 0x0d, 0xd5, 0x73, 0x4e, 0x56, 0x78, 0x56, 0x13, 0x9f, - 0x6e, 0x82, 0x2d, 0xcf, 0x53, 0x09, 0x5a, 0xc1, 0xfb, 0xb0, 0x50, 0xb9, 0x8a, 0xf8, 0x82, 0x93, - 0x3c, 0xad, 0x5b, 0x5c, 0x5a, 0x15, 0x75, 0xb8, 0x0e, 0x40, 0x6a, 0x4e, 0x6e, 0x70, 0x01, 0x12, - 0xb1, 0x82, 0x6a, 0xb9, 0xfa, 0x41, 0xe3, 0xd0, 0x8e, 0xdb, 0xb5, 0x23, 0xda, 0x59, 0xfb, 0x8d, - 0x1f, 0x84, 0xf7, 0xa2, 0xba, 0xe4, 0x11, 0x97, 0xd6, 0x0d, 0x2c, 0xa7, 0x20, 0xe7, 0xa9, 0x8f, - 0xe9, 0xd9, 0xaa, 0x67, 0xff, 0xcc, 0x55, 0x0f, 0x0f, 0xb8, 0x98, 0x1e, 0x9b, 0x5c, 0x26, 0xf0, - 0xd6, 0x75, 0xec, 0xca, 0x7a, 0xc2, 0xc7, 0x7f, 0x37, 0x43, 0xae, 0xb6, 0xa5, 0x6d, 0xec, 0x6c, - 0x47, 0x5e, 0xbb, 0xf3, 0x39, 0xa3, 0x68, 0x3a, 0xa3, 0xe8, 0x7b, 0x46, 0xd1, 0xc7, 0x9c, 0x66, - 0xa6, 0x73, 0x9a, 0xf9, 0x9a, 0xd3, 0xcc, 0x6b, 0x63, 0x20, 0xcc, 0x70, 0xdc, 0xb5, 0x7b, 0xf0, - 0xc6, 0x84, 0x34, 0x5c, 0xf5, 0x86, 0xae, 0x90, 0x5d, 0xae, 0x7c, 0x21, 0x59, 0x00, 0xe0, 0x1b, - 0x08, 0xd9, 0x84, 0x25, 0xa7, 0x0f, 0x03, 0xae, 0xbb, 0xf9, 0xe8, 0xfc, 0xcd, 0xdf, 0x00, 0x00, - 0x00, 0xff, 0xff, 0x12, 0x03, 0x73, 0x9f, 0x4b, 0x02, 0x00, 0x00, + // 333 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x7c, 0x91, 0xc1, 0x4e, 0xfa, 0x40, + 0x10, 0xc6, 0x59, 0xc8, 0x9f, 0x7f, 0x58, 0x23, 0xca, 0x1a, 0x22, 0x56, 0x5d, 0x49, 0x2f, 0x92, + 0x98, 0x74, 0x13, 0xb8, 0x1b, 0x21, 0x5e, 0x8c, 0x44, 0x63, 0x8f, 0xde, 0x0a, 0x5d, 0x60, 0x93, + 0xba, 0x53, 0x76, 0x97, 0x48, 0xdf, 0xc2, 0xc7, 0xf2, 0xc8, 0xd1, 0xa3, 0x01, 0x1f, 0xc4, 0xd0, + 0x52, 0xa0, 0x4a, 0x3c, 0xee, 0xf7, 0xfd, 0x76, 0xe6, 0x9b, 0x19, 0x4c, 0xb8, 0xee, 0x2b, 0x78, + 0x65, 0xe3, 0x09, 0x57, 0x91, 0x13, 0x2a, 0x30, 0x40, 0x8a, 0x89, 0x66, 0x9d, 0x0d, 0x01, 0x86, + 0x01, 0x67, 0x5e, 0x28, 0x98, 0x27, 0x25, 0x18, 0xcf, 0x08, 0x90, 0x3a, 0xa1, 0xac, 0x83, 0xd5, + 0x4f, 0x33, 0x4d, 0x04, 0xbb, 0x8a, 0x8f, 0x1e, 0x07, 0x03, 0xae, 0xba, 0x42, 0x9b, 0x76, 0x10, + 0xb8, 0x7c, 0x3c, 0xe1, 0xda, 0xd8, 0x97, 0xb8, 0xfa, 0xb4, 0x2c, 0x1e, 0x7b, 0x9d, 0xe8, 0xee, + 0x76, 0x65, 0x90, 0x32, 0xce, 0x0b, 0xbf, 0x86, 0xea, 0xa8, 0x51, 0x70, 0xf3, 0xc2, 0xb7, 0x5b, + 0xf8, 0x78, 0x1b, 0x6c, 0xfb, 0xbe, 0x4a, 0xd1, 0x1a, 0xfe, 0x0f, 0x4b, 0x95, 0xab, 0x98, 0x2f, + 0xb9, 0xe9, 0xd3, 0xbe, 0xc1, 0x95, 0x75, 0x53, 0x97, 0xeb, 0x10, 0xa4, 0xe6, 0xe4, 0x0a, 0x97, + 0x20, 0x15, 0x6b, 0xa8, 0x5e, 0x68, 0xec, 0x35, 0xf7, 0x9d, 0x24, 0xae, 0x13, 0xd3, 0xee, 0xc6, + 0x6f, 0x7e, 0x21, 0xfc, 0x2f, 0xee, 0x4b, 0xee, 0x71, 0x65, 0x13, 0x60, 0x35, 0x05, 0x39, 0xcd, + 0x7c, 0xcc, 0xce, 0x66, 0x9d, 0xfc, 0x32, 0xd7, 0x19, 0xae, 0x71, 0x39, 0x3b, 0x36, 0x39, 0x4f, + 0xe1, 0x9d, 0xeb, 0xb0, 0xb2, 0x09, 0xc9, 0x03, 0x3e, 0xfc, 0xb9, 0x0d, 0x72, 0xb1, 0xab, 0xc2, + 0xd6, 0x9e, 0xfe, 0xc8, 0xd3, 0xe9, 0xbe, 0xcf, 0x29, 0x9a, 0xcd, 0x29, 0xfa, 0x9c, 0x53, 0xf4, + 0xb6, 0xa0, 0xb9, 0xd9, 0x82, 0xe6, 0x3e, 0x16, 0x34, 0xf7, 0xdc, 0x1c, 0x0a, 0x33, 0x9a, 0xf4, + 0x9c, 0x3e, 0xbc, 0x30, 0x21, 0x0d, 0x57, 0xfd, 0x91, 0x27, 0x64, 0x8f, 0xab, 0x40, 0x48, 0x16, + 0x02, 0x04, 0x06, 0x22, 0x36, 0x65, 0xe9, 0xb9, 0xa3, 0x90, 0xeb, 0x5e, 0x31, 0x3e, 0x79, 0xeb, + 0x3b, 0x00, 0x00, 0xff, 0xff, 0xa1, 0x6e, 0x29, 0x3a, 0x3f, 0x02, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -244,7 +244,7 @@ const _ = grpc.SupportPackageIsVersion4 type QueryClient interface { // this line is used by starport scaffolding # 2 QueryOfferListAll(ctx context.Context, in *OfferListAllRequest, opts ...grpc.CallOption) (*OfferListResponse, error) - QueryOfferByID(ctx context.Context, in *QueryOfferByIDRequest, opts ...grpc.CallOption) (*OfferListResponse, error) + QueryOfferByID(ctx context.Context, in *QueryOfferByIDRequest, opts ...grpc.CallOption) (*Offer, error) QueryOfferByAddr(ctx context.Context, in *QueryOfferByAddrRequest, opts ...grpc.CallOption) (*OfferListResponse, error) } @@ -265,8 +265,8 @@ func (c *queryClient) QueryOfferListAll(ctx context.Context, in *OfferListAllReq return out, nil } -func (c *queryClient) QueryOfferByID(ctx context.Context, in *QueryOfferByIDRequest, opts ...grpc.CallOption) (*OfferListResponse, error) { - out := new(OfferListResponse) +func (c *queryClient) QueryOfferByID(ctx context.Context, in *QueryOfferByIDRequest, opts ...grpc.CallOption) (*Offer, error) { + out := new(Offer) err := c.cc.Invoke(ctx, "/escrow.Query/QueryOfferByID", in, out, opts...) if err != nil { return nil, err @@ -287,7 +287,7 @@ func (c *queryClient) QueryOfferByAddr(ctx context.Context, in *QueryOfferByAddr type QueryServer interface { // this line is used by starport scaffolding # 2 QueryOfferListAll(context.Context, *OfferListAllRequest) (*OfferListResponse, error) - QueryOfferByID(context.Context, *QueryOfferByIDRequest) (*OfferListResponse, error) + QueryOfferByID(context.Context, *QueryOfferByIDRequest) (*Offer, error) QueryOfferByAddr(context.Context, *QueryOfferByAddrRequest) (*OfferListResponse, error) } @@ -298,7 +298,7 @@ type UnimplementedQueryServer struct { func (*UnimplementedQueryServer) QueryOfferListAll(ctx context.Context, req *OfferListAllRequest) (*OfferListResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method QueryOfferListAll not implemented") } -func (*UnimplementedQueryServer) QueryOfferByID(ctx context.Context, req *QueryOfferByIDRequest) (*OfferListResponse, error) { +func (*UnimplementedQueryServer) QueryOfferByID(ctx context.Context, req *QueryOfferByIDRequest) (*Offer, error) { return nil, status.Errorf(codes.Unimplemented, "method QueryOfferByID not implemented") } func (*UnimplementedQueryServer) QueryOfferByAddr(ctx context.Context, req *QueryOfferByAddrRequest) (*OfferListResponse, error) { From 6ae8cd0f06434860c4d19350b336b2a78a194c37 Mon Sep 17 00:00:00 2001 From: yaruwang Date: Fri, 6 Aug 2021 16:15:50 +0200 Subject: [PATCH 15/22] escrow response, cancel offer --- proto/escrow/query.proto | 12 +- proto/escrow/tx.proto | 31 +- scripts/init.sh | 3 +- x/escrow/client/cli/tx.go | 69 ++- x/escrow/handler.go | 12 +- x/escrow/keeper/msg_server.go | 74 ++- x/escrow/keeper/store.go | 44 +- x/escrow/types/codec.go | 4 +- x/escrow/types/msgs.go | 97 +++- x/escrow/types/query.pb.go | 384 +++++++++++++++- x/escrow/types/tx.pb.go | 844 +++++++++++++++++++++++++++++++--- x/escrow/utils/errors.go | 10 - x/escrow/utils/utils.go | 191 -------- x/escrow/utils/utils_test.go | 88 ---- 14 files changed, 1423 insertions(+), 440 deletions(-) delete mode 100644 x/escrow/utils/errors.go delete mode 100644 x/escrow/utils/utils.go delete mode 100644 x/escrow/utils/utils_test.go diff --git a/proto/escrow/query.proto b/proto/escrow/query.proto index 13cde94..8cb1533 100644 --- a/proto/escrow/query.proto +++ b/proto/escrow/query.proto @@ -1,9 +1,9 @@ syntax = "proto3"; package escrow; +import "gogoproto/gogo.proto"; import "google/api/annotations.proto"; -import "escrow/tx.proto"; -// this line is used by starport scaffolding # 1 +import "cosmos/base/v1beta1/coin.proto"; option go_package = "github.com/interchainberlin/pooltoy/x/escrow/types"; @@ -29,3 +29,11 @@ message OfferListResponse { repeated Offer offerList = 1; } +message Offer { + string sender = 1; + repeated cosmos.base.v1beta1.Coin amount = 2 + [(gogoproto.nullable) = false, (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins"]; + repeated cosmos.base.v1beta1.Coin request = 3 + [(gogoproto.nullable) = false, (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins"]; + int64 id =4; +} diff --git a/proto/escrow/tx.proto b/proto/escrow/tx.proto index f7f8480..c3b0859 100644 --- a/proto/escrow/tx.proto +++ b/proto/escrow/tx.proto @@ -11,12 +11,13 @@ option go_package = "github.com/interchainberlin/pooltoy/x/escrow/types"; // Msg defines the Msg service. service Msg { // this line is used by starport scaffolding # proto/tx/rpc - rpc Offer(Offer) returns (OfferResponse); - //rpc CancelOffer(CancelOfferRequest) returns(CancelOfferResponse); + rpc Offer(OfferRequest) returns (OfferResponse); + rpc Response(ResponseRequest) returns (ResponseResult); + rpc CancelOffer(CancelOfferRequest) returns(CancelOfferResponse); } // this line is used by starport scaffolding # proto/tx/message -message Offer { +message OfferRequest { string sender = 1; repeated cosmos.base.v1beta1.Coin amount = 2 [(gogoproto.nullable) = false, (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins"]; @@ -24,19 +25,21 @@ message Offer { [(gogoproto.nullable) = false, (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins"]; } -//message Coin { -// string coin = 1 -// [(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Coin"]; -//} message OfferResponse { string sender = 1; int64 index = 2; } -// -//message CancelOfferRequest { -// string sender = 1; -// int64 ID = 2; -//} -// -//message CancelOfferResponse{} +message ResponseRequest { + string sender = 1; + int64 id = 2; +} + +message ResponseResult {} + +message CancelOfferRequest { + string sender = 1; + int64 id = 2; +} + +message CancelOfferResponse {} diff --git a/scripts/init.sh b/scripts/init.sh index 2eb1c44..2792088 100755 --- a/scripts/init.sh +++ b/scripts/init.sh @@ -1,4 +1,5 @@ #!/bin/bash + rm -rf ~/.pooltoy pooltoy config keyring-backend test @@ -8,7 +9,7 @@ pooltoy config pooltoy init mynode --chain-id pooltoy-5 -jq -c '.balances[]' accounts1.json | while read i; do +jq -c '.balances[]' accounts.json | while read i; do echo "y" | pooltoy keys add $(echo "$i" | jq -r ".name") --keyring-backend test pooltoy add-genesis-account $(pooltoy keys show $(echo "$i" | jq -r ".name") --address) $(echo $i | jq -r '.coins | map(.amount+.denom) | join(",")') --keyring-backend test done diff --git a/x/escrow/client/cli/tx.go b/x/escrow/client/cli/tx.go index 3059499..baaed20 100644 --- a/x/escrow/client/cli/tx.go +++ b/x/escrow/client/cli/tx.go @@ -5,6 +5,8 @@ import ( "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/flags" "github.com/cosmos/cosmos-sdk/client/tx" + "strconv" + //"github.com/cosmos/cosmos-sdk/client/tx" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/spf13/cobra" @@ -23,7 +25,7 @@ func GetTxCmd() *cobra.Command { } // this line is used by starport scaffolding # 1 - escrowTxCmd.AddCommand(escrowOffer()) + escrowTxCmd.AddCommand(escrowOffer(), escrowResponse(), escrowCancelOffer()) return escrowTxCmd } @@ -43,23 +45,68 @@ func escrowOffer() *cobra.Command { return err } - offer := types.NewOfferRequest(addr, args[1], args[2]) + offerReq := types.NewOfferRequest(addr, args[1], args[2]) - return tx.GenerateOrBroadcastTxCLI(ctx, cmd.Flags(), offer) + return tx.GenerateOrBroadcastTxCLI(ctx, cmd.Flags(), offerReq) + }, + } + flags.AddTxFlagsToCmd(cmd) + return cmd +} +func escrowResponse() *cobra.Command { + cmd := &cobra.Command{ + Use: "response [address] [id] --from [username]", + Short: "response to an offer at escrow", + Args: cobra.ExactArgs(2), + RunE: func(cmd *cobra.Command, args []string) error { + ctx, err := client.GetClientTxContext(cmd) + if err != nil { + return err + } - // method:2 - // msgClient := types.NewMsgClient(ctx) - // offer := &types.OfferRequest{Sender: args[0], Amount: args[1], Request: args[2]} - //res, err := msgClient.Offer(context.Background(), offer) - // if err != nil{ - // return err - //} - // return ctx.PrintProto(res) + addr, err := sdk.AccAddressFromBech32(args[0]) + if err != nil { + return err + } + i, err := strconv.ParseInt(args[1], 10, 64) + if err != nil { + return err + } + responseReq := types.NewResponseRequest(addr, i) + return tx.GenerateOrBroadcastTxCLI(ctx, cmd.Flags(), responseReq) }, } + flags.AddTxFlagsToCmd(cmd) return cmd } +func escrowCancelOffer() *cobra.Command { + cmd := &cobra.Command{ + Use: "cancel [address] [id] --from [username]", + Short: "cancel an offer", + Args: cobra.ExactArgs(2), + RunE: func(cmd *cobra.Command, args []string) error { + ctx, err := client.GetClientTxContext(cmd) + if err != nil { + return err + } + addr, err := sdk.AccAddressFromBech32(args[0]) + if err != nil { + return err + } + i, err := strconv.ParseInt(args[1], 10, 64) + if err != nil { + return err + } + cancelReq := types.NewCancelOfferRequest(addr, i) + return tx.GenerateOrBroadcastTxCLI(ctx, cmd.Flags(), cancelReq) + + }, + } + + flags.AddTxFlagsToCmd(cmd) + return cmd +} diff --git a/x/escrow/handler.go b/x/escrow/handler.go index e9f6b9e..999c7d0 100644 --- a/x/escrow/handler.go +++ b/x/escrow/handler.go @@ -11,17 +11,19 @@ import ( // NewHandler ... func NewHandler(k keeper.Keeper) sdk.Handler { // this line is used by starport scaffolding # handler/msgServer - return func(ctx sdk.Context, msg sdk.Msg) (*sdk.Result, error) { - ctx = ctx.WithEventManager(sdk.NewEventManager()) - switch msg := msg.(type) { // this line is used by starport scaffolding # 1 - case *types.Offer: + case *types.OfferRequest: res, err := k.Offer(sdk.WrapSDKContext(ctx), msg) return sdk.WrapServiceResult(ctx, res, err) - + case *types.ResponseRequest: + res, err := k.Response(sdk.WrapSDKContext(ctx), msg) + return sdk.WrapServiceResult(ctx, res, err) + case *types.CancelOfferRequest: + res, err := k.CancelOffer(sdk.WrapSDKContext(ctx), msg) + return sdk.WrapServiceResult(ctx, res, err) default: errMsg := fmt.Sprintf("unrecognized %s message type: %v", types.ModuleName, msg.Type()) return nil, sdkerrors.Wrap(sdkerrors.ErrUnknownRequest, errMsg) diff --git a/x/escrow/keeper/msg_server.go b/x/escrow/keeper/msg_server.go index 7c4d0d5..8c6f9a7 100644 --- a/x/escrow/keeper/msg_server.go +++ b/x/escrow/keeper/msg_server.go @@ -21,7 +21,7 @@ func NewMsgServerImpl(keeper Keeper) types.MsgServer { var _ types.MsgServer = Keeper{} // todo: merge OfferSend and Offer into 1 -func (k Keeper) Offer(c context.Context, msg *types.Offer) (*types.OfferResponse, error) { +func (k Keeper) Offer(c context.Context, msg *types.OfferRequest) (*types.OfferResponse, error) { ctx := sdk.UnwrapSDKContext(c) res, err := k.OfferSend(ctx, msg) if err != nil { @@ -36,26 +36,76 @@ func (k Keeper) Offer(c context.Context, msg *types.Offer) (*types.OfferResponse return res, nil } -func (k Keeper) OfferSend(ctx sdk.Context, msg *types.Offer) (*types.OfferResponse, error) { - +func (k Keeper) OfferSend(ctx sdk.Context, msg *types.OfferRequest) (*types.OfferResponse, error) { addr, err := sdk.AccAddressFromBech32(msg.Sender) if err != nil { return &types.OfferResponse{}, err } -// coins, err := sdk.ParseCoinsNormalized(msg.Amount) -// if err != nil { -// return &types.OfferResponse{}, err -// } - - // moduleAcc:= k.AccountKeeper.GetModuleAddress(types.ModuleName) - err = k.BankKeeper.SendCoinsFromAccountToModule(ctx, addr,types.ModuleName,msg.Amount) + err = k.BankKeeper.SendCoinsFromAccountToModule(ctx, addr, types.ModuleName, msg.Amount) if err != nil { return &types.OfferResponse{}, err } - - //*k.index +=1 // some checks this index is not in store return &types.OfferResponse{Sender: msg.Sender, Index: k.GetLatestID(ctx)}, nil } +func (k Keeper) Response(c context.Context, msg *types.ResponseRequest) (*types.ResponseResult, error) { + responser, err := sdk.AccAddressFromBech32(msg.Sender) + if err != nil { + return nil, err + } + ctx := sdk.UnwrapSDKContext(c) + offer, err := k.QueryOfferByID(c, &types.QueryOfferByIDRequest{msg.Id}) + if err != nil { + return nil, err + } + offerer, err := sdk.AccAddressFromBech32(offer.Sender) + if err != nil { + return nil, err + } + + escrowAcc :=k.AccountKeeper.GetModuleAccount(ctx, types.ModuleName) + err = k.BankKeeper.SendCoins(ctx, escrowAcc.GetAddress(), responser, offer.Amount) + if err != nil { + return nil, err + } + + err = k.BankKeeper.SendCoins(ctx, responser, offerer, offer.Request) + + err = k.DeleteOffer(ctx, msg.Id) + if err != nil { + return nil, err + } + + return &types.ResponseResult{}, nil +} + + +func (k Keeper) CancelOffer(c context.Context, msg *types.CancelOfferRequest) (*types.CancelOfferResponse, error) { + ctx := sdk.UnwrapSDKContext(c) + offer, err := k.QueryOfferByID(c, &types.QueryOfferByIDRequest{msg.Id}) + if err != nil { + return nil, err + } + if offer.Sender != msg.Sender{ + return nil, sdkerrors.Wrap(err, fmt.Sprintf("unauthorized to cancel this offer")) + } + + offerer, err := sdk.AccAddressFromBech32(offer.Sender) + if err != nil { + return nil, err + } + escrowAcc :=k.AccountKeeper.GetModuleAccount(ctx, types.ModuleName) + err = k.BankKeeper.SendCoins(ctx, escrowAcc.GetAddress(), offerer, offer.Amount) + if err != nil { + return nil, err + } + + err = k.DeleteOffer(ctx, msg.Id) + if err != nil { + return nil, err + } + + return &types.CancelOfferResponse{}, nil +} diff --git a/x/escrow/keeper/store.go b/x/escrow/keeper/store.go index 79b2452..325ee67 100644 --- a/x/escrow/keeper/store.go +++ b/x/escrow/keeper/store.go @@ -11,15 +11,21 @@ import ( // "github.com/cosmos/cosmos-sdk/types/address" ) -func (k Keeper) InsertOffer(ctx sdk.Context, offer types.Offer) ([]byte, error) { +func (k Keeper) InsertOffer(ctx sdk.Context, offerReq types.OfferRequest) ([]byte, error) { store := ctx.KVStore(k.storeKey) - addr, err := sdk.AccAddressFromBech32(offer.Sender) + addr, err := sdk.AccAddressFromBech32(offerReq.Sender) if err != nil { return []byte{}, err } storeK := []byte(types.OfferPrefix) storeK = append(storeK, addr...) id := k.GetUpdatedID(ctx) + offer := types.Offer{ + Sender: offerReq.Sender, + Amount: offerReq.Amount, + Request: offerReq.Request, + Id: id, + } storeK = append(storeK, []byte(strconv.FormatInt(id, 10))...) // todo maybe we do not need int64 for index @@ -32,6 +38,30 @@ func (k Keeper) InsertOffer(ctx sdk.Context, offer types.Offer) ([]byte, error) return storeV, nil } +func (k Keeper) DeleteOffer(ctx sdk.Context, id int64) error { + store := ctx.KVStore(k.storeKey) + iterator := sdk.KVStorePrefixIterator(store, []byte(types.OfferPrefix)) + defer iterator.Close() + + foundID := false + for ; iterator.Valid(); iterator.Next() { + idBytes := iterator.Key()[types.AddrPrefixLen:] + i, err := BytesToInt64(idBytes) + if err != nil { + return errors.New("convert ID failed") + } + if i == id { + foundID = true + store.Delete(iterator.Key()) + } + } + // the ID not found + if foundID == false { + return errors.New("ID not found") + } + return nil +} + func (k Keeper) ListOffer(ctx sdk.Context, offer types.OfferListAllRequest) (types.OfferListResponse, error) { store := ctx.KVStore(k.storeKey) offers := []*types.Offer{} @@ -57,6 +87,7 @@ func (k Keeper) ListOfferByAddr(ctx sdk.Context, offer types.QueryOfferByAddrReq iterator := addrStore.Iterator(nil, nil) defer iterator.Close() + offers := []*types.Offer{} for ; iterator.Valid(); iterator.Next() { var offer types.Offer @@ -102,6 +133,7 @@ func (k Keeper) ListOfferByID(ctx sdk.Context, offerReq types.QueryOfferByIDRequ if offer.Sender == "" { return offer, errors.New("ID not found") } + return offer, nil } @@ -114,9 +146,9 @@ func BytesToInt64(b []byte) (int64, error) { } // store for record latest ID -func (k Keeper) GetLatestID(ctx sdk.Context) int64{ +func (k Keeper) GetLatestID(ctx sdk.Context) int64 { idStore := ctx.KVStore(k.idStoreKey) - if !idStore.Has([]byte(types.IDStoreKey)){ + if !idStore.Has([]byte(types.IDStoreKey)) { // store is empty return int64(-1) } @@ -127,10 +159,10 @@ func (k Keeper) GetLatestID(ctx sdk.Context) int64{ } // store id + 1 -func (k Keeper) GetUpdatedID(ctx sdk.Context) int64{ +func (k Keeper) GetUpdatedID(ctx sdk.Context) int64 { id := k.GetLatestID(ctx) idStore := ctx.KVStore(k.idStoreKey) idStore.Set([]byte(types.IDStoreKey), []byte(strconv.FormatInt(id+1, 10))) - return id+1 + return id + 1 } diff --git a/x/escrow/types/codec.go b/x/escrow/types/codec.go index bdb6f1d..43eb19c 100644 --- a/x/escrow/types/codec.go +++ b/x/escrow/types/codec.go @@ -16,7 +16,9 @@ func RegisterCodec(cdc *codec.LegacyAmino) { func RegisterInterfaces(registry cdctypes.InterfaceRegistry) { // this line is used by starport scaffolding # 3 - registry.RegisterImplementations((*sdk.Msg)(nil), &Offer{}) + registry.RegisterImplementations((*sdk.Msg)(nil), &OfferRequest{}) + registry.RegisterImplementations((*sdk.Msg)(nil), &ResponseRequest{}) + registry.RegisterImplementations((*sdk.Msg)(nil), &CancelOfferRequest{}) msgservice.RegisterMsgServiceDesc(registry, &_Msg_serviceDesc) diff --git a/x/escrow/types/msgs.go b/x/escrow/types/msgs.go index 481719a..788eae1 100644 --- a/x/escrow/types/msgs.go +++ b/x/escrow/types/msgs.go @@ -1,50 +1,115 @@ package types import ( - fmt "fmt" + "fmt" sdk "github.com/cosmos/cosmos-sdk/types" ) var ( - _ sdk.Msg = &Offer{} + _ sdk.Msg = &OfferRequest{} + _ sdk.Msg = &ResponseRequest{} + _ sdk.Msg = &CancelOfferRequest{} ) const ( - TypeOffer = "offer" + TypeOfferRequest = "offer" + TypeResponseRequest = "response" + TypeCancelOfferRequest = "CancelOffer" ) // NewMsgMint is a constructor function for NewMsgMint -func NewOfferRequest(sender sdk.AccAddress, amount string, request string) *Offer { +func NewOfferRequest(sender sdk.AccAddress, amount string, request string) *OfferRequest { amt,_ := sdk.ParseCoinsNormalized(amount) req,_ := sdk.ParseCoinsNormalized(request) - return &Offer{Sender: sender.String(), Amount: amt, Request: req} + return &OfferRequest{Sender: sender.String(), Amount: amt, Request: req} } // Route should return the name of the module -func (msg *Offer) Route() string { return RouterKey } +func (msg *OfferRequest) Route() string { return RouterKey } // Type should return the action -func (msg *Offer) Type() string { return TypeOffer} +func (msg *OfferRequest) Type() string { return TypeOfferRequest} // ValidateBasic runs stateless checks on the message -func (msg *Offer) ValidateBasic() error { - //addr, err := sdk.AccAddressFromBech32(msg.Sender) - //fmt.Println("validation basic!!!!", addr) - //if err != nil { - // return sdkerrors.Wrap(sdkerrors.ErrInvalidAddress, msg.Sender) - //} - //// todo add more validation +func (msg *OfferRequest) ValidateBasic() error { + // todo add more validation return nil } // GetSignBytes encodes the message for signing -func (msg *Offer) GetSignBytes() []byte { +func (msg *OfferRequest) GetSignBytes() []byte { panic("amino support disabled") } // GetSigners defines whose signature is required -func (msg *Offer) GetSigners() []sdk.AccAddress { +func (msg *OfferRequest) GetSigners() []sdk.AccAddress { + sender, err := sdk.AccAddressFromBech32(msg.Sender) + if err != nil { + fmt.Println(err) + // panic(err) + } + return []sdk.AccAddress{sdk.AccAddress(sender)} +} + +func NewResponseRequest(sender sdk.AccAddress, id int64) *ResponseRequest { + return &ResponseRequest{Sender: sender.String(), Id: id} +} + +// Route should return the name of the module +func (msg *ResponseRequest) Route() string { return RouterKey } + +// Type should return the action +func (msg *ResponseRequest) Type() string { return TypeResponseRequest} + +// ValidateBasic runs stateless checks on the message +func (msg *ResponseRequest) ValidateBasic() error { + // todo add more validation + return nil +} + +// GetSignBytes encodes the message for signing +func (msg *ResponseRequest) GetSignBytes() []byte { + panic("amino support disabled") +} + +// GetSigners defines whose signature is required +func (msg *ResponseRequest) GetSigners() []sdk.AccAddress { + sender, err := sdk.AccAddressFromBech32(msg.Sender) + if err != nil { + fmt.Println(err) + // panic(err) + } + return []sdk.AccAddress{sdk.AccAddress(sender)} +} + + + +func NewCancelOfferRequest(addr sdk.Address, id int64) *CancelOfferRequest { + return &CancelOfferRequest{Sender:addr.String(), Id: id} +} + +// Route should return the name of the module +func (msg *CancelOfferRequest) Route() string { return RouterKey } + +// Type should return the action +func (msg *CancelOfferRequest) Type() string { return TypeCancelOfferRequest} + +// ValidateBasic runs stateless checks on the message +func (msg *CancelOfferRequest) ValidateBasic() error { + + // todo add more validation + + return nil +} + +// GetSignBytes encodes the message for signing +func (msg *CancelOfferRequest) GetSignBytes() []byte { + panic("amino support disabled") +} + +// GetSigners defines whose signature is required +func (msg *CancelOfferRequest) GetSigners() []sdk.AccAddress { sender, err := sdk.AccAddressFromBech32(msg.Sender) if err != nil { fmt.Println(err) diff --git a/x/escrow/types/query.pb.go b/x/escrow/types/query.pb.go index f00b684..b54deff 100644 --- a/x/escrow/types/query.pb.go +++ b/x/escrow/types/query.pb.go @@ -6,6 +6,9 @@ package types import ( context "context" fmt "fmt" + github_com_cosmos_cosmos_sdk_types "github.com/cosmos/cosmos-sdk/types" + types "github.com/cosmos/cosmos-sdk/types" + _ "github.com/gogo/protobuf/gogoproto" grpc1 "github.com/gogo/protobuf/grpc" proto "github.com/gogo/protobuf/proto" _ "google.golang.org/genproto/googleapis/api/annotations" @@ -196,38 +199,115 @@ func (m *OfferListResponse) GetOfferList() []*Offer { return nil } +type Offer struct { + Sender string `protobuf:"bytes,1,opt,name=sender,proto3" json:"sender,omitempty"` + Amount github_com_cosmos_cosmos_sdk_types.Coins `protobuf:"bytes,2,rep,name=amount,proto3,castrepeated=github.com/cosmos/cosmos-sdk/types.Coins" json:"amount"` + Request github_com_cosmos_cosmos_sdk_types.Coins `protobuf:"bytes,3,rep,name=request,proto3,castrepeated=github.com/cosmos/cosmos-sdk/types.Coins" json:"request"` + Id int64 `protobuf:"varint,4,opt,name=id,proto3" json:"id,omitempty"` +} + +func (m *Offer) Reset() { *m = Offer{} } +func (m *Offer) String() string { return proto.CompactTextString(m) } +func (*Offer) ProtoMessage() {} +func (*Offer) Descriptor() ([]byte, []int) { + return fileDescriptor_6d37bf65b8b6e159, []int{4} +} +func (m *Offer) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *Offer) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_Offer.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 *Offer) XXX_Merge(src proto.Message) { + xxx_messageInfo_Offer.Merge(m, src) +} +func (m *Offer) XXX_Size() int { + return m.Size() +} +func (m *Offer) XXX_DiscardUnknown() { + xxx_messageInfo_Offer.DiscardUnknown(m) +} + +var xxx_messageInfo_Offer proto.InternalMessageInfo + +func (m *Offer) GetSender() string { + if m != nil { + return m.Sender + } + return "" +} + +func (m *Offer) GetAmount() github_com_cosmos_cosmos_sdk_types.Coins { + if m != nil { + return m.Amount + } + return nil +} + +func (m *Offer) GetRequest() github_com_cosmos_cosmos_sdk_types.Coins { + if m != nil { + return m.Request + } + return nil +} + +func (m *Offer) GetId() int64 { + if m != nil { + return m.Id + } + return 0 +} + func init() { proto.RegisterType((*OfferListAllRequest)(nil), "escrow.OfferListAllRequest") proto.RegisterType((*QueryOfferByIDRequest)(nil), "escrow.QueryOfferByIDRequest") proto.RegisterType((*QueryOfferByAddrRequest)(nil), "escrow.QueryOfferByAddrRequest") proto.RegisterType((*OfferListResponse)(nil), "escrow.OfferListResponse") + proto.RegisterType((*Offer)(nil), "escrow.Offer") } func init() { proto.RegisterFile("escrow/query.proto", fileDescriptor_6d37bf65b8b6e159) } var fileDescriptor_6d37bf65b8b6e159 = []byte{ - // 333 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x7c, 0x91, 0xc1, 0x4e, 0xfa, 0x40, - 0x10, 0xc6, 0x59, 0xc8, 0x9f, 0x7f, 0x58, 0x23, 0xca, 0x1a, 0x22, 0x56, 0x5d, 0x49, 0x2f, 0x92, - 0x98, 0x74, 0x13, 0xb8, 0x1b, 0x21, 0x5e, 0x8c, 0x44, 0x63, 0x8f, 0xde, 0x0a, 0x5d, 0x60, 0x93, - 0xba, 0x53, 0x76, 0x97, 0x48, 0xdf, 0xc2, 0xc7, 0xf2, 0xc8, 0xd1, 0xa3, 0x01, 0x1f, 0xc4, 0xd0, - 0x52, 0xa0, 0x4a, 0x3c, 0xee, 0xf7, 0xfd, 0x76, 0xe6, 0x9b, 0x19, 0x4c, 0xb8, 0xee, 0x2b, 0x78, - 0x65, 0xe3, 0x09, 0x57, 0x91, 0x13, 0x2a, 0x30, 0x40, 0x8a, 0x89, 0x66, 0x9d, 0x0d, 0x01, 0x86, - 0x01, 0x67, 0x5e, 0x28, 0x98, 0x27, 0x25, 0x18, 0xcf, 0x08, 0x90, 0x3a, 0xa1, 0xac, 0x83, 0xd5, - 0x4f, 0x33, 0x4d, 0x04, 0xbb, 0x8a, 0x8f, 0x1e, 0x07, 0x03, 0xae, 0xba, 0x42, 0x9b, 0x76, 0x10, - 0xb8, 0x7c, 0x3c, 0xe1, 0xda, 0xd8, 0x97, 0xb8, 0xfa, 0xb4, 0x2c, 0x1e, 0x7b, 0x9d, 0xe8, 0xee, - 0x76, 0x65, 0x90, 0x32, 0xce, 0x0b, 0xbf, 0x86, 0xea, 0xa8, 0x51, 0x70, 0xf3, 0xc2, 0xb7, 0x5b, - 0xf8, 0x78, 0x1b, 0x6c, 0xfb, 0xbe, 0x4a, 0xd1, 0x1a, 0xfe, 0x0f, 0x4b, 0x95, 0xab, 0x98, 0x2f, - 0xb9, 0xe9, 0xd3, 0xbe, 0xc1, 0x95, 0x75, 0x53, 0x97, 0xeb, 0x10, 0xa4, 0xe6, 0xe4, 0x0a, 0x97, - 0x20, 0x15, 0x6b, 0xa8, 0x5e, 0x68, 0xec, 0x35, 0xf7, 0x9d, 0x24, 0xae, 0x13, 0xd3, 0xee, 0xc6, - 0x6f, 0x7e, 0x21, 0xfc, 0x2f, 0xee, 0x4b, 0xee, 0x71, 0x65, 0x13, 0x60, 0x35, 0x05, 0x39, 0xcd, - 0x7c, 0xcc, 0xce, 0x66, 0x9d, 0xfc, 0x32, 0xd7, 0x19, 0xae, 0x71, 0x39, 0x3b, 0x36, 0x39, 0x4f, - 0xe1, 0x9d, 0xeb, 0xb0, 0xb2, 0x09, 0xc9, 0x03, 0x3e, 0xfc, 0xb9, 0x0d, 0x72, 0xb1, 0xab, 0xc2, - 0xd6, 0x9e, 0xfe, 0xc8, 0xd3, 0xe9, 0xbe, 0xcf, 0x29, 0x9a, 0xcd, 0x29, 0xfa, 0x9c, 0x53, 0xf4, - 0xb6, 0xa0, 0xb9, 0xd9, 0x82, 0xe6, 0x3e, 0x16, 0x34, 0xf7, 0xdc, 0x1c, 0x0a, 0x33, 0x9a, 0xf4, - 0x9c, 0x3e, 0xbc, 0x30, 0x21, 0x0d, 0x57, 0xfd, 0x91, 0x27, 0x64, 0x8f, 0xab, 0x40, 0x48, 0x16, - 0x02, 0x04, 0x06, 0x22, 0x36, 0x65, 0xe9, 0xb9, 0xa3, 0x90, 0xeb, 0x5e, 0x31, 0x3e, 0x79, 0xeb, - 0x3b, 0x00, 0x00, 0xff, 0xff, 0xa1, 0x6e, 0x29, 0x3a, 0x3f, 0x02, 0x00, 0x00, + // 452 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x93, 0xcf, 0x6e, 0xd3, 0x40, + 0x10, 0xc6, 0xe3, 0x84, 0xa6, 0xea, 0x20, 0x2a, 0xba, 0x50, 0x70, 0x03, 0x38, 0x95, 0x2f, 0x44, + 0x42, 0x78, 0x69, 0x7a, 0x47, 0x34, 0x70, 0x41, 0x54, 0x20, 0x7c, 0xe4, 0xe6, 0x3f, 0x53, 0x77, + 0x85, 0xb3, 0xe3, 0xee, 0x6e, 0x80, 0xbc, 0x05, 0xcf, 0xc1, 0x93, 0xf4, 0xd8, 0x23, 0x27, 0x40, + 0x09, 0x6f, 0xc1, 0x05, 0x65, 0xbd, 0x4e, 0x13, 0xa8, 0x38, 0x71, 0xb2, 0x77, 0xbe, 0xcf, 0xb3, + 0xbb, 0xbf, 0x6f, 0x0c, 0x0c, 0x75, 0xa6, 0xe8, 0x23, 0x3f, 0x9b, 0xa0, 0x9a, 0x46, 0x95, 0x22, + 0x43, 0xac, 0x5b, 0xd7, 0x7a, 0xb7, 0x0b, 0x2a, 0xc8, 0x96, 0xf8, 0xe2, 0xad, 0x56, 0x7b, 0xf7, + 0x0b, 0xa2, 0xa2, 0x44, 0x9e, 0x54, 0x82, 0x27, 0x52, 0x92, 0x49, 0x8c, 0x20, 0xa9, 0x9d, 0x1a, + 0x64, 0xa4, 0xc7, 0xa4, 0x79, 0x9a, 0x68, 0xe4, 0x1f, 0x0e, 0x52, 0x34, 0xc9, 0x01, 0xcf, 0x48, + 0xc8, 0x5a, 0x0f, 0x77, 0xe1, 0xd6, 0x9b, 0x93, 0x13, 0x54, 0xc7, 0x42, 0x9b, 0xa3, 0xb2, 0x8c, + 0xf1, 0x6c, 0x82, 0xda, 0x84, 0x0f, 0x61, 0xf7, 0xed, 0xe2, 0x04, 0x56, 0x1b, 0x4d, 0x5f, 0xbe, + 0x70, 0x02, 0xdb, 0x86, 0xb6, 0xc8, 0x7d, 0x6f, 0xdf, 0x1b, 0x74, 0xe2, 0xb6, 0xc8, 0xc3, 0x43, + 0xb8, 0xbb, 0x6a, 0x3c, 0xca, 0x73, 0xd5, 0x58, 0x7d, 0xd8, 0xa4, 0x45, 0x15, 0x95, 0xf5, 0x6f, + 0xc5, 0xcd, 0x32, 0x7c, 0x06, 0x3b, 0xcb, 0x4d, 0x63, 0xd4, 0x15, 0x49, 0x8d, 0xec, 0x11, 0x6c, + 0x51, 0x53, 0xf4, 0xbd, 0xfd, 0xce, 0xe0, 0xfa, 0xf0, 0x46, 0x54, 0xdf, 0x3c, 0xb2, 0xee, 0xf8, + 0x52, 0x0f, 0x7f, 0x79, 0xb0, 0x61, 0x8b, 0xec, 0x0e, 0x74, 0x35, 0xca, 0x7c, 0xb9, 0x89, 0x5b, + 0xb1, 0x0c, 0xba, 0xc9, 0x98, 0x26, 0xd2, 0xf8, 0x6d, 0xdb, 0x6b, 0x2f, 0xaa, 0x49, 0x44, 0x0b, + 0x12, 0x91, 0x23, 0x11, 0x3d, 0x27, 0x21, 0x47, 0x4f, 0xce, 0xbf, 0xf5, 0x5b, 0x5f, 0xbe, 0xf7, + 0x07, 0x85, 0x30, 0xa7, 0x93, 0x34, 0xca, 0x68, 0xcc, 0x1d, 0xb6, 0xfa, 0xf1, 0x58, 0xe7, 0xef, + 0xb9, 0x99, 0x56, 0xa8, 0xed, 0x07, 0x3a, 0x76, 0xad, 0x19, 0xc2, 0xa6, 0xaa, 0x6f, 0xeb, 0x77, + 0xfe, 0xff, 0x2e, 0x4d, 0x6f, 0x07, 0xfd, 0x5a, 0x03, 0x7d, 0xf8, 0xd3, 0x83, 0x0d, 0x4b, 0x9d, + 0xbd, 0x82, 0x9d, 0x4b, 0xfc, 0x2e, 0x43, 0x76, 0x6f, 0x0d, 0xdb, 0x7a, 0xb2, 0xbd, 0xbd, 0xbf, + 0xc4, 0x65, 0x02, 0x4f, 0x61, 0x7b, 0x3d, 0x74, 0xf6, 0xa0, 0x31, 0x5f, 0x39, 0x0c, 0xbd, 0xf5, + 0x7c, 0xd8, 0x6b, 0xb8, 0xf9, 0xe7, 0x2c, 0xb0, 0xfe, 0x55, 0x1d, 0x56, 0xa6, 0xe4, 0x1f, 0xe7, + 0x19, 0x1d, 0x9f, 0xcf, 0x02, 0xef, 0x62, 0x16, 0x78, 0x3f, 0x66, 0x81, 0xf7, 0x79, 0x1e, 0xb4, + 0x2e, 0xe6, 0x41, 0xeb, 0xeb, 0x3c, 0x68, 0xbd, 0x1b, 0xae, 0x30, 0x14, 0xd2, 0xa0, 0xca, 0x4e, + 0x13, 0x21, 0x53, 0x54, 0xa5, 0x90, 0xbc, 0x22, 0x2a, 0x0d, 0x4d, 0xf9, 0x27, 0xee, 0xfe, 0x25, + 0xcb, 0x34, 0xed, 0xda, 0x81, 0x3f, 0xfc, 0x1d, 0x00, 0x00, 0xff, 0xff, 0xee, 0x2e, 0x6d, 0x9a, + 0x62, 0x03, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -502,6 +582,69 @@ func (m *OfferListResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { return len(dAtA) - i, nil } +func (m *Offer) 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 *Offer) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *Offer) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.Id != 0 { + i = encodeVarintQuery(dAtA, i, uint64(m.Id)) + i-- + dAtA[i] = 0x20 + } + if len(m.Request) > 0 { + for iNdEx := len(m.Request) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Request[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintQuery(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x1a + } + } + if len(m.Amount) > 0 { + for iNdEx := len(m.Amount) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Amount[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintQuery(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + } + if len(m.Sender) > 0 { + i -= len(m.Sender) + copy(dAtA[i:], m.Sender) + i = encodeVarintQuery(dAtA, i, uint64(len(m.Sender))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + func encodeVarintQuery(dAtA []byte, offset int, v uint64) int { offset -= sovQuery(v) base := offset @@ -562,6 +705,34 @@ func (m *OfferListResponse) Size() (n int) { return n } +func (m *Offer) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Sender) + if l > 0 { + n += 1 + l + sovQuery(uint64(l)) + } + if len(m.Amount) > 0 { + for _, e := range m.Amount { + l = e.Size() + n += 1 + l + sovQuery(uint64(l)) + } + } + if len(m.Request) > 0 { + for _, e := range m.Request { + l = e.Size() + n += 1 + l + sovQuery(uint64(l)) + } + } + if m.Id != 0 { + n += 1 + sovQuery(uint64(m.Id)) + } + return n +} + func sovQuery(x uint64) (n int) { return (math_bits.Len64(x|1) + 6) / 7 } @@ -853,6 +1024,175 @@ func (m *OfferListResponse) Unmarshal(dAtA []byte) error { } return nil } +func (m *Offer) 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 ErrIntOverflowQuery + } + 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: Offer: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Offer: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Sender", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + 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 ErrInvalidLengthQuery + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Sender = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Amount", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Amount = append(m.Amount, types.Coin{}) + if err := m.Amount[len(m.Amount)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Request", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Request = append(m.Request, types.Coin{}) + if err := m.Request[len(m.Request)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 4: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Id", wireType) + } + m.Id = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Id |= int64(b&0x7F) << shift + if b < 0x80 { + break + } + } + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func skipQuery(dAtA []byte) (n int, err error) { l := len(dAtA) iNdEx := 0 diff --git a/x/escrow/types/tx.pb.go b/x/escrow/types/tx.pb.go index 0f2ced2..00dabe2 100644 --- a/x/escrow/types/tx.pb.go +++ b/x/escrow/types/tx.pb.go @@ -31,24 +31,24 @@ var _ = math.Inf const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package // this line is used by starport scaffolding # proto/tx/message -type Offer struct { +type OfferRequest struct { Sender string `protobuf:"bytes,1,opt,name=sender,proto3" json:"sender,omitempty"` Amount github_com_cosmos_cosmos_sdk_types.Coins `protobuf:"bytes,2,rep,name=amount,proto3,castrepeated=github.com/cosmos/cosmos-sdk/types.Coins" json:"amount"` Request github_com_cosmos_cosmos_sdk_types.Coins `protobuf:"bytes,3,rep,name=request,proto3,castrepeated=github.com/cosmos/cosmos-sdk/types.Coins" json:"request"` } -func (m *Offer) Reset() { *m = Offer{} } -func (m *Offer) String() string { return proto.CompactTextString(m) } -func (*Offer) ProtoMessage() {} -func (*Offer) Descriptor() ([]byte, []int) { +func (m *OfferRequest) Reset() { *m = OfferRequest{} } +func (m *OfferRequest) String() string { return proto.CompactTextString(m) } +func (*OfferRequest) ProtoMessage() {} +func (*OfferRequest) Descriptor() ([]byte, []int) { return fileDescriptor_8e01f3e45c7c056c, []int{0} } -func (m *Offer) XXX_Unmarshal(b []byte) error { +func (m *OfferRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) } -func (m *Offer) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { +func (m *OfferRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { if deterministic { - return xxx_messageInfo_Offer.Marshal(b, m, deterministic) + return xxx_messageInfo_OfferRequest.Marshal(b, m, deterministic) } else { b = b[:cap(b)] n, err := m.MarshalToSizedBuffer(b) @@ -58,43 +58,39 @@ func (m *Offer) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return b[:n], nil } } -func (m *Offer) XXX_Merge(src proto.Message) { - xxx_messageInfo_Offer.Merge(m, src) +func (m *OfferRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_OfferRequest.Merge(m, src) } -func (m *Offer) XXX_Size() int { +func (m *OfferRequest) XXX_Size() int { return m.Size() } -func (m *Offer) XXX_DiscardUnknown() { - xxx_messageInfo_Offer.DiscardUnknown(m) +func (m *OfferRequest) XXX_DiscardUnknown() { + xxx_messageInfo_OfferRequest.DiscardUnknown(m) } -var xxx_messageInfo_Offer proto.InternalMessageInfo +var xxx_messageInfo_OfferRequest proto.InternalMessageInfo -func (m *Offer) GetSender() string { +func (m *OfferRequest) GetSender() string { if m != nil { return m.Sender } return "" } -func (m *Offer) GetAmount() github_com_cosmos_cosmos_sdk_types.Coins { +func (m *OfferRequest) GetAmount() github_com_cosmos_cosmos_sdk_types.Coins { if m != nil { return m.Amount } return nil } -func (m *Offer) GetRequest() github_com_cosmos_cosmos_sdk_types.Coins { +func (m *OfferRequest) GetRequest() github_com_cosmos_cosmos_sdk_types.Coins { if m != nil { return m.Request } return nil } -//message Coin { -// string coin = 1 -// [(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Coin"]; -//} type OfferResponse struct { Sender string `protobuf:"bytes,1,opt,name=sender,proto3" json:"sender,omitempty"` Index int64 `protobuf:"varint,2,opt,name=index,proto3" json:"index,omitempty"` @@ -147,36 +143,222 @@ func (m *OfferResponse) GetIndex() int64 { return 0 } +type ResponseRequest struct { + Sender string `protobuf:"bytes,1,opt,name=sender,proto3" json:"sender,omitempty"` + Id int64 `protobuf:"varint,2,opt,name=id,proto3" json:"id,omitempty"` +} + +func (m *ResponseRequest) Reset() { *m = ResponseRequest{} } +func (m *ResponseRequest) String() string { return proto.CompactTextString(m) } +func (*ResponseRequest) ProtoMessage() {} +func (*ResponseRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_8e01f3e45c7c056c, []int{2} +} +func (m *ResponseRequest) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *ResponseRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_ResponseRequest.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 *ResponseRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_ResponseRequest.Merge(m, src) +} +func (m *ResponseRequest) XXX_Size() int { + return m.Size() +} +func (m *ResponseRequest) XXX_DiscardUnknown() { + xxx_messageInfo_ResponseRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_ResponseRequest proto.InternalMessageInfo + +func (m *ResponseRequest) GetSender() string { + if m != nil { + return m.Sender + } + return "" +} + +func (m *ResponseRequest) GetId() int64 { + if m != nil { + return m.Id + } + return 0 +} + +type ResponseResult struct { +} + +func (m *ResponseResult) Reset() { *m = ResponseResult{} } +func (m *ResponseResult) String() string { return proto.CompactTextString(m) } +func (*ResponseResult) ProtoMessage() {} +func (*ResponseResult) Descriptor() ([]byte, []int) { + return fileDescriptor_8e01f3e45c7c056c, []int{3} +} +func (m *ResponseResult) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *ResponseResult) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_ResponseResult.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 *ResponseResult) XXX_Merge(src proto.Message) { + xxx_messageInfo_ResponseResult.Merge(m, src) +} +func (m *ResponseResult) XXX_Size() int { + return m.Size() +} +func (m *ResponseResult) XXX_DiscardUnknown() { + xxx_messageInfo_ResponseResult.DiscardUnknown(m) +} + +var xxx_messageInfo_ResponseResult proto.InternalMessageInfo + +type CancelOfferRequest struct { + Sender string `protobuf:"bytes,1,opt,name=sender,proto3" json:"sender,omitempty"` + Id int64 `protobuf:"varint,2,opt,name=id,proto3" json:"id,omitempty"` +} + +func (m *CancelOfferRequest) Reset() { *m = CancelOfferRequest{} } +func (m *CancelOfferRequest) String() string { return proto.CompactTextString(m) } +func (*CancelOfferRequest) ProtoMessage() {} +func (*CancelOfferRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_8e01f3e45c7c056c, []int{4} +} +func (m *CancelOfferRequest) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *CancelOfferRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_CancelOfferRequest.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 *CancelOfferRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_CancelOfferRequest.Merge(m, src) +} +func (m *CancelOfferRequest) XXX_Size() int { + return m.Size() +} +func (m *CancelOfferRequest) XXX_DiscardUnknown() { + xxx_messageInfo_CancelOfferRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_CancelOfferRequest proto.InternalMessageInfo + +func (m *CancelOfferRequest) GetSender() string { + if m != nil { + return m.Sender + } + return "" +} + +func (m *CancelOfferRequest) GetId() int64 { + if m != nil { + return m.Id + } + return 0 +} + +type CancelOfferResponse struct { +} + +func (m *CancelOfferResponse) Reset() { *m = CancelOfferResponse{} } +func (m *CancelOfferResponse) String() string { return proto.CompactTextString(m) } +func (*CancelOfferResponse) ProtoMessage() {} +func (*CancelOfferResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_8e01f3e45c7c056c, []int{5} +} +func (m *CancelOfferResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *CancelOfferResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_CancelOfferResponse.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 *CancelOfferResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_CancelOfferResponse.Merge(m, src) +} +func (m *CancelOfferResponse) XXX_Size() int { + return m.Size() +} +func (m *CancelOfferResponse) XXX_DiscardUnknown() { + xxx_messageInfo_CancelOfferResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_CancelOfferResponse proto.InternalMessageInfo + func init() { - proto.RegisterType((*Offer)(nil), "escrow.Offer") + proto.RegisterType((*OfferRequest)(nil), "escrow.OfferRequest") proto.RegisterType((*OfferResponse)(nil), "escrow.OfferResponse") + proto.RegisterType((*ResponseRequest)(nil), "escrow.ResponseRequest") + proto.RegisterType((*ResponseResult)(nil), "escrow.ResponseResult") + proto.RegisterType((*CancelOfferRequest)(nil), "escrow.CancelOfferRequest") + proto.RegisterType((*CancelOfferResponse)(nil), "escrow.CancelOfferResponse") } func init() { proto.RegisterFile("escrow/tx.proto", fileDescriptor_8e01f3e45c7c056c) } var fileDescriptor_8e01f3e45c7c056c = []byte{ - // 326 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x91, 0xb1, 0x4e, 0xeb, 0x30, - 0x14, 0x86, 0x93, 0x46, 0xcd, 0xd5, 0xf5, 0x55, 0x75, 0xa5, 0xa8, 0xa0, 0xd0, 0xc1, 0xad, 0x3a, - 0x65, 0xa9, 0x4d, 0x0b, 0x2b, 0x4b, 0x59, 0x41, 0x48, 0x19, 0xd9, 0x92, 0xf4, 0x34, 0xb5, 0x68, - 0x7d, 0x82, 0xed, 0x42, 0xfb, 0x16, 0x3c, 0x07, 0x4f, 0xd2, 0xb1, 0x23, 0x13, 0xa0, 0x76, 0xe4, - 0x25, 0x50, 0xe3, 0x44, 0x82, 0x81, 0x8d, 0xc9, 0xfe, 0xcf, 0xd1, 0xf9, 0x7e, 0xfd, 0xe7, 0x90, - 0xff, 0xa0, 0x33, 0x85, 0x8f, 0xdc, 0xac, 0x58, 0xa1, 0xd0, 0x60, 0xe0, 0xdb, 0x42, 0xa7, 0x9d, - 0x63, 0x8e, 0x65, 0x89, 0x1f, 0x7e, 0xb6, 0xdb, 0xa1, 0x19, 0xea, 0x05, 0x6a, 0x9e, 0x26, 0x1a, - 0xf8, 0xc3, 0x30, 0x05, 0x93, 0x0c, 0x79, 0x86, 0x42, 0xda, 0x7e, 0xff, 0xc3, 0x25, 0xcd, 0x9b, - 0xe9, 0x14, 0x54, 0x70, 0x4c, 0x7c, 0x0d, 0x72, 0x02, 0x2a, 0x74, 0x7b, 0x6e, 0xf4, 0x37, 0xae, - 0x54, 0x90, 0x11, 0x3f, 0x59, 0xe0, 0x52, 0x9a, 0xb0, 0xd1, 0xf3, 0xa2, 0x7f, 0xa3, 0x13, 0x66, - 0x91, 0xec, 0x80, 0x64, 0x15, 0x92, 0x5d, 0xa2, 0x90, 0xe3, 0xd3, 0xcd, 0x6b, 0xd7, 0x79, 0x7e, - 0xeb, 0x46, 0xb9, 0x30, 0xb3, 0x65, 0xca, 0x32, 0x5c, 0xf0, 0xca, 0xdf, 0x3e, 0x03, 0x3d, 0xb9, - 0xe3, 0x66, 0x5d, 0x80, 0x2e, 0x07, 0x74, 0x5c, 0xa1, 0x03, 0x20, 0x7f, 0x14, 0xdc, 0x2f, 0x41, - 0x9b, 0xd0, 0xfb, 0x7d, 0x97, 0x9a, 0xdd, 0xbf, 0x20, 0xad, 0x32, 0x6c, 0x0c, 0xba, 0x40, 0xa9, - 0xe1, 0xc7, 0xd0, 0x6d, 0xd2, 0x14, 0x72, 0x02, 0xab, 0xb0, 0xd1, 0x73, 0x23, 0x2f, 0xb6, 0x62, - 0x74, 0x4e, 0xbc, 0x6b, 0x9d, 0x07, 0x83, 0x7a, 0x65, 0x2d, 0x66, 0x77, 0xcf, 0x4a, 0xd9, 0x39, - 0xfa, 0x26, 0x6b, 0x8f, 0xf1, 0xd5, 0x66, 0x47, 0xdd, 0xed, 0x8e, 0xba, 0xef, 0x3b, 0xea, 0x3e, - 0xed, 0xa9, 0xb3, 0xdd, 0x53, 0xe7, 0x65, 0x4f, 0x9d, 0xdb, 0xd1, 0x97, 0x04, 0x42, 0x1a, 0x50, - 0xd9, 0x2c, 0x11, 0x32, 0x05, 0x35, 0x17, 0x92, 0x17, 0x88, 0x73, 0x83, 0x6b, 0xbe, 0xe2, 0xf5, - 0xc5, 0x0f, 0x89, 0x52, 0xbf, 0xbc, 0xdb, 0xd9, 0x67, 0x00, 0x00, 0x00, 0xff, 0xff, 0x52, 0xb9, - 0x44, 0x4a, 0x08, 0x02, 0x00, 0x00, + // 418 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x53, 0xbd, 0x8e, 0xd4, 0x30, + 0x10, 0x8e, 0x13, 0x5d, 0x80, 0x39, 0xb8, 0x43, 0x66, 0xef, 0x08, 0x41, 0xca, 0xad, 0x52, 0xa5, + 0xc1, 0xe6, 0x16, 0x1a, 0x04, 0x34, 0x77, 0x12, 0x15, 0x08, 0x29, 0x25, 0x5d, 0x7e, 0x7c, 0x39, + 0x8b, 0xac, 0x1d, 0x62, 0x07, 0x76, 0xdf, 0x82, 0xe7, 0xe0, 0x29, 0x28, 0xb7, 0xdc, 0x92, 0x0a, + 0xd0, 0xee, 0x1b, 0xf0, 0x04, 0x28, 0x71, 0x02, 0xcb, 0x2e, 0x08, 0x0a, 0xaa, 0xd8, 0xf3, 0xf9, + 0xfb, 0x66, 0xbe, 0x99, 0x09, 0x1c, 0x32, 0x95, 0xd5, 0xf2, 0x1d, 0xd5, 0x33, 0x52, 0xd5, 0x52, + 0x4b, 0xec, 0x9a, 0x80, 0x3f, 0x2a, 0x64, 0x21, 0xbb, 0x10, 0x6d, 0x4f, 0x06, 0xf5, 0x83, 0x4c, + 0xaa, 0xa9, 0x54, 0x34, 0x4d, 0x14, 0xa3, 0x6f, 0x4f, 0x53, 0xa6, 0x93, 0x53, 0x9a, 0x49, 0x2e, + 0x0c, 0x1e, 0x7e, 0x43, 0x70, 0xfd, 0xe5, 0xc5, 0x05, 0xab, 0x63, 0xf6, 0xa6, 0x61, 0x4a, 0xe3, + 0x63, 0x70, 0x15, 0x13, 0x39, 0xab, 0x3d, 0x34, 0x46, 0xd1, 0xb5, 0xb8, 0xbf, 0xe1, 0x0c, 0xdc, + 0x64, 0x2a, 0x1b, 0xa1, 0x3d, 0x7b, 0xec, 0x44, 0xfb, 0x93, 0x3b, 0xc4, 0x28, 0x93, 0x56, 0x99, + 0xf4, 0xca, 0xe4, 0x5c, 0x72, 0x71, 0x76, 0x7f, 0xf1, 0xf9, 0xc4, 0xfa, 0xf0, 0xe5, 0x24, 0x2a, + 0xb8, 0xbe, 0x6c, 0x52, 0x92, 0xc9, 0x29, 0xed, 0xcb, 0x30, 0x9f, 0x7b, 0x2a, 0x7f, 0x4d, 0xf5, + 0xbc, 0x62, 0xaa, 0x23, 0xa8, 0xb8, 0x97, 0xc6, 0x0c, 0xae, 0xd4, 0xa6, 0x0e, 0xcf, 0xf9, 0xff, + 0x59, 0x06, 0xed, 0xf0, 0x29, 0xdc, 0xe8, 0x3d, 0xab, 0x4a, 0x0a, 0xc5, 0xfe, 0x68, 0x7a, 0x04, + 0x7b, 0x5c, 0xe4, 0x6c, 0xe6, 0xd9, 0x63, 0x14, 0x39, 0xb1, 0xb9, 0x84, 0x8f, 0xe0, 0x70, 0x60, + 0xfe, 0xad, 0x6b, 0x07, 0x60, 0xf3, 0xbc, 0x67, 0xdb, 0x3c, 0x0f, 0x6f, 0xc2, 0xc1, 0x4f, 0xaa, + 0x6a, 0x4a, 0x1d, 0x3e, 0x01, 0x7c, 0x9e, 0x88, 0x8c, 0x95, 0xff, 0x34, 0x85, 0x6d, 0xbd, 0x23, + 0xb8, 0xf5, 0x0b, 0xdb, 0x48, 0x4f, 0x3e, 0x22, 0x70, 0x5e, 0xa8, 0x02, 0x3f, 0x84, 0xbd, 0x0e, + 0xc0, 0x23, 0x62, 0xb6, 0x84, 0x6c, 0x66, 0xf1, 0x8f, 0xb6, 0xa2, 0x7d, 0x37, 0x1e, 0xc3, 0xd5, + 0x1f, 0xe7, 0xdb, 0xc3, 0x93, 0x2d, 0xc7, 0xfe, 0xf1, 0x2e, 0xd0, 0xfa, 0xc1, 0xcf, 0x60, 0x7f, + 0xa3, 0x22, 0xec, 0x0f, 0xcf, 0x76, 0x4d, 0xfa, 0x77, 0x7f, 0x8b, 0x19, 0xb5, 0xb3, 0xe7, 0x8b, + 0x55, 0x80, 0x96, 0xab, 0x00, 0x7d, 0x5d, 0x05, 0xe8, 0xfd, 0x3a, 0xb0, 0x96, 0xeb, 0xc0, 0xfa, + 0xb4, 0x0e, 0xac, 0x57, 0x93, 0x8d, 0x81, 0x73, 0xa1, 0x59, 0x9d, 0x5d, 0x26, 0x5c, 0xa4, 0xac, + 0x2e, 0xb9, 0xa0, 0x95, 0x94, 0xa5, 0x96, 0x73, 0x3a, 0xa3, 0xc3, 0x7f, 0xd2, 0x2e, 0x40, 0xea, + 0x76, 0xdb, 0xfe, 0xe0, 0x7b, 0x00, 0x00, 0x00, 0xff, 0xff, 0x94, 0x14, 0x40, 0x45, 0x3e, 0x03, + 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -192,7 +374,9 @@ const _ = grpc.SupportPackageIsVersion4 // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. type MsgClient interface { // this line is used by starport scaffolding # proto/tx/rpc - Offer(ctx context.Context, in *Offer, opts ...grpc.CallOption) (*OfferResponse, error) + Offer(ctx context.Context, in *OfferRequest, opts ...grpc.CallOption) (*OfferResponse, error) + Response(ctx context.Context, in *ResponseRequest, opts ...grpc.CallOption) (*ResponseResult, error) + CancelOffer(ctx context.Context, in *CancelOfferRequest, opts ...grpc.CallOption) (*CancelOfferResponse, error) } type msgClient struct { @@ -203,7 +387,7 @@ func NewMsgClient(cc grpc1.ClientConn) MsgClient { return &msgClient{cc} } -func (c *msgClient) Offer(ctx context.Context, in *Offer, opts ...grpc.CallOption) (*OfferResponse, error) { +func (c *msgClient) Offer(ctx context.Context, in *OfferRequest, opts ...grpc.CallOption) (*OfferResponse, error) { out := new(OfferResponse) err := c.cc.Invoke(ctx, "/escrow.Msg/Offer", in, out, opts...) if err != nil { @@ -212,26 +396,52 @@ func (c *msgClient) Offer(ctx context.Context, in *Offer, opts ...grpc.CallOptio return out, nil } +func (c *msgClient) Response(ctx context.Context, in *ResponseRequest, opts ...grpc.CallOption) (*ResponseResult, error) { + out := new(ResponseResult) + err := c.cc.Invoke(ctx, "/escrow.Msg/Response", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *msgClient) CancelOffer(ctx context.Context, in *CancelOfferRequest, opts ...grpc.CallOption) (*CancelOfferResponse, error) { + out := new(CancelOfferResponse) + err := c.cc.Invoke(ctx, "/escrow.Msg/CancelOffer", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + // MsgServer is the server API for Msg service. type MsgServer interface { // this line is used by starport scaffolding # proto/tx/rpc - Offer(context.Context, *Offer) (*OfferResponse, error) + Offer(context.Context, *OfferRequest) (*OfferResponse, error) + Response(context.Context, *ResponseRequest) (*ResponseResult, error) + CancelOffer(context.Context, *CancelOfferRequest) (*CancelOfferResponse, error) } // UnimplementedMsgServer can be embedded to have forward compatible implementations. type UnimplementedMsgServer struct { } -func (*UnimplementedMsgServer) Offer(ctx context.Context, req *Offer) (*OfferResponse, error) { +func (*UnimplementedMsgServer) Offer(ctx context.Context, req *OfferRequest) (*OfferResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method Offer not implemented") } +func (*UnimplementedMsgServer) Response(ctx context.Context, req *ResponseRequest) (*ResponseResult, error) { + return nil, status.Errorf(codes.Unimplemented, "method Response not implemented") +} +func (*UnimplementedMsgServer) CancelOffer(ctx context.Context, req *CancelOfferRequest) (*CancelOfferResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method CancelOffer not implemented") +} func RegisterMsgServer(s grpc1.Server, srv MsgServer) { s.RegisterService(&_Msg_serviceDesc, srv) } func _Msg_Offer_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(Offer) + in := new(OfferRequest) if err := dec(in); err != nil { return nil, err } @@ -243,7 +453,43 @@ func _Msg_Offer_Handler(srv interface{}, ctx context.Context, dec func(interface FullMethod: "/escrow.Msg/Offer", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(MsgServer).Offer(ctx, req.(*Offer)) + return srv.(MsgServer).Offer(ctx, req.(*OfferRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Msg_Response_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ResponseRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(MsgServer).Response(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/escrow.Msg/Response", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MsgServer).Response(ctx, req.(*ResponseRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Msg_CancelOffer_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(CancelOfferRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(MsgServer).CancelOffer(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/escrow.Msg/CancelOffer", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MsgServer).CancelOffer(ctx, req.(*CancelOfferRequest)) } return interceptor(ctx, in, info, handler) } @@ -256,12 +502,20 @@ var _Msg_serviceDesc = grpc.ServiceDesc{ MethodName: "Offer", Handler: _Msg_Offer_Handler, }, + { + MethodName: "Response", + Handler: _Msg_Response_Handler, + }, + { + MethodName: "CancelOffer", + Handler: _Msg_CancelOffer_Handler, + }, }, Streams: []grpc.StreamDesc{}, Metadata: "escrow/tx.proto", } -func (m *Offer) Marshal() (dAtA []byte, err error) { +func (m *OfferRequest) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) n, err := m.MarshalToSizedBuffer(dAtA[:size]) @@ -271,12 +525,12 @@ func (m *Offer) Marshal() (dAtA []byte, err error) { return dAtA[:n], nil } -func (m *Offer) MarshalTo(dAtA []byte) (int, error) { +func (m *OfferRequest) MarshalTo(dAtA []byte) (int, error) { size := m.Size() return m.MarshalToSizedBuffer(dAtA[:size]) } -func (m *Offer) MarshalToSizedBuffer(dAtA []byte) (int, error) { +func (m *OfferRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { i := len(dAtA) _ = i var l int @@ -354,6 +608,122 @@ func (m *OfferResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { return len(dAtA) - i, nil } +func (m *ResponseRequest) 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 *ResponseRequest) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *ResponseRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.Id != 0 { + i = encodeVarintTx(dAtA, i, uint64(m.Id)) + i-- + dAtA[i] = 0x10 + } + if len(m.Sender) > 0 { + i -= len(m.Sender) + copy(dAtA[i:], m.Sender) + i = encodeVarintTx(dAtA, i, uint64(len(m.Sender))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *ResponseResult) 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 *ResponseResult) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *ResponseResult) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + return len(dAtA) - i, nil +} + +func (m *CancelOfferRequest) 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 *CancelOfferRequest) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *CancelOfferRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.Id != 0 { + i = encodeVarintTx(dAtA, i, uint64(m.Id)) + i-- + dAtA[i] = 0x10 + } + if len(m.Sender) > 0 { + i -= len(m.Sender) + copy(dAtA[i:], m.Sender) + i = encodeVarintTx(dAtA, i, uint64(len(m.Sender))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *CancelOfferResponse) 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 *CancelOfferResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *CancelOfferResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + return len(dAtA) - i, nil +} + func encodeVarintTx(dAtA []byte, offset int, v uint64) int { offset -= sovTx(v) base := offset @@ -365,7 +735,7 @@ func encodeVarintTx(dAtA []byte, offset int, v uint64) int { dAtA[offset] = uint8(v) return base } -func (m *Offer) Size() (n int) { +func (m *OfferRequest) Size() (n int) { if m == nil { return 0 } @@ -406,13 +776,63 @@ func (m *OfferResponse) Size() (n int) { return n } -func sovTx(x uint64) (n int) { - return (math_bits.Len64(x|1) + 6) / 7 -} -func sozTx(x uint64) (n int) { +func (m *ResponseRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Sender) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + if m.Id != 0 { + n += 1 + sovTx(uint64(m.Id)) + } + return n +} + +func (m *ResponseResult) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + return n +} + +func (m *CancelOfferRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Sender) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + if m.Id != 0 { + n += 1 + sovTx(uint64(m.Id)) + } + return n +} + +func (m *CancelOfferResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + return n +} + +func sovTx(x uint64) (n int) { + return (math_bits.Len64(x|1) + 6) / 7 +} +func sozTx(x uint64) (n int) { return sovTx(uint64((x << 1) ^ uint64((int64(x) >> 63)))) } -func (m *Offer) Unmarshal(dAtA []byte) error { +func (m *OfferRequest) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -435,10 +855,10 @@ func (m *Offer) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: Offer: wiretype end group for non-group") + return fmt.Errorf("proto: OfferRequest: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: Offer: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: OfferRequest: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: @@ -663,6 +1083,308 @@ func (m *OfferResponse) Unmarshal(dAtA []byte) error { } return nil } +func (m *ResponseRequest) 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 ErrIntOverflowTx + } + 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: ResponseRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ResponseRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Sender", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + 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 ErrInvalidLengthTx + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Sender = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Id", wireType) + } + m.Id = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Id |= int64(b&0x7F) << shift + if b < 0x80 { + break + } + } + default: + iNdEx = preIndex + skippy, err := skipTx(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthTx + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *ResponseResult) 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 ErrIntOverflowTx + } + 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: ResponseResult: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ResponseResult: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + default: + iNdEx = preIndex + skippy, err := skipTx(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthTx + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *CancelOfferRequest) 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 ErrIntOverflowTx + } + 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: CancelOfferRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: CancelOfferRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Sender", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + 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 ErrInvalidLengthTx + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Sender = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Id", wireType) + } + m.Id = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Id |= int64(b&0x7F) << shift + if b < 0x80 { + break + } + } + default: + iNdEx = preIndex + skippy, err := skipTx(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthTx + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *CancelOfferResponse) 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 ErrIntOverflowTx + } + 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: CancelOfferResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: CancelOfferResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + default: + iNdEx = preIndex + skippy, err := skipTx(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthTx + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func skipTx(dAtA []byte) (n int, err error) { l := len(dAtA) iNdEx := 0 diff --git a/x/escrow/utils/errors.go b/x/escrow/utils/errors.go deleted file mode 100644 index 699d334..0000000 --- a/x/escrow/utils/errors.go +++ /dev/null @@ -1,10 +0,0 @@ -package utils - -import sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" - -var ErrParseEmojiandNum = sdkerrors.Register("escrow", 106, "parse emoji string into numbers and emojis failed") -var ErrParseEmojiToCoins = sdkerrors.Register("escrow", 107, "parse emoji string into coins failed") - -var ErrEmojiCoinsCheck = sdkerrors.Register("escrow", 108, "emoji coins check failed") - -var ErrEmojiStr = sdkerrors.Register("escrow", 109, "parse emoji string into emoji failed") diff --git a/x/escrow/utils/utils.go b/x/escrow/utils/utils.go deleted file mode 100644 index 048adce..0000000 --- a/x/escrow/utils/utils.go +++ /dev/null @@ -1,191 +0,0 @@ -package utils - -import ( - sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/interchainberlin/pooltoy/x/faucet/utils" - "strconv" - "strings" - "unicode" -) - -// ----------------------------------------------------------------------------- -// -// ----------------------------------------------------------------------------- - -// find the max mactch, e.g. str = "\U0001f1e6\U0001f1fd\U0001f6e9", \U0001f1e6\U0001f1fd\" is an emoji, "\U0001f1e6" is also an emoji, it should find "\U0001f1e6\U0001f1fd". -// maxlen is the max length of a single emoji's runes, here is 5 according to the emojiCodeMap. -// ----------------------------------------------------------------------------- - -func GetCoinsWithCheck(emostr string) (coins sdk.Coins, err error) { - nums, emos, err := ParseEmojiandNum(emostr) - if err != nil { - return sdk.Coins{}, err - } - - coins, err = GetCoins(nums, emos) - if err != nil { - return sdk.Coins{}, err - } - emptyCoins := sdk.Coins{} - if coins.IsEqual(emptyCoins) { // todo do we allow empty coins? - return coins, nil - } - if !coins.IsAllPositive() { - return sdk.Coins{}, ErrEmojiCoinsCheck - } - //if err := coins.Validate(); err != nil { - // fmt.Println("validation failed", err) - // return sdk.Coins{}, err - //} - - //not allow the same emoji appear twice ⭐⭐, one should write 2⭐, this is for distinguish accidental input - memo := map[string]bool{} - for _, coin := range coins { - _, found := memo[coin.Denom] - if found { - return sdk.Coins{}, ErrEmojiCoinsCheck - } else { - memo[coin.Denom] = true - } - } - - return coins, nil -} - -func GetCoins(nums, emos []string) (coins sdk.Coins, err error) { - if len(nums) != len(emos) { - return sdk.Coins{}, ErrParseEmojiToCoins - } - coin := sdk.Coin{} - j := 0 - for _, emo := range emos { - emolist, err := ParseEmo(emo, 5) - if err != nil { - return sdk.Coins{}, ErrParseEmojiToCoins - } - - for i := range emolist { - if i == 0 { - n, err := strconv.Atoi(nums[j]) - if err != nil { - return sdk.Coins{}, ErrParseEmojiToCoins - } - coin.Amount = sdk.NewInt(int64(n)) - j++ - } else { - coin.Amount = sdk.NewInt(1) - } - - coin.Denom = emolist[i] - coins = append(coins, coin) - } - } - - return coins, nil -} - -// parse the string, to get list of nums and emojis -func ParseEmojiandNum(str string) (nums []string, emos []string, err error) { - numBuf := strings.Builder{} - emojiBuf := strings.Builder{} - writebuf := true - - for _, r := range []rune(str) { - - ok := unicode.IsDigit(r) - - switch writebuf { - case true: - if ok { - numBuf.WriteRune(r) - } else { - emojiBuf.WriteRune(r) - writebuf = false - } - - case false: - if ok { - num, emo, ok := FlushBuf(&numBuf, &emojiBuf) - if !ok { - return nil, nil, ErrParseEmojiandNum - } - nums = append(nums, num) - emos = append(emos, emo) - numBuf.WriteRune(r) - writebuf = true - } else { - emojiBuf.WriteRune(r) - } - } - } - - num, emo, ok := FlushBuf(&numBuf, &emojiBuf) - if !ok { - return nil, nil, ErrParseEmojiandNum - } - nums = append(nums, num) - emos = append(emos, emo) - - return nums, emos, nil -} - -func FlushBuf(numBuf, emojiBuf *strings.Builder) (num string, emo string, ok bool) { - - if numBuf.String() == "" && emojiBuf.String() == "" { - return "", "", false - } - - if numBuf.String() != "" && emojiBuf.String() == "" { - return "", "", false - } - - if numBuf.String() == "" && emojiBuf.String() != "" { - emo = emojiBuf.String() - num = "1" - numBuf.Reset() - emojiBuf.Reset() - } - - if numBuf.String() != "" && emojiBuf.String() != "" { - num = numBuf.String() - emo = emojiBuf.String() - numBuf.Reset() - emojiBuf.Reset() - } - - return num, emo, true -} - -// parse emojis string which does not contain numbers -func ParseEmo(emo string, emojiMaxLen int) (emolist []string, err error) { - // use rune rather than string to avoid index jumping - r := []rune(emo) - emojimap := utils.ReverseMapKV(utils.EmojiCodeMap) - - i := 0 - for i < len(r) { - maxLen := emojiMaxLen - if i+emojiMaxLen >= len(r) { - maxLen = len(r) - i - } - - hasEmoji := true - - for j := maxLen; j > 0; j-- { - _, found := emojimap[string(r[i:i+j])] - if found { - emolist = append(emolist, string(r[i:i+j])) - i += j - hasEmoji = true - break - } - hasEmoji = false - } - - if hasEmoji == false { - return []string{}, ErrEmojiStr - } - } - - return emolist, nil -} diff --git a/x/escrow/utils/utils_test.go b/x/escrow/utils/utils_test.go deleted file mode 100644 index 772ab9c..0000000 --- a/x/escrow/utils/utils_test.go +++ /dev/null @@ -1,88 +0,0 @@ -package utils - -import ( - sdk "github.com/cosmos/cosmos-sdk/types" - "testing" -) - -func TestParseCoins_Cases_Pass(t *testing.T) { - type ParseCase struct { - EmoStr string - Coins sdk.Coins - } - - samples := []ParseCase{ - { - EmoStr: "1🆗", - Coins: []sdk.Coin{ - {Denom: "🆗", Amount: sdk.NewInt(1)}, - }, - }, - { - EmoStr: "🆗🍍", - Coins: []sdk.Coin{ - {Denom: "🆗", Amount: sdk.NewInt(1)}, - {Denom: "🍍", Amount: sdk.NewInt(1)}, - }, - }, - { - EmoStr: "12🆗🍍", - Coins: []sdk.Coin{ - {Denom: "🆗", Amount: sdk.NewInt(12)}, - {Denom: "🍍", Amount: sdk.NewInt(1)}, - }, - }, - { - EmoStr: "12" + "\U0001f1e6\U0001f1f2", - Coins: []sdk.Coin{ - {Denom: "\U0001f1e6\U0001f1f2", Amount: sdk.NewInt(12)}, - }, - }, - - { - EmoStr: "10\U0001f9d1\u200d\U0001f3a8" + - "40\U0001f632" + "\U0001f1e6\U0001f1fa" + "\U0001f3a8" + "2\U0001f9d6\U0001f3fb\u200d\u2640\ufe0f", - Coins: []sdk.Coin{ - {Denom: "\U0001f9d1\u200d\U0001f3a8", Amount: sdk.NewInt(10)}, - {Denom: "\U0001f632", Amount: sdk.NewInt(40)}, - {Denom: "\U0001f1e6\U0001f1fa", Amount: sdk.NewInt(1)}, - {Denom: "\U0001f3a8", Amount: sdk.NewInt(1)}, - {Denom: "\U0001f9d6\U0001f3fb\u200d\u2640\ufe0f", Amount: sdk.NewInt(2)}, - }, - }, - } - - for i, sample := range samples { - coins, err := GetCoinsWithCheck(sample.EmoStr) - if err != nil { - t.Fatalf("failed case %d", i) - } - - if !coins.IsEqual(sample.Coins) { - t.Fatalf("failed case %d: %s", i, coins.String()) - } - } -} - -func TestParseCoins_Cases_Fail(t *testing.T) { - str := []string{ - "", - "-123🆗", // negative - "0🆗", // zero - "1e10🆗", // scientific notation - "1.2🆗", // decimal - "1,223🆗", // formatted - "1,223", // no emoji - "1🆗🆗", // duplicate emoji - "1🆗2🍍3🆗", // duplicate emoji - // "00002🆗⭐", // leading zero //todo if allow ??? - "01 🆗", //space - } - - for i, s := range str { - _, err := GetCoinsWithCheck(s) - if err == nil { - t.Fatalf("failed case %d", i) - } - } -} From a6546a0403a0bfe810a8a50461210da4469ffdb8 Mon Sep 17 00:00:00 2001 From: yaruwang Date: Fri, 6 Aug 2021 18:21:22 +0200 Subject: [PATCH 16/22] rebased on main --- app/app.go | 43 +++------------------------------ proto/pooltoy/query.proto | 1 - x/faucet/client/cli/tx.go | 3 --- x/faucet/handler_test.go | 1 - x/faucet/keeper/keeper.go | 2 -- x/faucet/keeper/query_server.go | 2 -- 6 files changed, 3 insertions(+), 49 deletions(-) diff --git a/app/app.go b/app/app.go index 5412a98..1e6e653 100644 --- a/app/app.go +++ b/app/app.go @@ -1,16 +1,11 @@ package app import ( - store "github.com/cosmos/cosmos-sdk/store/types" - "github.com/cosmos/cosmos-sdk/x/upgrade" - upgradekeeper "github.com/cosmos/cosmos-sdk/x/upgrade/keeper" - upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types" "github.com/interchainberlin/pooltoy/x/escrow" "io" "os" "path/filepath" "time" - "github.com/cosmos/cosmos-sdk/baseapp" "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/grpc/tmservice" @@ -23,7 +18,6 @@ import ( "github.com/cosmos/cosmos-sdk/simapp" store "github.com/cosmos/cosmos-sdk/store/types" sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/cosmos-sdk/types/module" "github.com/cosmos/cosmos-sdk/version" "github.com/cosmos/cosmos-sdk/x/auth" @@ -100,7 +94,6 @@ import ( upgradeclient "github.com/cosmos/cosmos-sdk/x/upgrade/client" upgradekeeper "github.com/cosmos/cosmos-sdk/x/upgrade/keeper" upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types" - ) const Name = "pooltoy" @@ -111,14 +104,13 @@ func getGovProposalHandlers() []govclient.ProposalHandler { var govProposalHandlers []govclient.ProposalHandler // this line is used by starport scaffolding # stargate/app/govProposalHandlers - govProposalHandlers = append(govProposalHandlers, + govProposalHandlers = append( + govProposalHandlers, paramsclient.ProposalHandler, distrclient.ProposalHandler, upgradeclient.ProposalHandler, upgradeclient.CancelProposalHandler, // this line is used by starport scaffolding # stargate/app/govProposalHandler - upgradeclient.ProposalHandler, - upgradeclient.CancelProposalHandler, ) return govProposalHandlers @@ -145,7 +137,6 @@ var ( crisis.AppModuleBasic{}, slashing.AppModuleBasic{}, ibc.AppModuleBasic{}, - upgrade.AppModuleBasic{}, evidence.AppModuleBasic{}, transfer.AppModuleBasic{}, pooltoy.AppModuleBasic{}, @@ -214,7 +205,6 @@ type App struct { GovKeeper govkeeper.Keeper UpgradeKeeper upgradekeeper.Keeper CrisisKeeper crisiskeeper.Keeper - UpgradeKeeper upgradekeeper.Keeper ParamsKeeper paramskeeper.Keeper IBCKeeper *ibckeeper.Keeper // IBC Keeper must be a pointer in the app, so we can SetRouter on it correctly EvidenceKeeper evidencekeeper.Keeper @@ -257,7 +247,7 @@ func New( keys := sdk.NewKVStoreKeys( authtypes.StoreKey, banktypes.StoreKey, stakingtypes.StoreKey, minttypes.StoreKey, distrtypes.StoreKey, slashingtypes.StoreKey, - govtypes.StoreKey, paramstypes.StoreKey, ibchost.StoreKey, upgradetypes.StoreKey, + govtypes.StoreKey, paramstypes.StoreKey, ibchost.StoreKey, evidencetypes.StoreKey, ibctransfertypes.StoreKey, capabilitytypes.StoreKey, pooltoytypes.StoreKey, faucettypes.StoreKey, @@ -320,9 +310,6 @@ func New( app.CrisisKeeper = crisiskeeper.NewKeeper( app.GetSubspace(crisistypes.ModuleName), invCheckPeriod, app.BankKeeper, authtypes.FeeCollectorName, ) - - app.UpgradeKeeper = upgradekeeper.NewKeeper(skipUpgradeHeights, keys[upgradetypes.StoreKey], appCodec, homePath) - // register the staking hooks // NOTE: stakingKeeper above is passed by reference, so that it will contain these hooks app.StakingKeeper = *stakingKeeper.SetHooks( @@ -342,7 +329,6 @@ func New( AddRoute(paramproposal.RouterKey, params.NewParamChangeProposalHandler(app.ParamsKeeper)). AddRoute(upgradetypes.RouterKey, upgrade.NewSoftwareUpgradeProposalHandler(app.UpgradeKeeper)). AddRoute(distrtypes.RouterKey, distr.NewCommunityPoolSpendProposalHandler(app.DistrKeeper)). - AddRoute(upgradetypes.RouterKey, upgrade.NewSoftwareUpgradeProposalHandler(app.UpgradeKeeper)). AddRoute(ibchost.RouterKey, ibcclient.NewClientUpdateProposalHandler(app.IBCKeeper.ClientKeeper)) app.GovKeeper = govkeeper.NewKeeper( appCodec, keys[govtypes.StoreKey], app.GetSubspace(govtypes.ModuleName), app.AccountKeeper, app.BankKeeper, @@ -541,29 +527,6 @@ func New( ), ) app.SetEndBlocker(app.EndBlocker) - app.UpgradeKeeper.SetUpgradeHandler("pooltoy-upgrade-0", - func(ctx sdk.Context, plan upgradetypes.Plan) { - // a place to run genesis initialization logic for new modules that were just added as part of the upgrade... - - // var genState liquiditytypes.GenesisState - // genState.Params = liquiditytypes.DefaultParams() - // genState.Params.PoolCreationFee = sdk.NewCoins(sdk.NewCoin("uatom", sdk.NewInt(40000000))) - // app.LiquidityKeeper.InitGenesis(ctx, genState) - }) - - upgradeInfo, err := app.UpgradeKeeper.ReadUpgradeInfoFromDisk() - if err != nil { - panic(err) - } - - if upgradeInfo.Name == "pooltoy-upgrade-0" && !app.UpgradeKeeper.IsSkipHeight(upgradeInfo.Height) { - storeUpgrades := store.StoreUpgrades{ - // Added: []string{liquiditytypes.ModuleName}, - } - - // configure store loader that checks if version == upgradeHeight and applies store upgrades - app.SetStoreLoader(upgradetypes.UpgradeStoreLoader(upgradeInfo.Height, &storeUpgrades)) - } if loadLatest { if err := app.LoadLatestVersion(); err != nil { diff --git a/proto/pooltoy/query.proto b/proto/pooltoy/query.proto index 9bfd689..af3606b 100644 --- a/proto/pooltoy/query.proto +++ b/proto/pooltoy/query.proto @@ -14,7 +14,6 @@ service Query { rpc QueryListUsers(QueryListUsersRequest) returns (QueryListUsersResponse) { option (google.api.http).get = "/pooltoy/user"; } - rpc QueryMostEmojiOwner(QueryMostEmojiOwnerRequest) returns (QueryMostEmojiOwnerResponse){} } message QueryListUsersRequest { diff --git a/x/faucet/client/cli/tx.go b/x/faucet/client/cli/tx.go index 469d6ab..8a30cad 100644 --- a/x/faucet/client/cli/tx.go +++ b/x/faucet/client/cli/tx.go @@ -2,8 +2,6 @@ package cli import ( "fmt" - "github.com/interchainberlin/pooltoy/x/faucet/utils" - "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/flags" "github.com/cosmos/cosmos-sdk/client/tx" @@ -75,7 +73,6 @@ func txMintFor() *cobra.Command { return err } msg := types.NewMsgMint(sender, minter, args[1]) - if err = msg.ValidateBasic(); err != nil { return fmt.Errorf("message validation failed: %w", err) } diff --git a/x/faucet/handler_test.go b/x/faucet/handler_test.go index 9e7bb32..9750159 100644 --- a/x/faucet/handler_test.go +++ b/x/faucet/handler_test.go @@ -2,7 +2,6 @@ package faucet import ( "fmt" - "github.com/interchainberlin/pooltoy/x/faucet/utils" "testing" sdk "github.com/cosmos/cosmos-sdk/types" diff --git a/x/faucet/keeper/keeper.go b/x/faucet/keeper/keeper.go index 1635f87..80b5ac4 100644 --- a/x/faucet/keeper/keeper.go +++ b/x/faucet/keeper/keeper.go @@ -2,7 +2,6 @@ package keeper import ( "fmt" - "github.com/interchainberlin/pooltoy/x/faucet/utils" "time" "github.com/cosmos/cosmos-sdk/codec" @@ -57,7 +56,6 @@ func (k Keeper) Logger(ctx sdk.Context) log.Logger { func (k Keeper) MintAndSend(ctx sdk.Context, msg *types.MsgMint) error { // TODO: should most of this logic be in the msg_server? - mintTime := ctx.BlockTime().Unix() if msg.Denom == k.StakingKeeper.BondDenom(ctx) { return types.ErrCantWithdrawStake diff --git a/x/faucet/keeper/query_server.go b/x/faucet/keeper/query_server.go index b7d0ca3..508611c 100644 --- a/x/faucet/keeper/query_server.go +++ b/x/faucet/keeper/query_server.go @@ -11,8 +11,6 @@ import ( "github.com/interchainberlin/pooltoy/x/faucet/types" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" - "sort" - "time" ) var _ types.QueryServer = Keeper{} From 1657012ba5548033e1528ffc25a72f368a6f86fc Mon Sep 17 00:00:00 2001 From: billy rennekamp Date: Mon, 9 Aug 2021 13:52:36 +0200 Subject: [PATCH 17/22] removed address from tx cli and added error to bug --- x/escrow/client/cli/tx.go | 33 +++++++++++++-------------------- x/escrow/keeper/msg_server.go | 27 +++++++++++++++++++++------ 2 files changed, 34 insertions(+), 26 deletions(-) diff --git a/x/escrow/client/cli/tx.go b/x/escrow/client/cli/tx.go index baaed20..c45b764 100644 --- a/x/escrow/client/cli/tx.go +++ b/x/escrow/client/cli/tx.go @@ -2,13 +2,14 @@ package cli import ( "fmt" + "strconv" + "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/flags" "github.com/cosmos/cosmos-sdk/client/tx" - "strconv" //"github.com/cosmos/cosmos-sdk/client/tx" - sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/spf13/cobra" // "github.com/cosmos/cosmos-sdk/client/flags" "github.com/interchainberlin/pooltoy/x/escrow/types" @@ -31,19 +32,15 @@ func GetTxCmd() *cobra.Command { func escrowOffer() *cobra.Command { cmd := &cobra.Command{ - Use: "offer [address] [offer] [request] --from [username]", + Use: "offer [offer] [request] --from [username]", Short: "send coins to escrow", - Args: cobra.ExactArgs(3), + Args: cobra.ExactArgs(2), RunE: func(cmd *cobra.Command, args []string) error { ctx, err := client.GetClientTxContext(cmd) if err != nil { return err } - - addr, err := sdk.AccAddressFromBech32(args[0]) - if err != nil { - return err - } + addr := ctx.FromAddress offerReq := types.NewOfferRequest(addr, args[1], args[2]) @@ -56,7 +53,7 @@ func escrowOffer() *cobra.Command { func escrowResponse() *cobra.Command { cmd := &cobra.Command{ - Use: "response [address] [id] --from [username]", + Use: "response [id] --from [username]", Short: "response to an offer at escrow", Args: cobra.ExactArgs(2), RunE: func(cmd *cobra.Command, args []string) error { @@ -64,11 +61,8 @@ func escrowResponse() *cobra.Command { if err != nil { return err } + addr := ctx.FromAddress - addr, err := sdk.AccAddressFromBech32(args[0]) - if err != nil { - return err - } i, err := strconv.ParseInt(args[1], 10, 64) if err != nil { return err @@ -85,18 +79,17 @@ func escrowResponse() *cobra.Command { func escrowCancelOffer() *cobra.Command { cmd := &cobra.Command{ - Use: "cancel [address] [id] --from [username]", + Use: "cancel [id] --from [username]", Short: "cancel an offer", - Args: cobra.ExactArgs(2), + Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { ctx, err := client.GetClientTxContext(cmd) if err != nil { return err } - addr, err := sdk.AccAddressFromBech32(args[0]) - if err != nil { - return err - } + + addr := ctx.FromAddress + i, err := strconv.ParseInt(args[1], 10, 64) if err != nil { return err diff --git a/x/escrow/keeper/msg_server.go b/x/escrow/keeper/msg_server.go index 8c6f9a7..df69b81 100644 --- a/x/escrow/keeper/msg_server.go +++ b/x/escrow/keeper/msg_server.go @@ -3,6 +3,7 @@ package keeper import ( "context" "fmt" + sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" "github.com/interchainberlin/pooltoy/x/escrow/types" @@ -65,7 +66,7 @@ func (k Keeper) Response(c context.Context, msg *types.ResponseRequest) (*types. return nil, err } - escrowAcc :=k.AccountKeeper.GetModuleAccount(ctx, types.ModuleName) + escrowAcc := k.AccountKeeper.GetModuleAccount(ctx, types.ModuleName) err = k.BankKeeper.SendCoins(ctx, escrowAcc.GetAddress(), responser, offer.Amount) if err != nil { return nil, err @@ -81,31 +82,45 @@ func (k Keeper) Response(c context.Context, msg *types.ResponseRequest) (*types. return &types.ResponseResult{}, nil } - func (k Keeper) CancelOffer(c context.Context, msg *types.CancelOfferRequest) (*types.CancelOfferResponse, error) { ctx := sdk.UnwrapSDKContext(c) offer, err := k.QueryOfferByID(c, &types.QueryOfferByIDRequest{msg.Id}) + fmt.Println("offer", offer) if err != nil { return nil, err } - if offer.Sender != msg.Sender{ - return nil, sdkerrors.Wrap(err, fmt.Sprintf("unauthorized to cancel this offer")) - } offerer, err := sdk.AccAddressFromBech32(offer.Sender) + fmt.Println("offerer", offerer) + if err != nil { + return nil, err + } + + sender, err := sdk.AccAddressFromBech32(msg.Sender) + fmt.Println("sender", sender) if err != nil { return nil, err } - escrowAcc :=k.AccountKeeper.GetModuleAccount(ctx, types.ModuleName) + + if !offerer.Equals(sender) { + fmt.Println("offer.Sender != msg.Sender") + return nil, sdkerrors.Wrap(XXXXX, fmt.Sprintf("unauthorized to cancel this offer")) + } + fmt.Println("offer.Sender == msg.Sender") + + escrowAcc := k.AccountKeeper.GetModuleAccount(ctx, types.ModuleName) + fmt.Println("escrowAcc", escrowAcc) err = k.BankKeeper.SendCoins(ctx, escrowAcc.GetAddress(), offerer, offer.Amount) if err != nil { return nil, err } + fmt.Println("send coins successful") err = k.DeleteOffer(ctx, msg.Id) if err != nil { return nil, err } + fmt.Println("delete offer successful") return &types.CancelOfferResponse{}, nil } From b19288d5c9e44380733d1f87317878d5f84ea5fd Mon Sep 17 00:00:00 2001 From: yaruwang Date: Thu, 12 Aug 2021 12:21:32 +0200 Subject: [PATCH 18/22] add escrow module in genesis --- app/app.go | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/app/app.go b/app/app.go index 1e6e653..ca4d771 100644 --- a/app/app.go +++ b/app/app.go @@ -1,11 +1,6 @@ package app import ( - "github.com/interchainberlin/pooltoy/x/escrow" - "io" - "os" - "path/filepath" - "time" "github.com/cosmos/cosmos-sdk/baseapp" "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/grpc/tmservice" @@ -73,11 +68,16 @@ import ( stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" appparams "github.com/interchainberlin/pooltoy/app/params" "github.com/interchainberlin/pooltoy/regex" + "github.com/interchainberlin/pooltoy/x/escrow" escrowkeeper "github.com/interchainberlin/pooltoy/x/escrow/keeper" escrowtypes "github.com/interchainberlin/pooltoy/x/escrow/types" "github.com/interchainberlin/pooltoy/x/faucet" faucetkeeper "github.com/interchainberlin/pooltoy/x/faucet/keeper" faucettypes "github.com/interchainberlin/pooltoy/x/faucet/types" + "io" + "os" + "path/filepath" + "time" "github.com/interchainberlin/pooltoy/x/pooltoy" pooltoykeeper "github.com/interchainberlin/pooltoy/x/pooltoy/keeper" @@ -460,7 +460,7 @@ func New( if upgradeInfo.Name == "pooltoy-upgrade-0" && !app.UpgradeKeeper.IsSkipHeight(upgradeInfo.Height) { storeUpgrades := store.StoreUpgrades{ - // Added: []string{liquiditytypes.ModuleName}, + Added: []string{escrowtypes.ModuleName}, } // configure store loader that checks if version == upgradeHeight and applies store upgrades From 9459ffb595c5f15f18ccdd673d3eecdf2b4b50f2 Mon Sep 17 00:00:00 2001 From: yaruwang Date: Thu, 12 Aug 2021 14:53:54 +0200 Subject: [PATCH 19/22] change chain id to 6 --- scripts/init.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/scripts/init.sh b/scripts/init.sh index 2792088..fef68c4 100755 --- a/scripts/init.sh +++ b/scripts/init.sh @@ -3,17 +3,17 @@ rm -rf ~/.pooltoy pooltoy config keyring-backend test -pooltoy config chain-id pooltoy-5 +pooltoy config chain-id pooltoy-6 pooltoy config -pooltoy init mynode --chain-id pooltoy-5 +pooltoy init mynode --chain-id pooltoy-6 jq -c '.balances[]' accounts.json | while read i; do echo "y" | pooltoy keys add $(echo "$i" | jq -r ".name") --keyring-backend test pooltoy add-genesis-account $(pooltoy keys show $(echo "$i" | jq -r ".name") --address) $(echo $i | jq -r '.coins | map(.amount+.denom) | join(",")') --keyring-backend test done -pooltoy gentx alice 100000000stake --keyring-backend test --chain-id pooltoy-5 +pooltoy gentx alice 100000000stake --keyring-backend test --chain-id pooltoy-6 pooltoy collect-gentxs pooltoy validate-genesis # test to make sure the genesis file is correctly formatted From 8989d4d7576985ef3202c28497171cf1eb4e25a6 Mon Sep 17 00:00:00 2001 From: yaruwang Date: Thu, 12 Aug 2021 15:29:06 +0200 Subject: [PATCH 20/22] debug cancel offer --- x/escrow/keeper/msg_server.go | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/x/escrow/keeper/msg_server.go b/x/escrow/keeper/msg_server.go index 8c6f9a7..ca2bb49 100644 --- a/x/escrow/keeper/msg_server.go +++ b/x/escrow/keeper/msg_server.go @@ -88,14 +88,20 @@ func (k Keeper) CancelOffer(c context.Context, msg *types.CancelOfferRequest) (* if err != nil { return nil, err } - if offer.Sender != msg.Sender{ - return nil, sdkerrors.Wrap(err, fmt.Sprintf("unauthorized to cancel this offer")) + offerer, err := sdk.AccAddressFromBech32(offer.Sender) + if err != nil { + return nil, err } - offerer, err := sdk.AccAddressFromBech32(offer.Sender) + sender, err := sdk.AccAddressFromBech32(msg.Sender) if err != nil { return nil, err } + + if !offerer.Equals(sender) { + return nil, sdkerrors.ErrUnauthorized + } + escrowAcc :=k.AccountKeeper.GetModuleAccount(ctx, types.ModuleName) err = k.BankKeeper.SendCoins(ctx, escrowAcc.GetAddress(), offerer, offer.Amount) if err != nil { From 4c0eff29bef249d14bfe62257fc00e02daf6dd73 Mon Sep 17 00:00:00 2001 From: yaruwang Date: Thu, 12 Aug 2021 16:19:19 +0200 Subject: [PATCH 21/22] refactor the escrow offer --- x/escrow/client/cli/tx.go | 8 +++----- x/escrow/keeper/msg_server.go | 21 +++++---------------- 2 files changed, 8 insertions(+), 21 deletions(-) diff --git a/x/escrow/client/cli/tx.go b/x/escrow/client/cli/tx.go index c45b764..59a320e 100644 --- a/x/escrow/client/cli/tx.go +++ b/x/escrow/client/cli/tx.go @@ -42,7 +42,7 @@ func escrowOffer() *cobra.Command { } addr := ctx.FromAddress - offerReq := types.NewOfferRequest(addr, args[1], args[2]) + offerReq := types.NewOfferRequest(addr, args[0], args[1]) return tx.GenerateOrBroadcastTxCLI(ctx, cmd.Flags(), offerReq) }, @@ -88,13 +88,11 @@ func escrowCancelOffer() *cobra.Command { return err } - addr := ctx.FromAddress - - i, err := strconv.ParseInt(args[1], 10, 64) + i, err := strconv.ParseInt(args[0], 10, 64) if err != nil { return err } - cancelReq := types.NewCancelOfferRequest(addr, i) + cancelReq := types.NewCancelOfferRequest(ctx.FromAddress, i) return tx.GenerateOrBroadcastTxCLI(ctx, cmd.Flags(), cancelReq) }, diff --git a/x/escrow/keeper/msg_server.go b/x/escrow/keeper/msg_server.go index ca2bb49..82d6034 100644 --- a/x/escrow/keeper/msg_server.go +++ b/x/escrow/keeper/msg_server.go @@ -2,7 +2,6 @@ package keeper import ( "context" - "fmt" sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" "github.com/interchainberlin/pooltoy/x/escrow/types" @@ -20,23 +19,8 @@ func NewMsgServerImpl(keeper Keeper) types.MsgServer { var _ types.MsgServer = Keeper{} -// todo: merge OfferSend and Offer into 1 func (k Keeper) Offer(c context.Context, msg *types.OfferRequest) (*types.OfferResponse, error) { ctx := sdk.UnwrapSDKContext(c) - res, err := k.OfferSend(ctx, msg) - if err != nil { - return nil, sdkerrors.Wrap(err, fmt.Sprintf("unable to offer")) - } - - _, err = k.InsertOffer(ctx, *msg) - if err != nil { - return nil, err - } - - return res, nil -} - -func (k Keeper) OfferSend(ctx sdk.Context, msg *types.OfferRequest) (*types.OfferResponse, error) { addr, err := sdk.AccAddressFromBech32(msg.Sender) if err != nil { return &types.OfferResponse{}, err @@ -47,6 +31,11 @@ func (k Keeper) OfferSend(ctx sdk.Context, msg *types.OfferRequest) (*types.Offe return &types.OfferResponse{}, err } + _, err = k.InsertOffer(ctx, *msg) + if err != nil { + return nil, err + } + return &types.OfferResponse{Sender: msg.Sender, Index: k.GetLatestID(ctx)}, nil } From f2fe0298f5ff684e0c995215347a52e578d5bc3f Mon Sep 17 00:00:00 2001 From: yaruwangway <69694322+yaruwangway@users.noreply.github.com> Date: Tue, 2 Aug 2022 17:07:10 +0200 Subject: [PATCH 22/22] Update msg_server.go --- x/escrow/keeper/msg_server.go | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/x/escrow/keeper/msg_server.go b/x/escrow/keeper/msg_server.go index 82d6034..3577245 100644 --- a/x/escrow/keeper/msg_server.go +++ b/x/escrow/keeper/msg_server.go @@ -61,7 +61,10 @@ func (k Keeper) Response(c context.Context, msg *types.ResponseRequest) (*types. } err = k.BankKeeper.SendCoins(ctx, responser, offerer, offer.Request) - + if err != nil { + return nil, err + } + err = k.DeleteOffer(ctx, msg.Id) if err != nil { return nil, err