From b7c439a7daab63c110fdd797e1363c64c9696fff Mon Sep 17 00:00:00 2001 From: Assaf Morami Date: Thu, 14 Jul 2022 16:14:09 +0300 Subject: [PATCH 01/93] WIP: Start to implement IBC receive hooks Here specifically is ibc-open-channel --- go-cosmwasm/types/types.go | 6 + x/compute/internal/keeper/keeper.go | 14 +- x/compute/internal/keeper/relay.go | 241 ++++++++++++++++++++++++++++ x/compute/internal/types/errors.go | 3 - 4 files changed, 255 insertions(+), 9 deletions(-) create mode 100644 x/compute/internal/keeper/relay.go diff --git a/go-cosmwasm/types/types.go b/go-cosmwasm/types/types.go index 9c8713186..83d166bb4 100644 --- a/go-cosmwasm/types/types.go +++ b/go-cosmwasm/types/types.go @@ -72,6 +72,12 @@ type HandleType int const ( HandleTypeExecute HandleType = iota HandleTypeReply + HandleTypeIbcChannelOpen + HandleTypeIbcChannelConnect + HandleTypeIbcChannelClose + HandleTypeIbcPacketReceive + HandleTypeIbcPacketAck + HandleTypeIbcPacketTimeout ) type CosmosMsgVersion int diff --git a/x/compute/internal/keeper/keeper.go b/x/compute/internal/keeper/keeper.go index 72dc060d2..6215d155a 100644 --- a/x/compute/internal/keeper/keeper.go +++ b/x/compute/internal/keeper/keeper.go @@ -440,6 +440,7 @@ func (k Keeper) Instantiate(ctx sdk.Context, codeID uint64, creator sdk.AccAddre gas := gasForContract(ctx) response, key, gasUsed, err := k.wasmer.Instantiate(codeInfo.CodeHash, env, initMsg, prefixStore, cosmwasmAPI, querier, ctx.GasMeter(), gas, verificationInfo, contractAddress) consumeGas(ctx, gasUsed) + if err != nil { switch res := response.(type) { case v1wasmTypes.DataWithInternalReplyInfo: @@ -659,7 +660,7 @@ func (k Keeper) querySmartImpl(ctx sdk.Context, contractAddr sdk.AccAddress, req params := types.NewEnv( ctx, sdk.AccAddress{}, /* empty because it's unused in queries */ - []sdk.Coin{}, /* empty because it's unused in queries */ + sdk.NewCoins(), /* empty because it's unused in queries */ contractAddr, contractKey, ) @@ -1082,15 +1083,16 @@ func (k Keeper) reply(ctx sdk.Context, contractAddress sdk.AccAddress, reply v1w } response, gasUsed, execErr := k.wasmer.Execute(codeInfo.CodeHash, env, marshaledReply, prefixStore, cosmwasmAPI, querier, ctx.GasMeter(), gas, ogSigInfo, wasmTypes.HandleTypeReply) + consumeGas(ctx, gasUsed) + if execErr != nil { - return nil, sdkerrors.Wrap(types.ErrReplyFailed, execErr.Error()) + return nil, sdkerrors.Wrap(types.ErrExecuteFailed, execErr.Error()) } switch res := response.(type) { case *v010wasmTypes.HandleResponse: - return nil, sdkerrors.Wrap(types.ErrReplyFailed, fmt.Sprintf("response of reply should always be a CosmWasm v1 response type: %+v", res)) + return nil, sdkerrors.Wrap(types.ErrExecuteFailed, fmt.Sprintf("response of reply should always be a CosmWasm v1 response type: %+v", res)) case *v1wasmTypes.Response: - consumeGas(ctx, gasUsed) ctx.EventManager().EmitEvent(sdk.NewEvent( types.EventTypeReply, @@ -1099,11 +1101,11 @@ func (k Keeper) reply(ctx sdk.Context, contractAddress sdk.AccAddress, reply v1w data, err := k.handleContractResponse(ctx, contractAddress, contractInfo.IBCPortID, res.Messages, res.Attributes, res.Events, res.Data, ogTx, ogSigInfo, wasmTypes.CosmosMsgVersionV1) if err != nil { - return nil, sdkerrors.Wrap(types.ErrReplyFailed, err.Error()) + return nil, sdkerrors.Wrap(types.ErrExecuteFailed, err.Error()) } return data, nil default: - return nil, sdkerrors.Wrap(types.ErrReplyFailed, fmt.Sprintf("cannot detect response type: %+v", res)) + return nil, sdkerrors.Wrap(types.ErrExecuteFailed, fmt.Sprintf("cannot detect response type: %+v", res)) } } diff --git a/x/compute/internal/keeper/relay.go b/x/compute/internal/keeper/relay.go new file mode 100644 index 000000000..587f5a14b --- /dev/null +++ b/x/compute/internal/keeper/relay.go @@ -0,0 +1,241 @@ +package keeper + +import ( + "encoding/json" + "time" + + "github.com/cosmos/cosmos-sdk/telemetry" + sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + sdktxsigning "github.com/cosmos/cosmos-sdk/types/tx/signing" + wasmTypes "github.com/enigmampc/SecretNetwork/go-cosmwasm/types" + v1types "github.com/enigmampc/SecretNetwork/go-cosmwasm/types/v1" + + "github.com/enigmampc/SecretNetwork/x/compute/internal/types" +) + +var _ types.IBCContractKeeper = (*Keeper)(nil) + +// OnOpenChannel calls the contract to participate in the IBC channel handshake step. +// In the IBC protocol this is either the `Channel Open Init` event on the initiating chain or +// `Channel Open Try` on the counterparty chain. +// Protocol version and channel ordering should be verified for example. +// See https://github.com/cosmos/ics/tree/master/spec/ics-004-channel-and-packet-semantics#channel-lifecycle-management +func (k Keeper) OnOpenChannel( + ctx sdk.Context, + contractAddress sdk.AccAddress, + msg v1types.IBCChannelOpenMsg, +) (string, error) { + defer telemetry.MeasureSince(time.Now(), "compute", "keeper", "ibc-open-channel") + version := "" + + ctx.GasMeter().ConsumeGas(types.InstanceCost, "Loading Compute module: ibc-open-channel") + + verificationInfo := types.NewVerificationInfo([]byte{}, sdktxsigning.SignMode_SIGN_MODE_UNSPECIFIED, []byte{}, []byte{}, []byte{}, nil) + + _, codeInfo, prefixStore, err := k.contractInstance(ctx, contractAddress) + if err != nil { + return "", err + } + + store := ctx.KVStore(k.storeKey) + + contractKey := store.Get(types.GetContractEnclaveKey(contractAddress)) + env := types.NewEnv( + ctx, + sdk.AccAddress{}, /* empty because it's unused in queries */ + sdk.NewCoins(), /* empty because it's unused in queries */ + contractAddress, + contractKey, + ) + + // prepare querier + querier := QueryHandler{ + Ctx: ctx, + Plugins: k.queryPlugins, + } + + msgBz, err := json.Marshal(msg) + if err != nil { + return "", sdkerrors.Wrap(err, "ibc-open-channel") + } + + gas := gasForContract(ctx) + res, gasUsed, err := k.wasmer.Execute(codeInfo.CodeHash, env, msgBz, prefixStore, cosmwasmAPI, querier, ctx.GasMeter(), gas, verificationInfo, wasmTypes.HandleTypeReply) + consumeGas(ctx, gasUsed) + + if err != nil { + return "", sdkerrors.Wrap(types.ErrExecuteFailed, err.Error()) + } + + ///////// + res, gasUsed, execErr := k.wasmVM.IBCChannelOpen(codeInfo.CodeHash, env, msg, prefixStore, cosmwasmAPI, querier, ctx.GasMeter(), gas, costJSONDeserialization) + + if execErr != nil { + return "", sdkerrors.Wrap(types.ErrExecuteFailed, execErr.Error()) + } + + if res != nil { + version = res.Version + } + + return version, nil +} + +// OnConnectChannel calls the contract to let it know the IBC channel was established. +// In the IBC protocol this is either the `Channel Open Ack` event on the initiating chain or +// `Channel Open Confirm` on the counterparty chain. +// +// There is an open issue with the [cosmos-sdk](https://github.com/cosmos/cosmos-sdk/issues/8334) +// that the counterparty channelID is empty on the initiating chain +// See https://github.com/cosmos/ics/tree/master/spec/ics-004-channel-and-packet-semantics#channel-lifecycle-management +func (k Keeper) OnConnectChannel( + ctx sdk.Context, + contractAddr sdk.AccAddress, + msg v1types.IBCChannelConnectMsg, +) error { + defer telemetry.MeasureSince(time.Now(), "compute", "keeper", "ibc-connect-channel") + contractInfo, codeInfo, prefixStore, err := k.contractInstance(ctx, contractAddr) + if err != nil { + return err + } + + env := types.NewEnv(ctx, contractAddr) + querier := k.newQueryHandler(ctx, contractAddr) + + gas := k.runtimeGasForContract(ctx) + res, gasUsed, execErr := k.wasmVM.IBCChannelConnect(codeInfo.CodeHash, env, msg, prefixStore, cosmwasmAPI, querier, ctx.GasMeter(), gas, costJSONDeserialization) + k.consumeRuntimeGas(ctx, gasUsed) + if execErr != nil { + return sdkerrors.Wrap(types.ErrExecuteFailed, execErr.Error()) + } + + return k.handleIBCBasicContractResponse(ctx, contractAddr, contractInfo.IBCPortID, res) +} + +// OnCloseChannel calls the contract to let it know the IBC channel is closed. +// Calling modules MAY atomically execute appropriate application logic in conjunction with calling chanCloseConfirm. +// +// Once closed, channels cannot be reopened and identifiers cannot be reused. Identifier reuse is prevented because +// we want to prevent potential replay of previously sent packets +// See https://github.com/cosmos/ics/tree/master/spec/ics-004-channel-and-packet-semantics#channel-lifecycle-management +func (k Keeper) OnCloseChannel( + ctx sdk.Context, + contractAddr sdk.AccAddress, + msg v1types.IBCChannelCloseMsg, +) error { + defer telemetry.MeasureSince(time.Now(), "compute", "keeper", "ibc-close-channel") + + contractInfo, codeInfo, prefixStore, err := k.contractInstance(ctx, contractAddr) + if err != nil { + return err + } + + params := types.NewEnv(ctx, contractAddr) + querier := k.newQueryHandler(ctx, contractAddr) + + gas := k.runtimeGasForContract(ctx) + res, gasUsed, execErr := k.wasmVM.IBCChannelClose(codeInfo.CodeHash, params, msg, prefixStore, cosmwasmAPI, querier, ctx.GasMeter(), gas, costJSONDeserialization) + k.consumeRuntimeGas(ctx, gasUsed) + if execErr != nil { + return sdkerrors.Wrap(types.ErrExecuteFailed, execErr.Error()) + } + + return k.handleIBCBasicContractResponse(ctx, contractAddr, contractInfo.IBCPortID, res) +} + +// OnRecvPacket calls the contract to process the incoming IBC packet. The contract fully owns the data processing and +// returns the acknowledgement data for the chain level. This allows custom applications and protocols on top +// of IBC. Although it is recommended to use the standard acknowledgement envelope defined in +// https://github.com/cosmos/ics/tree/master/spec/ics-004-channel-and-packet-semantics#acknowledgement-envelope +// +// For more information see: https://github.com/cosmos/ics/tree/master/spec/ics-004-channel-and-packet-semantics#packet-flow--handling +func (k Keeper) OnRecvPacket( + ctx sdk.Context, + contractAddr sdk.AccAddress, + msg v1types.IBCPacketReceiveMsg, +) ([]byte, error) { + defer telemetry.MeasureSince(time.Now(), "compute", "keeper", "ibc-recv-packet") + contractInfo, codeInfo, prefixStore, err := k.contractInstance(ctx, contractAddr) + if err != nil { + return nil, err + } + + env := types.NewEnv(ctx, contractAddr) + querier := k.newQueryHandler(ctx, contractAddr) + + gas := k.runtimeGasForContract(ctx) + res, gasUsed, execErr := k.wasmVM.IBCPacketReceive(codeInfo.CodeHash, env, msg, prefixStore, cosmwasmAPI, querier, ctx.GasMeter(), gas, costJSONDeserialization) + k.consumeRuntimeGas(ctx, gasUsed) + if execErr != nil { + return nil, sdkerrors.Wrap(types.ErrExecuteFailed, execErr.Error()) + } + if res.Err != "" { // handle error case as before https://github.com/CosmWasm/wasmvm/commit/c300106fe5c9426a495f8e10821e00a9330c56c6 + return nil, sdkerrors.Wrap(types.ErrExecuteFailed, res.Err) + } + // note submessage reply results can overwrite the `Acknowledgement` data + return k.handleContractResponse(ctx, contractAddr, contractInfo.IBCPortID, res.Ok.Messages, res.Ok.Attributes, res.Ok.Acknowledgement, res.Ok.Events) +} + +// OnAckPacket calls the contract to handle the "acknowledgement" data which can contain success or failure of a packet +// acknowledgement written on the receiving chain for example. This is application level data and fully owned by the +// contract. The use of the standard acknowledgement envelope is recommended: https://github.com/cosmos/ics/tree/master/spec/ics-004-channel-and-packet-semantics#acknowledgement-envelope +// +// On application errors the contract can revert an operation like returning tokens as in ibc-transfer. +// +// For more information see: https://github.com/cosmos/ics/tree/master/spec/ics-004-channel-and-packet-semantics#packet-flow--handling +func (k Keeper) OnAckPacket( + ctx sdk.Context, + contractAddr sdk.AccAddress, + msg v1types.IBCPacketAckMsg, +) error { + defer telemetry.MeasureSince(time.Now(), "compute", "keeper", "ibc-ack-packet") + contractInfo, codeInfo, prefixStore, err := k.contractInstance(ctx, contractAddr) + if err != nil { + return err + } + + env := types.NewEnv(ctx, contractAddr) + querier := k.newQueryHandler(ctx, contractAddr) + + gas := k.runtimeGasForContract(ctx) + res, gasUsed, execErr := k.wasmVM.IBCPacketAck(codeInfo.CodeHash, env, msg, prefixStore, cosmwasmAPI, querier, ctx.GasMeter(), gas, costJSONDeserialization) + k.consumeRuntimeGas(ctx, gasUsed) + if execErr != nil { + return sdkerrors.Wrap(types.ErrExecuteFailed, execErr.Error()) + } + return k.handleIBCBasicContractResponse(ctx, contractAddr, contractInfo.IBCPortID, res) +} + +// OnTimeoutPacket calls the contract to let it know the packet was never received on the destination chain within +// the timeout boundaries. +// The contract should handle this on the application level and undo the original operation +func (k Keeper) OnTimeoutPacket( + ctx sdk.Context, + contractAddr sdk.AccAddress, + msg v1types.IBCPacketTimeoutMsg, +) error { + defer telemetry.MeasureSince(time.Now(), "compute", "keeper", "ibc-timeout-packet") + + contractInfo, codeInfo, prefixStore, err := k.contractInstance(ctx, contractAddr) + if err != nil { + return err + } + + env := types.NewEnv(ctx, contractAddr) + querier := k.newQueryHandler(ctx, contractAddr) + + gas := k.runtimeGasForContract(ctx) + res, gasUsed, execErr := k.wasmVM.IBCPacketTimeout(codeInfo.CodeHash, env, msg, prefixStore, cosmwasmAPI, querier, ctx.GasMeter(), gas, costJSONDeserialization) + k.consumeRuntimeGas(ctx, gasUsed) + if execErr != nil { + return sdkerrors.Wrap(types.ErrExecuteFailed, execErr.Error()) + } + + return k.handleIBCBasicContractResponse(ctx, contractAddr, contractInfo.IBCPortID, res) +} + +func (k Keeper) handleIBCBasicContractResponse(ctx sdk.Context, addr sdk.AccAddress, id string, res *v1types.IBCBasicResponse) error { + _, err := k.handleContractResponse(ctx, addr, id, res.Messages, res.Attributes, nil, res.Events) + return err +} diff --git a/x/compute/internal/types/errors.go b/x/compute/internal/types/errors.go index 7c7dfff50..1cd214613 100644 --- a/x/compute/internal/types/errors.go +++ b/x/compute/internal/types/errors.go @@ -64,9 +64,6 @@ var ( // ErrUnknownMsg error by a message handler to show that it is not responsible for this message type ErrUnknownMsg = sdkErrors.Register(DefaultCodespace, 18, "unknown message from the contract") - // ErrReplyFailed error for rust execution contract failure - ErrReplyFailed = sdkErrors.Register(DefaultCodespace, 19, "reply to contract failed") - // ErrInvalidEvent error if an attribute/event from the contract is invalid ErrInvalidEvent = sdkErrors.Register(DefaultCodespace, 21, "invalid event") ) From f769b836cfaa161b1ccee21d1532b2d30ed71782 Mon Sep 17 00:00:00 2001 From: Assaf Morami Date: Tue, 19 Jul 2022 15:17:59 +0300 Subject: [PATCH 02/93] CosmWasm v1 IBC OnOpenChannel --- go-cosmwasm/lib.go | 58 +++++++++++--------- go-cosmwasm/types/v1/ibc.go | 30 ++++++---- x/compute/internal/keeper/relay.go | 22 ++++---- x/compute/internal/types/exported_keepers.go | 46 ++++++++++++++++ 4 files changed, 107 insertions(+), 49 deletions(-) create mode 100644 x/compute/internal/types/exported_keepers.go diff --git a/go-cosmwasm/lib.go b/go-cosmwasm/lib.go index a14ae2d61..523e6fdaa 100644 --- a/go-cosmwasm/lib.go +++ b/go-cosmwasm/lib.go @@ -85,11 +85,17 @@ func (w *Wasmer) GetCode(code CodeID) (WasmCode, error) { } // This struct helps us to distinguish between v0.10 contract response and v1 contract response -type V010orV1ContractExecResponse struct { - V1 *V1ContractExecResponse `json:"v1,omitempty"` - V010 *V010ContractExecResponse `json:"v010,omitempty"` - InternaReplyEnclaveSig []byte `json:"internal_reply_enclave_sig"` - InternalMsgId []byte `json:"internal_msg_id"` +type ContractExecResponse struct { + V1 *V1ContractExecResponse `json:"v1,omitempty"` + V010 *V010ContractExecResponse `json:"v010,omitempty"` + InternaReplyEnclaveSig []byte `json:"internal_reply_enclave_sig"` + InternalMsgId []byte `json:"internal_msg_id"` + IBCChannelOpen *v1types.IBCChannelOpenResult `json:"ibc_channel_open,omitempty"` + IBCChannelConnect *v1types.IBCBasicResponse `json:"ibc_channel_connect,omitempty"` + IBCChannelClose *v1types.IBCBasicResponse `json:"ibc_channel_close,omitempty"` + IBCPacketReceive *v1types.IBCReceiveResult `json:"ibc_packet_receive,omitempty"` + IBCPacketAck *v1types.IBCBasicResponse `json:"ibc_packet_ack,omitempty"` + IBCPacketTimeout *v1types.IBCBasicResponse `json:"ibc_packet_timeout,omitempty"` } type V010ContractExecResponse struct { @@ -260,55 +266,55 @@ func (w *Wasmer) Execute( return nil, gasUsed, err } - var respV010orV1 V010orV1ContractExecResponse - err = json.Unmarshal(data, &respV010orV1) + var resp ContractExecResponse + err = json.Unmarshal(data, &resp) if err != nil { // unidentified response 🤷 return nil, gasUsed, fmt.Errorf("handle: cannot parse response from json: %w", err) } - isOutputAddressedToReply := (len(respV010orV1.InternaReplyEnclaveSig) > 0 && len(respV010orV1.InternalMsgId) > 0) + isOutputAddressedToReply := (len(resp.InternaReplyEnclaveSig) > 0 && len(resp.InternalMsgId) > 0) // handle v0.10 response - if respV010orV1.V010 != nil { - if respV010orV1.V010.Err != nil { + if resp.V010 != nil { + if resp.V010.Err != nil { return v1types.DataWithInternalReplyInfo{ - InternalMsgId: respV010orV1.InternalMsgId, - InternaReplyEnclaveSig: respV010orV1.InternaReplyEnclaveSig, - Data: []byte(respV010orV1.V010.Err.GenericErr.Msg), - }, gasUsed, fmt.Errorf("%+v", respV010orV1.V010.Err) + InternalMsgId: resp.InternalMsgId, + InternaReplyEnclaveSig: resp.InternaReplyEnclaveSig, + Data: []byte(resp.V010.Err.GenericErr.Msg), + }, gasUsed, fmt.Errorf("%+v", resp.V010.Err) } - if respV010orV1.V010.Ok != nil { + if resp.V010.Ok != nil { if isOutputAddressedToReply { - respV010orV1.V010.Ok.Data, err = AppendReplyInternalDataToData(respV010orV1.V010.Ok.Data, respV010orV1.InternaReplyEnclaveSig, respV010orV1.InternalMsgId) + resp.V010.Ok.Data, err = AppendReplyInternalDataToData(resp.V010.Ok.Data, resp.InternaReplyEnclaveSig, resp.InternalMsgId) if err != nil { return nil, gasUsed, fmt.Errorf("cannot serialize v010 DataWithInternalReplyInfo into binary : %w", err) } } - return respV010orV1.V010.Ok, gasUsed, nil + return resp.V010.Ok, gasUsed, nil } } // handle v1 response - if respV010orV1.V1 != nil { - if respV010orV1.V1.Err != nil { + if resp.V1 != nil { + if resp.V1.Err != nil { return v1types.DataWithInternalReplyInfo{ - InternalMsgId: respV010orV1.InternalMsgId, - InternaReplyEnclaveSig: respV010orV1.InternaReplyEnclaveSig, - Data: []byte(respV010orV1.V1.Err.GenericErr.Msg), - }, gasUsed, fmt.Errorf("%+v", respV010orV1.V1.Err) + InternalMsgId: resp.InternalMsgId, + InternaReplyEnclaveSig: resp.InternaReplyEnclaveSig, + Data: []byte(resp.V1.Err.GenericErr.Msg), + }, gasUsed, fmt.Errorf("%+v", resp.V1.Err) } - if respV010orV1.V1.Ok != nil { + if resp.V1.Ok != nil { if isOutputAddressedToReply { - respV010orV1.V1.Ok.Data, err = AppendReplyInternalDataToData(respV010orV1.V1.Ok.Data, respV010orV1.InternaReplyEnclaveSig, respV010orV1.InternalMsgId) + resp.V1.Ok.Data, err = AppendReplyInternalDataToData(resp.V1.Ok.Data, resp.InternaReplyEnclaveSig, resp.InternalMsgId) if err != nil { return nil, gasUsed, fmt.Errorf("cannot serialize v1 DataWithInternalReplyInfo into binary : %w", err) } } - return respV010orV1.V1.Ok, gasUsed, nil + return resp.V1.Ok, gasUsed, nil } } diff --git a/go-cosmwasm/types/v1/ibc.go b/go-cosmwasm/types/v1/ibc.go index 87b60a361..1d5d994fb 100644 --- a/go-cosmwasm/types/v1/ibc.go +++ b/go-cosmwasm/types/v1/ibc.go @@ -1,8 +1,6 @@ package v1types -import ( - abci "github.com/tendermint/tendermint/abci/types" -) +import v010msgtypes "github.com/enigmampc/SecretNetwork/go-cosmwasm/types/v010" type IBCEndpoint struct { PortID string `json:"port_id"` @@ -137,16 +135,19 @@ func (m *IBCCloseConfirm) ToMsg() IBCChannelCloseMsg { } type IBCPacketReceiveMsg struct { - Packet IBCPacket `json:"packet"` + Packet IBCPacket `json:"packet"` + Relayer string `json:"relayer"` } type IBCPacketAckMsg struct { Acknowledgement IBCAcknowledgement `json:"acknowledgement"` OriginalPacket IBCPacket `json:"original_packet"` + Relayer string `json:"relayer"` } type IBCPacketTimeoutMsg struct { - Packet IBCPacket `json:"packet"` + Packet IBCPacket `json:"packet"` + Relayer string `json:"relayer"` } // TODO: test what the sdk Order.String() represents and how to parse back @@ -196,10 +197,17 @@ type IBCPacket struct { // IBCChannelOpenResult is the raw response from the ibc_channel_open call. // This is mirrors Rust's ContractResult<()>. -// We just check if Err == "" to see if this is success (no other data on success) +// Check if Err == "" to see if this is success +// On Success, IBCV3ChannelOpenResponse *may* be set if the contract is ibcv3 compatible and wishes to +// define a custom version in the handshake. type IBCChannelOpenResult struct { - Ok *struct{} `json:"ok,omitempty"` - Err string `json:"error,omitempty"` + Ok *IBC3ChannelOpenResponse `json:"ok,omitempty"` + Err string `json:"error,omitempty"` +} + +// IBC3ChannelOpenResponse is version negotiation data for the handshake +type IBC3ChannelOpenResponse struct { + Version string `json:"version"` } // This is the return value for the majority of the ibc handlers. @@ -223,7 +231,7 @@ type IBCBasicResponse struct { // "fire and forget". Messages []SubMsg `json:"messages"` // attributes for a log event to return over abci interface - Attributes []abci.EventAttribute `json:"attributes"` + Attributes []v010msgtypes.LogAttribute `json:"attributes"` // custom events (separate from the main one that contains the attributes // above) Events []Event `json:"events"` @@ -254,8 +262,8 @@ type IBCReceiveResponse struct { // If the ReplyOn value matches the result, the runtime will invoke this // contract's `reply` entry point after execution. Otherwise, this is all // "fire and forget". - Messages []SubMsg `json:"messages"` - Attributes []abci.EventAttribute `json:"attributes"` + Messages []SubMsg `json:"messages"` + Attributes []v010msgtypes.LogAttribute `json:"attributes"` // custom events (separate from the main one that contains the attributes // above) Events []Event `json:"events"` diff --git a/x/compute/internal/keeper/relay.go b/x/compute/internal/keeper/relay.go index 587f5a14b..d21e76661 100644 --- a/x/compute/internal/keeper/relay.go +++ b/x/compute/internal/keeper/relay.go @@ -2,6 +2,7 @@ package keeper import ( "encoding/json" + "fmt" "time" "github.com/cosmos/cosmos-sdk/telemetry" @@ -27,7 +28,6 @@ func (k Keeper) OnOpenChannel( msg v1types.IBCChannelOpenMsg, ) (string, error) { defer telemetry.MeasureSince(time.Now(), "compute", "keeper", "ibc-open-channel") - version := "" ctx.GasMeter().ConsumeGas(types.InstanceCost, "Loading Compute module: ibc-open-channel") @@ -68,18 +68,16 @@ func (k Keeper) OnOpenChannel( return "", sdkerrors.Wrap(types.ErrExecuteFailed, err.Error()) } - ///////// - res, gasUsed, execErr := k.wasmVM.IBCChannelOpen(codeInfo.CodeHash, env, msg, prefixStore, cosmwasmAPI, querier, ctx.GasMeter(), gas, costJSONDeserialization) - - if execErr != nil { - return "", sdkerrors.Wrap(types.ErrExecuteFailed, execErr.Error()) + switch resp := res.(type) { + case *v1types.IBC3ChannelOpenResponse: + if resp != nil { + return resp.Version, nil + } else { + return "", nil + } + default: + return "", sdkerrors.Wrap(types.ErrExecuteFailed, fmt.Sprintf("cannot cast res to IBC3ChannelOpenResponse: %+v", res)) } - - if res != nil { - version = res.Version - } - - return version, nil } // OnConnectChannel calls the contract to let it know the IBC channel was established. diff --git a/x/compute/internal/types/exported_keepers.go b/x/compute/internal/types/exported_keepers.go new file mode 100644 index 000000000..477f668e7 --- /dev/null +++ b/x/compute/internal/types/exported_keepers.go @@ -0,0 +1,46 @@ +package types + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" + capabilitytypes "github.com/cosmos/cosmos-sdk/x/capability/types" + v1types "github.com/enigmampc/SecretNetwork/go-cosmwasm/types/v1" +) + +// IBCContractKeeper IBC lifecycle event handler +type IBCContractKeeper interface { + OnOpenChannel( + ctx sdk.Context, + contractAddr sdk.AccAddress, + msg v1types.IBCChannelOpenMsg, + ) (string, error) + OnConnectChannel( + ctx sdk.Context, + contractAddr sdk.AccAddress, + msg v1types.IBCChannelConnectMsg, + ) error + OnCloseChannel( + ctx sdk.Context, + contractAddr sdk.AccAddress, + msg v1types.IBCChannelCloseMsg, + ) error + OnRecvPacket( + ctx sdk.Context, + contractAddr sdk.AccAddress, + msg v1types.IBCPacketReceiveMsg, + ) ([]byte, error) + OnAckPacket( + ctx sdk.Context, + contractAddr sdk.AccAddress, + acknowledgement v1types.IBCPacketAckMsg, + ) error + OnTimeoutPacket( + ctx sdk.Context, + contractAddr sdk.AccAddress, + msg v1types.IBCPacketTimeoutMsg, + ) error + // ClaimCapability allows the transfer module to claim a capability + // that IBC module passes to it + ClaimCapability(ctx sdk.Context, cap *capabilitytypes.Capability, name string) error + // AuthenticateCapability wraps the scopedKeeper's AuthenticateCapability function + AuthenticateCapability(ctx sdk.Context, cap *capabilitytypes.Capability, name string) bool +} From 26413fdb8c61f22b4cfd9d7247546097dd940669 Mon Sep 17 00:00:00 2001 From: Assaf Morami Date: Mon, 25 Jul 2022 12:54:49 +0300 Subject: [PATCH 03/93] Parse IBC results in go-cosmwasm --- go-cosmwasm/lib.go | 88 ++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 77 insertions(+), 11 deletions(-) diff --git a/go-cosmwasm/lib.go b/go-cosmwasm/lib.go index 523e6fdaa..45411542c 100644 --- a/go-cosmwasm/lib.go +++ b/go-cosmwasm/lib.go @@ -91,11 +91,11 @@ type ContractExecResponse struct { InternaReplyEnclaveSig []byte `json:"internal_reply_enclave_sig"` InternalMsgId []byte `json:"internal_msg_id"` IBCChannelOpen *v1types.IBCChannelOpenResult `json:"ibc_channel_open,omitempty"` - IBCChannelConnect *v1types.IBCBasicResponse `json:"ibc_channel_connect,omitempty"` - IBCChannelClose *v1types.IBCBasicResponse `json:"ibc_channel_close,omitempty"` + IBCChannelConnect *v1types.IBCBasicResult `json:"ibc_channel_connect,omitempty"` + IBCChannelClose *v1types.IBCBasicResult `json:"ibc_channel_close,omitempty"` IBCPacketReceive *v1types.IBCReceiveResult `json:"ibc_packet_receive,omitempty"` - IBCPacketAck *v1types.IBCBasicResponse `json:"ibc_packet_ack,omitempty"` - IBCPacketTimeout *v1types.IBCBasicResponse `json:"ibc_packet_timeout,omitempty"` + IBCPacketAck *v1types.IBCBasicResult `json:"ibc_packet_ack,omitempty"` + IBCPacketTimeout *v1types.IBCBasicResult `json:"ibc_packet_timeout,omitempty"` } type V010ContractExecResponse struct { @@ -284,16 +284,16 @@ func (w *Wasmer) Execute( InternaReplyEnclaveSig: resp.InternaReplyEnclaveSig, Data: []byte(resp.V010.Err.GenericErr.Msg), }, gasUsed, fmt.Errorf("%+v", resp.V010.Err) - } - - if resp.V010.Ok != nil { + } else if resp.V010.Ok != nil { if isOutputAddressedToReply { resp.V010.Ok.Data, err = AppendReplyInternalDataToData(resp.V010.Ok.Data, resp.InternaReplyEnclaveSig, resp.InternalMsgId) if err != nil { - return nil, gasUsed, fmt.Errorf("cannot serialize v010 DataWithInternalReplyInfo into binary : %w", err) + return nil, gasUsed, fmt.Errorf("cannot serialize v0.10 DataWithInternalReplyInfo into binary : %w", err) } } return resp.V010.Ok, gasUsed, nil + } else { + return nil, gasUsed, fmt.Errorf("cannot parse v0.10 handle response: %+v", resp) } } @@ -305,9 +305,7 @@ func (w *Wasmer) Execute( InternaReplyEnclaveSig: resp.InternaReplyEnclaveSig, Data: []byte(resp.V1.Err.GenericErr.Msg), }, gasUsed, fmt.Errorf("%+v", resp.V1.Err) - } - - if resp.V1.Ok != nil { + } else if resp.V1.Ok != nil { if isOutputAddressedToReply { resp.V1.Ok.Data, err = AppendReplyInternalDataToData(resp.V1.Ok.Data, resp.InternaReplyEnclaveSig, resp.InternalMsgId) if err != nil { @@ -315,6 +313,74 @@ func (w *Wasmer) Execute( } } return resp.V1.Ok, gasUsed, nil + } else { + return nil, gasUsed, fmt.Errorf("cannot parse v1 handle response: %+v", resp) + } + } + + // handle IBCChannelOpen response + if resp.IBCChannelOpen != nil { + if resp.IBCChannelOpen.Err != "" { + return nil, gasUsed, fmt.Errorf("%s", resp.IBCChannelOpen.Err) + } else if resp.IBCChannelOpen.Ok != nil { + return resp.IBCChannelOpen.Ok, gasUsed, nil + } else { + return nil, gasUsed, fmt.Errorf("cannot parse IBCChannelOpen response: %+v", resp) + } + } + + // handle IBCChannelConnect response + if resp.IBCChannelConnect != nil { + if resp.IBCChannelConnect.Err != "" { + return nil, gasUsed, fmt.Errorf("%s", resp.IBCChannelConnect.Err) + } else if resp.IBCChannelConnect.Ok != nil { + return resp.IBCChannelConnect.Ok, gasUsed, nil + } else { + return nil, gasUsed, fmt.Errorf("cannot parse IBCChannelConnect response: %+v", resp) + } + } + + // handle IBCChannelClose response + if resp.IBCChannelClose != nil { + if resp.IBCChannelClose.Err != "" { + return nil, gasUsed, fmt.Errorf("%s", resp.IBCChannelClose.Err) + } else if resp.IBCChannelClose.Ok != nil { + return resp.IBCChannelClose.Ok, gasUsed, nil + } else { + return nil, gasUsed, fmt.Errorf("cannot parse IBCChannelClose response: %+v", resp) + } + } + + // handle IBCPacketReceive response + if resp.IBCPacketReceive != nil { + if resp.IBCPacketReceive.Err != "" { + return nil, gasUsed, fmt.Errorf("%s", resp.IBCPacketReceive.Err) + } else if resp.IBCPacketReceive.Ok != nil { + return resp.IBCPacketReceive.Ok, gasUsed, nil + } else { + return nil, gasUsed, fmt.Errorf("cannot parse IBCPacketReceive response: %+v", resp) + } + } + + // handle IBCPacketAck response + if resp.IBCPacketAck != nil { + if resp.IBCPacketAck.Err != "" { + return nil, gasUsed, fmt.Errorf("%s", resp.IBCPacketAck.Err) + } else if resp.IBCPacketAck.Ok != nil { + return resp.IBCPacketAck.Ok, gasUsed, nil + } else { + return nil, gasUsed, fmt.Errorf("cannot parse IBCPacketAck response: %+v", resp) + } + } + + // handle IBCPacketTimeout response + if resp.IBCPacketTimeout != nil { + if resp.IBCPacketTimeout.Err != "" { + return nil, gasUsed, fmt.Errorf("%s", resp.IBCPacketTimeout.Err) + } else if resp.IBCPacketTimeout.Ok != nil { + return resp.IBCPacketTimeout.Ok, gasUsed, nil + } else { + return nil, gasUsed, fmt.Errorf("cannot parse IBCPacketTimeout response: %+v", resp) } } From d3cda943dabdc9184022e35133f64b4bed5794cc Mon Sep 17 00:00:00 2001 From: Assaf Morami Date: Mon, 25 Jul 2022 13:19:24 +0300 Subject: [PATCH 04/93] Refactor IBC contract calls, lots of shared code --- x/compute/internal/keeper/ibc.go | 5 ++++ x/compute/internal/keeper/keeper.go | 3 ++ x/compute/internal/keeper/relay.go | 46 +++++++++++++++++------------ 3 files changed, 35 insertions(+), 19 deletions(-) diff --git a/x/compute/internal/keeper/ibc.go b/x/compute/internal/keeper/ibc.go index 8df6fdecc..900927b82 100644 --- a/x/compute/internal/keeper/ibc.go +++ b/x/compute/internal/keeper/ibc.go @@ -37,3 +37,8 @@ func PortIDForContract(addr sdk.AccAddress) string { func (k Keeper) ClaimCapability(ctx sdk.Context, cap *capabilitytypes.Capability, name string) error { return k.capabilityKeeper.ClaimCapability(ctx, cap, name) } + +// AuthenticateCapability wraps the scopedKeeper's AuthenticateCapability function +func (k Keeper) AuthenticateCapability(ctx sdk.Context, cap *capabilitytypes.Capability, name string) bool { + return k.capabilityKeeper.AuthenticateCapability(ctx, cap, name) +} diff --git a/x/compute/internal/keeper/keeper.go b/x/compute/internal/keeper/keeper.go index 6215d155a..d3417db06 100644 --- a/x/compute/internal/keeper/keeper.go +++ b/x/compute/internal/keeper/keeper.go @@ -10,6 +10,7 @@ import ( "time" capabilitykeeper "github.com/cosmos/cosmos-sdk/x/capability/keeper" + capabilitytypes "github.com/cosmos/cosmos-sdk/x/capability/types" channelkeeper "github.com/cosmos/ibc-go/v3/modules/core/04-channel/keeper" portkeeper "github.com/cosmos/ibc-go/v3/modules/core/05-port/keeper" wasmTypes "github.com/enigmampc/SecretNetwork/go-cosmwasm/types" @@ -1109,3 +1110,5 @@ func (k Keeper) reply(ctx sdk.Context, contractAddress sdk.AccAddress, reply v1w return nil, sdkerrors.Wrap(types.ErrExecuteFailed, fmt.Sprintf("cannot detect response type: %+v", res)) } } + + diff --git a/x/compute/internal/keeper/relay.go b/x/compute/internal/keeper/relay.go index d21e76661..b855d3513 100644 --- a/x/compute/internal/keeper/relay.go +++ b/x/compute/internal/keeper/relay.go @@ -17,20 +17,10 @@ import ( var _ types.IBCContractKeeper = (*Keeper)(nil) -// OnOpenChannel calls the contract to participate in the IBC channel handshake step. -// In the IBC protocol this is either the `Channel Open Init` event on the initiating chain or -// `Channel Open Try` on the counterparty chain. -// Protocol version and channel ordering should be verified for example. -// See https://github.com/cosmos/ics/tree/master/spec/ics-004-channel-and-packet-semantics#channel-lifecycle-management -func (k Keeper) OnOpenChannel( - ctx sdk.Context, +func (k Keeper) ibcContractCall(ctx sdk.Context, contractAddress sdk.AccAddress, - msg v1types.IBCChannelOpenMsg, -) (string, error) { - defer telemetry.MeasureSince(time.Now(), "compute", "keeper", "ibc-open-channel") - - ctx.GasMeter().ConsumeGas(types.InstanceCost, "Loading Compute module: ibc-open-channel") - + msgBz []byte, +) (interface{}, error) { verificationInfo := types.NewVerificationInfo([]byte{}, sdktxsigning.SignMode_SIGN_MODE_UNSPECIFIED, []byte{}, []byte{}, []byte{}, nil) _, codeInfo, prefixStore, err := k.contractInstance(ctx, contractAddress) @@ -43,8 +33,8 @@ func (k Keeper) OnOpenChannel( contractKey := store.Get(types.GetContractEnclaveKey(contractAddress)) env := types.NewEnv( ctx, - sdk.AccAddress{}, /* empty because it's unused in queries */ - sdk.NewCoins(), /* empty because it's unused in queries */ + sdk.AccAddress{}, /* there's no MessageInfo for IBC contract calls */ + sdk.NewCoins(), /* there's no MessageInfo for IBC contract calls */ contractAddress, contractKey, ) @@ -55,15 +45,33 @@ func (k Keeper) OnOpenChannel( Plugins: k.queryPlugins, } + gas := gasForContract(ctx) + res, gasUsed, err := k.wasmer.Execute(codeInfo.CodeHash, env, msgBz, prefixStore, cosmwasmAPI, querier, ctx.GasMeter(), gas, verificationInfo, wasmTypes.HandleTypeReply) + consumeGas(ctx, gasUsed) + + return res, err +} + +// OnOpenChannel calls the contract to participate in the IBC channel handshake step. +// In the IBC protocol this is either the `Channel Open Init` event on the initiating chain or +// `Channel Open Try` on the counterparty chain. +// Protocol version and channel ordering should be verified for example. +// See https://github.com/cosmos/ics/tree/master/spec/ics-004-channel-and-packet-semantics#channel-lifecycle-management +func (k Keeper) OnOpenChannel( + ctx sdk.Context, + contractAddress sdk.AccAddress, + msg v1types.IBCChannelOpenMsg, +) (string, error) { + defer telemetry.MeasureSince(time.Now(), "compute", "keeper", "ibc-open-channel") + + ctx.GasMeter().ConsumeGas(types.InstanceCost, "Loading Compute module: ibc-open-channel") + msgBz, err := json.Marshal(msg) if err != nil { return "", sdkerrors.Wrap(err, "ibc-open-channel") } - gas := gasForContract(ctx) - res, gasUsed, err := k.wasmer.Execute(codeInfo.CodeHash, env, msgBz, prefixStore, cosmwasmAPI, querier, ctx.GasMeter(), gas, verificationInfo, wasmTypes.HandleTypeReply) - consumeGas(ctx, gasUsed) - + res, err := k.ibcContractCall(ctx, contractAddress, msgBz) if err != nil { return "", sdkerrors.Wrap(types.ErrExecuteFailed, err.Error()) } From bd46776cc7aee99616380e0e551feecce0343f98 Mon Sep 17 00:00:00 2001 From: Assaf Morami Date: Mon, 25 Jul 2022 13:39:46 +0300 Subject: [PATCH 05/93] IBC keeper OnTimeoutPacket OnAckPacket OnCloseChannel OnConnectChannel --- x/compute/internal/keeper/keeper.go | 3 - x/compute/internal/keeper/relay.go | 129 +++++++++++++++++----------- 2 files changed, 79 insertions(+), 53 deletions(-) diff --git a/x/compute/internal/keeper/keeper.go b/x/compute/internal/keeper/keeper.go index d3417db06..6215d155a 100644 --- a/x/compute/internal/keeper/keeper.go +++ b/x/compute/internal/keeper/keeper.go @@ -10,7 +10,6 @@ import ( "time" capabilitykeeper "github.com/cosmos/cosmos-sdk/x/capability/keeper" - capabilitytypes "github.com/cosmos/cosmos-sdk/x/capability/types" channelkeeper "github.com/cosmos/ibc-go/v3/modules/core/04-channel/keeper" portkeeper "github.com/cosmos/ibc-go/v3/modules/core/05-port/keeper" wasmTypes "github.com/enigmampc/SecretNetwork/go-cosmwasm/types" @@ -1110,5 +1109,3 @@ func (k Keeper) reply(ctx sdk.Context, contractAddress sdk.AccAddress, reply v1w return nil, sdkerrors.Wrap(types.ErrExecuteFailed, fmt.Sprintf("cannot detect response type: %+v", res)) } } - - diff --git a/x/compute/internal/keeper/relay.go b/x/compute/internal/keeper/relay.go index b855d3513..2d05822f2 100644 --- a/x/compute/internal/keeper/relay.go +++ b/x/compute/internal/keeper/relay.go @@ -20,6 +20,7 @@ var _ types.IBCContractKeeper = (*Keeper)(nil) func (k Keeper) ibcContractCall(ctx sdk.Context, contractAddress sdk.AccAddress, msgBz []byte, + callType wasmTypes.HandleType, ) (interface{}, error) { verificationInfo := types.NewVerificationInfo([]byte{}, sdktxsigning.SignMode_SIGN_MODE_UNSPECIFIED, []byte{}, []byte{}, []byte{}, nil) @@ -46,12 +47,33 @@ func (k Keeper) ibcContractCall(ctx sdk.Context, } gas := gasForContract(ctx) - res, gasUsed, err := k.wasmer.Execute(codeInfo.CodeHash, env, msgBz, prefixStore, cosmwasmAPI, querier, ctx.GasMeter(), gas, verificationInfo, wasmTypes.HandleTypeReply) + res, gasUsed, err := k.wasmer.Execute(codeInfo.CodeHash, env, msgBz, prefixStore, cosmwasmAPI, querier, ctx.GasMeter(), gas, verificationInfo, callType) consumeGas(ctx, gasUsed) return res, err } +func (k Keeper) parseThenHandleIBCBasicContractResponse(ctx sdk.Context, + contractAddress sdk.AccAddress, + res interface{}, +) error { + switch resp := res.(type) { + case *v1types.IBCBasicResponse: + if resp != nil { + contractInfo, _, _, err := k.contractInstance(ctx, contractAddress) + if err != nil { + return err + } + + return k.handleIBCBasicContractResponse(ctx, contractAddress, contractInfo.IBCPortID, resp) + } else { + return sdkerrors.Wrap(types.ErrExecuteFailed, fmt.Sprintf("cannot parse IBCBasicResponse: %+v", res)) + } + default: + return sdkerrors.Wrap(types.ErrExecuteFailed, fmt.Sprintf("cannot cast res to IBCBasicResponse: %+v", res)) + } +} + // OnOpenChannel calls the contract to participate in the IBC channel handshake step. // In the IBC protocol this is either the `Channel Open Init` event on the initiating chain or // `Channel Open Try` on the counterparty chain. @@ -71,7 +93,7 @@ func (k Keeper) OnOpenChannel( return "", sdkerrors.Wrap(err, "ibc-open-channel") } - res, err := k.ibcContractCall(ctx, contractAddress, msgBz) + res, err := k.ibcContractCall(ctx, contractAddress, msgBz, wasmTypes.HandleTypeIbcChannelConnect) if err != nil { return "", sdkerrors.Wrap(types.ErrExecuteFailed, err.Error()) } @@ -84,7 +106,7 @@ func (k Keeper) OnOpenChannel( return "", nil } default: - return "", sdkerrors.Wrap(types.ErrExecuteFailed, fmt.Sprintf("cannot cast res to IBC3ChannelOpenResponse: %+v", res)) + return "", sdkerrors.Wrap(types.ErrExecuteFailed, fmt.Sprintf("ibc-open-channel: cannot cast res to IBC3ChannelOpenResponse: %+v", res)) } } @@ -97,26 +119,28 @@ func (k Keeper) OnOpenChannel( // See https://github.com/cosmos/ics/tree/master/spec/ics-004-channel-and-packet-semantics#channel-lifecycle-management func (k Keeper) OnConnectChannel( ctx sdk.Context, - contractAddr sdk.AccAddress, + contractAddress sdk.AccAddress, msg v1types.IBCChannelConnectMsg, ) error { defer telemetry.MeasureSince(time.Now(), "compute", "keeper", "ibc-connect-channel") - contractInfo, codeInfo, prefixStore, err := k.contractInstance(ctx, contractAddr) + + ctx.GasMeter().ConsumeGas(types.InstanceCost, "Loading Compute module: ibc-connect-channel") + + msgBz, err := json.Marshal(msg) if err != nil { - return err + return sdkerrors.Wrap(err, "ibc-connect-channel") } - env := types.NewEnv(ctx, contractAddr) - querier := k.newQueryHandler(ctx, contractAddr) - - gas := k.runtimeGasForContract(ctx) - res, gasUsed, execErr := k.wasmVM.IBCChannelConnect(codeInfo.CodeHash, env, msg, prefixStore, cosmwasmAPI, querier, ctx.GasMeter(), gas, costJSONDeserialization) - k.consumeRuntimeGas(ctx, gasUsed) - if execErr != nil { - return sdkerrors.Wrap(types.ErrExecuteFailed, execErr.Error()) + res, err := k.ibcContractCall(ctx, contractAddress, msgBz, wasmTypes.HandleTypeIbcChannelConnect) + if err != nil { + return sdkerrors.Wrap(types.ErrExecuteFailed, err.Error()) } - return k.handleIBCBasicContractResponse(ctx, contractAddr, contractInfo.IBCPortID, res) + err = k.parseThenHandleIBCBasicContractResponse(ctx, contractAddress, res) + if err != nil { + sdkerrors.Wrap(err, "ibc-connect-channel") + } + return nil } // OnCloseChannel calls the contract to let it know the IBC channel is closed. @@ -127,27 +151,28 @@ func (k Keeper) OnConnectChannel( // See https://github.com/cosmos/ics/tree/master/spec/ics-004-channel-and-packet-semantics#channel-lifecycle-management func (k Keeper) OnCloseChannel( ctx sdk.Context, - contractAddr sdk.AccAddress, + contractAddress sdk.AccAddress, msg v1types.IBCChannelCloseMsg, ) error { defer telemetry.MeasureSince(time.Now(), "compute", "keeper", "ibc-close-channel") - contractInfo, codeInfo, prefixStore, err := k.contractInstance(ctx, contractAddr) + ctx.GasMeter().ConsumeGas(types.InstanceCost, "Loading Compute module: ibc-close-channel") + + msgBz, err := json.Marshal(msg) if err != nil { - return err + return sdkerrors.Wrap(err, "ibc-close-channel") } - params := types.NewEnv(ctx, contractAddr) - querier := k.newQueryHandler(ctx, contractAddr) - - gas := k.runtimeGasForContract(ctx) - res, gasUsed, execErr := k.wasmVM.IBCChannelClose(codeInfo.CodeHash, params, msg, prefixStore, cosmwasmAPI, querier, ctx.GasMeter(), gas, costJSONDeserialization) - k.consumeRuntimeGas(ctx, gasUsed) - if execErr != nil { - return sdkerrors.Wrap(types.ErrExecuteFailed, execErr.Error()) + res, err := k.ibcContractCall(ctx, contractAddress, msgBz, wasmTypes.HandleTypeIbcChannelClose) + if err != nil { + return sdkerrors.Wrap(types.ErrExecuteFailed, err.Error()) } - return k.handleIBCBasicContractResponse(ctx, contractAddr, contractInfo.IBCPortID, res) + err = k.parseThenHandleIBCBasicContractResponse(ctx, contractAddress, res) + if err != nil { + sdkerrors.Wrap(err, "ibc-close-channel") + } + return nil } // OnRecvPacket calls the contract to process the incoming IBC packet. The contract fully owns the data processing and @@ -192,25 +217,28 @@ func (k Keeper) OnRecvPacket( // For more information see: https://github.com/cosmos/ics/tree/master/spec/ics-004-channel-and-packet-semantics#packet-flow--handling func (k Keeper) OnAckPacket( ctx sdk.Context, - contractAddr sdk.AccAddress, + contractAddress sdk.AccAddress, msg v1types.IBCPacketAckMsg, ) error { defer telemetry.MeasureSince(time.Now(), "compute", "keeper", "ibc-ack-packet") - contractInfo, codeInfo, prefixStore, err := k.contractInstance(ctx, contractAddr) + + ctx.GasMeter().ConsumeGas(types.InstanceCost, "Loading Compute module: ibc-ack-packet") + + msgBz, err := json.Marshal(msg) if err != nil { - return err + return sdkerrors.Wrap(err, "ibc-ack-packet") } - env := types.NewEnv(ctx, contractAddr) - querier := k.newQueryHandler(ctx, contractAddr) + res, err := k.ibcContractCall(ctx, contractAddress, msgBz, wasmTypes.HandleTypeIbcPacketAck) + if err != nil { + return sdkerrors.Wrap(types.ErrExecuteFailed, err.Error()) + } - gas := k.runtimeGasForContract(ctx) - res, gasUsed, execErr := k.wasmVM.IBCPacketAck(codeInfo.CodeHash, env, msg, prefixStore, cosmwasmAPI, querier, ctx.GasMeter(), gas, costJSONDeserialization) - k.consumeRuntimeGas(ctx, gasUsed) - if execErr != nil { - return sdkerrors.Wrap(types.ErrExecuteFailed, execErr.Error()) + err = k.parseThenHandleIBCBasicContractResponse(ctx, contractAddress, res) + if err != nil { + sdkerrors.Wrap(err, "ibc-ack-packet") } - return k.handleIBCBasicContractResponse(ctx, contractAddr, contractInfo.IBCPortID, res) + return nil } // OnTimeoutPacket calls the contract to let it know the packet was never received on the destination chain within @@ -218,27 +246,28 @@ func (k Keeper) OnAckPacket( // The contract should handle this on the application level and undo the original operation func (k Keeper) OnTimeoutPacket( ctx sdk.Context, - contractAddr sdk.AccAddress, + contractAddress sdk.AccAddress, msg v1types.IBCPacketTimeoutMsg, ) error { defer telemetry.MeasureSince(time.Now(), "compute", "keeper", "ibc-timeout-packet") - contractInfo, codeInfo, prefixStore, err := k.contractInstance(ctx, contractAddr) + ctx.GasMeter().ConsumeGas(types.InstanceCost, "Loading Compute module: ibc-timeout-packet") + + msgBz, err := json.Marshal(msg) if err != nil { - return err + return sdkerrors.Wrap(err, "ibc-timeout-packet") } - env := types.NewEnv(ctx, contractAddr) - querier := k.newQueryHandler(ctx, contractAddr) - - gas := k.runtimeGasForContract(ctx) - res, gasUsed, execErr := k.wasmVM.IBCPacketTimeout(codeInfo.CodeHash, env, msg, prefixStore, cosmwasmAPI, querier, ctx.GasMeter(), gas, costJSONDeserialization) - k.consumeRuntimeGas(ctx, gasUsed) - if execErr != nil { - return sdkerrors.Wrap(types.ErrExecuteFailed, execErr.Error()) + res, err := k.ibcContractCall(ctx, contractAddress, msgBz, wasmTypes.HandleTypeIbcPacketTimeout) + if err != nil { + return sdkerrors.Wrap(types.ErrExecuteFailed, err.Error()) } - return k.handleIBCBasicContractResponse(ctx, contractAddr, contractInfo.IBCPortID, res) + err = k.parseThenHandleIBCBasicContractResponse(ctx, contractAddress, res) + if err != nil { + sdkerrors.Wrap(err, "ibc-timeout-packet") + } + return nil } func (k Keeper) handleIBCBasicContractResponse(ctx sdk.Context, addr sdk.AccAddress, id string, res *v1types.IBCBasicResponse) error { From 1277f839a64288ae41069ce0769191c7414844f1 Mon Sep 17 00:00:00 2001 From: Assaf Morami Date: Tue, 26 Jul 2022 11:24:09 +0300 Subject: [PATCH 06/93] Keeper OnRecvPacket --- x/compute/internal/keeper/relay.go | 62 +++++++++++++++++++----------- 1 file changed, 39 insertions(+), 23 deletions(-) diff --git a/x/compute/internal/keeper/relay.go b/x/compute/internal/keeper/relay.go index 2d05822f2..a60a928e0 100644 --- a/x/compute/internal/keeper/relay.go +++ b/x/compute/internal/keeper/relay.go @@ -55,6 +55,7 @@ func (k Keeper) ibcContractCall(ctx sdk.Context, func (k Keeper) parseThenHandleIBCBasicContractResponse(ctx sdk.Context, contractAddress sdk.AccAddress, + inputMsg []byte, res interface{}, ) error { switch resp := res.(type) { @@ -65,9 +66,9 @@ func (k Keeper) parseThenHandleIBCBasicContractResponse(ctx sdk.Context, return err } - return k.handleIBCBasicContractResponse(ctx, contractAddress, contractInfo.IBCPortID, resp) + return k.handleIBCBasicContractResponse(ctx, contractAddress, contractInfo.IBCPortID, inputMsg, resp) } else { - return sdkerrors.Wrap(types.ErrExecuteFailed, fmt.Sprintf("cannot parse IBCBasicResponse: %+v", res)) + return sdkerrors.Wrap(types.ErrExecuteFailed, fmt.Sprintf("null pointer IBCBasicResponse: %+v", res)) } default: return sdkerrors.Wrap(types.ErrExecuteFailed, fmt.Sprintf("cannot cast res to IBCBasicResponse: %+v", res)) @@ -136,7 +137,7 @@ func (k Keeper) OnConnectChannel( return sdkerrors.Wrap(types.ErrExecuteFailed, err.Error()) } - err = k.parseThenHandleIBCBasicContractResponse(ctx, contractAddress, res) + err = k.parseThenHandleIBCBasicContractResponse(ctx, contractAddress, msgBz, res) if err != nil { sdkerrors.Wrap(err, "ibc-connect-channel") } @@ -168,7 +169,7 @@ func (k Keeper) OnCloseChannel( return sdkerrors.Wrap(types.ErrExecuteFailed, err.Error()) } - err = k.parseThenHandleIBCBasicContractResponse(ctx, contractAddress, res) + err = k.parseThenHandleIBCBasicContractResponse(ctx, contractAddress, msgBz, res) if err != nil { sdkerrors.Wrap(err, "ibc-close-channel") } @@ -183,29 +184,42 @@ func (k Keeper) OnCloseChannel( // For more information see: https://github.com/cosmos/ics/tree/master/spec/ics-004-channel-and-packet-semantics#packet-flow--handling func (k Keeper) OnRecvPacket( ctx sdk.Context, - contractAddr sdk.AccAddress, + contractAddress sdk.AccAddress, msg v1types.IBCPacketReceiveMsg, ) ([]byte, error) { defer telemetry.MeasureSince(time.Now(), "compute", "keeper", "ibc-recv-packet") - contractInfo, codeInfo, prefixStore, err := k.contractInstance(ctx, contractAddr) + + ctx.GasMeter().ConsumeGas(types.InstanceCost, "Loading Compute module: ibc-recv-packet") + + msgBz, err := json.Marshal(msg) if err != nil { - return nil, err + return nil, sdkerrors.Wrap(err, "ibc-recv-packet") } - env := types.NewEnv(ctx, contractAddr) - querier := k.newQueryHandler(ctx, contractAddr) - - gas := k.runtimeGasForContract(ctx) - res, gasUsed, execErr := k.wasmVM.IBCPacketReceive(codeInfo.CodeHash, env, msg, prefixStore, cosmwasmAPI, querier, ctx.GasMeter(), gas, costJSONDeserialization) - k.consumeRuntimeGas(ctx, gasUsed) - if execErr != nil { - return nil, sdkerrors.Wrap(types.ErrExecuteFailed, execErr.Error()) + res, err := k.ibcContractCall(ctx, contractAddress, msgBz, wasmTypes.HandleTypeIbcChannelConnect) + if err != nil { + return nil, sdkerrors.Wrap(types.ErrExecuteFailed, err.Error()) } - if res.Err != "" { // handle error case as before https://github.com/CosmWasm/wasmvm/commit/c300106fe5c9426a495f8e10821e00a9330c56c6 - return nil, sdkerrors.Wrap(types.ErrExecuteFailed, res.Err) + + switch resp := res.(type) { + case *v1types.IBCReceiveResponse: + if resp != nil { + contractInfo, _, _, err := k.contractInstance(ctx, contractAddress) + if err != nil { + return nil, err + } + verificationInfo := types.NewVerificationInfo([]byte{}, sdktxsigning.SignMode_SIGN_MODE_UNSPECIFIED, []byte{}, []byte{}, []byte{}, nil) + + // note submessage reply results can overwrite the `Acknowledgement` data + return k.handleContractResponse(ctx, contractAddress, contractInfo.IBCPortID, resp.Messages, resp.Attributes, resp.Events, resp.Acknowledgement, msgBz, verificationInfo, wasmTypes.CosmosMsgVersionV1) + } else { + // should never get here as it's already checked in + // https://github.com/scrtlabs/SecretNetwork/blob/bd46776c/go-cosmwasm/lib.go#L358 + return nil, sdkerrors.Wrap(types.ErrExecuteFailed, fmt.Sprintf("ibc-recv-packet: null pointer IBCReceiveResponse: %+v", res)) + } + default: + return nil, sdkerrors.Wrap(types.ErrExecuteFailed, fmt.Sprintf("ibc-recv-packet: cannot cast res to IBCReceiveResponse: %+v", res)) } - // note submessage reply results can overwrite the `Acknowledgement` data - return k.handleContractResponse(ctx, contractAddr, contractInfo.IBCPortID, res.Ok.Messages, res.Ok.Attributes, res.Ok.Acknowledgement, res.Ok.Events) } // OnAckPacket calls the contract to handle the "acknowledgement" data which can contain success or failure of a packet @@ -234,7 +248,7 @@ func (k Keeper) OnAckPacket( return sdkerrors.Wrap(types.ErrExecuteFailed, err.Error()) } - err = k.parseThenHandleIBCBasicContractResponse(ctx, contractAddress, res) + err = k.parseThenHandleIBCBasicContractResponse(ctx, contractAddress, msgBz, res) if err != nil { sdkerrors.Wrap(err, "ibc-ack-packet") } @@ -263,14 +277,16 @@ func (k Keeper) OnTimeoutPacket( return sdkerrors.Wrap(types.ErrExecuteFailed, err.Error()) } - err = k.parseThenHandleIBCBasicContractResponse(ctx, contractAddress, res) + err = k.parseThenHandleIBCBasicContractResponse(ctx, contractAddress, msgBz, res) if err != nil { sdkerrors.Wrap(err, "ibc-timeout-packet") } return nil } -func (k Keeper) handleIBCBasicContractResponse(ctx sdk.Context, addr sdk.AccAddress, id string, res *v1types.IBCBasicResponse) error { - _, err := k.handleContractResponse(ctx, addr, id, res.Messages, res.Attributes, nil, res.Events) +func (k Keeper) handleIBCBasicContractResponse(ctx sdk.Context, addr sdk.AccAddress, ibcPortID string, inputMsg []byte, res *v1types.IBCBasicResponse) error { + verificationInfo := types.NewVerificationInfo([]byte{}, sdktxsigning.SignMode_SIGN_MODE_UNSPECIFIED, []byte{}, []byte{}, []byte{}, nil) + + _, err := k.handleContractResponse(ctx, addr, ibcPortID, res.Messages, res.Attributes, res.Events, nil, inputMsg, verificationInfo, wasmTypes.CosmosMsgVersionV1) return err } From 1d801535b04b6817744212f4905db5c5f7e0f214 Mon Sep 17 00:00:00 2001 From: Assaf Morami Date: Tue, 26 Jul 2022 17:33:18 +0300 Subject: [PATCH 07/93] WIP: IBC on the enclave side --- .../src/contract_operations.rs | 71 +++++++++++++++++-- .../enclaves/shared/cosmos-types/src/types.rs | 6 ++ 2 files changed, 72 insertions(+), 5 deletions(-) diff --git a/cosmwasm/enclaves/shared/contract-engine/src/contract_operations.rs b/cosmwasm/enclaves/shared/contract-engine/src/contract_operations.rs index 4a5ec1661..82b69eb50 100644 --- a/cosmwasm/enclaves/shared/contract-engine/src/contract_operations.rs +++ b/cosmwasm/enclaves/shared/contract-engine/src/contract_operations.rs @@ -221,12 +221,12 @@ pub fn parse_message( sig_info: &SigInfo, handle_type: &HandleType, ) -> Result { - let orig_secret_msg = SecretMessage::from_slice(message)?; - return match handle_type { HandleType::HANDLE_TYPE_EXECUTE => { + let orig_secret_msg = SecretMessage::from_slice(message)?; + trace!( - "handle input before decryption: {:?}", + "execute input before decryption: {:?}", base64::encode(&message) ); let decrypted_msg = orig_secret_msg.decrypt()?; @@ -238,10 +238,14 @@ pub fn parse_message( contract_hash_for_validation: None, }) } - HandleType::HANDLE_TYPE_REPLY => { + let orig_secret_msg = SecretMessage::from_slice(message)?; + if sig_info.sign_mode == SignMode::SIGN_MODE_UNSPECIFIED { - trace!("reply input is not encrypted"); + trace!( + "reply input is not encrypted: {:?}", + base64::encode(&message) + ); let decrypted_msg = orig_secret_msg.msg.clone(); let mut reply: Reply = serde_json::from_slice(&decrypted_msg) .map_err(|err| { @@ -508,6 +512,63 @@ pub fn parse_message( } } } + HandleType::HANDLE_TYPE_IBC_CHANNEL_OPEN => todo!(), + HandleType::HANDLE_TYPE_IBC_CHANNEL_CONNECT => todo!(), + HandleType::HANDLE_TYPE_IBC_CHANNEL_CLOSE => todo!(), + HandleType::HANDLE_TYPE_IBC_PACKET_RECEIVE => { + let orig_secret_msg = match SecretMessage::from_slice(message) { + Ok(orig_secret_msg) => orig_secret_msg, + Err(_) => { + trace!( + "ibc_packet_receive msg is not SecretMessage (probably plaintext): {:?}", + base64::encode(&message) + ); + + SecretMessage { + nonce: [0; 32], + user_public_key: [0; 32], + msg: message.into(), + } + } + }; + + match orig_secret_msg.decrypt() { + Ok(decrypted_msg) => { + // IBC packet is encrypted + + trace!( + "ibc_packet_receive input before decryption: {:?}", + base64::encode(&message) + ); + + Ok(ParsedMessage { + should_validate_sig_info: true, + was_msg_encrypted: true, + secret_msg: orig_secret_msg, + decrypted_msg, + contract_hash_for_validation: None, + }) + } + Err(_) => { + // assume packet is not encrypted, continue in plaintext mode + + trace!( + "ibc_packet_receive input is not encrypted: {:?}", + base64::encode(&message) + ); + + Ok(ParsedMessage { + should_validate_sig_info: false, + was_msg_encrypted: false, + secret_msg: orig_secret_msg, + decrypted_msg: orig_secret_msg.msg, + contract_hash_for_validation: None, + }) + } + } + } + HandleType::HANDLE_TYPE_IBC_PACKET_ACK => todo!(), + HandleType::HANDLE_TYPE_IBC_PACKET_TIMEOUT => todo!(), }; } diff --git a/cosmwasm/enclaves/shared/cosmos-types/src/types.rs b/cosmwasm/enclaves/shared/cosmos-types/src/types.rs index 873a80733..b86c0460d 100644 --- a/cosmwasm/enclaves/shared/cosmos-types/src/types.rs +++ b/cosmwasm/enclaves/shared/cosmos-types/src/types.rs @@ -146,6 +146,12 @@ pub enum SignModeDef { pub enum HandleType { HANDLE_TYPE_EXECUTE = 0, HANDLE_TYPE_REPLY = 1, + HANDLE_TYPE_IBC_CHANNEL_OPEN = 2, + HANDLE_TYPE_IBC_CHANNEL_CONNECT = 3, + HANDLE_TYPE_IBC_CHANNEL_CLOSE = 4, + HANDLE_TYPE_IBC_PACKET_RECEIVE = 5, + HANDLE_TYPE_IBC_PACKET_ACK = 6, + HANDLE_TYPE_IBC_PACKET_TIMEOUT = 7, } impl HandleType { From 0e412a90295352ccb16e883d405675e3911dd8d8 Mon Sep 17 00:00:00 2001 From: Assaf Morami Date: Wed, 27 Jul 2022 09:12:36 +0300 Subject: [PATCH 08/93] Remove old CosmWasm remnants --- x/compute/client/cli/tx.go | 22 +---- x/compute/internal/keeper/keeper.go | 27 +----- x/compute/internal/types/msg.go | 135 +--------------------------- 3 files changed, 5 insertions(+), 179 deletions(-) diff --git a/x/compute/client/cli/tx.go b/x/compute/client/cli/tx.go index 606cc6c07..82beb5b14 100644 --- a/x/compute/client/cli/tx.go +++ b/x/compute/client/cli/tx.go @@ -31,7 +31,6 @@ const ( flagProposalType = "type" flagIoMasterKey = "enclave-key" flagCodeHash = "code-hash" - // flagAdmin = "admin" ) // GetTxCmd returns the transaction commands for this module @@ -47,10 +46,6 @@ func GetTxCmd() *cobra.Command { StoreCodeCmd(), InstantiateContractCmd(), ExecuteContractCmd(), - // Currently not supporting these commands - // MigrateContractCmd(cdc), - // UpdateContractAdminCmd(cdc), - // ClearContractAdminCmd(cdc), ) return txCmd } @@ -105,20 +100,6 @@ func parseStoreCodeArgs(args []string, cliCtx client.Context, flags *flag.FlagSe return types.MsgStoreCode{}, fmt.Errorf("invalid input file. Use wasm binary or gzip") } - /* - var perm *types.AccessConfig - if onlyAddrStr := viper.GetString(flagInstantiateByAddress); onlyAddrStr != "" { - allowedAddr, err := sdk.AccAddressFromBech32(onlyAddrStr) - if err != nil { - return types.MsgStoreCode{}, sdkerrors.Wrap(err, flagInstantiateByAddress) - } - x := types.OnlyAddress.With(allowedAddr) - perm = &x - } else if everybody := viper.GetBool(flagInstantiateByEverybody); everybody { - perm = &types.AllowEverybody - } - */ - source, err := flags.GetString(flagSource) if err != nil { return types.MsgStoreCode{}, fmt.Errorf("source: %s", err) @@ -134,7 +115,6 @@ func parseStoreCodeArgs(args []string, cliCtx client.Context, flags *flag.FlagSe WASMByteCode: wasm, Source: source, Builder: builder, - // InstantiatePermission: perm, } return msg, nil } @@ -142,7 +122,7 @@ func parseStoreCodeArgs(args []string, cliCtx client.Context, flags *flag.FlagSe // InstantiateContractCmd will instantiate a contract from previously uploaded code. func InstantiateContractCmd() *cobra.Command { cmd := &cobra.Command{ - Use: "instantiate [code_id_int64] [json_encoded_init_args] --label [text] " /* --admin [address,optional] */ + "--amount [coins,optional]", + Use: "instantiate [code_id_int64] [json_encoded_init_args] --label [text] --amount [coins,optional]", Short: "Instantiate a wasm contract", Args: cobra.ExactArgs(2), RunE: func(cmd *cobra.Command, args []string) error { diff --git a/x/compute/internal/keeper/keeper.go b/x/compute/internal/keeper/keeper.go index 6215d155a..5980b8672 100644 --- a/x/compute/internal/keeper/keeper.go +++ b/x/compute/internal/keeper/keeper.go @@ -163,15 +163,6 @@ func (k Keeper) setParams(ctx sdk.Context, ps types.Params) { // Create uploads and compiles a WASM contract, returning a short identifier for the contract func (k Keeper) Create(ctx sdk.Context, creator sdk.AccAddress, wasmCode []byte, source string, builder string) (codeID uint64, err error) { - /* - return k.create(ctx, creator, wasmCode, source, builder, &types.AccessConfig{Type: types.Everybody} , k.authZPolicy ) - } - - func (k Keeper) create(ctx sdk.Context, creator sdk.AccAddress, wasmCode []byte, source string, builder string, instantiateAccess *types.AccessConfig ) (codeID uint64, err error) { - if !authZ.CanCreateCode(k.getUploadAccessConfig(ctx), creator) { - return 0, sdkerrors.Wrap(sdkerrors.ErrUnauthorized, "can not create code") - } - */ wasmCode, err = uncompress(wasmCode) if err != nil { return 0, sdkerrors.Wrap(types.ErrCreateFailed, err.Error()) @@ -180,18 +171,12 @@ func (k Keeper) Create(ctx sdk.Context, creator sdk.AccAddress, wasmCode []byte, codeHash, err := k.wasmer.Create(wasmCode) if err != nil { - // return 0, sdkerrors.Wrap(err, "cosmwasm create") return 0, sdkerrors.Wrap(types.ErrCreateFailed, err.Error()) } store := ctx.KVStore(k.storeKey) codeID = k.autoIncrementID(ctx, types.KeyLastCodeID) - /* - if instantiateAccess == nil { - defaultAccessConfig := k.getInstantiateAccessConfig(ctx).With(creator) - instantiateAccess = &defaultAccessConfig - } - */ - codeInfo := types.NewCodeInfo(codeHash, creator, source, builder /* , *instantiateAccess */) + + codeInfo := types.NewCodeInfo(codeHash, creator, source, builder) // 0x01 | codeID (uint64) -> ContractInfo store.Set(types.GetCodeKey(codeID), k.cdc.MustMarshal(&codeInfo)) @@ -418,10 +403,6 @@ func (k Keeper) Instantiate(ctx sdk.Context, codeID uint64, creator sdk.AccAddre var codeInfo types.CodeInfo k.cdc.MustUnmarshal(bz, &codeInfo) - // if !authZ.CanInstantiateContract(codeInfo.InstantiateConfig, creator) { - // return nil, sdkerrors.Wrap(sdkerrors.ErrUnauthorized, "can not instantiate") - // } - // prepare env for contract instantiate call env := types.NewEnv(ctx, creator, deposit, contractAddress, nil) @@ -464,8 +445,6 @@ func (k Keeper) Instantiate(ctx sdk.Context, codeID uint64, creator sdk.AccAddre contractInfo := types.NewContractInfo(codeID, creator, label, createdAt) store.Set(types.GetContractAddressKey(contractAddress), k.cdc.MustMarshal(&contractInfo)) - // fmt.Printf("Storing key: %v for account %s\n", key, contractAddress) - store.Set(types.GetContractEnclaveKey(contractAddress), key) store.Set(types.GetContractLabelPrefix(label), contractAddress) @@ -993,8 +972,6 @@ func (k Keeper) importContract(ctx sdk.Context, contractAddr sdk.AccAddress, cus return sdkerrors.Wrapf(types.ErrDuplicate, "contract: %s", contractAddr) } - // historyEntry := c.ResetFromGenesis(ctx) - // k.appendToContractHistory(ctx, contractAddr, historyEntry) k.setContractCustomInfo(ctx, contractAddr, customInfo) k.setContractInfo(ctx, contractAddr, c) return k.importContractState(ctx, contractAddr, state) diff --git a/x/compute/internal/types/msg.go b/x/compute/internal/types/msg.go index 7eb0f4877..5d7b8fcc4 100644 --- a/x/compute/internal/types/msg.go +++ b/x/compute/internal/types/msg.go @@ -29,13 +29,7 @@ func (msg MsgStoreCode) ValidateBasic() error { if err := validateBuilder(msg.Builder); err != nil { return sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "builder %s", err.Error()) } - /* - if msg.InstantiatePermission != nil { - if err := msg.InstantiatePermission.ValidateBasic(); err != nil { - return sdkerrors.Wrap(err, "instantiate permission") - } - } - */ + return nil } @@ -72,16 +66,6 @@ func (msg MsgInstantiateContract) ValidateBasic() error { return sdkerrors.ErrInvalidCoins } - /* - if len(msg.Admin) != 0 { - if err := sdk.VerifyAddressFormat(msg.Admin); err != nil { - return err - } - } - if !json.Valid(msg.InitMsg) { - return sdkerrors.Wrap(ErrInvalid, "init msg json") - } - */ return nil } @@ -112,11 +96,7 @@ func (msg MsgExecuteContract) ValidateBasic() error { if !msg.SentFunds.IsValid() { return sdkerrors.Wrap(sdkerrors.ErrInvalidCoins, "sentFunds") } - /* - if !json.Valid(msg.Msg) { - return sdkerrors.Wrap(ErrInvalid, "msg json") - } - */ + return nil } @@ -127,114 +107,3 @@ func (msg MsgExecuteContract) GetSignBytes() []byte { func (msg MsgExecuteContract) GetSigners() []sdk.AccAddress { return []sdk.AccAddress{msg.Sender} } - -/* -type MsgMigrateContract struct { - Sender sdk.AccAddress `json:"sender" yaml:"sender"` - Contract sdk.AccAddress `json:"contract" yaml:"contract"` - CodeID uint64 `json:"code_id" yaml:"code_id"` - MigrateMsg json.RawMessage `json:"msg" yaml:"msg"` -} - -func (msg MsgMigrateContract) Route() string { - return RouterKey -} - -func (msg MsgMigrateContract) Type() string { - return "migrate" -} - -func (msg MsgMigrateContract) ValidateBasic() error { - if msg.CodeID == 0 { - return sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "code_id is required") - } - if err := sdk.VerifyAddressFormat(msg.Sender); err != nil { - return sdkerrors.Wrap(err, "sender") - } - if err := sdk.VerifyAddressFormat(msg.Contract); err != nil { - return sdkerrors.Wrap(err, "contract") - } - if !json.Valid(msg.MigrateMsg) { - return sdkerrors.Wrap(ErrInvalid, "migrate msg json") - } - - return nil -} - -func (msg MsgMigrateContract) GetSignBytes() []byte { - return sdk.MustSortJSON(ModuleCdc.MustMarshalJSON(msg)) -} - -func (msg MsgMigrateContract) GetSigners() []sdk.AccAddress { - return []sdk.AccAddress{msg.Sender} -} - -type MsgUpdateAdmin struct { - Sender sdk.AccAddress `json:"sender" yaml:"sender"` - NewAdmin sdk.AccAddress `json:"new_admin" yaml:"new_admin"` - Contract sdk.AccAddress `json:"contract" yaml:"contract"` -} - -func (msg MsgUpdateAdmin) Route() string { - return RouterKey -} - -func (msg MsgUpdateAdmin) Type() string { - return "update-contract-admin" -} - -func (msg MsgUpdateAdmin) ValidateBasic() error { - if err := sdk.VerifyAddressFormat(msg.Sender); err != nil { - return sdkerrors.Wrap(err, "sender") - } - if err := sdk.VerifyAddressFormat(msg.Contract); err != nil { - return sdkerrors.Wrap(err, "contract") - } - if err := sdk.VerifyAddressFormat(msg.NewAdmin); err != nil { - return sdkerrors.Wrap(err, "new admin") - } - if msg.Sender.Equals(msg.NewAdmin) { - return sdkerrors.Wrap(ErrInvalidMsg, "new admin is the same as the old") - } - return nil -} - -func (msg MsgUpdateAdmin) GetSignBytes() []byte { - return sdk.MustSortJSON(ModuleCdc.MustMarshalJSON(msg)) -} - -func (msg MsgUpdateAdmin) GetSigners() []sdk.AccAddress { - return []sdk.AccAddress{msg.Sender} -} - -type MsgClearAdmin struct { - Sender sdk.AccAddress `json:"sender" yaml:"sender"` - Contract sdk.AccAddress `json:"contract" yaml:"contract"` -} - -func (msg MsgClearAdmin) Route() string { - return RouterKey -} - -func (msg MsgClearAdmin) Type() string { - return "clear-contract-admin" -} - -func (msg MsgClearAdmin) ValidateBasic() error { - if err := sdk.VerifyAddressFormat(msg.Sender); err != nil { - return sdkerrors.Wrap(err, "sender") - } - if err := sdk.VerifyAddressFormat(msg.Contract); err != nil { - return sdkerrors.Wrap(err, "contract") - } - return nil -} - -func (msg MsgClearAdmin) GetSignBytes() []byte { - return sdk.MustSortJSON(ModuleCdc.MustMarshalJSON(msg)) -} - -func (msg MsgClearAdmin) GetSigners() []sdk.AccAddress { - return []sdk.AccAddress{msg.Sender} -} -*/ From a60a2cbf5a2093e1a000655393e7740002b9dec5 Mon Sep 17 00:00:00 2001 From: Assaf Morami Date: Tue, 2 Aug 2022 14:41:55 +0300 Subject: [PATCH 09/93] secret-contract-optimizer v1.0.8 --- deployment/dockerfiles/secret-contract-optimizer.Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deployment/dockerfiles/secret-contract-optimizer.Dockerfile b/deployment/dockerfiles/secret-contract-optimizer.Dockerfile index c37099388..91639d96d 100644 --- a/deployment/dockerfiles/secret-contract-optimizer.Dockerfile +++ b/deployment/dockerfiles/secret-contract-optimizer.Dockerfile @@ -1,4 +1,4 @@ -FROM rust:1.59-slim-bullseye +FROM rust:1.62-slim-bullseye RUN rustup target add wasm32-unknown-unknown RUN apt update && apt install -y binaryen clang && rm -rf /var/lib/apt/lists/* From a4a2b1caf11b99c2221e42c1df07b4fca0b67920 Mon Sep 17 00:00:00 2001 From: Assaf Morami Date: Tue, 2 Aug 2022 14:42:10 +0300 Subject: [PATCH 10/93] Some IBC progress --- .vscode/settings.json | 4 +- .../src/contract_operations.rs | 2 +- .../shared/cosmwasm-v1-types/src/ibc.rs | 123 ++++++++++++++++++ .../shared/cosmwasm-v1-types/src/lib.rs | 1 + .../testdata/v1-sanity-contract/src/msg.rs | 6 + 5 files changed, 134 insertions(+), 2 deletions(-) create mode 100644 cosmwasm/enclaves/shared/cosmwasm-v1-types/src/ibc.rs diff --git a/.vscode/settings.json b/.vscode/settings.json index 244f2f6bb..c7134c83c 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -3,7 +3,9 @@ "./cosmwasm/Cargo.toml", "./cosmwasm/enclaves/Cargo.toml", "./x/compute/internal/keeper/testdata/v1-sanity-contract/Cargo.toml", - "./x/compute/internal/keeper/testdata/test-contract/Cargo.toml" + "./x/compute/internal/keeper/testdata/test-contract/Cargo.toml", + "./cosmwasm/enclaves/shared/cosmwasm-v1-types/Cargo.toml", + "./cosmwasm/enclaves/shared/cosmwasm-v010-types/Cargo.toml" ], "rust-analyzer.diagnostics.experimental.enable": true, "rust-analyzer.rustfmt.rangeFormatting.enable": true, diff --git a/cosmwasm/enclaves/shared/contract-engine/src/contract_operations.rs b/cosmwasm/enclaves/shared/contract-engine/src/contract_operations.rs index 82b69eb50..5721d86b3 100644 --- a/cosmwasm/enclaves/shared/contract-engine/src/contract_operations.rs +++ b/cosmwasm/enclaves/shared/contract-engine/src/contract_operations.rs @@ -534,7 +534,7 @@ pub fn parse_message( match orig_secret_msg.decrypt() { Ok(decrypted_msg) => { - // IBC packet is encrypted + // IBC packet was encrypted trace!( "ibc_packet_receive input before decryption: {:?}", diff --git a/cosmwasm/enclaves/shared/cosmwasm-v1-types/src/ibc.rs b/cosmwasm/enclaves/shared/cosmwasm-v1-types/src/ibc.rs new file mode 100644 index 000000000..311e89d0b --- /dev/null +++ b/cosmwasm/enclaves/shared/cosmwasm-v1-types/src/ibc.rs @@ -0,0 +1,123 @@ +use crate::addresses::Addr; +use crate::timestamp::Timestamp; +use serde::{Deserialize, Serialize}; + +/// The message that is passed into `ibc_channel_open` +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] +#[serde(rename_all = "snake_case")] +pub enum IbcChannelOpenMsg { + /// The ChanOpenInit step from https://github.com/cosmos/ibc/tree/master/spec/core/ics-004-channel-and-packet-semantics#channel-lifecycle-management + OpenInit { channel: IbcChannel }, + /// The ChanOpenTry step from https://github.com/cosmos/ibc/tree/master/spec/core/ics-004-channel-and-packet-semantics#channel-lifecycle-management + OpenTry { + channel: IbcChannel, + counterparty_version: String, + }, +} + +/// IbcChannel defines all information on a channel. +/// This is generally used in the hand-shake process, but can be queried directly. +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] +pub struct IbcChannel { + pub endpoint: IbcEndpoint, + pub counterparty_endpoint: IbcEndpoint, + pub order: IbcOrder, + /// Note: in ibcv3 this may be "", in the IbcOpenChannel handshake messages + pub version: String, + /// The connection upon which this channel was created. If this is a multi-hop + /// channel, we only expose the first hop. + pub connection_id: String, +} + +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] +pub struct IbcEndpoint { + pub port_id: String, + pub channel_id: String, +} + +/// IbcOrder defines if a channel is ORDERED or UNORDERED +/// Values come from https://github.com/cosmos/cosmos-sdk/blob/v0.40.0/proto/ibc/core/channel/v1/channel.proto#L69-L80 +/// Naming comes from the protobuf files and go translations. +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] +pub enum IbcOrder { + #[serde(rename = "ORDER_UNORDERED")] + Unordered, + #[serde(rename = "ORDER_ORDERED")] + Ordered, +} + +/// The message that is passed into `ibc_channel_connect` +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] +#[serde(rename_all = "snake_case")] +pub enum IbcChannelConnectMsg { + /// The ChanOpenAck step from https://github.com/cosmos/ibc/tree/master/spec/core/ics-004-channel-and-packet-semantics#channel-lifecycle-management + OpenAck { + channel: IbcChannel, + counterparty_version: String, + }, + /// The ChanOpenConfirm step from https://github.com/cosmos/ibc/tree/master/spec/core/ics-004-channel-and-packet-semantics#channel-lifecycle-management + OpenConfirm { channel: IbcChannel }, +} + +/// The message that is passed into `ibc_channel_close` +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] +#[serde(rename_all = "snake_case")] +pub enum IbcChannelCloseMsg { + /// The ChanCloseInit step from https://github.com/cosmos/ibc/tree/master/spec/core/ics-004-channel-and-packet-semantics#channel-lifecycle-management + CloseInit { channel: IbcChannel }, + /// The ChanCloseConfirm step from https://github.com/cosmos/ibc/tree/master/spec/core/ics-004-channel-and-packet-semantics#channel-lifecycle-management + CloseConfirm { channel: IbcChannel }, // pub channel: IbcChannel, +} + +/// The message that is passed into `ibc_packet_receive` +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] +pub struct IbcPacketReceiveMsg { + pub packet: IbcPacket, + pub relayer: Addr, +} + +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] +pub struct IbcPacket { + /// The raw data sent from the other side in the packet + pub data: Binary, + /// identifies the channel and port on the sending chain. + pub src: IbcEndpoint, + /// identifies the channel and port on the receiving chain. + pub dest: IbcEndpoint, + /// The sequence number of the packet on the given channel + pub sequence: u64, + pub timeout: IbcTimeout, +} + +/// In IBC each package must set at least one type of timeout: +/// the timestamp or the block height. Using this rather complex enum instead of +/// two timeout fields we ensure that at least one timeout is set. +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] +#[serde(rename_all = "snake_case")] +pub struct IbcTimeout { + // use private fields to enforce the use of constructors, which ensure that at least one is set + block: Option, + timestamp: Option, +} + +/// IBCTimeoutHeight Height is a monotonically increasing data type +/// that can be compared against another Height for the purposes of updating and +/// freezing clients. +/// Ordering is (revision_number, timeout_height) +#[derive(Serialize, Deserialize, Copy, Clone, Debug, PartialEq, Eq)] +pub struct IbcTimeoutBlock { + /// the version that the client is currently on + /// (eg. after reseting the chain this could increment 1 as height drops to 0) + pub revision: u64, + /// block height after which the packet times out. + /// the height within the given revision + pub height: u64, +} + +/// The message that is passed into `ibc_packet_ack` +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] +pub struct IbcPacketAckMsg { + pub acknowledgement: IbcAcknowledgement, + pub original_packet: IbcPacket, + pub relayer: Addr, +} diff --git a/cosmwasm/enclaves/shared/cosmwasm-v1-types/src/lib.rs b/cosmwasm/enclaves/shared/cosmwasm-v1-types/src/lib.rs index 310434644..62f52dc66 100644 --- a/cosmwasm/enclaves/shared/cosmwasm-v1-types/src/lib.rs +++ b/cosmwasm/enclaves/shared/cosmwasm-v1-types/src/lib.rs @@ -2,6 +2,7 @@ pub mod addresses; pub mod coins; pub mod errors; +pub mod ibc; pub mod math; pub mod results; pub mod timestamp; diff --git a/x/compute/internal/keeper/testdata/v1-sanity-contract/src/msg.rs b/x/compute/internal/keeper/testdata/v1-sanity-contract/src/msg.rs index 2e8fc7f76..3198ffab5 100644 --- a/x/compute/internal/keeper/testdata/v1-sanity-contract/src/msg.rs +++ b/x/compute/internal/keeper/testdata/v1-sanity-contract/src/msg.rs @@ -88,6 +88,12 @@ pub enum ExecuteMsg { SubMsgLoopIner { iter: u64, }, + SentFunds { +to_type: "init"/"exec" +to_contract: "secret1.." +to_contract_hash: "ABC" +funds + }, MultipleSubMessages {}, MultipleSubMessagesNoReply {}, From 88827c0115e19b08c105e0d9fab4dd060385fcd2 Mon Sep 17 00:00:00 2001 From: Assaf Morami Date: Thu, 14 Jul 2022 16:14:09 +0300 Subject: [PATCH 11/93] WIP: Start to implement IBC receive hooks Here specifically is ibc-open-channel --- go-cosmwasm/types/types.go | 6 + x/compute/internal/keeper/keeper.go | 11 +- x/compute/internal/keeper/relay.go | 241 ++++++++++++++++++++++++++++ x/compute/internal/types/errors.go | 3 - 4 files changed, 253 insertions(+), 8 deletions(-) create mode 100644 x/compute/internal/keeper/relay.go diff --git a/go-cosmwasm/types/types.go b/go-cosmwasm/types/types.go index 9c8713186..83d166bb4 100644 --- a/go-cosmwasm/types/types.go +++ b/go-cosmwasm/types/types.go @@ -72,6 +72,12 @@ type HandleType int const ( HandleTypeExecute HandleType = iota HandleTypeReply + HandleTypeIbcChannelOpen + HandleTypeIbcChannelConnect + HandleTypeIbcChannelClose + HandleTypeIbcPacketReceive + HandleTypeIbcPacketAck + HandleTypeIbcPacketTimeout ) type CosmosMsgVersion int diff --git a/x/compute/internal/keeper/keeper.go b/x/compute/internal/keeper/keeper.go index 808d18abd..e763a8033 100644 --- a/x/compute/internal/keeper/keeper.go +++ b/x/compute/internal/keeper/keeper.go @@ -440,6 +440,7 @@ func (k Keeper) Instantiate(ctx sdk.Context, codeID uint64, creator sdk.AccAddre gas := gasForContract(ctx) response, key, gasUsed, err := k.wasmer.Instantiate(codeInfo.CodeHash, env, initMsg, prefixStore, cosmwasmAPI, querier, ctx.GasMeter(), gas, verificationInfo, contractAddress) consumeGas(ctx, gasUsed) + if err != nil { switch res := response.(type) { case v1wasmTypes.DataWithInternalReplyInfo: @@ -659,7 +660,7 @@ func (k Keeper) querySmartImpl(ctx sdk.Context, contractAddr sdk.AccAddress, req params := types.NewEnv( ctx, sdk.AccAddress{}, /* empty because it's unused in queries */ - []sdk.Coin{}, /* empty because it's unused in queries */ + sdk.NewCoins(), /* empty because it's unused in queries */ contractAddr, contractKey, ) @@ -1088,12 +1089,12 @@ func (k Keeper) reply(ctx sdk.Context, contractAddress sdk.AccAddress, reply v1w consumeGas(ctx, gasUsed) if execErr != nil { - return nil, sdkerrors.Wrap(types.ErrReplyFailed, execErr.Error()) + return nil, sdkerrors.Wrap(types.ErrExecuteFailed, execErr.Error()) } switch res := response.(type) { case *v010wasmTypes.HandleResponse: - return nil, sdkerrors.Wrap(types.ErrReplyFailed, fmt.Sprintf("response of reply should always be a CosmWasm v1 response type: %+v", res)) + return nil, sdkerrors.Wrap(types.ErrExecuteFailed, fmt.Sprintf("response of reply should always be a CosmWasm v1 response type: %+v", res)) case *v1wasmTypes.Response: ctx.EventManager().EmitEvent(sdk.NewEvent( types.EventTypeReply, @@ -1102,11 +1103,11 @@ func (k Keeper) reply(ctx sdk.Context, contractAddress sdk.AccAddress, reply v1w data, err := k.handleContractResponse(ctx, contractAddress, contractInfo.IBCPortID, res.Messages, res.Attributes, res.Events, res.Data, ogTx, ogSigInfo, wasmTypes.CosmosMsgVersionV1) if err != nil { - return nil, sdkerrors.Wrap(types.ErrReplyFailed, err.Error()) + return nil, sdkerrors.Wrap(types.ErrExecuteFailed, err.Error()) } return data, nil default: - return nil, sdkerrors.Wrap(types.ErrReplyFailed, fmt.Sprintf("cannot detect response type: %+v", res)) + return nil, sdkerrors.Wrap(types.ErrExecuteFailed, fmt.Sprintf("cannot detect response type: %+v", res)) } } diff --git a/x/compute/internal/keeper/relay.go b/x/compute/internal/keeper/relay.go new file mode 100644 index 000000000..587f5a14b --- /dev/null +++ b/x/compute/internal/keeper/relay.go @@ -0,0 +1,241 @@ +package keeper + +import ( + "encoding/json" + "time" + + "github.com/cosmos/cosmos-sdk/telemetry" + sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + sdktxsigning "github.com/cosmos/cosmos-sdk/types/tx/signing" + wasmTypes "github.com/enigmampc/SecretNetwork/go-cosmwasm/types" + v1types "github.com/enigmampc/SecretNetwork/go-cosmwasm/types/v1" + + "github.com/enigmampc/SecretNetwork/x/compute/internal/types" +) + +var _ types.IBCContractKeeper = (*Keeper)(nil) + +// OnOpenChannel calls the contract to participate in the IBC channel handshake step. +// In the IBC protocol this is either the `Channel Open Init` event on the initiating chain or +// `Channel Open Try` on the counterparty chain. +// Protocol version and channel ordering should be verified for example. +// See https://github.com/cosmos/ics/tree/master/spec/ics-004-channel-and-packet-semantics#channel-lifecycle-management +func (k Keeper) OnOpenChannel( + ctx sdk.Context, + contractAddress sdk.AccAddress, + msg v1types.IBCChannelOpenMsg, +) (string, error) { + defer telemetry.MeasureSince(time.Now(), "compute", "keeper", "ibc-open-channel") + version := "" + + ctx.GasMeter().ConsumeGas(types.InstanceCost, "Loading Compute module: ibc-open-channel") + + verificationInfo := types.NewVerificationInfo([]byte{}, sdktxsigning.SignMode_SIGN_MODE_UNSPECIFIED, []byte{}, []byte{}, []byte{}, nil) + + _, codeInfo, prefixStore, err := k.contractInstance(ctx, contractAddress) + if err != nil { + return "", err + } + + store := ctx.KVStore(k.storeKey) + + contractKey := store.Get(types.GetContractEnclaveKey(contractAddress)) + env := types.NewEnv( + ctx, + sdk.AccAddress{}, /* empty because it's unused in queries */ + sdk.NewCoins(), /* empty because it's unused in queries */ + contractAddress, + contractKey, + ) + + // prepare querier + querier := QueryHandler{ + Ctx: ctx, + Plugins: k.queryPlugins, + } + + msgBz, err := json.Marshal(msg) + if err != nil { + return "", sdkerrors.Wrap(err, "ibc-open-channel") + } + + gas := gasForContract(ctx) + res, gasUsed, err := k.wasmer.Execute(codeInfo.CodeHash, env, msgBz, prefixStore, cosmwasmAPI, querier, ctx.GasMeter(), gas, verificationInfo, wasmTypes.HandleTypeReply) + consumeGas(ctx, gasUsed) + + if err != nil { + return "", sdkerrors.Wrap(types.ErrExecuteFailed, err.Error()) + } + + ///////// + res, gasUsed, execErr := k.wasmVM.IBCChannelOpen(codeInfo.CodeHash, env, msg, prefixStore, cosmwasmAPI, querier, ctx.GasMeter(), gas, costJSONDeserialization) + + if execErr != nil { + return "", sdkerrors.Wrap(types.ErrExecuteFailed, execErr.Error()) + } + + if res != nil { + version = res.Version + } + + return version, nil +} + +// OnConnectChannel calls the contract to let it know the IBC channel was established. +// In the IBC protocol this is either the `Channel Open Ack` event on the initiating chain or +// `Channel Open Confirm` on the counterparty chain. +// +// There is an open issue with the [cosmos-sdk](https://github.com/cosmos/cosmos-sdk/issues/8334) +// that the counterparty channelID is empty on the initiating chain +// See https://github.com/cosmos/ics/tree/master/spec/ics-004-channel-and-packet-semantics#channel-lifecycle-management +func (k Keeper) OnConnectChannel( + ctx sdk.Context, + contractAddr sdk.AccAddress, + msg v1types.IBCChannelConnectMsg, +) error { + defer telemetry.MeasureSince(time.Now(), "compute", "keeper", "ibc-connect-channel") + contractInfo, codeInfo, prefixStore, err := k.contractInstance(ctx, contractAddr) + if err != nil { + return err + } + + env := types.NewEnv(ctx, contractAddr) + querier := k.newQueryHandler(ctx, contractAddr) + + gas := k.runtimeGasForContract(ctx) + res, gasUsed, execErr := k.wasmVM.IBCChannelConnect(codeInfo.CodeHash, env, msg, prefixStore, cosmwasmAPI, querier, ctx.GasMeter(), gas, costJSONDeserialization) + k.consumeRuntimeGas(ctx, gasUsed) + if execErr != nil { + return sdkerrors.Wrap(types.ErrExecuteFailed, execErr.Error()) + } + + return k.handleIBCBasicContractResponse(ctx, contractAddr, contractInfo.IBCPortID, res) +} + +// OnCloseChannel calls the contract to let it know the IBC channel is closed. +// Calling modules MAY atomically execute appropriate application logic in conjunction with calling chanCloseConfirm. +// +// Once closed, channels cannot be reopened and identifiers cannot be reused. Identifier reuse is prevented because +// we want to prevent potential replay of previously sent packets +// See https://github.com/cosmos/ics/tree/master/spec/ics-004-channel-and-packet-semantics#channel-lifecycle-management +func (k Keeper) OnCloseChannel( + ctx sdk.Context, + contractAddr sdk.AccAddress, + msg v1types.IBCChannelCloseMsg, +) error { + defer telemetry.MeasureSince(time.Now(), "compute", "keeper", "ibc-close-channel") + + contractInfo, codeInfo, prefixStore, err := k.contractInstance(ctx, contractAddr) + if err != nil { + return err + } + + params := types.NewEnv(ctx, contractAddr) + querier := k.newQueryHandler(ctx, contractAddr) + + gas := k.runtimeGasForContract(ctx) + res, gasUsed, execErr := k.wasmVM.IBCChannelClose(codeInfo.CodeHash, params, msg, prefixStore, cosmwasmAPI, querier, ctx.GasMeter(), gas, costJSONDeserialization) + k.consumeRuntimeGas(ctx, gasUsed) + if execErr != nil { + return sdkerrors.Wrap(types.ErrExecuteFailed, execErr.Error()) + } + + return k.handleIBCBasicContractResponse(ctx, contractAddr, contractInfo.IBCPortID, res) +} + +// OnRecvPacket calls the contract to process the incoming IBC packet. The contract fully owns the data processing and +// returns the acknowledgement data for the chain level. This allows custom applications and protocols on top +// of IBC. Although it is recommended to use the standard acknowledgement envelope defined in +// https://github.com/cosmos/ics/tree/master/spec/ics-004-channel-and-packet-semantics#acknowledgement-envelope +// +// For more information see: https://github.com/cosmos/ics/tree/master/spec/ics-004-channel-and-packet-semantics#packet-flow--handling +func (k Keeper) OnRecvPacket( + ctx sdk.Context, + contractAddr sdk.AccAddress, + msg v1types.IBCPacketReceiveMsg, +) ([]byte, error) { + defer telemetry.MeasureSince(time.Now(), "compute", "keeper", "ibc-recv-packet") + contractInfo, codeInfo, prefixStore, err := k.contractInstance(ctx, contractAddr) + if err != nil { + return nil, err + } + + env := types.NewEnv(ctx, contractAddr) + querier := k.newQueryHandler(ctx, contractAddr) + + gas := k.runtimeGasForContract(ctx) + res, gasUsed, execErr := k.wasmVM.IBCPacketReceive(codeInfo.CodeHash, env, msg, prefixStore, cosmwasmAPI, querier, ctx.GasMeter(), gas, costJSONDeserialization) + k.consumeRuntimeGas(ctx, gasUsed) + if execErr != nil { + return nil, sdkerrors.Wrap(types.ErrExecuteFailed, execErr.Error()) + } + if res.Err != "" { // handle error case as before https://github.com/CosmWasm/wasmvm/commit/c300106fe5c9426a495f8e10821e00a9330c56c6 + return nil, sdkerrors.Wrap(types.ErrExecuteFailed, res.Err) + } + // note submessage reply results can overwrite the `Acknowledgement` data + return k.handleContractResponse(ctx, contractAddr, contractInfo.IBCPortID, res.Ok.Messages, res.Ok.Attributes, res.Ok.Acknowledgement, res.Ok.Events) +} + +// OnAckPacket calls the contract to handle the "acknowledgement" data which can contain success or failure of a packet +// acknowledgement written on the receiving chain for example. This is application level data and fully owned by the +// contract. The use of the standard acknowledgement envelope is recommended: https://github.com/cosmos/ics/tree/master/spec/ics-004-channel-and-packet-semantics#acknowledgement-envelope +// +// On application errors the contract can revert an operation like returning tokens as in ibc-transfer. +// +// For more information see: https://github.com/cosmos/ics/tree/master/spec/ics-004-channel-and-packet-semantics#packet-flow--handling +func (k Keeper) OnAckPacket( + ctx sdk.Context, + contractAddr sdk.AccAddress, + msg v1types.IBCPacketAckMsg, +) error { + defer telemetry.MeasureSince(time.Now(), "compute", "keeper", "ibc-ack-packet") + contractInfo, codeInfo, prefixStore, err := k.contractInstance(ctx, contractAddr) + if err != nil { + return err + } + + env := types.NewEnv(ctx, contractAddr) + querier := k.newQueryHandler(ctx, contractAddr) + + gas := k.runtimeGasForContract(ctx) + res, gasUsed, execErr := k.wasmVM.IBCPacketAck(codeInfo.CodeHash, env, msg, prefixStore, cosmwasmAPI, querier, ctx.GasMeter(), gas, costJSONDeserialization) + k.consumeRuntimeGas(ctx, gasUsed) + if execErr != nil { + return sdkerrors.Wrap(types.ErrExecuteFailed, execErr.Error()) + } + return k.handleIBCBasicContractResponse(ctx, contractAddr, contractInfo.IBCPortID, res) +} + +// OnTimeoutPacket calls the contract to let it know the packet was never received on the destination chain within +// the timeout boundaries. +// The contract should handle this on the application level and undo the original operation +func (k Keeper) OnTimeoutPacket( + ctx sdk.Context, + contractAddr sdk.AccAddress, + msg v1types.IBCPacketTimeoutMsg, +) error { + defer telemetry.MeasureSince(time.Now(), "compute", "keeper", "ibc-timeout-packet") + + contractInfo, codeInfo, prefixStore, err := k.contractInstance(ctx, contractAddr) + if err != nil { + return err + } + + env := types.NewEnv(ctx, contractAddr) + querier := k.newQueryHandler(ctx, contractAddr) + + gas := k.runtimeGasForContract(ctx) + res, gasUsed, execErr := k.wasmVM.IBCPacketTimeout(codeInfo.CodeHash, env, msg, prefixStore, cosmwasmAPI, querier, ctx.GasMeter(), gas, costJSONDeserialization) + k.consumeRuntimeGas(ctx, gasUsed) + if execErr != nil { + return sdkerrors.Wrap(types.ErrExecuteFailed, execErr.Error()) + } + + return k.handleIBCBasicContractResponse(ctx, contractAddr, contractInfo.IBCPortID, res) +} + +func (k Keeper) handleIBCBasicContractResponse(ctx sdk.Context, addr sdk.AccAddress, id string, res *v1types.IBCBasicResponse) error { + _, err := k.handleContractResponse(ctx, addr, id, res.Messages, res.Attributes, nil, res.Events) + return err +} diff --git a/x/compute/internal/types/errors.go b/x/compute/internal/types/errors.go index 7c7dfff50..1cd214613 100644 --- a/x/compute/internal/types/errors.go +++ b/x/compute/internal/types/errors.go @@ -64,9 +64,6 @@ var ( // ErrUnknownMsg error by a message handler to show that it is not responsible for this message type ErrUnknownMsg = sdkErrors.Register(DefaultCodespace, 18, "unknown message from the contract") - // ErrReplyFailed error for rust execution contract failure - ErrReplyFailed = sdkErrors.Register(DefaultCodespace, 19, "reply to contract failed") - // ErrInvalidEvent error if an attribute/event from the contract is invalid ErrInvalidEvent = sdkErrors.Register(DefaultCodespace, 21, "invalid event") ) From eb9f61759f638a04d82c52aa32df6eddfb73d529 Mon Sep 17 00:00:00 2001 From: Assaf Morami Date: Tue, 19 Jul 2022 15:17:59 +0300 Subject: [PATCH 12/93] CosmWasm v1 IBC OnOpenChannel --- go-cosmwasm/lib.go | 58 +++++++++++--------- go-cosmwasm/types/v1/ibc.go | 30 ++++++---- x/compute/internal/keeper/relay.go | 22 ++++---- x/compute/internal/types/exported_keepers.go | 46 ++++++++++++++++ 4 files changed, 107 insertions(+), 49 deletions(-) create mode 100644 x/compute/internal/types/exported_keepers.go diff --git a/go-cosmwasm/lib.go b/go-cosmwasm/lib.go index a6f14b5fd..9ce15c57c 100644 --- a/go-cosmwasm/lib.go +++ b/go-cosmwasm/lib.go @@ -85,11 +85,17 @@ func (w *Wasmer) GetCode(code CodeID) (WasmCode, error) { } // This struct helps us to distinguish between v0.10 contract response and v1 contract response -type V010orV1ContractExecResponse struct { - V1 *V1ContractExecResponse `json:"v1,omitempty"` - V010 *V010ContractExecResponse `json:"v010,omitempty"` - InternaReplyEnclaveSig []byte `json:"internal_reply_enclave_sig"` - InternalMsgId []byte `json:"internal_msg_id"` +type ContractExecResponse struct { + V1 *V1ContractExecResponse `json:"v1,omitempty"` + V010 *V010ContractExecResponse `json:"v010,omitempty"` + InternaReplyEnclaveSig []byte `json:"internal_reply_enclave_sig"` + InternalMsgId []byte `json:"internal_msg_id"` + IBCChannelOpen *v1types.IBCChannelOpenResult `json:"ibc_channel_open,omitempty"` + IBCChannelConnect *v1types.IBCBasicResponse `json:"ibc_channel_connect,omitempty"` + IBCChannelClose *v1types.IBCBasicResponse `json:"ibc_channel_close,omitempty"` + IBCPacketReceive *v1types.IBCReceiveResult `json:"ibc_packet_receive,omitempty"` + IBCPacketAck *v1types.IBCBasicResponse `json:"ibc_packet_ack,omitempty"` + IBCPacketTimeout *v1types.IBCBasicResponse `json:"ibc_packet_timeout,omitempty"` } type V010ContractExecResponse struct { @@ -260,55 +266,55 @@ func (w *Wasmer) Execute( return nil, gasUsed, err } - var respV010orV1 V010orV1ContractExecResponse - err = json.Unmarshal(data, &respV010orV1) + var resp ContractExecResponse + err = json.Unmarshal(data, &resp) if err != nil { // unidentified response 🤷 return nil, gasUsed, fmt.Errorf("handle: cannot parse response from json: %w", err) } - isOutputAddressedToReply := (len(respV010orV1.InternaReplyEnclaveSig) > 0 && len(respV010orV1.InternalMsgId) > 0) + isOutputAddressedToReply := (len(resp.InternaReplyEnclaveSig) > 0 && len(resp.InternalMsgId) > 0) // handle v0.10 response - if respV010orV1.V010 != nil { - if respV010orV1.V010.Err != nil { + if resp.V010 != nil { + if resp.V010.Err != nil { return v1types.DataWithInternalReplyInfo{ - InternalMsgId: respV010orV1.InternalMsgId, - InternaReplyEnclaveSig: respV010orV1.InternaReplyEnclaveSig, - Data: []byte(respV010orV1.V010.Err.GenericErr.Msg), - }, gasUsed, fmt.Errorf("%+v", respV010orV1.V010.Err) + InternalMsgId: resp.InternalMsgId, + InternaReplyEnclaveSig: resp.InternaReplyEnclaveSig, + Data: []byte(resp.V010.Err.GenericErr.Msg), + }, gasUsed, fmt.Errorf("%+v", resp.V010.Err) } - if respV010orV1.V010.Ok != nil { + if resp.V010.Ok != nil { if isOutputAddressedToReply { - respV010orV1.V010.Ok.Data, err = AppendReplyInternalDataToData(respV010orV1.V010.Ok.Data, respV010orV1.InternaReplyEnclaveSig, respV010orV1.InternalMsgId) + resp.V010.Ok.Data, err = AppendReplyInternalDataToData(resp.V010.Ok.Data, resp.InternaReplyEnclaveSig, resp.InternalMsgId) if err != nil { return nil, gasUsed, fmt.Errorf("cannot serialize v010 DataWithInternalReplyInfo into binary : %w", err) } } - return respV010orV1.V010.Ok, gasUsed, nil + return resp.V010.Ok, gasUsed, nil } } // handle v1 response - if respV010orV1.V1 != nil { - if respV010orV1.V1.Err != nil { + if resp.V1 != nil { + if resp.V1.Err != nil { return v1types.DataWithInternalReplyInfo{ - InternalMsgId: respV010orV1.InternalMsgId, - InternaReplyEnclaveSig: respV010orV1.InternaReplyEnclaveSig, - Data: []byte(respV010orV1.V1.Err.GenericErr.Msg), - }, gasUsed, fmt.Errorf("%+v", respV010orV1.V1.Err) + InternalMsgId: resp.InternalMsgId, + InternaReplyEnclaveSig: resp.InternaReplyEnclaveSig, + Data: []byte(resp.V1.Err.GenericErr.Msg), + }, gasUsed, fmt.Errorf("%+v", resp.V1.Err) } - if respV010orV1.V1.Ok != nil { + if resp.V1.Ok != nil { if isOutputAddressedToReply { - respV010orV1.V1.Ok.Data, err = AppendReplyInternalDataToData(respV010orV1.V1.Ok.Data, respV010orV1.InternaReplyEnclaveSig, respV010orV1.InternalMsgId) + resp.V1.Ok.Data, err = AppendReplyInternalDataToData(resp.V1.Ok.Data, resp.InternaReplyEnclaveSig, resp.InternalMsgId) if err != nil { return nil, gasUsed, fmt.Errorf("cannot serialize v1 DataWithInternalReplyInfo into binary : %w", err) } } - return respV010orV1.V1.Ok, gasUsed, nil + return resp.V1.Ok, gasUsed, nil } } diff --git a/go-cosmwasm/types/v1/ibc.go b/go-cosmwasm/types/v1/ibc.go index 87b60a361..1d5d994fb 100644 --- a/go-cosmwasm/types/v1/ibc.go +++ b/go-cosmwasm/types/v1/ibc.go @@ -1,8 +1,6 @@ package v1types -import ( - abci "github.com/tendermint/tendermint/abci/types" -) +import v010msgtypes "github.com/enigmampc/SecretNetwork/go-cosmwasm/types/v010" type IBCEndpoint struct { PortID string `json:"port_id"` @@ -137,16 +135,19 @@ func (m *IBCCloseConfirm) ToMsg() IBCChannelCloseMsg { } type IBCPacketReceiveMsg struct { - Packet IBCPacket `json:"packet"` + Packet IBCPacket `json:"packet"` + Relayer string `json:"relayer"` } type IBCPacketAckMsg struct { Acknowledgement IBCAcknowledgement `json:"acknowledgement"` OriginalPacket IBCPacket `json:"original_packet"` + Relayer string `json:"relayer"` } type IBCPacketTimeoutMsg struct { - Packet IBCPacket `json:"packet"` + Packet IBCPacket `json:"packet"` + Relayer string `json:"relayer"` } // TODO: test what the sdk Order.String() represents and how to parse back @@ -196,10 +197,17 @@ type IBCPacket struct { // IBCChannelOpenResult is the raw response from the ibc_channel_open call. // This is mirrors Rust's ContractResult<()>. -// We just check if Err == "" to see if this is success (no other data on success) +// Check if Err == "" to see if this is success +// On Success, IBCV3ChannelOpenResponse *may* be set if the contract is ibcv3 compatible and wishes to +// define a custom version in the handshake. type IBCChannelOpenResult struct { - Ok *struct{} `json:"ok,omitempty"` - Err string `json:"error,omitempty"` + Ok *IBC3ChannelOpenResponse `json:"ok,omitempty"` + Err string `json:"error,omitempty"` +} + +// IBC3ChannelOpenResponse is version negotiation data for the handshake +type IBC3ChannelOpenResponse struct { + Version string `json:"version"` } // This is the return value for the majority of the ibc handlers. @@ -223,7 +231,7 @@ type IBCBasicResponse struct { // "fire and forget". Messages []SubMsg `json:"messages"` // attributes for a log event to return over abci interface - Attributes []abci.EventAttribute `json:"attributes"` + Attributes []v010msgtypes.LogAttribute `json:"attributes"` // custom events (separate from the main one that contains the attributes // above) Events []Event `json:"events"` @@ -254,8 +262,8 @@ type IBCReceiveResponse struct { // If the ReplyOn value matches the result, the runtime will invoke this // contract's `reply` entry point after execution. Otherwise, this is all // "fire and forget". - Messages []SubMsg `json:"messages"` - Attributes []abci.EventAttribute `json:"attributes"` + Messages []SubMsg `json:"messages"` + Attributes []v010msgtypes.LogAttribute `json:"attributes"` // custom events (separate from the main one that contains the attributes // above) Events []Event `json:"events"` diff --git a/x/compute/internal/keeper/relay.go b/x/compute/internal/keeper/relay.go index 587f5a14b..d21e76661 100644 --- a/x/compute/internal/keeper/relay.go +++ b/x/compute/internal/keeper/relay.go @@ -2,6 +2,7 @@ package keeper import ( "encoding/json" + "fmt" "time" "github.com/cosmos/cosmos-sdk/telemetry" @@ -27,7 +28,6 @@ func (k Keeper) OnOpenChannel( msg v1types.IBCChannelOpenMsg, ) (string, error) { defer telemetry.MeasureSince(time.Now(), "compute", "keeper", "ibc-open-channel") - version := "" ctx.GasMeter().ConsumeGas(types.InstanceCost, "Loading Compute module: ibc-open-channel") @@ -68,18 +68,16 @@ func (k Keeper) OnOpenChannel( return "", sdkerrors.Wrap(types.ErrExecuteFailed, err.Error()) } - ///////// - res, gasUsed, execErr := k.wasmVM.IBCChannelOpen(codeInfo.CodeHash, env, msg, prefixStore, cosmwasmAPI, querier, ctx.GasMeter(), gas, costJSONDeserialization) - - if execErr != nil { - return "", sdkerrors.Wrap(types.ErrExecuteFailed, execErr.Error()) + switch resp := res.(type) { + case *v1types.IBC3ChannelOpenResponse: + if resp != nil { + return resp.Version, nil + } else { + return "", nil + } + default: + return "", sdkerrors.Wrap(types.ErrExecuteFailed, fmt.Sprintf("cannot cast res to IBC3ChannelOpenResponse: %+v", res)) } - - if res != nil { - version = res.Version - } - - return version, nil } // OnConnectChannel calls the contract to let it know the IBC channel was established. diff --git a/x/compute/internal/types/exported_keepers.go b/x/compute/internal/types/exported_keepers.go new file mode 100644 index 000000000..477f668e7 --- /dev/null +++ b/x/compute/internal/types/exported_keepers.go @@ -0,0 +1,46 @@ +package types + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" + capabilitytypes "github.com/cosmos/cosmos-sdk/x/capability/types" + v1types "github.com/enigmampc/SecretNetwork/go-cosmwasm/types/v1" +) + +// IBCContractKeeper IBC lifecycle event handler +type IBCContractKeeper interface { + OnOpenChannel( + ctx sdk.Context, + contractAddr sdk.AccAddress, + msg v1types.IBCChannelOpenMsg, + ) (string, error) + OnConnectChannel( + ctx sdk.Context, + contractAddr sdk.AccAddress, + msg v1types.IBCChannelConnectMsg, + ) error + OnCloseChannel( + ctx sdk.Context, + contractAddr sdk.AccAddress, + msg v1types.IBCChannelCloseMsg, + ) error + OnRecvPacket( + ctx sdk.Context, + contractAddr sdk.AccAddress, + msg v1types.IBCPacketReceiveMsg, + ) ([]byte, error) + OnAckPacket( + ctx sdk.Context, + contractAddr sdk.AccAddress, + acknowledgement v1types.IBCPacketAckMsg, + ) error + OnTimeoutPacket( + ctx sdk.Context, + contractAddr sdk.AccAddress, + msg v1types.IBCPacketTimeoutMsg, + ) error + // ClaimCapability allows the transfer module to claim a capability + // that IBC module passes to it + ClaimCapability(ctx sdk.Context, cap *capabilitytypes.Capability, name string) error + // AuthenticateCapability wraps the scopedKeeper's AuthenticateCapability function + AuthenticateCapability(ctx sdk.Context, cap *capabilitytypes.Capability, name string) bool +} From a3e703ae40ed049d12814d5420c47463e034eeb1 Mon Sep 17 00:00:00 2001 From: Assaf Morami Date: Mon, 25 Jul 2022 12:54:49 +0300 Subject: [PATCH 13/93] Parse IBC results in go-cosmwasm --- go-cosmwasm/lib.go | 88 ++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 77 insertions(+), 11 deletions(-) diff --git a/go-cosmwasm/lib.go b/go-cosmwasm/lib.go index 9ce15c57c..e9d600ff0 100644 --- a/go-cosmwasm/lib.go +++ b/go-cosmwasm/lib.go @@ -91,11 +91,11 @@ type ContractExecResponse struct { InternaReplyEnclaveSig []byte `json:"internal_reply_enclave_sig"` InternalMsgId []byte `json:"internal_msg_id"` IBCChannelOpen *v1types.IBCChannelOpenResult `json:"ibc_channel_open,omitempty"` - IBCChannelConnect *v1types.IBCBasicResponse `json:"ibc_channel_connect,omitempty"` - IBCChannelClose *v1types.IBCBasicResponse `json:"ibc_channel_close,omitempty"` + IBCChannelConnect *v1types.IBCBasicResult `json:"ibc_channel_connect,omitempty"` + IBCChannelClose *v1types.IBCBasicResult `json:"ibc_channel_close,omitempty"` IBCPacketReceive *v1types.IBCReceiveResult `json:"ibc_packet_receive,omitempty"` - IBCPacketAck *v1types.IBCBasicResponse `json:"ibc_packet_ack,omitempty"` - IBCPacketTimeout *v1types.IBCBasicResponse `json:"ibc_packet_timeout,omitempty"` + IBCPacketAck *v1types.IBCBasicResult `json:"ibc_packet_ack,omitempty"` + IBCPacketTimeout *v1types.IBCBasicResult `json:"ibc_packet_timeout,omitempty"` } type V010ContractExecResponse struct { @@ -284,16 +284,16 @@ func (w *Wasmer) Execute( InternaReplyEnclaveSig: resp.InternaReplyEnclaveSig, Data: []byte(resp.V010.Err.GenericErr.Msg), }, gasUsed, fmt.Errorf("%+v", resp.V010.Err) - } - - if resp.V010.Ok != nil { + } else if resp.V010.Ok != nil { if isOutputAddressedToReply { resp.V010.Ok.Data, err = AppendReplyInternalDataToData(resp.V010.Ok.Data, resp.InternaReplyEnclaveSig, resp.InternalMsgId) if err != nil { - return nil, gasUsed, fmt.Errorf("cannot serialize v010 DataWithInternalReplyInfo into binary : %w", err) + return nil, gasUsed, fmt.Errorf("cannot serialize v0.10 DataWithInternalReplyInfo into binary : %w", err) } } return resp.V010.Ok, gasUsed, nil + } else { + return nil, gasUsed, fmt.Errorf("cannot parse v0.10 handle response: %+v", resp) } } @@ -305,9 +305,7 @@ func (w *Wasmer) Execute( InternaReplyEnclaveSig: resp.InternaReplyEnclaveSig, Data: []byte(resp.V1.Err.GenericErr.Msg), }, gasUsed, fmt.Errorf("%+v", resp.V1.Err) - } - - if resp.V1.Ok != nil { + } else if resp.V1.Ok != nil { if isOutputAddressedToReply { resp.V1.Ok.Data, err = AppendReplyInternalDataToData(resp.V1.Ok.Data, resp.InternaReplyEnclaveSig, resp.InternalMsgId) if err != nil { @@ -315,6 +313,74 @@ func (w *Wasmer) Execute( } } return resp.V1.Ok, gasUsed, nil + } else { + return nil, gasUsed, fmt.Errorf("cannot parse v1 handle response: %+v", resp) + } + } + + // handle IBCChannelOpen response + if resp.IBCChannelOpen != nil { + if resp.IBCChannelOpen.Err != "" { + return nil, gasUsed, fmt.Errorf("%s", resp.IBCChannelOpen.Err) + } else if resp.IBCChannelOpen.Ok != nil { + return resp.IBCChannelOpen.Ok, gasUsed, nil + } else { + return nil, gasUsed, fmt.Errorf("cannot parse IBCChannelOpen response: %+v", resp) + } + } + + // handle IBCChannelConnect response + if resp.IBCChannelConnect != nil { + if resp.IBCChannelConnect.Err != "" { + return nil, gasUsed, fmt.Errorf("%s", resp.IBCChannelConnect.Err) + } else if resp.IBCChannelConnect.Ok != nil { + return resp.IBCChannelConnect.Ok, gasUsed, nil + } else { + return nil, gasUsed, fmt.Errorf("cannot parse IBCChannelConnect response: %+v", resp) + } + } + + // handle IBCChannelClose response + if resp.IBCChannelClose != nil { + if resp.IBCChannelClose.Err != "" { + return nil, gasUsed, fmt.Errorf("%s", resp.IBCChannelClose.Err) + } else if resp.IBCChannelClose.Ok != nil { + return resp.IBCChannelClose.Ok, gasUsed, nil + } else { + return nil, gasUsed, fmt.Errorf("cannot parse IBCChannelClose response: %+v", resp) + } + } + + // handle IBCPacketReceive response + if resp.IBCPacketReceive != nil { + if resp.IBCPacketReceive.Err != "" { + return nil, gasUsed, fmt.Errorf("%s", resp.IBCPacketReceive.Err) + } else if resp.IBCPacketReceive.Ok != nil { + return resp.IBCPacketReceive.Ok, gasUsed, nil + } else { + return nil, gasUsed, fmt.Errorf("cannot parse IBCPacketReceive response: %+v", resp) + } + } + + // handle IBCPacketAck response + if resp.IBCPacketAck != nil { + if resp.IBCPacketAck.Err != "" { + return nil, gasUsed, fmt.Errorf("%s", resp.IBCPacketAck.Err) + } else if resp.IBCPacketAck.Ok != nil { + return resp.IBCPacketAck.Ok, gasUsed, nil + } else { + return nil, gasUsed, fmt.Errorf("cannot parse IBCPacketAck response: %+v", resp) + } + } + + // handle IBCPacketTimeout response + if resp.IBCPacketTimeout != nil { + if resp.IBCPacketTimeout.Err != "" { + return nil, gasUsed, fmt.Errorf("%s", resp.IBCPacketTimeout.Err) + } else if resp.IBCPacketTimeout.Ok != nil { + return resp.IBCPacketTimeout.Ok, gasUsed, nil + } else { + return nil, gasUsed, fmt.Errorf("cannot parse IBCPacketTimeout response: %+v", resp) } } From 7929c348a817af5cae1ae8bce7658c2c1d6c59d6 Mon Sep 17 00:00:00 2001 From: Assaf Morami Date: Mon, 25 Jul 2022 13:19:24 +0300 Subject: [PATCH 14/93] Refactor IBC contract calls, lots of shared code --- x/compute/internal/keeper/ibc.go | 5 ++++ x/compute/internal/keeper/keeper.go | 3 ++ x/compute/internal/keeper/relay.go | 46 +++++++++++++++++------------ 3 files changed, 35 insertions(+), 19 deletions(-) diff --git a/x/compute/internal/keeper/ibc.go b/x/compute/internal/keeper/ibc.go index 8df6fdecc..900927b82 100644 --- a/x/compute/internal/keeper/ibc.go +++ b/x/compute/internal/keeper/ibc.go @@ -37,3 +37,8 @@ func PortIDForContract(addr sdk.AccAddress) string { func (k Keeper) ClaimCapability(ctx sdk.Context, cap *capabilitytypes.Capability, name string) error { return k.capabilityKeeper.ClaimCapability(ctx, cap, name) } + +// AuthenticateCapability wraps the scopedKeeper's AuthenticateCapability function +func (k Keeper) AuthenticateCapability(ctx sdk.Context, cap *capabilitytypes.Capability, name string) bool { + return k.capabilityKeeper.AuthenticateCapability(ctx, cap, name) +} diff --git a/x/compute/internal/keeper/keeper.go b/x/compute/internal/keeper/keeper.go index e763a8033..ae053a22e 100644 --- a/x/compute/internal/keeper/keeper.go +++ b/x/compute/internal/keeper/keeper.go @@ -10,6 +10,7 @@ import ( "time" capabilitykeeper "github.com/cosmos/cosmos-sdk/x/capability/keeper" + capabilitytypes "github.com/cosmos/cosmos-sdk/x/capability/types" channelkeeper "github.com/cosmos/ibc-go/v3/modules/core/04-channel/keeper" portkeeper "github.com/cosmos/ibc-go/v3/modules/core/05-port/keeper" wasmTypes "github.com/enigmampc/SecretNetwork/go-cosmwasm/types" @@ -1111,3 +1112,5 @@ func (k Keeper) reply(ctx sdk.Context, contractAddress sdk.AccAddress, reply v1w return nil, sdkerrors.Wrap(types.ErrExecuteFailed, fmt.Sprintf("cannot detect response type: %+v", res)) } } + + diff --git a/x/compute/internal/keeper/relay.go b/x/compute/internal/keeper/relay.go index d21e76661..b855d3513 100644 --- a/x/compute/internal/keeper/relay.go +++ b/x/compute/internal/keeper/relay.go @@ -17,20 +17,10 @@ import ( var _ types.IBCContractKeeper = (*Keeper)(nil) -// OnOpenChannel calls the contract to participate in the IBC channel handshake step. -// In the IBC protocol this is either the `Channel Open Init` event on the initiating chain or -// `Channel Open Try` on the counterparty chain. -// Protocol version and channel ordering should be verified for example. -// See https://github.com/cosmos/ics/tree/master/spec/ics-004-channel-and-packet-semantics#channel-lifecycle-management -func (k Keeper) OnOpenChannel( - ctx sdk.Context, +func (k Keeper) ibcContractCall(ctx sdk.Context, contractAddress sdk.AccAddress, - msg v1types.IBCChannelOpenMsg, -) (string, error) { - defer telemetry.MeasureSince(time.Now(), "compute", "keeper", "ibc-open-channel") - - ctx.GasMeter().ConsumeGas(types.InstanceCost, "Loading Compute module: ibc-open-channel") - + msgBz []byte, +) (interface{}, error) { verificationInfo := types.NewVerificationInfo([]byte{}, sdktxsigning.SignMode_SIGN_MODE_UNSPECIFIED, []byte{}, []byte{}, []byte{}, nil) _, codeInfo, prefixStore, err := k.contractInstance(ctx, contractAddress) @@ -43,8 +33,8 @@ func (k Keeper) OnOpenChannel( contractKey := store.Get(types.GetContractEnclaveKey(contractAddress)) env := types.NewEnv( ctx, - sdk.AccAddress{}, /* empty because it's unused in queries */ - sdk.NewCoins(), /* empty because it's unused in queries */ + sdk.AccAddress{}, /* there's no MessageInfo for IBC contract calls */ + sdk.NewCoins(), /* there's no MessageInfo for IBC contract calls */ contractAddress, contractKey, ) @@ -55,15 +45,33 @@ func (k Keeper) OnOpenChannel( Plugins: k.queryPlugins, } + gas := gasForContract(ctx) + res, gasUsed, err := k.wasmer.Execute(codeInfo.CodeHash, env, msgBz, prefixStore, cosmwasmAPI, querier, ctx.GasMeter(), gas, verificationInfo, wasmTypes.HandleTypeReply) + consumeGas(ctx, gasUsed) + + return res, err +} + +// OnOpenChannel calls the contract to participate in the IBC channel handshake step. +// In the IBC protocol this is either the `Channel Open Init` event on the initiating chain or +// `Channel Open Try` on the counterparty chain. +// Protocol version and channel ordering should be verified for example. +// See https://github.com/cosmos/ics/tree/master/spec/ics-004-channel-and-packet-semantics#channel-lifecycle-management +func (k Keeper) OnOpenChannel( + ctx sdk.Context, + contractAddress sdk.AccAddress, + msg v1types.IBCChannelOpenMsg, +) (string, error) { + defer telemetry.MeasureSince(time.Now(), "compute", "keeper", "ibc-open-channel") + + ctx.GasMeter().ConsumeGas(types.InstanceCost, "Loading Compute module: ibc-open-channel") + msgBz, err := json.Marshal(msg) if err != nil { return "", sdkerrors.Wrap(err, "ibc-open-channel") } - gas := gasForContract(ctx) - res, gasUsed, err := k.wasmer.Execute(codeInfo.CodeHash, env, msgBz, prefixStore, cosmwasmAPI, querier, ctx.GasMeter(), gas, verificationInfo, wasmTypes.HandleTypeReply) - consumeGas(ctx, gasUsed) - + res, err := k.ibcContractCall(ctx, contractAddress, msgBz) if err != nil { return "", sdkerrors.Wrap(types.ErrExecuteFailed, err.Error()) } From 4604b60c352b86ea1e1f3444d4330409b2e6238a Mon Sep 17 00:00:00 2001 From: Assaf Morami Date: Mon, 25 Jul 2022 13:39:46 +0300 Subject: [PATCH 15/93] IBC keeper OnTimeoutPacket OnAckPacket OnCloseChannel OnConnectChannel --- x/compute/internal/keeper/keeper.go | 3 - x/compute/internal/keeper/relay.go | 129 +++++++++++++++++----------- 2 files changed, 79 insertions(+), 53 deletions(-) diff --git a/x/compute/internal/keeper/keeper.go b/x/compute/internal/keeper/keeper.go index ae053a22e..e763a8033 100644 --- a/x/compute/internal/keeper/keeper.go +++ b/x/compute/internal/keeper/keeper.go @@ -10,7 +10,6 @@ import ( "time" capabilitykeeper "github.com/cosmos/cosmos-sdk/x/capability/keeper" - capabilitytypes "github.com/cosmos/cosmos-sdk/x/capability/types" channelkeeper "github.com/cosmos/ibc-go/v3/modules/core/04-channel/keeper" portkeeper "github.com/cosmos/ibc-go/v3/modules/core/05-port/keeper" wasmTypes "github.com/enigmampc/SecretNetwork/go-cosmwasm/types" @@ -1112,5 +1111,3 @@ func (k Keeper) reply(ctx sdk.Context, contractAddress sdk.AccAddress, reply v1w return nil, sdkerrors.Wrap(types.ErrExecuteFailed, fmt.Sprintf("cannot detect response type: %+v", res)) } } - - diff --git a/x/compute/internal/keeper/relay.go b/x/compute/internal/keeper/relay.go index b855d3513..2d05822f2 100644 --- a/x/compute/internal/keeper/relay.go +++ b/x/compute/internal/keeper/relay.go @@ -20,6 +20,7 @@ var _ types.IBCContractKeeper = (*Keeper)(nil) func (k Keeper) ibcContractCall(ctx sdk.Context, contractAddress sdk.AccAddress, msgBz []byte, + callType wasmTypes.HandleType, ) (interface{}, error) { verificationInfo := types.NewVerificationInfo([]byte{}, sdktxsigning.SignMode_SIGN_MODE_UNSPECIFIED, []byte{}, []byte{}, []byte{}, nil) @@ -46,12 +47,33 @@ func (k Keeper) ibcContractCall(ctx sdk.Context, } gas := gasForContract(ctx) - res, gasUsed, err := k.wasmer.Execute(codeInfo.CodeHash, env, msgBz, prefixStore, cosmwasmAPI, querier, ctx.GasMeter(), gas, verificationInfo, wasmTypes.HandleTypeReply) + res, gasUsed, err := k.wasmer.Execute(codeInfo.CodeHash, env, msgBz, prefixStore, cosmwasmAPI, querier, ctx.GasMeter(), gas, verificationInfo, callType) consumeGas(ctx, gasUsed) return res, err } +func (k Keeper) parseThenHandleIBCBasicContractResponse(ctx sdk.Context, + contractAddress sdk.AccAddress, + res interface{}, +) error { + switch resp := res.(type) { + case *v1types.IBCBasicResponse: + if resp != nil { + contractInfo, _, _, err := k.contractInstance(ctx, contractAddress) + if err != nil { + return err + } + + return k.handleIBCBasicContractResponse(ctx, contractAddress, contractInfo.IBCPortID, resp) + } else { + return sdkerrors.Wrap(types.ErrExecuteFailed, fmt.Sprintf("cannot parse IBCBasicResponse: %+v", res)) + } + default: + return sdkerrors.Wrap(types.ErrExecuteFailed, fmt.Sprintf("cannot cast res to IBCBasicResponse: %+v", res)) + } +} + // OnOpenChannel calls the contract to participate in the IBC channel handshake step. // In the IBC protocol this is either the `Channel Open Init` event on the initiating chain or // `Channel Open Try` on the counterparty chain. @@ -71,7 +93,7 @@ func (k Keeper) OnOpenChannel( return "", sdkerrors.Wrap(err, "ibc-open-channel") } - res, err := k.ibcContractCall(ctx, contractAddress, msgBz) + res, err := k.ibcContractCall(ctx, contractAddress, msgBz, wasmTypes.HandleTypeIbcChannelConnect) if err != nil { return "", sdkerrors.Wrap(types.ErrExecuteFailed, err.Error()) } @@ -84,7 +106,7 @@ func (k Keeper) OnOpenChannel( return "", nil } default: - return "", sdkerrors.Wrap(types.ErrExecuteFailed, fmt.Sprintf("cannot cast res to IBC3ChannelOpenResponse: %+v", res)) + return "", sdkerrors.Wrap(types.ErrExecuteFailed, fmt.Sprintf("ibc-open-channel: cannot cast res to IBC3ChannelOpenResponse: %+v", res)) } } @@ -97,26 +119,28 @@ func (k Keeper) OnOpenChannel( // See https://github.com/cosmos/ics/tree/master/spec/ics-004-channel-and-packet-semantics#channel-lifecycle-management func (k Keeper) OnConnectChannel( ctx sdk.Context, - contractAddr sdk.AccAddress, + contractAddress sdk.AccAddress, msg v1types.IBCChannelConnectMsg, ) error { defer telemetry.MeasureSince(time.Now(), "compute", "keeper", "ibc-connect-channel") - contractInfo, codeInfo, prefixStore, err := k.contractInstance(ctx, contractAddr) + + ctx.GasMeter().ConsumeGas(types.InstanceCost, "Loading Compute module: ibc-connect-channel") + + msgBz, err := json.Marshal(msg) if err != nil { - return err + return sdkerrors.Wrap(err, "ibc-connect-channel") } - env := types.NewEnv(ctx, contractAddr) - querier := k.newQueryHandler(ctx, contractAddr) - - gas := k.runtimeGasForContract(ctx) - res, gasUsed, execErr := k.wasmVM.IBCChannelConnect(codeInfo.CodeHash, env, msg, prefixStore, cosmwasmAPI, querier, ctx.GasMeter(), gas, costJSONDeserialization) - k.consumeRuntimeGas(ctx, gasUsed) - if execErr != nil { - return sdkerrors.Wrap(types.ErrExecuteFailed, execErr.Error()) + res, err := k.ibcContractCall(ctx, contractAddress, msgBz, wasmTypes.HandleTypeIbcChannelConnect) + if err != nil { + return sdkerrors.Wrap(types.ErrExecuteFailed, err.Error()) } - return k.handleIBCBasicContractResponse(ctx, contractAddr, contractInfo.IBCPortID, res) + err = k.parseThenHandleIBCBasicContractResponse(ctx, contractAddress, res) + if err != nil { + sdkerrors.Wrap(err, "ibc-connect-channel") + } + return nil } // OnCloseChannel calls the contract to let it know the IBC channel is closed. @@ -127,27 +151,28 @@ func (k Keeper) OnConnectChannel( // See https://github.com/cosmos/ics/tree/master/spec/ics-004-channel-and-packet-semantics#channel-lifecycle-management func (k Keeper) OnCloseChannel( ctx sdk.Context, - contractAddr sdk.AccAddress, + contractAddress sdk.AccAddress, msg v1types.IBCChannelCloseMsg, ) error { defer telemetry.MeasureSince(time.Now(), "compute", "keeper", "ibc-close-channel") - contractInfo, codeInfo, prefixStore, err := k.contractInstance(ctx, contractAddr) + ctx.GasMeter().ConsumeGas(types.InstanceCost, "Loading Compute module: ibc-close-channel") + + msgBz, err := json.Marshal(msg) if err != nil { - return err + return sdkerrors.Wrap(err, "ibc-close-channel") } - params := types.NewEnv(ctx, contractAddr) - querier := k.newQueryHandler(ctx, contractAddr) - - gas := k.runtimeGasForContract(ctx) - res, gasUsed, execErr := k.wasmVM.IBCChannelClose(codeInfo.CodeHash, params, msg, prefixStore, cosmwasmAPI, querier, ctx.GasMeter(), gas, costJSONDeserialization) - k.consumeRuntimeGas(ctx, gasUsed) - if execErr != nil { - return sdkerrors.Wrap(types.ErrExecuteFailed, execErr.Error()) + res, err := k.ibcContractCall(ctx, contractAddress, msgBz, wasmTypes.HandleTypeIbcChannelClose) + if err != nil { + return sdkerrors.Wrap(types.ErrExecuteFailed, err.Error()) } - return k.handleIBCBasicContractResponse(ctx, contractAddr, contractInfo.IBCPortID, res) + err = k.parseThenHandleIBCBasicContractResponse(ctx, contractAddress, res) + if err != nil { + sdkerrors.Wrap(err, "ibc-close-channel") + } + return nil } // OnRecvPacket calls the contract to process the incoming IBC packet. The contract fully owns the data processing and @@ -192,25 +217,28 @@ func (k Keeper) OnRecvPacket( // For more information see: https://github.com/cosmos/ics/tree/master/spec/ics-004-channel-and-packet-semantics#packet-flow--handling func (k Keeper) OnAckPacket( ctx sdk.Context, - contractAddr sdk.AccAddress, + contractAddress sdk.AccAddress, msg v1types.IBCPacketAckMsg, ) error { defer telemetry.MeasureSince(time.Now(), "compute", "keeper", "ibc-ack-packet") - contractInfo, codeInfo, prefixStore, err := k.contractInstance(ctx, contractAddr) + + ctx.GasMeter().ConsumeGas(types.InstanceCost, "Loading Compute module: ibc-ack-packet") + + msgBz, err := json.Marshal(msg) if err != nil { - return err + return sdkerrors.Wrap(err, "ibc-ack-packet") } - env := types.NewEnv(ctx, contractAddr) - querier := k.newQueryHandler(ctx, contractAddr) + res, err := k.ibcContractCall(ctx, contractAddress, msgBz, wasmTypes.HandleTypeIbcPacketAck) + if err != nil { + return sdkerrors.Wrap(types.ErrExecuteFailed, err.Error()) + } - gas := k.runtimeGasForContract(ctx) - res, gasUsed, execErr := k.wasmVM.IBCPacketAck(codeInfo.CodeHash, env, msg, prefixStore, cosmwasmAPI, querier, ctx.GasMeter(), gas, costJSONDeserialization) - k.consumeRuntimeGas(ctx, gasUsed) - if execErr != nil { - return sdkerrors.Wrap(types.ErrExecuteFailed, execErr.Error()) + err = k.parseThenHandleIBCBasicContractResponse(ctx, contractAddress, res) + if err != nil { + sdkerrors.Wrap(err, "ibc-ack-packet") } - return k.handleIBCBasicContractResponse(ctx, contractAddr, contractInfo.IBCPortID, res) + return nil } // OnTimeoutPacket calls the contract to let it know the packet was never received on the destination chain within @@ -218,27 +246,28 @@ func (k Keeper) OnAckPacket( // The contract should handle this on the application level and undo the original operation func (k Keeper) OnTimeoutPacket( ctx sdk.Context, - contractAddr sdk.AccAddress, + contractAddress sdk.AccAddress, msg v1types.IBCPacketTimeoutMsg, ) error { defer telemetry.MeasureSince(time.Now(), "compute", "keeper", "ibc-timeout-packet") - contractInfo, codeInfo, prefixStore, err := k.contractInstance(ctx, contractAddr) + ctx.GasMeter().ConsumeGas(types.InstanceCost, "Loading Compute module: ibc-timeout-packet") + + msgBz, err := json.Marshal(msg) if err != nil { - return err + return sdkerrors.Wrap(err, "ibc-timeout-packet") } - env := types.NewEnv(ctx, contractAddr) - querier := k.newQueryHandler(ctx, contractAddr) - - gas := k.runtimeGasForContract(ctx) - res, gasUsed, execErr := k.wasmVM.IBCPacketTimeout(codeInfo.CodeHash, env, msg, prefixStore, cosmwasmAPI, querier, ctx.GasMeter(), gas, costJSONDeserialization) - k.consumeRuntimeGas(ctx, gasUsed) - if execErr != nil { - return sdkerrors.Wrap(types.ErrExecuteFailed, execErr.Error()) + res, err := k.ibcContractCall(ctx, contractAddress, msgBz, wasmTypes.HandleTypeIbcPacketTimeout) + if err != nil { + return sdkerrors.Wrap(types.ErrExecuteFailed, err.Error()) } - return k.handleIBCBasicContractResponse(ctx, contractAddr, contractInfo.IBCPortID, res) + err = k.parseThenHandleIBCBasicContractResponse(ctx, contractAddress, res) + if err != nil { + sdkerrors.Wrap(err, "ibc-timeout-packet") + } + return nil } func (k Keeper) handleIBCBasicContractResponse(ctx sdk.Context, addr sdk.AccAddress, id string, res *v1types.IBCBasicResponse) error { From 73b3e3abd7758075f0c0a548f6ba4e8fad0019f7 Mon Sep 17 00:00:00 2001 From: Assaf Morami Date: Tue, 26 Jul 2022 11:24:09 +0300 Subject: [PATCH 16/93] Keeper OnRecvPacket --- x/compute/internal/keeper/relay.go | 62 +++++++++++++++++++----------- 1 file changed, 39 insertions(+), 23 deletions(-) diff --git a/x/compute/internal/keeper/relay.go b/x/compute/internal/keeper/relay.go index 2d05822f2..a60a928e0 100644 --- a/x/compute/internal/keeper/relay.go +++ b/x/compute/internal/keeper/relay.go @@ -55,6 +55,7 @@ func (k Keeper) ibcContractCall(ctx sdk.Context, func (k Keeper) parseThenHandleIBCBasicContractResponse(ctx sdk.Context, contractAddress sdk.AccAddress, + inputMsg []byte, res interface{}, ) error { switch resp := res.(type) { @@ -65,9 +66,9 @@ func (k Keeper) parseThenHandleIBCBasicContractResponse(ctx sdk.Context, return err } - return k.handleIBCBasicContractResponse(ctx, contractAddress, contractInfo.IBCPortID, resp) + return k.handleIBCBasicContractResponse(ctx, contractAddress, contractInfo.IBCPortID, inputMsg, resp) } else { - return sdkerrors.Wrap(types.ErrExecuteFailed, fmt.Sprintf("cannot parse IBCBasicResponse: %+v", res)) + return sdkerrors.Wrap(types.ErrExecuteFailed, fmt.Sprintf("null pointer IBCBasicResponse: %+v", res)) } default: return sdkerrors.Wrap(types.ErrExecuteFailed, fmt.Sprintf("cannot cast res to IBCBasicResponse: %+v", res)) @@ -136,7 +137,7 @@ func (k Keeper) OnConnectChannel( return sdkerrors.Wrap(types.ErrExecuteFailed, err.Error()) } - err = k.parseThenHandleIBCBasicContractResponse(ctx, contractAddress, res) + err = k.parseThenHandleIBCBasicContractResponse(ctx, contractAddress, msgBz, res) if err != nil { sdkerrors.Wrap(err, "ibc-connect-channel") } @@ -168,7 +169,7 @@ func (k Keeper) OnCloseChannel( return sdkerrors.Wrap(types.ErrExecuteFailed, err.Error()) } - err = k.parseThenHandleIBCBasicContractResponse(ctx, contractAddress, res) + err = k.parseThenHandleIBCBasicContractResponse(ctx, contractAddress, msgBz, res) if err != nil { sdkerrors.Wrap(err, "ibc-close-channel") } @@ -183,29 +184,42 @@ func (k Keeper) OnCloseChannel( // For more information see: https://github.com/cosmos/ics/tree/master/spec/ics-004-channel-and-packet-semantics#packet-flow--handling func (k Keeper) OnRecvPacket( ctx sdk.Context, - contractAddr sdk.AccAddress, + contractAddress sdk.AccAddress, msg v1types.IBCPacketReceiveMsg, ) ([]byte, error) { defer telemetry.MeasureSince(time.Now(), "compute", "keeper", "ibc-recv-packet") - contractInfo, codeInfo, prefixStore, err := k.contractInstance(ctx, contractAddr) + + ctx.GasMeter().ConsumeGas(types.InstanceCost, "Loading Compute module: ibc-recv-packet") + + msgBz, err := json.Marshal(msg) if err != nil { - return nil, err + return nil, sdkerrors.Wrap(err, "ibc-recv-packet") } - env := types.NewEnv(ctx, contractAddr) - querier := k.newQueryHandler(ctx, contractAddr) - - gas := k.runtimeGasForContract(ctx) - res, gasUsed, execErr := k.wasmVM.IBCPacketReceive(codeInfo.CodeHash, env, msg, prefixStore, cosmwasmAPI, querier, ctx.GasMeter(), gas, costJSONDeserialization) - k.consumeRuntimeGas(ctx, gasUsed) - if execErr != nil { - return nil, sdkerrors.Wrap(types.ErrExecuteFailed, execErr.Error()) + res, err := k.ibcContractCall(ctx, contractAddress, msgBz, wasmTypes.HandleTypeIbcChannelConnect) + if err != nil { + return nil, sdkerrors.Wrap(types.ErrExecuteFailed, err.Error()) } - if res.Err != "" { // handle error case as before https://github.com/CosmWasm/wasmvm/commit/c300106fe5c9426a495f8e10821e00a9330c56c6 - return nil, sdkerrors.Wrap(types.ErrExecuteFailed, res.Err) + + switch resp := res.(type) { + case *v1types.IBCReceiveResponse: + if resp != nil { + contractInfo, _, _, err := k.contractInstance(ctx, contractAddress) + if err != nil { + return nil, err + } + verificationInfo := types.NewVerificationInfo([]byte{}, sdktxsigning.SignMode_SIGN_MODE_UNSPECIFIED, []byte{}, []byte{}, []byte{}, nil) + + // note submessage reply results can overwrite the `Acknowledgement` data + return k.handleContractResponse(ctx, contractAddress, contractInfo.IBCPortID, resp.Messages, resp.Attributes, resp.Events, resp.Acknowledgement, msgBz, verificationInfo, wasmTypes.CosmosMsgVersionV1) + } else { + // should never get here as it's already checked in + // https://github.com/scrtlabs/SecretNetwork/blob/bd46776c/go-cosmwasm/lib.go#L358 + return nil, sdkerrors.Wrap(types.ErrExecuteFailed, fmt.Sprintf("ibc-recv-packet: null pointer IBCReceiveResponse: %+v", res)) + } + default: + return nil, sdkerrors.Wrap(types.ErrExecuteFailed, fmt.Sprintf("ibc-recv-packet: cannot cast res to IBCReceiveResponse: %+v", res)) } - // note submessage reply results can overwrite the `Acknowledgement` data - return k.handleContractResponse(ctx, contractAddr, contractInfo.IBCPortID, res.Ok.Messages, res.Ok.Attributes, res.Ok.Acknowledgement, res.Ok.Events) } // OnAckPacket calls the contract to handle the "acknowledgement" data which can contain success or failure of a packet @@ -234,7 +248,7 @@ func (k Keeper) OnAckPacket( return sdkerrors.Wrap(types.ErrExecuteFailed, err.Error()) } - err = k.parseThenHandleIBCBasicContractResponse(ctx, contractAddress, res) + err = k.parseThenHandleIBCBasicContractResponse(ctx, contractAddress, msgBz, res) if err != nil { sdkerrors.Wrap(err, "ibc-ack-packet") } @@ -263,14 +277,16 @@ func (k Keeper) OnTimeoutPacket( return sdkerrors.Wrap(types.ErrExecuteFailed, err.Error()) } - err = k.parseThenHandleIBCBasicContractResponse(ctx, contractAddress, res) + err = k.parseThenHandleIBCBasicContractResponse(ctx, contractAddress, msgBz, res) if err != nil { sdkerrors.Wrap(err, "ibc-timeout-packet") } return nil } -func (k Keeper) handleIBCBasicContractResponse(ctx sdk.Context, addr sdk.AccAddress, id string, res *v1types.IBCBasicResponse) error { - _, err := k.handleContractResponse(ctx, addr, id, res.Messages, res.Attributes, nil, res.Events) +func (k Keeper) handleIBCBasicContractResponse(ctx sdk.Context, addr sdk.AccAddress, ibcPortID string, inputMsg []byte, res *v1types.IBCBasicResponse) error { + verificationInfo := types.NewVerificationInfo([]byte{}, sdktxsigning.SignMode_SIGN_MODE_UNSPECIFIED, []byte{}, []byte{}, []byte{}, nil) + + _, err := k.handleContractResponse(ctx, addr, ibcPortID, res.Messages, res.Attributes, res.Events, nil, inputMsg, verificationInfo, wasmTypes.CosmosMsgVersionV1) return err } From e4ffb9cdcf784e678db84d17937d8089a9742e55 Mon Sep 17 00:00:00 2001 From: Assaf Morami Date: Tue, 26 Jul 2022 17:33:18 +0300 Subject: [PATCH 17/93] WIP: IBC on the enclave side --- .../src/contract_operations.rs | 71 +++++++++++++++++-- .../enclaves/shared/cosmos-types/src/types.rs | 6 ++ 2 files changed, 72 insertions(+), 5 deletions(-) diff --git a/cosmwasm/enclaves/shared/contract-engine/src/contract_operations.rs b/cosmwasm/enclaves/shared/contract-engine/src/contract_operations.rs index 02bc35d2a..dd9d91d94 100644 --- a/cosmwasm/enclaves/shared/contract-engine/src/contract_operations.rs +++ b/cosmwasm/enclaves/shared/contract-engine/src/contract_operations.rs @@ -225,12 +225,12 @@ pub fn parse_message( sig_info: &SigInfo, handle_type: &HandleType, ) -> Result { - let orig_secret_msg = SecretMessage::from_slice(message)?; - return match handle_type { HandleType::HANDLE_TYPE_EXECUTE => { + let orig_secret_msg = SecretMessage::from_slice(message)?; + trace!( - "handle input before decryption: {:?}", + "execute input before decryption: {:?}", base64::encode(&message) ); let decrypted_msg = orig_secret_msg.decrypt()?; @@ -242,10 +242,14 @@ pub fn parse_message( contract_hash_for_validation: None, }) } - HandleType::HANDLE_TYPE_REPLY => { + let orig_secret_msg = SecretMessage::from_slice(message)?; + if sig_info.sign_mode == SignMode::SIGN_MODE_UNSPECIFIED { - trace!("reply input is not encrypted"); + trace!( + "reply input is not encrypted: {:?}", + base64::encode(&message) + ); let decrypted_msg = orig_secret_msg.msg.clone(); let mut reply: Reply = serde_json::from_slice(&decrypted_msg) .map_err(|err| { @@ -512,6 +516,63 @@ pub fn parse_message( } } } + HandleType::HANDLE_TYPE_IBC_CHANNEL_OPEN => todo!(), + HandleType::HANDLE_TYPE_IBC_CHANNEL_CONNECT => todo!(), + HandleType::HANDLE_TYPE_IBC_CHANNEL_CLOSE => todo!(), + HandleType::HANDLE_TYPE_IBC_PACKET_RECEIVE => { + let orig_secret_msg = match SecretMessage::from_slice(message) { + Ok(orig_secret_msg) => orig_secret_msg, + Err(_) => { + trace!( + "ibc_packet_receive msg is not SecretMessage (probably plaintext): {:?}", + base64::encode(&message) + ); + + SecretMessage { + nonce: [0; 32], + user_public_key: [0; 32], + msg: message.into(), + } + } + }; + + match orig_secret_msg.decrypt() { + Ok(decrypted_msg) => { + // IBC packet is encrypted + + trace!( + "ibc_packet_receive input before decryption: {:?}", + base64::encode(&message) + ); + + Ok(ParsedMessage { + should_validate_sig_info: true, + was_msg_encrypted: true, + secret_msg: orig_secret_msg, + decrypted_msg, + contract_hash_for_validation: None, + }) + } + Err(_) => { + // assume packet is not encrypted, continue in plaintext mode + + trace!( + "ibc_packet_receive input is not encrypted: {:?}", + base64::encode(&message) + ); + + Ok(ParsedMessage { + should_validate_sig_info: false, + was_msg_encrypted: false, + secret_msg: orig_secret_msg, + decrypted_msg: orig_secret_msg.msg, + contract_hash_for_validation: None, + }) + } + } + } + HandleType::HANDLE_TYPE_IBC_PACKET_ACK => todo!(), + HandleType::HANDLE_TYPE_IBC_PACKET_TIMEOUT => todo!(), }; } diff --git a/cosmwasm/enclaves/shared/cosmos-types/src/types.rs b/cosmwasm/enclaves/shared/cosmos-types/src/types.rs index 873a80733..b86c0460d 100644 --- a/cosmwasm/enclaves/shared/cosmos-types/src/types.rs +++ b/cosmwasm/enclaves/shared/cosmos-types/src/types.rs @@ -146,6 +146,12 @@ pub enum SignModeDef { pub enum HandleType { HANDLE_TYPE_EXECUTE = 0, HANDLE_TYPE_REPLY = 1, + HANDLE_TYPE_IBC_CHANNEL_OPEN = 2, + HANDLE_TYPE_IBC_CHANNEL_CONNECT = 3, + HANDLE_TYPE_IBC_CHANNEL_CLOSE = 4, + HANDLE_TYPE_IBC_PACKET_RECEIVE = 5, + HANDLE_TYPE_IBC_PACKET_ACK = 6, + HANDLE_TYPE_IBC_PACKET_TIMEOUT = 7, } impl HandleType { From 5bee32a09966063f6b2830e54ef87ace9465d71b Mon Sep 17 00:00:00 2001 From: Assaf Morami Date: Wed, 27 Jul 2022 09:12:36 +0300 Subject: [PATCH 18/93] Remove old CosmWasm remnants --- x/compute/client/cli/tx.go | 22 +---- x/compute/internal/keeper/keeper.go | 27 +----- x/compute/internal/types/msg.go | 135 +--------------------------- 3 files changed, 5 insertions(+), 179 deletions(-) diff --git a/x/compute/client/cli/tx.go b/x/compute/client/cli/tx.go index 606cc6c07..82beb5b14 100644 --- a/x/compute/client/cli/tx.go +++ b/x/compute/client/cli/tx.go @@ -31,7 +31,6 @@ const ( flagProposalType = "type" flagIoMasterKey = "enclave-key" flagCodeHash = "code-hash" - // flagAdmin = "admin" ) // GetTxCmd returns the transaction commands for this module @@ -47,10 +46,6 @@ func GetTxCmd() *cobra.Command { StoreCodeCmd(), InstantiateContractCmd(), ExecuteContractCmd(), - // Currently not supporting these commands - // MigrateContractCmd(cdc), - // UpdateContractAdminCmd(cdc), - // ClearContractAdminCmd(cdc), ) return txCmd } @@ -105,20 +100,6 @@ func parseStoreCodeArgs(args []string, cliCtx client.Context, flags *flag.FlagSe return types.MsgStoreCode{}, fmt.Errorf("invalid input file. Use wasm binary or gzip") } - /* - var perm *types.AccessConfig - if onlyAddrStr := viper.GetString(flagInstantiateByAddress); onlyAddrStr != "" { - allowedAddr, err := sdk.AccAddressFromBech32(onlyAddrStr) - if err != nil { - return types.MsgStoreCode{}, sdkerrors.Wrap(err, flagInstantiateByAddress) - } - x := types.OnlyAddress.With(allowedAddr) - perm = &x - } else if everybody := viper.GetBool(flagInstantiateByEverybody); everybody { - perm = &types.AllowEverybody - } - */ - source, err := flags.GetString(flagSource) if err != nil { return types.MsgStoreCode{}, fmt.Errorf("source: %s", err) @@ -134,7 +115,6 @@ func parseStoreCodeArgs(args []string, cliCtx client.Context, flags *flag.FlagSe WASMByteCode: wasm, Source: source, Builder: builder, - // InstantiatePermission: perm, } return msg, nil } @@ -142,7 +122,7 @@ func parseStoreCodeArgs(args []string, cliCtx client.Context, flags *flag.FlagSe // InstantiateContractCmd will instantiate a contract from previously uploaded code. func InstantiateContractCmd() *cobra.Command { cmd := &cobra.Command{ - Use: "instantiate [code_id_int64] [json_encoded_init_args] --label [text] " /* --admin [address,optional] */ + "--amount [coins,optional]", + Use: "instantiate [code_id_int64] [json_encoded_init_args] --label [text] --amount [coins,optional]", Short: "Instantiate a wasm contract", Args: cobra.ExactArgs(2), RunE: func(cmd *cobra.Command, args []string) error { diff --git a/x/compute/internal/keeper/keeper.go b/x/compute/internal/keeper/keeper.go index e763a8033..0789b31fb 100644 --- a/x/compute/internal/keeper/keeper.go +++ b/x/compute/internal/keeper/keeper.go @@ -163,15 +163,6 @@ func (k Keeper) setParams(ctx sdk.Context, ps types.Params) { // Create uploads and compiles a WASM contract, returning a short identifier for the contract func (k Keeper) Create(ctx sdk.Context, creator sdk.AccAddress, wasmCode []byte, source string, builder string) (codeID uint64, err error) { - /* - return k.create(ctx, creator, wasmCode, source, builder, &types.AccessConfig{Type: types.Everybody} , k.authZPolicy ) - } - - func (k Keeper) create(ctx sdk.Context, creator sdk.AccAddress, wasmCode []byte, source string, builder string, instantiateAccess *types.AccessConfig ) (codeID uint64, err error) { - if !authZ.CanCreateCode(k.getUploadAccessConfig(ctx), creator) { - return 0, sdkerrors.Wrap(sdkerrors.ErrUnauthorized, "can not create code") - } - */ wasmCode, err = uncompress(wasmCode) if err != nil { return 0, sdkerrors.Wrap(types.ErrCreateFailed, err.Error()) @@ -180,18 +171,12 @@ func (k Keeper) Create(ctx sdk.Context, creator sdk.AccAddress, wasmCode []byte, codeHash, err := k.wasmer.Create(wasmCode) if err != nil { - // return 0, sdkerrors.Wrap(err, "cosmwasm create") return 0, sdkerrors.Wrap(types.ErrCreateFailed, err.Error()) } store := ctx.KVStore(k.storeKey) codeID = k.autoIncrementID(ctx, types.KeyLastCodeID) - /* - if instantiateAccess == nil { - defaultAccessConfig := k.getInstantiateAccessConfig(ctx).With(creator) - instantiateAccess = &defaultAccessConfig - } - */ - codeInfo := types.NewCodeInfo(codeHash, creator, source, builder /* , *instantiateAccess */) + + codeInfo := types.NewCodeInfo(codeHash, creator, source, builder) // 0x01 | codeID (uint64) -> ContractInfo store.Set(types.GetCodeKey(codeID), k.cdc.MustMarshal(&codeInfo)) @@ -418,10 +403,6 @@ func (k Keeper) Instantiate(ctx sdk.Context, codeID uint64, creator sdk.AccAddre var codeInfo types.CodeInfo k.cdc.MustUnmarshal(bz, &codeInfo) - // if !authZ.CanInstantiateContract(codeInfo.InstantiateConfig, creator) { - // return nil, sdkerrors.Wrap(sdkerrors.ErrUnauthorized, "can not instantiate") - // } - // prepare env for contract instantiate call env := types.NewEnv(ctx, creator, deposit, contractAddress, nil) @@ -464,8 +445,6 @@ func (k Keeper) Instantiate(ctx sdk.Context, codeID uint64, creator sdk.AccAddre contractInfo := types.NewContractInfo(codeID, creator, label, createdAt) store.Set(types.GetContractAddressKey(contractAddress), k.cdc.MustMarshal(&contractInfo)) - // fmt.Printf("Storing key: %v for account %s\n", key, contractAddress) - store.Set(types.GetContractEnclaveKey(contractAddress), key) store.Set(types.GetContractLabelPrefix(label), contractAddress) @@ -997,8 +976,6 @@ func (k Keeper) importContract(ctx sdk.Context, contractAddr sdk.AccAddress, cus return sdkerrors.Wrapf(types.ErrDuplicate, "contract: %s", contractAddr) } - // historyEntry := c.ResetFromGenesis(ctx) - // k.appendToContractHistory(ctx, contractAddr, historyEntry) k.setContractCustomInfo(ctx, contractAddr, customInfo) k.setContractInfo(ctx, contractAddr, c) return k.importContractState(ctx, contractAddr, state) diff --git a/x/compute/internal/types/msg.go b/x/compute/internal/types/msg.go index 7eb0f4877..5d7b8fcc4 100644 --- a/x/compute/internal/types/msg.go +++ b/x/compute/internal/types/msg.go @@ -29,13 +29,7 @@ func (msg MsgStoreCode) ValidateBasic() error { if err := validateBuilder(msg.Builder); err != nil { return sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "builder %s", err.Error()) } - /* - if msg.InstantiatePermission != nil { - if err := msg.InstantiatePermission.ValidateBasic(); err != nil { - return sdkerrors.Wrap(err, "instantiate permission") - } - } - */ + return nil } @@ -72,16 +66,6 @@ func (msg MsgInstantiateContract) ValidateBasic() error { return sdkerrors.ErrInvalidCoins } - /* - if len(msg.Admin) != 0 { - if err := sdk.VerifyAddressFormat(msg.Admin); err != nil { - return err - } - } - if !json.Valid(msg.InitMsg) { - return sdkerrors.Wrap(ErrInvalid, "init msg json") - } - */ return nil } @@ -112,11 +96,7 @@ func (msg MsgExecuteContract) ValidateBasic() error { if !msg.SentFunds.IsValid() { return sdkerrors.Wrap(sdkerrors.ErrInvalidCoins, "sentFunds") } - /* - if !json.Valid(msg.Msg) { - return sdkerrors.Wrap(ErrInvalid, "msg json") - } - */ + return nil } @@ -127,114 +107,3 @@ func (msg MsgExecuteContract) GetSignBytes() []byte { func (msg MsgExecuteContract) GetSigners() []sdk.AccAddress { return []sdk.AccAddress{msg.Sender} } - -/* -type MsgMigrateContract struct { - Sender sdk.AccAddress `json:"sender" yaml:"sender"` - Contract sdk.AccAddress `json:"contract" yaml:"contract"` - CodeID uint64 `json:"code_id" yaml:"code_id"` - MigrateMsg json.RawMessage `json:"msg" yaml:"msg"` -} - -func (msg MsgMigrateContract) Route() string { - return RouterKey -} - -func (msg MsgMigrateContract) Type() string { - return "migrate" -} - -func (msg MsgMigrateContract) ValidateBasic() error { - if msg.CodeID == 0 { - return sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "code_id is required") - } - if err := sdk.VerifyAddressFormat(msg.Sender); err != nil { - return sdkerrors.Wrap(err, "sender") - } - if err := sdk.VerifyAddressFormat(msg.Contract); err != nil { - return sdkerrors.Wrap(err, "contract") - } - if !json.Valid(msg.MigrateMsg) { - return sdkerrors.Wrap(ErrInvalid, "migrate msg json") - } - - return nil -} - -func (msg MsgMigrateContract) GetSignBytes() []byte { - return sdk.MustSortJSON(ModuleCdc.MustMarshalJSON(msg)) -} - -func (msg MsgMigrateContract) GetSigners() []sdk.AccAddress { - return []sdk.AccAddress{msg.Sender} -} - -type MsgUpdateAdmin struct { - Sender sdk.AccAddress `json:"sender" yaml:"sender"` - NewAdmin sdk.AccAddress `json:"new_admin" yaml:"new_admin"` - Contract sdk.AccAddress `json:"contract" yaml:"contract"` -} - -func (msg MsgUpdateAdmin) Route() string { - return RouterKey -} - -func (msg MsgUpdateAdmin) Type() string { - return "update-contract-admin" -} - -func (msg MsgUpdateAdmin) ValidateBasic() error { - if err := sdk.VerifyAddressFormat(msg.Sender); err != nil { - return sdkerrors.Wrap(err, "sender") - } - if err := sdk.VerifyAddressFormat(msg.Contract); err != nil { - return sdkerrors.Wrap(err, "contract") - } - if err := sdk.VerifyAddressFormat(msg.NewAdmin); err != nil { - return sdkerrors.Wrap(err, "new admin") - } - if msg.Sender.Equals(msg.NewAdmin) { - return sdkerrors.Wrap(ErrInvalidMsg, "new admin is the same as the old") - } - return nil -} - -func (msg MsgUpdateAdmin) GetSignBytes() []byte { - return sdk.MustSortJSON(ModuleCdc.MustMarshalJSON(msg)) -} - -func (msg MsgUpdateAdmin) GetSigners() []sdk.AccAddress { - return []sdk.AccAddress{msg.Sender} -} - -type MsgClearAdmin struct { - Sender sdk.AccAddress `json:"sender" yaml:"sender"` - Contract sdk.AccAddress `json:"contract" yaml:"contract"` -} - -func (msg MsgClearAdmin) Route() string { - return RouterKey -} - -func (msg MsgClearAdmin) Type() string { - return "clear-contract-admin" -} - -func (msg MsgClearAdmin) ValidateBasic() error { - if err := sdk.VerifyAddressFormat(msg.Sender); err != nil { - return sdkerrors.Wrap(err, "sender") - } - if err := sdk.VerifyAddressFormat(msg.Contract); err != nil { - return sdkerrors.Wrap(err, "contract") - } - return nil -} - -func (msg MsgClearAdmin) GetSignBytes() []byte { - return sdk.MustSortJSON(ModuleCdc.MustMarshalJSON(msg)) -} - -func (msg MsgClearAdmin) GetSigners() []sdk.AccAddress { - return []sdk.AccAddress{msg.Sender} -} -*/ From ee0a8e081b4f06e4ac388bf2bfea84a57af78d7a Mon Sep 17 00:00:00 2001 From: Assaf Morami Date: Tue, 2 Aug 2022 14:41:55 +0300 Subject: [PATCH 19/93] secret-contract-optimizer v1.0.8 --- deployment/dockerfiles/secret-contract-optimizer.Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deployment/dockerfiles/secret-contract-optimizer.Dockerfile b/deployment/dockerfiles/secret-contract-optimizer.Dockerfile index c37099388..91639d96d 100644 --- a/deployment/dockerfiles/secret-contract-optimizer.Dockerfile +++ b/deployment/dockerfiles/secret-contract-optimizer.Dockerfile @@ -1,4 +1,4 @@ -FROM rust:1.59-slim-bullseye +FROM rust:1.62-slim-bullseye RUN rustup target add wasm32-unknown-unknown RUN apt update && apt install -y binaryen clang && rm -rf /var/lib/apt/lists/* From a921247234a73a06c913e530b5c0d29f702f5481 Mon Sep 17 00:00:00 2001 From: Assaf Morami Date: Tue, 2 Aug 2022 14:42:10 +0300 Subject: [PATCH 20/93] Some IBC progress --- .vscode/settings.json | 4 +- .../src/contract_operations.rs | 2 +- .../shared/cosmwasm-v1-types/src/ibc.rs | 123 ++++++++++++++++++ .../shared/cosmwasm-v1-types/src/lib.rs | 1 + .../testdata/v1-sanity-contract/src/msg.rs | 6 + 5 files changed, 134 insertions(+), 2 deletions(-) create mode 100644 cosmwasm/enclaves/shared/cosmwasm-v1-types/src/ibc.rs diff --git a/.vscode/settings.json b/.vscode/settings.json index 0b900924e..45d553f7d 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -3,7 +3,9 @@ "./cosmwasm/Cargo.toml", "./cosmwasm/enclaves/Cargo.toml", "./x/compute/internal/keeper/testdata/v1-sanity-contract/Cargo.toml", - "./x/compute/internal/keeper/testdata/test-contract/Cargo.toml" + "./x/compute/internal/keeper/testdata/test-contract/Cargo.toml", + "./cosmwasm/enclaves/shared/cosmwasm-v1-types/Cargo.toml", + "./cosmwasm/enclaves/shared/cosmwasm-v010-types/Cargo.toml" ], "rust-analyzer.diagnostics.experimental.enable": true, "rust-analyzer.rustfmt.rangeFormatting.enable": true, diff --git a/cosmwasm/enclaves/shared/contract-engine/src/contract_operations.rs b/cosmwasm/enclaves/shared/contract-engine/src/contract_operations.rs index dd9d91d94..980734985 100644 --- a/cosmwasm/enclaves/shared/contract-engine/src/contract_operations.rs +++ b/cosmwasm/enclaves/shared/contract-engine/src/contract_operations.rs @@ -538,7 +538,7 @@ pub fn parse_message( match orig_secret_msg.decrypt() { Ok(decrypted_msg) => { - // IBC packet is encrypted + // IBC packet was encrypted trace!( "ibc_packet_receive input before decryption: {:?}", diff --git a/cosmwasm/enclaves/shared/cosmwasm-v1-types/src/ibc.rs b/cosmwasm/enclaves/shared/cosmwasm-v1-types/src/ibc.rs new file mode 100644 index 000000000..311e89d0b --- /dev/null +++ b/cosmwasm/enclaves/shared/cosmwasm-v1-types/src/ibc.rs @@ -0,0 +1,123 @@ +use crate::addresses::Addr; +use crate::timestamp::Timestamp; +use serde::{Deserialize, Serialize}; + +/// The message that is passed into `ibc_channel_open` +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] +#[serde(rename_all = "snake_case")] +pub enum IbcChannelOpenMsg { + /// The ChanOpenInit step from https://github.com/cosmos/ibc/tree/master/spec/core/ics-004-channel-and-packet-semantics#channel-lifecycle-management + OpenInit { channel: IbcChannel }, + /// The ChanOpenTry step from https://github.com/cosmos/ibc/tree/master/spec/core/ics-004-channel-and-packet-semantics#channel-lifecycle-management + OpenTry { + channel: IbcChannel, + counterparty_version: String, + }, +} + +/// IbcChannel defines all information on a channel. +/// This is generally used in the hand-shake process, but can be queried directly. +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] +pub struct IbcChannel { + pub endpoint: IbcEndpoint, + pub counterparty_endpoint: IbcEndpoint, + pub order: IbcOrder, + /// Note: in ibcv3 this may be "", in the IbcOpenChannel handshake messages + pub version: String, + /// The connection upon which this channel was created. If this is a multi-hop + /// channel, we only expose the first hop. + pub connection_id: String, +} + +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] +pub struct IbcEndpoint { + pub port_id: String, + pub channel_id: String, +} + +/// IbcOrder defines if a channel is ORDERED or UNORDERED +/// Values come from https://github.com/cosmos/cosmos-sdk/blob/v0.40.0/proto/ibc/core/channel/v1/channel.proto#L69-L80 +/// Naming comes from the protobuf files and go translations. +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] +pub enum IbcOrder { + #[serde(rename = "ORDER_UNORDERED")] + Unordered, + #[serde(rename = "ORDER_ORDERED")] + Ordered, +} + +/// The message that is passed into `ibc_channel_connect` +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] +#[serde(rename_all = "snake_case")] +pub enum IbcChannelConnectMsg { + /// The ChanOpenAck step from https://github.com/cosmos/ibc/tree/master/spec/core/ics-004-channel-and-packet-semantics#channel-lifecycle-management + OpenAck { + channel: IbcChannel, + counterparty_version: String, + }, + /// The ChanOpenConfirm step from https://github.com/cosmos/ibc/tree/master/spec/core/ics-004-channel-and-packet-semantics#channel-lifecycle-management + OpenConfirm { channel: IbcChannel }, +} + +/// The message that is passed into `ibc_channel_close` +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] +#[serde(rename_all = "snake_case")] +pub enum IbcChannelCloseMsg { + /// The ChanCloseInit step from https://github.com/cosmos/ibc/tree/master/spec/core/ics-004-channel-and-packet-semantics#channel-lifecycle-management + CloseInit { channel: IbcChannel }, + /// The ChanCloseConfirm step from https://github.com/cosmos/ibc/tree/master/spec/core/ics-004-channel-and-packet-semantics#channel-lifecycle-management + CloseConfirm { channel: IbcChannel }, // pub channel: IbcChannel, +} + +/// The message that is passed into `ibc_packet_receive` +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] +pub struct IbcPacketReceiveMsg { + pub packet: IbcPacket, + pub relayer: Addr, +} + +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] +pub struct IbcPacket { + /// The raw data sent from the other side in the packet + pub data: Binary, + /// identifies the channel and port on the sending chain. + pub src: IbcEndpoint, + /// identifies the channel and port on the receiving chain. + pub dest: IbcEndpoint, + /// The sequence number of the packet on the given channel + pub sequence: u64, + pub timeout: IbcTimeout, +} + +/// In IBC each package must set at least one type of timeout: +/// the timestamp or the block height. Using this rather complex enum instead of +/// two timeout fields we ensure that at least one timeout is set. +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] +#[serde(rename_all = "snake_case")] +pub struct IbcTimeout { + // use private fields to enforce the use of constructors, which ensure that at least one is set + block: Option, + timestamp: Option, +} + +/// IBCTimeoutHeight Height is a monotonically increasing data type +/// that can be compared against another Height for the purposes of updating and +/// freezing clients. +/// Ordering is (revision_number, timeout_height) +#[derive(Serialize, Deserialize, Copy, Clone, Debug, PartialEq, Eq)] +pub struct IbcTimeoutBlock { + /// the version that the client is currently on + /// (eg. after reseting the chain this could increment 1 as height drops to 0) + pub revision: u64, + /// block height after which the packet times out. + /// the height within the given revision + pub height: u64, +} + +/// The message that is passed into `ibc_packet_ack` +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] +pub struct IbcPacketAckMsg { + pub acknowledgement: IbcAcknowledgement, + pub original_packet: IbcPacket, + pub relayer: Addr, +} diff --git a/cosmwasm/enclaves/shared/cosmwasm-v1-types/src/lib.rs b/cosmwasm/enclaves/shared/cosmwasm-v1-types/src/lib.rs index 310434644..62f52dc66 100644 --- a/cosmwasm/enclaves/shared/cosmwasm-v1-types/src/lib.rs +++ b/cosmwasm/enclaves/shared/cosmwasm-v1-types/src/lib.rs @@ -2,6 +2,7 @@ pub mod addresses; pub mod coins; pub mod errors; +pub mod ibc; pub mod math; pub mod results; pub mod timestamp; diff --git a/x/compute/internal/keeper/testdata/v1-sanity-contract/src/msg.rs b/x/compute/internal/keeper/testdata/v1-sanity-contract/src/msg.rs index 929213d67..4b8253550 100644 --- a/x/compute/internal/keeper/testdata/v1-sanity-contract/src/msg.rs +++ b/x/compute/internal/keeper/testdata/v1-sanity-contract/src/msg.rs @@ -141,6 +141,12 @@ pub enum ExecuteMsg { SubMsgLoopIner { iter: u64, }, + SentFunds { +to_type: "init"/"exec" +to_contract: "secret1.." +to_contract_hash: "ABC" +funds + }, MultipleSubMessages {}, MultipleSubMessagesNoReply {}, QuickError {}, From d7ee442943c655770871a606c77f72caf7da8b21 Mon Sep 17 00:00:00 2001 From: Assaf Morami Date: Thu, 11 Aug 2022 10:02:07 +0300 Subject: [PATCH 21/93] Revert a stupid change --- .../internal/keeper/testdata/v1-sanity-contract/src/msg.rs | 6 ------ 1 file changed, 6 deletions(-) diff --git a/x/compute/internal/keeper/testdata/v1-sanity-contract/src/msg.rs b/x/compute/internal/keeper/testdata/v1-sanity-contract/src/msg.rs index 4b8253550..929213d67 100644 --- a/x/compute/internal/keeper/testdata/v1-sanity-contract/src/msg.rs +++ b/x/compute/internal/keeper/testdata/v1-sanity-contract/src/msg.rs @@ -141,12 +141,6 @@ pub enum ExecuteMsg { SubMsgLoopIner { iter: u64, }, - SentFunds { -to_type: "init"/"exec" -to_contract: "secret1.." -to_contract_hash: "ABC" -funds - }, MultipleSubMessages {}, MultipleSubMessagesNoReply {}, QuickError {}, From 5c22a983865a6057547ff91c8ea05ed6f99f6ebc Mon Sep 17 00:00:00 2001 From: Lior Bondarevski Date: Thu, 11 Aug 2022 23:31:39 +0300 Subject: [PATCH 22/93] Decrypt only data from IBC --- .../src/contract_operations.rs | 37 +++++++++++++++++-- 1 file changed, 34 insertions(+), 3 deletions(-) diff --git a/cosmwasm/enclaves/shared/contract-engine/src/contract_operations.rs b/cosmwasm/enclaves/shared/contract-engine/src/contract_operations.rs index 980734985..ab9010c5c 100644 --- a/cosmwasm/enclaves/shared/contract-engine/src/contract_operations.rs +++ b/cosmwasm/enclaves/shared/contract-engine/src/contract_operations.rs @@ -11,6 +11,7 @@ use enclave_cosmos_types::types::{ContractCode, HandleType, SigInfo}; use enclave_cosmwasm_v010_types as cosmwasm_v010_types; use enclave_cosmwasm_v010_types::encoding::Binary; use enclave_cosmwasm_v1_types::addresses::Addr; +use enclave_cosmwasm_v1_types::ibc::{IbcPacket, IbcPacketReceiveMsg}; use enclave_cosmwasm_v1_types::results::{ DecryptedReply, Event, Reply, SubMsgResponse, SubMsgResult, }; @@ -315,7 +316,6 @@ pub fn parse_message( }); } - // Here we are sure the reply is OK because only OK is encrypted trace!( "reply input before decryption: {:?}", base64::encode(&message) @@ -520,6 +520,7 @@ pub fn parse_message( HandleType::HANDLE_TYPE_IBC_CHANNEL_CONNECT => todo!(), HandleType::HANDLE_TYPE_IBC_CHANNEL_CLOSE => todo!(), HandleType::HANDLE_TYPE_IBC_PACKET_RECEIVE => { + // LIORRR TODO: Maybe mark whether the message was encrypted or not. let orig_secret_msg = match SecretMessage::from_slice(message) { Ok(orig_secret_msg) => orig_secret_msg, Err(_) => { @@ -536,7 +537,29 @@ pub fn parse_message( } }; - match orig_secret_msg.decrypt() { + let mut parsed_encrypted_ibc_packet_receive_msg: IbcPacketReceiveMsg = serde_json::from_slice( + &orig_secret_msg.msg.as_slice().to_vec(), + ) + .map_err(|err| { + warn!( + "IbcPacketReceiveMsg got an error while trying to deserialize msg input bytes into json {:?}: {}", + String::from_utf8_lossy(&orig_secret_msg.msg), + err + ); + EnclaveError::FailedToDeserialize + })?; + + let tmp_secret_data = SecretMessage { + nonce: orig_secret_msg.nonce, + user_public_key: orig_secret_msg.user_public_key, + msg: parsed_encrypted_ibc_packet_receive_msg + .packet + .data + .as_slice() + .to_vec(), + }; + + match tmp_secret_data.decrypt() { Ok(decrypted_msg) => { // IBC packet was encrypted @@ -545,11 +568,19 @@ pub fn parse_message( base64::encode(&message) ); + parsed_encrypted_ibc_packet_receive_msg.packet.data = tmp_secret_data; + Ok(ParsedMessage { should_validate_sig_info: true, was_msg_encrypted: true, secret_msg: orig_secret_msg, - decrypted_msg, + decrypted_msg: serde_json::to_vec(&parsed_encrypted_ibc_packet_receive_msg).map_err(|err| { + warn!( + "got an error while trying to serialize IbcPacketReceive into bytes {:?}: {}", + parsed_encrypted_ibc_packet_receive_msg, err + ); + EnclaveError::FailedToSerialize + })?, contract_hash_for_validation: None, }) } From 752c3379ac01cfba7c441631577b612b8f574c61 Mon Sep 17 00:00:00 2001 From: Lior Bondarevski Date: Fri, 12 Aug 2022 01:03:17 +0300 Subject: [PATCH 23/93] Fix compilation --- .../src/contract_operations.rs | 9 ++-- .../shared/contract-engine/src/wasm/engine.rs | 42 +++++++++++++++++++ .../shared/cosmwasm-v1-types/src/ibc.rs | 7 ++++ 3 files changed, 55 insertions(+), 3 deletions(-) diff --git a/cosmwasm/enclaves/shared/contract-engine/src/contract_operations.rs b/cosmwasm/enclaves/shared/contract-engine/src/contract_operations.rs index ab9010c5c..5aec01c35 100644 --- a/cosmwasm/enclaves/shared/contract-engine/src/contract_operations.rs +++ b/cosmwasm/enclaves/shared/contract-engine/src/contract_operations.rs @@ -11,7 +11,7 @@ use enclave_cosmos_types::types::{ContractCode, HandleType, SigInfo}; use enclave_cosmwasm_v010_types as cosmwasm_v010_types; use enclave_cosmwasm_v010_types::encoding::Binary; use enclave_cosmwasm_v1_types::addresses::Addr; -use enclave_cosmwasm_v1_types::ibc::{IbcPacket, IbcPacketReceiveMsg}; +use enclave_cosmwasm_v1_types::ibc::IbcPacketReceiveMsg; use enclave_cosmwasm_v1_types::results::{ DecryptedReply, Event, Reply, SubMsgResponse, SubMsgResult, }; @@ -568,7 +568,8 @@ pub fn parse_message( base64::encode(&message) ); - parsed_encrypted_ibc_packet_receive_msg.packet.data = tmp_secret_data; + parsed_encrypted_ibc_packet_receive_msg.packet.data = + decrypted_msg.as_slice().into(); Ok(ParsedMessage { should_validate_sig_info: true, @@ -592,11 +593,13 @@ pub fn parse_message( base64::encode(&message) ); + let decrypted_msg = orig_secret_msg.msg.clone(); + Ok(ParsedMessage { should_validate_sig_info: false, was_msg_encrypted: false, secret_msg: orig_secret_msg, - decrypted_msg: orig_secret_msg.msg, + decrypted_msg, contract_hash_for_validation: None, }) } diff --git a/cosmwasm/enclaves/shared/contract-engine/src/wasm/engine.rs b/cosmwasm/enclaves/shared/contract-engine/src/wasm/engine.rs index 880cb9970..957ac76ad 100644 --- a/cosmwasm/enclaves/shared/contract-engine/src/wasm/engine.rs +++ b/cosmwasm/enclaves/shared/contract-engine/src/wasm/engine.rs @@ -146,6 +146,48 @@ impl Engine { RuntimeValue::I32(msg_ptr as i32), ], ), + HandleType::HANDLE_TYPE_IBC_CHANNEL_OPEN => ( + "ibc_channel_open", + vec![ + RuntimeValue::I32(env_ptr as i32), + RuntimeValue::I32(msg_ptr as i32), + ], + ), + HandleType::HANDLE_TYPE_IBC_CHANNEL_CONNECT => ( + "ibc_channel_connect", + vec![ + RuntimeValue::I32(env_ptr as i32), + RuntimeValue::I32(msg_ptr as i32), + ], + ), + HandleType::HANDLE_TYPE_IBC_CHANNEL_CLOSE => ( + "ibc_channel_close", + vec![ + RuntimeValue::I32(env_ptr as i32), + RuntimeValue::I32(msg_ptr as i32), + ], + ), + HandleType::HANDLE_TYPE_IBC_PACKET_RECEIVE => ( + "ibc_packet_receive", + vec![ + RuntimeValue::I32(env_ptr as i32), + RuntimeValue::I32(msg_ptr as i32), + ], + ), + HandleType::HANDLE_TYPE_IBC_PACKET_ACK => ( + "ibc_packet_ack", + vec![ + RuntimeValue::I32(env_ptr as i32), + RuntimeValue::I32(msg_ptr as i32), + ], + ), + HandleType::HANDLE_TYPE_IBC_PACKET_TIMEOUT => ( + "ibc_packet_timeout", + vec![ + RuntimeValue::I32(env_ptr as i32), + RuntimeValue::I32(msg_ptr as i32), + ], + ), }, }; diff --git a/cosmwasm/enclaves/shared/cosmwasm-v1-types/src/ibc.rs b/cosmwasm/enclaves/shared/cosmwasm-v1-types/src/ibc.rs index 311e89d0b..ed1854d70 100644 --- a/cosmwasm/enclaves/shared/cosmwasm-v1-types/src/ibc.rs +++ b/cosmwasm/enclaves/shared/cosmwasm-v1-types/src/ibc.rs @@ -1,5 +1,6 @@ use crate::addresses::Addr; use crate::timestamp::Timestamp; +use enclave_cosmwasm_v010_types::encoding::Binary; use serde::{Deserialize, Serialize}; /// The message that is passed into `ibc_channel_open` @@ -89,6 +90,12 @@ pub struct IbcPacket { pub timeout: IbcTimeout, } +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] +#[non_exhaustive] +pub struct IbcAcknowledgement { + pub data: Binary, +} + /// In IBC each package must set at least one type of timeout: /// the timestamp or the block height. Using this rather complex enum instead of /// two timeout fields we ensure that at least one timeout is set. From 05bad147c095dd40d95f50ea3c206dfd06b062ec Mon Sep 17 00:00:00 2001 From: Lior Bondarevski Date: Sun, 14 Aug 2022 13:55:43 +0300 Subject: [PATCH 24/93] Parse every IBC submessage --- .../src/contract_operations.rs | 253 ++++++++++++++++-- .../enclaves/shared/contract-engine/src/io.rs | 29 ++ .../enclaves/shared/cosmos-types/src/types.rs | 13 + .../shared/cosmwasm-v1-types/src/ibc.rs | 45 +++- 4 files changed, 322 insertions(+), 18 deletions(-) diff --git a/cosmwasm/enclaves/shared/contract-engine/src/contract_operations.rs b/cosmwasm/enclaves/shared/contract-engine/src/contract_operations.rs index 5aec01c35..98aa1e219 100644 --- a/cosmwasm/enclaves/shared/contract-engine/src/contract_operations.rs +++ b/cosmwasm/enclaves/shared/contract-engine/src/contract_operations.rs @@ -11,7 +11,7 @@ use enclave_cosmos_types::types::{ContractCode, HandleType, SigInfo}; use enclave_cosmwasm_v010_types as cosmwasm_v010_types; use enclave_cosmwasm_v010_types::encoding::Binary; use enclave_cosmwasm_v1_types::addresses::Addr; -use enclave_cosmwasm_v1_types::ibc::IbcPacketReceiveMsg; +use enclave_cosmwasm_v1_types::ibc::{IbcPacketAckMsg, IbcPacketReceiveMsg, IbcPacketTimeoutMsg}; use enclave_cosmwasm_v1_types::results::{ DecryptedReply, Event, Reply, SubMsgResponse, SubMsgResult, }; @@ -174,6 +174,7 @@ pub fn init( pub struct ParsedMessage { pub should_validate_sig_info: bool, pub was_msg_encrypted: bool, + pub is_ibc_msg: bool, pub secret_msg: SecretMessage, pub decrypted_msg: Vec, pub contract_hash_for_validation: Option>, @@ -238,6 +239,7 @@ pub fn parse_message( Ok(ParsedMessage { should_validate_sig_info: true, was_msg_encrypted: true, + is_ibc_msg: false, secret_msg: orig_secret_msg, decrypted_msg, contract_hash_for_validation: None, @@ -310,6 +312,7 @@ pub fn parse_message( return Ok(ParsedMessage { should_validate_sig_info: false, was_msg_encrypted: false, + is_ibc_msg: false, secret_msg: reply_secret_msg, decrypted_msg: serialized_reply, contract_hash_for_validation: None, @@ -414,6 +417,7 @@ pub fn parse_message( Ok(ParsedMessage { should_validate_sig_info: true, was_msg_encrypted: true, + is_ibc_msg: false, secret_msg: reply_secret_msg, decrypted_msg: decrypted_reply_as_vec, contract_hash_for_validation: Some( @@ -507,6 +511,7 @@ pub fn parse_message( Ok(ParsedMessage { should_validate_sig_info: true, was_msg_encrypted: true, + is_ibc_msg: false, secret_msg: reply_secret_msg, decrypted_msg: decrypted_reply_as_vec, contract_hash_for_validation: Some( @@ -516,9 +521,32 @@ pub fn parse_message( } } } - HandleType::HANDLE_TYPE_IBC_CHANNEL_OPEN => todo!(), - HandleType::HANDLE_TYPE_IBC_CHANNEL_CONNECT => todo!(), - HandleType::HANDLE_TYPE_IBC_CHANNEL_CLOSE => todo!(), + HandleType::HANDLE_TYPE_IBC_CHANNEL_OPEN + | HandleType::HANDLE_TYPE_IBC_CHANNEL_CONNECT + | HandleType::HANDLE_TYPE_IBC_CHANNEL_CLOSE => { + trace!( + "parsing {} msg (Should always be plaintext): {:?}", + HandleType::to_export_name(&handle_type), + base64::encode(&message) + ); + + let scrt_msg = SecretMessage { + nonce: [0; 32], + user_public_key: [0; 32], + msg: message.into(), + }; + + let decrypted_msg = scrt_msg.msg.clone(); + + Ok(ParsedMessage { + should_validate_sig_info: false, + was_msg_encrypted: false, + is_ibc_msg: true, + secret_msg: scrt_msg, + decrypted_msg, + contract_hash_for_validation: None, + }) + } HandleType::HANDLE_TYPE_IBC_PACKET_RECEIVE => { // LIORRR TODO: Maybe mark whether the message was encrypted or not. let orig_secret_msg = match SecretMessage::from_slice(message) { @@ -542,7 +570,7 @@ pub fn parse_message( ) .map_err(|err| { warn!( - "IbcPacketReceiveMsg got an error while trying to deserialize msg input bytes into json {:?}: {}", + "ibc_packet_receive msg got an error while trying to deserialize msg input bytes into json {:?}: {}", String::from_utf8_lossy(&orig_secret_msg.msg), err ); @@ -574,6 +602,7 @@ pub fn parse_message( Ok(ParsedMessage { should_validate_sig_info: true, was_msg_encrypted: true, + is_ibc_msg: true, secret_msg: orig_secret_msg, decrypted_msg: serde_json::to_vec(&parsed_encrypted_ibc_packet_receive_msg).map_err(|err| { warn!( @@ -598,6 +627,194 @@ pub fn parse_message( Ok(ParsedMessage { should_validate_sig_info: false, was_msg_encrypted: false, + is_ibc_msg: true, + secret_msg: orig_secret_msg, + decrypted_msg, + contract_hash_for_validation: None, + }) + } + } + } + HandleType::HANDLE_TYPE_IBC_PACKET_ACK => { + // LIORRR TODO: Maybe mark whether the message was encrypted or not. + let orig_secret_msg = match SecretMessage::from_slice(message) { + Ok(orig_secret_msg) => orig_secret_msg, + Err(_) => { + trace!( + "ibc_packet_ack msg is not SecretMessage (probably plaintext): {:?}", + base64::encode(&message) + ); + + SecretMessage { + nonce: [0; 32], + user_public_key: [0; 32], + msg: message.into(), + } + } + }; + + let mut parsed_encrypted_ibc_packet_ack_msg: IbcPacketAckMsg = serde_json::from_slice( + &orig_secret_msg.msg.as_slice().to_vec(), + ).map_err(|err| { + warn!( + "ibc_packet_ack msg got an error while trying to deserialize msg input bytes into json {:?}: {}", + String::from_utf8_lossy(&orig_secret_msg.msg), + err + ); + EnclaveError::FailedToDeserialize + })?; + + let tmp_secret_data = SecretMessage { + nonce: orig_secret_msg.nonce, + user_public_key: orig_secret_msg.user_public_key, + msg: parsed_encrypted_ibc_packet_ack_msg + .original_packet + .data + .as_slice() + .to_vec(), + }; + + match tmp_secret_data.decrypt() { + Ok(decrypted_msg) => { + // IBC packet was encrypted + + trace!( + "ibc_packet_receive input before decryption: {:?}", + base64::encode(&message) + ); + + parsed_encrypted_ibc_packet_ack_msg.original_packet.data = + decrypted_msg.as_slice().into(); + + let tmp_secret_ack_data = SecretMessage { + nonce: orig_secret_msg.nonce, + user_public_key: orig_secret_msg.user_public_key, + msg: parsed_encrypted_ibc_packet_ack_msg + .acknowledgement + .data + .as_slice() + .to_vec(), + }; + + parsed_encrypted_ibc_packet_ack_msg.acknowledgement.data = + tmp_secret_ack_data.decrypt()?.as_slice().into(); + + Ok(ParsedMessage { + should_validate_sig_info: true, + was_msg_encrypted: true, + is_ibc_msg: true, + secret_msg: orig_secret_msg, + decrypted_msg: serde_json::to_vec(&parsed_encrypted_ibc_packet_ack_msg).map_err(|err| { + warn!( + "got an error while trying to serialize ibc_packet_ack msg into bytes {:?}: {}", + parsed_encrypted_ibc_packet_ack_msg, err + ); + EnclaveError::FailedToSerialize + })?, + contract_hash_for_validation: None, + }) + } + Err(_) => { + // assume packet is not encrypted, continue in plaintext mode + + trace!( + "ibc_packet_ack input is not encrypted: {:?}", + base64::encode(&message) + ); + + let decrypted_msg = orig_secret_msg.msg.clone(); + + Ok(ParsedMessage { + should_validate_sig_info: false, + was_msg_encrypted: false, + is_ibc_msg: true, + secret_msg: orig_secret_msg, + decrypted_msg, + contract_hash_for_validation: None, + }) + } + } + } + HandleType::HANDLE_TYPE_IBC_PACKET_TIMEOUT => { + // LIORRR TODO: Maybe mark whether the message was encrypted or not. + let orig_secret_msg = match SecretMessage::from_slice(message) { + Ok(orig_secret_msg) => orig_secret_msg, + Err(_) => { + trace!( + "ibc_packet_timeout msg is not SecretMessage (probably plaintext): {:?}", + base64::encode(&message) + ); + + SecretMessage { + nonce: [0; 32], + user_public_key: [0; 32], + msg: message.into(), + } + } + }; + + let mut parsed_encrypted_ibc_packet_timeout_msg: IbcPacketTimeoutMsg = serde_json::from_slice( + &orig_secret_msg.msg.as_slice().to_vec(), + ).map_err(|err| { + warn!( + "ibc_packet_timeout msg got an error while trying to deserialize msg input bytes into json {:?}: {}", + String::from_utf8_lossy(&orig_secret_msg.msg), + err + ); + EnclaveError::FailedToDeserialize + })?; + + let tmp_secret_data = SecretMessage { + nonce: orig_secret_msg.nonce, + user_public_key: orig_secret_msg.user_public_key, + msg: parsed_encrypted_ibc_packet_timeout_msg + .packet + .data + .as_slice() + .to_vec(), + }; + + match tmp_secret_data.decrypt() { + Ok(decrypted_msg) => { + // IBC packet was encrypted + + trace!( + "ibc_packet_timeout input before decryption: {:?}", + base64::encode(&message) + ); + + parsed_encrypted_ibc_packet_timeout_msg.packet.data = + decrypted_msg.as_slice().into(); + + Ok(ParsedMessage { + should_validate_sig_info: true, + was_msg_encrypted: true, + is_ibc_msg: true, + secret_msg: orig_secret_msg, + decrypted_msg: serde_json::to_vec(&parsed_encrypted_ibc_packet_timeout_msg).map_err(|err| { + warn!( + "got an error while trying to serialize ibc_packet_timeout msg into bytes {:?}: {}", + parsed_encrypted_ibc_packet_timeout_msg, err + ); + EnclaveError::FailedToSerialize + })?, + contract_hash_for_validation: None, + }) + } + Err(_) => { + // assume packet is not encrypted, continue in plaintext mode + + trace!( + "ibc_packet_timeout input is not encrypted: {:?}", + base64::encode(&message) + ); + + let decrypted_msg = orig_secret_msg.msg.clone(); + + Ok(ParsedMessage { + should_validate_sig_info: false, + was_msg_encrypted: false, + is_ibc_msg: true, secret_msg: orig_secret_msg, decrypted_msg, contract_hash_for_validation: None, @@ -605,8 +822,6 @@ pub fn parse_message( } } } - HandleType::HANDLE_TYPE_IBC_PACKET_ACK => todo!(), - HandleType::HANDLE_TYPE_IBC_PACKET_TIMEOUT => todo!(), }; } @@ -674,6 +889,7 @@ pub fn handle( let ParsedMessage { should_validate_sig_info, was_msg_encrypted, + is_ibc_msg, secret_msg, decrypted_msg, contract_hash_for_validation, @@ -734,22 +950,25 @@ pub fn handle( let output = coalesce!(EnclaveError, { let vec_ptr = engine.handle(env_ptr, msg_info_ptr, msg_ptr, parsed_handle_type)?; - let output = engine.extract_vector(vec_ptr)?; + let mut output = engine.extract_vector(vec_ptr)?; debug!( "(2) nonce just before encrypt_output: nonce = {:?} pubkey = {:?}", secret_msg.nonce, secret_msg.user_public_key ); - let output = encrypt_output( - output, - &secret_msg, - &canonical_contract_address, - &env_v010.contract_code_hash, - reply_params, - &canonical_sender_address, - false, - )?; + if !is_ibc_msg || was_msg_encrypted { + output = encrypt_output( + output, + &secret_msg, + &canonical_contract_address, + &env_v010.contract_code_hash, + reply_params, + &canonical_sender_address, + false, + )?; + } + Ok(output) }) .map_err(|err| { diff --git a/cosmwasm/enclaves/shared/contract-engine/src/io.rs b/cosmwasm/enclaves/shared/contract-engine/src/io.rs index 4ddcc6e8f..99685f8af 100644 --- a/cosmwasm/enclaves/shared/contract-engine/src/io.rs +++ b/cosmwasm/enclaves/shared/contract-engine/src/io.rs @@ -52,6 +52,12 @@ enum RawWasmOutput { internal_reply_enclave_sig: Option, internal_msg_id: Option, }, + OkIBC { + #[serde(rename = "Ok")] + ok: enclave_cosmwasm_v1_types::ibc::IbcBasicResponse, + internal_reply_enclave_sig: Option, + internal_msg_id: Option, + }, } #[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] @@ -429,6 +435,13 @@ pub fn encrypt_output( None => None, // Not a reply, we don't need enclave sig } } + RawWasmOutput::OkIBC { + ok, + internal_reply_enclave_sig, + internal_msg_id, + } => { + //LIORRR TODO encryption + } }; let final_output: WasmOutput = match output { @@ -499,6 +512,22 @@ pub fn encrypt_output( internal_reply_enclave_sig: None, internal_msg_id: None, }, + + // LIORRRR TODO: make it work, maybe the same as in v1 response? + RawWasmOutput::OkIBC { + ok, + internal_reply_enclave_sig, + internal_msg_id, + } => WasmOutput { + v010: None, + v1: None, + query: Some(QueryOutput { + ok: None, + err: None, + }), + internal_reply_enclave_sig: None, + internal_msg_id: None, + }, }; trace!("WasmOutput: {:?}", final_output); diff --git a/cosmwasm/enclaves/shared/cosmos-types/src/types.rs b/cosmwasm/enclaves/shared/cosmos-types/src/types.rs index b86c0460d..39cf0dc5e 100644 --- a/cosmwasm/enclaves/shared/cosmos-types/src/types.rs +++ b/cosmwasm/enclaves/shared/cosmos-types/src/types.rs @@ -165,6 +165,19 @@ impl HandleType { } } } + + pub fn to_export_name(h: &HandleType) -> String { + match h { + HandleType::HANDLE_TYPE_EXECUTE => "execute".to_string(), + HandleType::HANDLE_TYPE_REPLY => "reply".to_string(), + HandleType::HANDLE_TYPE_IBC_CHANNEL_OPEN => "ibc_channel_open".to_string(), + HandleType::HANDLE_TYPE_IBC_CHANNEL_CONNECT => "ibc_channel_connect".to_string(), + HandleType::HANDLE_TYPE_IBC_CHANNEL_CLOSE => "ibc_channel_close".to_string(), + HandleType::HANDLE_TYPE_IBC_PACKET_RECEIVE => "ibc_packet_receive".to_string(), + HandleType::HANDLE_TYPE_IBC_PACKET_ACK => "ibc_packet_ack".to_string(), + HandleType::HANDLE_TYPE_IBC_PACKET_TIMEOUT => "ibc_packet_timeout".to_string(), + } + } } // This is called `VerificationInfo` on the Go side diff --git a/cosmwasm/enclaves/shared/cosmwasm-v1-types/src/ibc.rs b/cosmwasm/enclaves/shared/cosmwasm-v1-types/src/ibc.rs index ed1854d70..7ec4cdd0e 100644 --- a/cosmwasm/enclaves/shared/cosmwasm-v1-types/src/ibc.rs +++ b/cosmwasm/enclaves/shared/cosmwasm-v1-types/src/ibc.rs @@ -1,7 +1,9 @@ use crate::addresses::Addr; +use crate::results::{Event, SubMsg}; use crate::timestamp::Timestamp; -use enclave_cosmwasm_v010_types::encoding::Binary; +use enclave_cosmwasm_v010_types::{encoding::Binary, types::Empty, types::LogAttribute}; use serde::{Deserialize, Serialize}; +use std::fmt; /// The message that is passed into `ibc_channel_open` #[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] @@ -30,6 +32,39 @@ pub struct IbcChannel { pub connection_id: String, } +/// This is the return value for the majority of the ibc handlers. +/// That are able to dispatch messages / events on their own, +/// but have no meaningful return value to the calling code. +/// +/// Callbacks that have return values (like receive_packet) +/// or that cannot redispatch messages (like the handshake callbacks) +/// will use other Response types +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] +#[non_exhaustive] +pub struct IbcBasicResponse +where + T: Clone + fmt::Debug + PartialEq, +{ + /// Optional list of messages to pass. These will be executed in order. + /// If the ReplyOn member is set, they will invoke this contract's `reply` entry point + /// after execution. Otherwise, they act like "fire and forget". + /// Use `SubMsg::new` to create messages with the older "fire and forget" semantics. + pub messages: Vec>, + /// The attributes that will be emitted as part of a `wasm` event. + /// + /// More info about events (and their attributes) can be found in [*Cosmos SDK* docs]. + /// + /// [*Cosmos SDK* docs]: https://docs.cosmos.network/v0.42/core/events.html + pub attributes: Vec, + /// Extra, custom events separate from the main `wasm` one. These will have + /// `wasm-` prepended to the type. + /// + /// More info about events can be found in [*Cosmos SDK* docs]. + /// + /// [*Cosmos SDK* docs]: https://docs.cosmos.network/v0.42/core/events.html + pub events: Vec, +} + #[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] pub struct IbcEndpoint { pub port_id: String, @@ -128,3 +163,11 @@ pub struct IbcPacketAckMsg { pub original_packet: IbcPacket, pub relayer: Addr, } + +/// The message that is passed into `ibc_packet_timeout` +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] +#[non_exhaustive] +pub struct IbcPacketTimeoutMsg { + pub packet: IbcPacket, + pub relayer: Addr, +} From 92772fe6a12693b3a2caee1efacebb744e107b6a Mon Sep 17 00:00:00 2001 From: Lior Bondarevski Date: Mon, 15 Aug 2022 19:03:52 +0300 Subject: [PATCH 25/93] Make IBC handling nicer --- .../src/contract_operations.rs | 416 +++++++----------- .../shared/cosmwasm-v1-types/src/ibc.rs | 112 +++++ 2 files changed, 262 insertions(+), 266 deletions(-) diff --git a/cosmwasm/enclaves/shared/contract-engine/src/contract_operations.rs b/cosmwasm/enclaves/shared/contract-engine/src/contract_operations.rs index 98aa1e219..958dc2021 100644 --- a/cosmwasm/enclaves/shared/contract-engine/src/contract_operations.rs +++ b/cosmwasm/enclaves/shared/contract-engine/src/contract_operations.rs @@ -1,4 +1,7 @@ use log::*; +use serde::de::DeserializeOwned; +use serde::Serialize; +use std::fmt::Debug; use enclave_ffi_types::{Ctx, EnclaveError}; @@ -11,7 +14,9 @@ use enclave_cosmos_types::types::{ContractCode, HandleType, SigInfo}; use enclave_cosmwasm_v010_types as cosmwasm_v010_types; use enclave_cosmwasm_v010_types::encoding::Binary; use enclave_cosmwasm_v1_types::addresses::Addr; -use enclave_cosmwasm_v1_types::ibc::{IbcPacketAckMsg, IbcPacketReceiveMsg, IbcPacketTimeoutMsg}; +use enclave_cosmwasm_v1_types::ibc::{ + IbcPacketAckMsg, IbcPacketReceiveMsg, IbcPacketTimeoutMsg, IbcPacketTrait, +}; use enclave_cosmwasm_v1_types::results::{ DecryptedReply, Event, Reply, SubMsgResponse, SubMsgResult, }; @@ -180,6 +185,11 @@ pub struct ParsedMessage { pub contract_hash_for_validation: Option>, } +pub struct DecryptedSecretMessage { + pub secret_msg: SecretMessage, + pub decrypted_msg: Vec, +} + pub fn redact_custom_events(reply: &mut Reply) { reply.result = match &reply.result { SubMsgResult::Ok(r) => { @@ -221,6 +231,125 @@ pub fn redact_custom_events(reply: &mut Reply) { }; } +pub fn get_secret_msg(message: &[u8]) -> SecretMessage { + match SecretMessage::from_slice(message) { + Ok(orig_secret_msg) => orig_secret_msg, + Err(_) => { + trace!( + "Msg is not SecretMessage (probably plaintext): {:?}", + base64::encode(&message) + ); + + return SecretMessage { + nonce: [0; 32], + user_public_key: [0; 32], + msg: message.into(), + }; + } + } +} + +pub fn try_get_decrypted_secret_msg(message: &[u8]) -> Option { + let secret_msg = get_secret_msg(message); + match secret_msg.decrypt() { + Ok(decrypted_msg) => Some(DecryptedSecretMessage { + secret_msg, + decrypted_msg, + }), + Err(_) => None, + } +} + +pub fn parse_ibc_packet( + _t: T, + message: &[u8], + orig_secret_msg: SecretMessage, + function_name: &str, +) -> Result +where + T: IbcPacketTrait + Serialize + DeserializeOwned + Debug, +{ + let mut parsed_encrypted_ibc_packet: T = + serde_json::from_slice(&orig_secret_msg.msg.as_slice().to_vec()).map_err(|err| { + warn!( + "{} msg got an error while trying to deserialize msg input bytes into json {:?}: {}", + function_name, + String::from_utf8_lossy(&orig_secret_msg.msg), + err + ); + EnclaveError::FailedToDeserialize + })?; + + let tmp_secret_data = SecretMessage { + nonce: orig_secret_msg.nonce, + user_public_key: orig_secret_msg.user_public_key, + msg: parsed_encrypted_ibc_packet.get_packet().as_slice().to_vec(), + }; + + match tmp_secret_data.decrypt() { + Ok(decrypted_msg) => { + // IBC packet was encrypted + + trace!( + "{} input before decryption: {:?}", + function_name, + base64::encode(&message) + ); + + parsed_encrypted_ibc_packet.set_packet(decrypted_msg.as_slice().into()); + + match parsed_encrypted_ibc_packet.get_ack() { + Some(ack_data) => { + let tmp_secret_ack_data = SecretMessage { + nonce: orig_secret_msg.nonce, + user_public_key: orig_secret_msg.user_public_key, + msg: ack_data.as_slice().to_vec(), + }; + + parsed_encrypted_ibc_packet + .set_ack(tmp_secret_ack_data.decrypt()?.as_slice().into()); + } + None => {} + } + + Ok(ParsedMessage { + should_validate_sig_info: true, + was_msg_encrypted: true, + is_ibc_msg: true, + secret_msg: orig_secret_msg, + decrypted_msg: serde_json::to_vec(&parsed_encrypted_ibc_packet).map_err(|err| { + warn!( + "got an error while trying to serialize {} msg into bytes {:?}: {}", + function_name, parsed_encrypted_ibc_packet, err + ); + EnclaveError::FailedToSerialize + })?, + contract_hash_for_validation: None, + }) + } + Err(_) => { + // assume packet is not encrypted, continue in plaintext mode + + trace!( + "{} input is not encrypted: {:?}", + function_name, + base64::encode(&message) + ); + + let decrypted_msg = orig_secret_msg.msg.clone(); + + Ok(ParsedMessage { + should_validate_sig_info: false, + was_msg_encrypted: false, + is_ibc_msg: true, + secret_msg: orig_secret_msg, + decrypted_msg, + contract_hash_for_validation: None, + }) + } + } +} + // Parse the message that was passed to handle (Based on the assumption that it might be a reply or IBC as well) pub fn parse_message( message: &[u8], @@ -549,278 +678,33 @@ pub fn parse_message( } HandleType::HANDLE_TYPE_IBC_PACKET_RECEIVE => { // LIORRR TODO: Maybe mark whether the message was encrypted or not. - let orig_secret_msg = match SecretMessage::from_slice(message) { - Ok(orig_secret_msg) => orig_secret_msg, - Err(_) => { - trace!( - "ibc_packet_receive msg is not SecretMessage (probably plaintext): {:?}", - base64::encode(&message) - ); - - SecretMessage { - nonce: [0; 32], - user_public_key: [0; 32], - msg: message.into(), - } - } - }; - - let mut parsed_encrypted_ibc_packet_receive_msg: IbcPacketReceiveMsg = serde_json::from_slice( - &orig_secret_msg.msg.as_slice().to_vec(), + let orig_secret_msg = get_secret_msg(message); + parse_ibc_packet( + IbcPacketReceiveMsg::default(), + message, + orig_secret_msg, + "ibc_packet_receive", ) - .map_err(|err| { - warn!( - "ibc_packet_receive msg got an error while trying to deserialize msg input bytes into json {:?}: {}", - String::from_utf8_lossy(&orig_secret_msg.msg), - err - ); - EnclaveError::FailedToDeserialize - })?; - - let tmp_secret_data = SecretMessage { - nonce: orig_secret_msg.nonce, - user_public_key: orig_secret_msg.user_public_key, - msg: parsed_encrypted_ibc_packet_receive_msg - .packet - .data - .as_slice() - .to_vec(), - }; - - match tmp_secret_data.decrypt() { - Ok(decrypted_msg) => { - // IBC packet was encrypted - - trace!( - "ibc_packet_receive input before decryption: {:?}", - base64::encode(&message) - ); - - parsed_encrypted_ibc_packet_receive_msg.packet.data = - decrypted_msg.as_slice().into(); - - Ok(ParsedMessage { - should_validate_sig_info: true, - was_msg_encrypted: true, - is_ibc_msg: true, - secret_msg: orig_secret_msg, - decrypted_msg: serde_json::to_vec(&parsed_encrypted_ibc_packet_receive_msg).map_err(|err| { - warn!( - "got an error while trying to serialize IbcPacketReceive into bytes {:?}: {}", - parsed_encrypted_ibc_packet_receive_msg, err - ); - EnclaveError::FailedToSerialize - })?, - contract_hash_for_validation: None, - }) - } - Err(_) => { - // assume packet is not encrypted, continue in plaintext mode - - trace!( - "ibc_packet_receive input is not encrypted: {:?}", - base64::encode(&message) - ); - - let decrypted_msg = orig_secret_msg.msg.clone(); - - Ok(ParsedMessage { - should_validate_sig_info: false, - was_msg_encrypted: false, - is_ibc_msg: true, - secret_msg: orig_secret_msg, - decrypted_msg, - contract_hash_for_validation: None, - }) - } - } } HandleType::HANDLE_TYPE_IBC_PACKET_ACK => { // LIORRR TODO: Maybe mark whether the message was encrypted or not. - let orig_secret_msg = match SecretMessage::from_slice(message) { - Ok(orig_secret_msg) => orig_secret_msg, - Err(_) => { - trace!( - "ibc_packet_ack msg is not SecretMessage (probably plaintext): {:?}", - base64::encode(&message) - ); - - SecretMessage { - nonce: [0; 32], - user_public_key: [0; 32], - msg: message.into(), - } - } - }; - - let mut parsed_encrypted_ibc_packet_ack_msg: IbcPacketAckMsg = serde_json::from_slice( - &orig_secret_msg.msg.as_slice().to_vec(), - ).map_err(|err| { - warn!( - "ibc_packet_ack msg got an error while trying to deserialize msg input bytes into json {:?}: {}", - String::from_utf8_lossy(&orig_secret_msg.msg), - err - ); - EnclaveError::FailedToDeserialize - })?; - - let tmp_secret_data = SecretMessage { - nonce: orig_secret_msg.nonce, - user_public_key: orig_secret_msg.user_public_key, - msg: parsed_encrypted_ibc_packet_ack_msg - .original_packet - .data - .as_slice() - .to_vec(), - }; - - match tmp_secret_data.decrypt() { - Ok(decrypted_msg) => { - // IBC packet was encrypted - - trace!( - "ibc_packet_receive input before decryption: {:?}", - base64::encode(&message) - ); - - parsed_encrypted_ibc_packet_ack_msg.original_packet.data = - decrypted_msg.as_slice().into(); - - let tmp_secret_ack_data = SecretMessage { - nonce: orig_secret_msg.nonce, - user_public_key: orig_secret_msg.user_public_key, - msg: parsed_encrypted_ibc_packet_ack_msg - .acknowledgement - .data - .as_slice() - .to_vec(), - }; - - parsed_encrypted_ibc_packet_ack_msg.acknowledgement.data = - tmp_secret_ack_data.decrypt()?.as_slice().into(); - - Ok(ParsedMessage { - should_validate_sig_info: true, - was_msg_encrypted: true, - is_ibc_msg: true, - secret_msg: orig_secret_msg, - decrypted_msg: serde_json::to_vec(&parsed_encrypted_ibc_packet_ack_msg).map_err(|err| { - warn!( - "got an error while trying to serialize ibc_packet_ack msg into bytes {:?}: {}", - parsed_encrypted_ibc_packet_ack_msg, err - ); - EnclaveError::FailedToSerialize - })?, - contract_hash_for_validation: None, - }) - } - Err(_) => { - // assume packet is not encrypted, continue in plaintext mode - - trace!( - "ibc_packet_ack input is not encrypted: {:?}", - base64::encode(&message) - ); - - let decrypted_msg = orig_secret_msg.msg.clone(); - - Ok(ParsedMessage { - should_validate_sig_info: false, - was_msg_encrypted: false, - is_ibc_msg: true, - secret_msg: orig_secret_msg, - decrypted_msg, - contract_hash_for_validation: None, - }) - } - } + let orig_secret_msg = get_secret_msg(message); + parse_ibc_packet( + IbcPacketAckMsg::default(), + message, + orig_secret_msg, + "ibc_packet_receive", + ) } HandleType::HANDLE_TYPE_IBC_PACKET_TIMEOUT => { // LIORRR TODO: Maybe mark whether the message was encrypted or not. - let orig_secret_msg = match SecretMessage::from_slice(message) { - Ok(orig_secret_msg) => orig_secret_msg, - Err(_) => { - trace!( - "ibc_packet_timeout msg is not SecretMessage (probably plaintext): {:?}", - base64::encode(&message) - ); - - SecretMessage { - nonce: [0; 32], - user_public_key: [0; 32], - msg: message.into(), - } - } - }; - - let mut parsed_encrypted_ibc_packet_timeout_msg: IbcPacketTimeoutMsg = serde_json::from_slice( - &orig_secret_msg.msg.as_slice().to_vec(), - ).map_err(|err| { - warn!( - "ibc_packet_timeout msg got an error while trying to deserialize msg input bytes into json {:?}: {}", - String::from_utf8_lossy(&orig_secret_msg.msg), - err - ); - EnclaveError::FailedToDeserialize - })?; - - let tmp_secret_data = SecretMessage { - nonce: orig_secret_msg.nonce, - user_public_key: orig_secret_msg.user_public_key, - msg: parsed_encrypted_ibc_packet_timeout_msg - .packet - .data - .as_slice() - .to_vec(), - }; - - match tmp_secret_data.decrypt() { - Ok(decrypted_msg) => { - // IBC packet was encrypted - - trace!( - "ibc_packet_timeout input before decryption: {:?}", - base64::encode(&message) - ); - - parsed_encrypted_ibc_packet_timeout_msg.packet.data = - decrypted_msg.as_slice().into(); - - Ok(ParsedMessage { - should_validate_sig_info: true, - was_msg_encrypted: true, - is_ibc_msg: true, - secret_msg: orig_secret_msg, - decrypted_msg: serde_json::to_vec(&parsed_encrypted_ibc_packet_timeout_msg).map_err(|err| { - warn!( - "got an error while trying to serialize ibc_packet_timeout msg into bytes {:?}: {}", - parsed_encrypted_ibc_packet_timeout_msg, err - ); - EnclaveError::FailedToSerialize - })?, - contract_hash_for_validation: None, - }) - } - Err(_) => { - // assume packet is not encrypted, continue in plaintext mode - - trace!( - "ibc_packet_timeout input is not encrypted: {:?}", - base64::encode(&message) - ); - - let decrypted_msg = orig_secret_msg.msg.clone(); - - Ok(ParsedMessage { - should_validate_sig_info: false, - was_msg_encrypted: false, - is_ibc_msg: true, - secret_msg: orig_secret_msg, - decrypted_msg, - contract_hash_for_validation: None, - }) - } - } + let orig_secret_msg = get_secret_msg(message); + parse_ibc_packet( + IbcPacketTimeoutMsg::default(), + message, + orig_secret_msg, + "ibc_packet_timeout", + ) } }; } diff --git a/cosmwasm/enclaves/shared/cosmwasm-v1-types/src/ibc.rs b/cosmwasm/enclaves/shared/cosmwasm-v1-types/src/ibc.rs index 7ec4cdd0e..3ab599cc6 100644 --- a/cosmwasm/enclaves/shared/cosmwasm-v1-types/src/ibc.rs +++ b/cosmwasm/enclaves/shared/cosmwasm-v1-types/src/ibc.rs @@ -71,6 +71,15 @@ pub struct IbcEndpoint { pub channel_id: String, } +impl IbcEndpoint { + pub fn default() -> Self { + IbcEndpoint { + port_id: String::default(), + channel_id: String::default(), + } + } +} + /// IbcOrder defines if a channel is ORDERED or UNORDERED /// Values come from https://github.com/cosmos/cosmos-sdk/blob/v0.40.0/proto/ibc/core/channel/v1/channel.proto#L69-L80 /// Naming comes from the protobuf files and go translations. @@ -112,6 +121,61 @@ pub struct IbcPacketReceiveMsg { pub relayer: Addr, } +pub trait IbcPacketTrait { + type Data; + fn get_packet(&self) -> &Self::Data; + fn set_packet(&mut self, data: Self::Data); + fn get_ack(&self) -> Option; + fn set_ack(&mut self, data: Self::Data); +} + +macro_rules! impl_IbcPacketTrait { + ($($t:ty),+) => { + $(impl IbcPacketTrait for $t { + type Data = Binary; + fn get_packet(&self) -> &Self::Data { + &self.packet.data + } + fn set_packet(&mut self, data: Self::Data) { + self.packet.data = data; + } + fn get_ack(&self) -> Option { + return None; + } + fn set_ack(&mut self, _: Self::Data) { + // Nothing to do here + } + })* + } +} + +impl_IbcPacketTrait! {IbcPacketReceiveMsg, IbcPacketTimeoutMsg} + +impl IbcPacketTrait for IbcPacketAckMsg { + type Data = Binary; + fn get_packet(&self) -> &Self::Data { + &self.original_packet.data + } + fn set_packet(&mut self, data: Self::Data) { + self.original_packet.data = data; + } + fn get_ack(&self) -> Option { + return Some(self.acknowledgement.data.clone()); + } + fn set_ack(&mut self, data: Self::Data) { + self.acknowledgement.data = data; + } +} + +impl IbcPacketReceiveMsg { + pub fn default() -> Self { + Self { + packet: IbcPacket::default(), + relayer: Addr::unchecked("".to_string()), + } + } +} + #[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] pub struct IbcPacket { /// The raw data sent from the other side in the packet @@ -125,12 +189,32 @@ pub struct IbcPacket { pub timeout: IbcTimeout, } +impl IbcPacket { + pub fn default() -> Self { + Self { + data: vec![].as_slice().into(), + src: IbcEndpoint::default(), + dest: IbcEndpoint::default(), + sequence: 0, + timeout: IbcTimeout::default(), + } + } +} + #[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] #[non_exhaustive] pub struct IbcAcknowledgement { pub data: Binary, } +impl IbcAcknowledgement { + pub fn default() -> Self { + Self { + data: vec![].as_slice().into(), + } + } +} + /// In IBC each package must set at least one type of timeout: /// the timestamp or the block height. Using this rather complex enum instead of /// two timeout fields we ensure that at least one timeout is set. @@ -142,6 +226,15 @@ pub struct IbcTimeout { timestamp: Option, } +impl IbcTimeout { + pub fn default() -> Self { + Self { + block: None, + timestamp: None, + } + } +} + /// IBCTimeoutHeight Height is a monotonically increasing data type /// that can be compared against another Height for the purposes of updating and /// freezing clients. @@ -164,6 +257,16 @@ pub struct IbcPacketAckMsg { pub relayer: Addr, } +impl IbcPacketAckMsg { + pub fn default() -> Self { + Self { + acknowledgement: IbcAcknowledgement::default(), + original_packet: IbcPacket::default(), + relayer: Addr::unchecked("".to_string()), + } + } +} + /// The message that is passed into `ibc_packet_timeout` #[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] #[non_exhaustive] @@ -171,3 +274,12 @@ pub struct IbcPacketTimeoutMsg { pub packet: IbcPacket, pub relayer: Addr, } + +impl IbcPacketTimeoutMsg { + pub fn default() -> Self { + Self { + packet: IbcPacket::default(), + relayer: Addr::unchecked("".to_string()), + } + } +} From 084849d93e4b751b38197a1fb96c464f20c6d2e4 Mon Sep 17 00:00:00 2001 From: Lior Bondarevski Date: Tue, 16 Aug 2022 12:06:42 +0300 Subject: [PATCH 26/93] Encrypt IBC outputs for encrypted inputs --- .../enclaves/shared/contract-engine/src/io.rs | 264 +++++++++++++++++- .../shared/cosmwasm-v1-types/src/ibc.rs | 34 +++ go-cosmwasm/lib.go | 85 +++--- go-cosmwasm/types/v1/ibc.go | 11 +- x/compute/internal/keeper/relay.go | 2 +- 5 files changed, 334 insertions(+), 62 deletions(-) diff --git a/cosmwasm/enclaves/shared/contract-engine/src/io.rs b/cosmwasm/enclaves/shared/contract-engine/src/io.rs index 99685f8af..25f4452f6 100644 --- a/cosmwasm/enclaves/shared/contract-engine/src/io.rs +++ b/cosmwasm/enclaves/shared/contract-engine/src/io.rs @@ -58,6 +58,12 @@ enum RawWasmOutput { internal_reply_enclave_sig: Option, internal_msg_id: Option, }, + OkIBCReceive { + #[serde(rename = "Ok")] + ok: enclave_cosmwasm_v1_types::ibc::IbcReceiveResponse, + internal_reply_enclave_sig: Option, + internal_msg_id: Option, + }, } #[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] @@ -76,6 +82,22 @@ struct V1WasmOutput { pub err: Option, } +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] +struct IBCOutput { + #[serde(rename = "Ok")] + pub ok: Option, + #[serde(rename = "Err")] + pub err: Option, +} + +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] +struct IBCReceiveOutput { + #[serde(rename = "Ok")] + pub ok: Option, + #[serde(rename = "Err")] + pub err: Option, +} + #[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] struct QueryOutput { #[serde(rename = "Ok")] @@ -88,6 +110,8 @@ struct QueryOutput { struct WasmOutput { pub v010: Option, pub v1: Option, + pub ibc: Option, + pub ibc_receive: Option, pub query: Option, pub internal_reply_enclave_sig: Option, pub internal_msg_id: Option, @@ -440,7 +464,207 @@ pub fn encrypt_output( internal_reply_enclave_sig, internal_msg_id, } => { - //LIORRR TODO encryption + for sub_msg in &mut ok.messages { + if let enclave_cosmwasm_v1_types::results::CosmosMsg::Wasm(wasm_msg) = + &mut sub_msg.msg + { + encrypt_v1_wasm_msg( + wasm_msg, + &sub_msg.reply_on, + sub_msg.id, + secret_msg.nonce, + secret_msg.user_public_key, + contract_addr, + contract_hash, + )?; + + // The ID can be extracted from the encrypted wasm msg + // We don't encrypt it here to remain with the same type (u64) + sub_msg.id = 0; + } + } + + // v1: The attributes that will be emitted as part of a "wasm" event. + for attr in ok.attributes.iter_mut().filter(|attr| attr.encrypted) { + attr.key = encrypt_preserialized_string(&encryption_key, &attr.key, &None)?; + attr.value = encrypt_preserialized_string(&encryption_key, &attr.value, &None)?; + } + + // v1: Extra, custom events separate from the main wasm one. These will have "wasm-"" prepended to the type. + for event in ok.events.iter_mut() { + for attr in event.attributes.iter_mut().filter(|attr| attr.encrypted) { + attr.key = encrypt_preserialized_string(&encryption_key, &attr.key, &None)?; + attr.value = encrypt_preserialized_string(&encryption_key, &attr.value, &None)?; + } + } + + let msg_id = match reply_params { + Some(ref r) => { + let encrypted_id = Binary::from_base64(&encrypt_preserialized_string( + &encryption_key, + &r.sub_msg_id.to_string(), + &reply_params, + )?)?; + + Some(encrypted_id) + } + None => None, + }; + + *internal_msg_id = msg_id.clone(); + + *internal_reply_enclave_sig = match reply_params { + Some(_) => { + let mut events: Vec = vec![]; + + if ok.attributes.len() > 0 { + events.push(Event { + ty: "wasm".to_string(), + attributes: ok.attributes.clone(), + }) + } + + events.extend_from_slice(&ok.events.clone().as_slice()); + let custom_contract_event_prefix: String = "wasm-".to_string(); + for event in events.iter_mut() { + if event.ty != "wasm" { + event.ty = custom_contract_event_prefix.clone() + event.ty.as_str(); + } + } + + let reply = Reply { + id: msg_id.unwrap(), + result: SubMsgResult::Ok(SubMsgResponse { events, data: None }), + }; + + let reply_as_vec = serde_json::to_vec(&reply).map_err(|err| { + warn!( + "got an error while trying to serialize reply into bytes for internal_reply_enclave_sig {:?}: {}", + reply, err + ); + EnclaveError::FailedToSerialize + })?; + + let tmp_secret_msg = SecretMessage { + nonce: secret_msg.nonce, + user_public_key: secret_msg.user_public_key, + msg: reply_as_vec, + }; + + Some(Binary::from( + create_callback_signature(sender_addr, &tmp_secret_msg, &[]).as_slice(), + )) + } + None => None, // Not a reply, we don't need enclave sig + } + } + RawWasmOutput::OkIBCReceive { + ok, + internal_reply_enclave_sig, + internal_msg_id, + } => { + for sub_msg in &mut ok.messages { + if let enclave_cosmwasm_v1_types::results::CosmosMsg::Wasm(wasm_msg) = + &mut sub_msg.msg + { + encrypt_v1_wasm_msg( + wasm_msg, + &sub_msg.reply_on, + sub_msg.id, + secret_msg.nonce, + secret_msg.user_public_key, + contract_addr, + contract_hash, + )?; + + // The ID can be extracted from the encrypted wasm msg + // We don't encrypt it here to remain with the same type (u64) + sub_msg.id = 0; + } + } + + // v1: The attributes that will be emitted as part of a "wasm" event. + for attr in ok.attributes.iter_mut().filter(|attr| attr.encrypted) { + attr.key = encrypt_preserialized_string(&encryption_key, &attr.key, &None)?; + attr.value = encrypt_preserialized_string(&encryption_key, &attr.value, &None)?; + } + + // v1: Extra, custom events separate from the main wasm one. These will have "wasm-"" prepended to the type. + for event in ok.events.iter_mut() { + for attr in event.attributes.iter_mut().filter(|attr| attr.encrypted) { + attr.key = encrypt_preserialized_string(&encryption_key, &attr.key, &None)?; + attr.value = encrypt_preserialized_string(&encryption_key, &attr.value, &None)?; + } + } + + ok.acknowledgement = Binary::from_base64(&encrypt_serializable( + &encryption_key, + &ok.acknowledgement, + &reply_params, + )?)?; + + let msg_id = match reply_params { + Some(ref r) => { + let encrypted_id = Binary::from_base64(&encrypt_preserialized_string( + &encryption_key, + &r.sub_msg_id.to_string(), + &reply_params, + )?)?; + + Some(encrypted_id) + } + None => None, + }; + + *internal_msg_id = msg_id.clone(); + + *internal_reply_enclave_sig = match reply_params { + Some(_) => { + let mut events: Vec = vec![]; + + if ok.attributes.len() > 0 { + events.push(Event { + ty: "wasm".to_string(), + attributes: ok.attributes.clone(), + }) + } + + events.extend_from_slice(&ok.events.clone().as_slice()); + let custom_contract_event_prefix: String = "wasm-".to_string(); + for event in events.iter_mut() { + if event.ty != "wasm" { + event.ty = custom_contract_event_prefix.clone() + event.ty.as_str(); + } + } + + let reply = Reply { + id: msg_id.unwrap(), + result: SubMsgResult::Ok(SubMsgResponse { + events, + data: Some(ok.acknowledgement.clone()), + }), + }; + + let reply_as_vec = serde_json::to_vec(&reply).map_err(|err| { + warn!( + "got an error while trying to serialize reply into bytes for internal_reply_enclave_sig {:?}: {}", + reply, err + ); + EnclaveError::FailedToSerialize + })?; + + let tmp_secret_msg = SecretMessage { + nonce: secret_msg.nonce, + user_public_key: secret_msg.user_public_key, + msg: reply_as_vec, + }; + + Some(Binary::from( + create_callback_signature(sender_addr, &tmp_secret_msg, &[]).as_slice(), + )) + } + None => None, // Not a reply, we don't need enclave sig + } } }; @@ -454,6 +678,8 @@ pub fn encrypt_output( WasmOutput { v010: None, v1: None, + ibc: None, + ibc_receive: None, query: Some(QueryOutput { ok: None, err: Some(err), @@ -468,6 +694,8 @@ pub fn encrypt_output( ok: None, }), v1: None, + ibc: None, + ibc_receive: None, query: None, internal_reply_enclave_sig, internal_msg_id, @@ -484,6 +712,8 @@ pub fn encrypt_output( ok: Some(ok), }), v1: None, + ibc: None, + ibc_receive: None, query: None, internal_reply_enclave_sig, internal_msg_id, @@ -498,6 +728,8 @@ pub fn encrypt_output( err: None, ok: Some(ok), }), + ibc: None, + ibc_receive: None, query: None, internal_reply_enclave_sig, internal_msg_id, @@ -505,6 +737,8 @@ pub fn encrypt_output( RawWasmOutput::QueryOkV010 { ok } | RawWasmOutput::QueryOkV1 { ok } => WasmOutput { v010: None, v1: None, + ibc: None, + ibc_receive: None, query: Some(QueryOutput { ok: Some(ok), err: None, @@ -512,8 +746,6 @@ pub fn encrypt_output( internal_reply_enclave_sig: None, internal_msg_id: None, }, - - // LIORRRR TODO: make it work, maybe the same as in v1 response? RawWasmOutput::OkIBC { ok, internal_reply_enclave_sig, @@ -521,12 +753,30 @@ pub fn encrypt_output( } => WasmOutput { v010: None, v1: None, - query: Some(QueryOutput { - ok: None, + ibc: Some(IBCOutput { err: None, + ok: Some(ok), }), - internal_reply_enclave_sig: None, - internal_msg_id: None, + ibc_receive: None, + query: None, + internal_reply_enclave_sig, + internal_msg_id, + }, + RawWasmOutput::OkIBCReceive { + ok, + internal_reply_enclave_sig, + internal_msg_id, + } => WasmOutput { + v010: None, + v1: None, + ibc: None, + ibc_receive: Some(IBCReceiveOutput { + err: None, + ok: Some(ok), + }), + query: None, + internal_reply_enclave_sig, + internal_msg_id, }, }; diff --git a/cosmwasm/enclaves/shared/cosmwasm-v1-types/src/ibc.rs b/cosmwasm/enclaves/shared/cosmwasm-v1-types/src/ibc.rs index 3ab599cc6..cbb02ec70 100644 --- a/cosmwasm/enclaves/shared/cosmwasm-v1-types/src/ibc.rs +++ b/cosmwasm/enclaves/shared/cosmwasm-v1-types/src/ibc.rs @@ -65,6 +65,40 @@ where pub events: Vec, } +// This defines the return value on packet response processing. +// This "success" case should be returned even in application-level errors, +// Where the acknowledgement bytes contain an encoded error message to be returned to +// the calling chain. (Returning ContractResult::Err will abort processing of this packet +// and not inform the calling chain). +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] +#[non_exhaustive] +pub struct IbcReceiveResponse +where + T: Clone + fmt::Debug + PartialEq, +{ + /// The bytes we return to the contract that sent the packet. + /// This may represent a success or error of exection + pub acknowledgement: Binary, + /// Optional list of messages to pass. These will be executed in order. + /// If the ReplyOn member is set, they will invoke this contract's `reply` entry point + /// after execution. Otherwise, they act like "fire and forget". + /// Use `call` or `msg.into()` to create messages with the older "fire and forget" semantics. + pub messages: Vec>, + /// The attributes that will be emitted as part of a "wasm" event. + /// + /// More info about events (and their attributes) can be found in [*Cosmos SDK* docs]. + /// + /// [*Cosmos SDK* docs]: https://docs.cosmos.network/v0.42/core/events.html + pub attributes: Vec, + /// Extra, custom events separate from the main `wasm` one. These will have + /// `wasm-` prepended to the type. + /// + /// More info about events can be found in [*Cosmos SDK* docs]. + /// + /// [*Cosmos SDK* docs]: https://docs.cosmos.network/v0.42/core/events.html + pub events: Vec, +} + #[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] pub struct IbcEndpoint { pub port_id: String, diff --git a/go-cosmwasm/lib.go b/go-cosmwasm/lib.go index e9d600ff0..0809da070 100644 --- a/go-cosmwasm/lib.go +++ b/go-cosmwasm/lib.go @@ -91,11 +91,8 @@ type ContractExecResponse struct { InternaReplyEnclaveSig []byte `json:"internal_reply_enclave_sig"` InternalMsgId []byte `json:"internal_msg_id"` IBCChannelOpen *v1types.IBCChannelOpenResult `json:"ibc_channel_open,omitempty"` - IBCChannelConnect *v1types.IBCBasicResult `json:"ibc_channel_connect,omitempty"` - IBCChannelClose *v1types.IBCBasicResult `json:"ibc_channel_close,omitempty"` - IBCPacketReceive *v1types.IBCReceiveResult `json:"ibc_packet_receive,omitempty"` - IBCPacketAck *v1types.IBCBasicResult `json:"ibc_packet_ack,omitempty"` - IBCPacketTimeout *v1types.IBCBasicResult `json:"ibc_packet_timeout,omitempty"` + IBC *v1types.IBCBasicResult `json:"ibc,omitempty"` + IBCReceive *v1types.IBCReceiveResult `json:"ibc_receive,omitempty"` } type V010ContractExecResponse struct { @@ -330,57 +327,43 @@ func (w *Wasmer) Execute( } // handle IBCChannelConnect response - if resp.IBCChannelConnect != nil { - if resp.IBCChannelConnect.Err != "" { - return nil, gasUsed, fmt.Errorf("%s", resp.IBCChannelConnect.Err) - } else if resp.IBCChannelConnect.Ok != nil { - return resp.IBCChannelConnect.Ok, gasUsed, nil - } else { - return nil, gasUsed, fmt.Errorf("cannot parse IBCChannelConnect response: %+v", resp) - } - } - - // handle IBCChannelClose response - if resp.IBCChannelClose != nil { - if resp.IBCChannelClose.Err != "" { - return nil, gasUsed, fmt.Errorf("%s", resp.IBCChannelClose.Err) - } else if resp.IBCChannelClose.Ok != nil { - return resp.IBCChannelClose.Ok, gasUsed, nil - } else { - return nil, gasUsed, fmt.Errorf("cannot parse IBCChannelClose response: %+v", resp) - } - } - - // handle IBCPacketReceive response - if resp.IBCPacketReceive != nil { - if resp.IBCPacketReceive.Err != "" { - return nil, gasUsed, fmt.Errorf("%s", resp.IBCPacketReceive.Err) - } else if resp.IBCPacketReceive.Ok != nil { - return resp.IBCPacketReceive.Ok, gasUsed, nil - } else { - return nil, gasUsed, fmt.Errorf("cannot parse IBCPacketReceive response: %+v", resp) - } - } - - // handle IBCPacketAck response - if resp.IBCPacketAck != nil { - if resp.IBCPacketAck.Err != "" { - return nil, gasUsed, fmt.Errorf("%s", resp.IBCPacketAck.Err) - } else if resp.IBCPacketAck.Ok != nil { - return resp.IBCPacketAck.Ok, gasUsed, nil + if resp.IBC != nil { + if resp.IBC.Err != nil { + return v1types.DataWithInternalReplyInfo{ + InternalMsgId: resp.InternalMsgId, + InternaReplyEnclaveSig: resp.InternaReplyEnclaveSig, + Data: []byte(resp.IBC.Err.GenericErr.Msg), + }, gasUsed, fmt.Errorf("%+v", resp.IBC.Err) + } else if resp.IBC.Ok != nil { + if isOutputAddressedToReply { + resp.IBC.Ok.InternalData, err = AppendReplyInternalDataToData([]byte{}, resp.InternaReplyEnclaveSig, resp.InternalMsgId) + if err != nil { + return nil, gasUsed, fmt.Errorf("cannot serialize v1 DataWithInternalReplyInfo into binary : %w", err) + } + } + return resp.V1.Ok, gasUsed, nil } else { - return nil, gasUsed, fmt.Errorf("cannot parse IBCPacketAck response: %+v", resp) + return nil, gasUsed, fmt.Errorf("cannot parse v1 handle response: %+v", resp) } } - // handle IBCPacketTimeout response - if resp.IBCPacketTimeout != nil { - if resp.IBCPacketTimeout.Err != "" { - return nil, gasUsed, fmt.Errorf("%s", resp.IBCPacketTimeout.Err) - } else if resp.IBCPacketTimeout.Ok != nil { - return resp.IBCPacketTimeout.Ok, gasUsed, nil + if resp.IBCReceive != nil { + if resp.IBCReceive.Err != nil { + return v1types.DataWithInternalReplyInfo{ + InternalMsgId: resp.InternalMsgId, + InternaReplyEnclaveSig: resp.InternaReplyEnclaveSig, + Data: []byte(resp.IBCReceive.Err.GenericErr.Msg), + }, gasUsed, fmt.Errorf("%+v", resp.IBCReceive.Err) + } else if resp.IBCReceive.Ok != nil { + if isOutputAddressedToReply { + resp.IBCReceive.Ok.Acknowledgement, err = AppendReplyInternalDataToData(resp.IBCReceive.Ok.Acknowledgement, resp.InternaReplyEnclaveSig, resp.InternalMsgId) + if err != nil { + return nil, gasUsed, fmt.Errorf("cannot serialize v1 DataWithInternalReplyInfo into binary : %w", err) + } + } + return resp.V1.Ok, gasUsed, nil } else { - return nil, gasUsed, fmt.Errorf("cannot parse IBCPacketTimeout response: %+v", resp) + return nil, gasUsed, fmt.Errorf("cannot parse v1 handle response: %+v", resp) } } diff --git a/go-cosmwasm/types/v1/ibc.go b/go-cosmwasm/types/v1/ibc.go index 1d5d994fb..d98c6826b 100644 --- a/go-cosmwasm/types/v1/ibc.go +++ b/go-cosmwasm/types/v1/ibc.go @@ -1,6 +1,9 @@ package v1types -import v010msgtypes "github.com/enigmampc/SecretNetwork/go-cosmwasm/types/v010" +import ( + types "github.com/enigmampc/SecretNetwork/go-cosmwasm/types" + v010msgtypes "github.com/enigmampc/SecretNetwork/go-cosmwasm/types/v010" +) type IBCEndpoint struct { PortID string `json:"port_id"` @@ -219,12 +222,14 @@ type IBC3ChannelOpenResponse struct { // will use other Response types type IBCBasicResult struct { Ok *IBCBasicResponse `json:"ok,omitempty"` - Err string `json:"error,omitempty"` + Err *types.StdError `json:"Err,omitempty"` } // IBCBasicResponse defines the return value on a successful processing. // This is the counterpart of [IbcBasicResponse](https://github.com/CosmWasm/cosmwasm/blob/v0.14.0-beta1/packages/std/src/ibc.rs#L194-L216). type IBCBasicResponse struct { + // Used for internal purposes + InternalData []byte `json:"internal_data,omitempty"` // Messages comes directly from the contract and is its request for action. // If the ReplyOn value matches the result, the runtime will invoke this // contract's `reply` entry point after execution. Otherwise, this is all @@ -246,7 +251,7 @@ type IBCBasicResponse struct { // will use other Response types type IBCReceiveResult struct { Ok *IBCReceiveResponse `json:"ok,omitempty"` - Err string `json:"error,omitempty"` + Err *types.StdError `json:"Err,omitempty"` } // IBCReceiveResponse defines the return value on packet response processing. diff --git a/x/compute/internal/keeper/relay.go b/x/compute/internal/keeper/relay.go index a60a928e0..776f3e52d 100644 --- a/x/compute/internal/keeper/relay.go +++ b/x/compute/internal/keeper/relay.go @@ -287,6 +287,6 @@ func (k Keeper) OnTimeoutPacket( func (k Keeper) handleIBCBasicContractResponse(ctx sdk.Context, addr sdk.AccAddress, ibcPortID string, inputMsg []byte, res *v1types.IBCBasicResponse) error { verificationInfo := types.NewVerificationInfo([]byte{}, sdktxsigning.SignMode_SIGN_MODE_UNSPECIFIED, []byte{}, []byte{}, []byte{}, nil) - _, err := k.handleContractResponse(ctx, addr, ibcPortID, res.Messages, res.Attributes, res.Events, nil, inputMsg, verificationInfo, wasmTypes.CosmosMsgVersionV1) + _, err := k.handleContractResponse(ctx, addr, ibcPortID, res.Messages, res.Attributes, res.Events, res.InternalData, inputMsg, verificationInfo, wasmTypes.CosmosMsgVersionV1) return err } From ede75fab9fd663490fd475c1ddf197687571f02e Mon Sep 17 00:00:00 2001 From: Lior Bondarevski Date: Tue, 16 Aug 2022 12:12:58 +0300 Subject: [PATCH 27/93] Finalize output in a function --- .../enclaves/shared/contract-engine/src/io.rs | 227 +++++++++--------- 1 file changed, 115 insertions(+), 112 deletions(-) diff --git a/cosmwasm/enclaves/shared/contract-engine/src/io.rs b/cosmwasm/enclaves/shared/contract-engine/src/io.rs index 25f4452f6..edc64a5f1 100644 --- a/cosmwasm/enclaves/shared/contract-engine/src/io.rs +++ b/cosmwasm/enclaves/shared/contract-engine/src/io.rs @@ -184,6 +184,120 @@ fn b64_encode(data: &[u8]) -> String { base64::encode(data) } +pub fn finalize_raw_output(raw_output: RawWasmOutput) -> WasmOutput { + return match raw_output { + RawWasmOutput::Err { + err, + internal_msg_id, + internal_reply_enclave_sig, + } => { + if is_query_output { + WasmOutput { + v010: None, + v1: None, + ibc: None, + ibc_receive: None, + query: Some(QueryOutput { + ok: None, + err: Some(err), + }), + internal_reply_enclave_sig: None, + internal_msg_id: None, + } + } else { + WasmOutput { + v010: Some(V010WasmOutput { + err: Some(err), + ok: None, + }), + v1: None, + ibc: None, + ibc_receive: None, + query: None, + internal_reply_enclave_sig, + internal_msg_id, + } + } + } + RawWasmOutput::OkV010 { + ok, + internal_reply_enclave_sig, + internal_msg_id, + } => WasmOutput { + v010: Some(V010WasmOutput { + err: None, + ok: Some(ok), + }), + v1: None, + ibc: None, + ibc_receive: None, + query: None, + internal_reply_enclave_sig, + internal_msg_id, + }, + RawWasmOutput::OkV1 { + ok, + internal_reply_enclave_sig, + internal_msg_id, + } => WasmOutput { + v010: None, + v1: Some(V1WasmOutput { + err: None, + ok: Some(ok), + }), + ibc: None, + ibc_receive: None, + query: None, + internal_reply_enclave_sig, + internal_msg_id, + }, + RawWasmOutput::QueryOkV010 { ok } | RawWasmOutput::QueryOkV1 { ok } => WasmOutput { + v010: None, + v1: None, + ibc: None, + ibc_receive: None, + query: Some(QueryOutput { + ok: Some(ok), + err: None, + }), + internal_reply_enclave_sig: None, + internal_msg_id: None, + }, + RawWasmOutput::OkIBC { + ok, + internal_reply_enclave_sig, + internal_msg_id, + } => WasmOutput { + v010: None, + v1: None, + ibc: Some(IBCOutput { + err: None, + ok: Some(ok), + }), + ibc_receive: None, + query: None, + internal_reply_enclave_sig, + internal_msg_id, + }, + RawWasmOutput::OkIBCReceive { + ok, + internal_reply_enclave_sig, + internal_msg_id, + } => WasmOutput { + v010: None, + v1: None, + ibc: None, + ibc_receive: Some(IBCReceiveOutput { + err: None, + ok: Some(ok), + }), + query: None, + internal_reply_enclave_sig, + internal_msg_id, + }, + }; +} + pub fn encrypt_output( output: Vec, secret_msg: &SecretMessage, @@ -668,118 +782,7 @@ pub fn encrypt_output( } }; - let final_output: WasmOutput = match output { - RawWasmOutput::Err { - err, - internal_msg_id, - internal_reply_enclave_sig, - } => { - if is_query_output { - WasmOutput { - v010: None, - v1: None, - ibc: None, - ibc_receive: None, - query: Some(QueryOutput { - ok: None, - err: Some(err), - }), - internal_reply_enclave_sig: None, - internal_msg_id: None, - } - } else { - WasmOutput { - v010: Some(V010WasmOutput { - err: Some(err), - ok: None, - }), - v1: None, - ibc: None, - ibc_receive: None, - query: None, - internal_reply_enclave_sig, - internal_msg_id, - } - } - } - RawWasmOutput::OkV010 { - ok, - internal_reply_enclave_sig, - internal_msg_id, - } => WasmOutput { - v010: Some(V010WasmOutput { - err: None, - ok: Some(ok), - }), - v1: None, - ibc: None, - ibc_receive: None, - query: None, - internal_reply_enclave_sig, - internal_msg_id, - }, - RawWasmOutput::OkV1 { - ok, - internal_reply_enclave_sig, - internal_msg_id, - } => WasmOutput { - v010: None, - v1: Some(V1WasmOutput { - err: None, - ok: Some(ok), - }), - ibc: None, - ibc_receive: None, - query: None, - internal_reply_enclave_sig, - internal_msg_id, - }, - RawWasmOutput::QueryOkV010 { ok } | RawWasmOutput::QueryOkV1 { ok } => WasmOutput { - v010: None, - v1: None, - ibc: None, - ibc_receive: None, - query: Some(QueryOutput { - ok: Some(ok), - err: None, - }), - internal_reply_enclave_sig: None, - internal_msg_id: None, - }, - RawWasmOutput::OkIBC { - ok, - internal_reply_enclave_sig, - internal_msg_id, - } => WasmOutput { - v010: None, - v1: None, - ibc: Some(IBCOutput { - err: None, - ok: Some(ok), - }), - ibc_receive: None, - query: None, - internal_reply_enclave_sig, - internal_msg_id, - }, - RawWasmOutput::OkIBCReceive { - ok, - internal_reply_enclave_sig, - internal_msg_id, - } => WasmOutput { - v010: None, - v1: None, - ibc: None, - ibc_receive: Some(IBCReceiveOutput { - err: None, - ok: Some(ok), - }), - query: None, - internal_reply_enclave_sig, - internal_msg_id, - }, - }; - + let final_output = finalize_raw_output(output); trace!("WasmOutput: {:?}", final_output); let encrypted_output = serde_json::to_vec(&final_output).map_err(|err| { From 86501b029e41ed73da1040350314e592bcef071e Mon Sep 17 00:00:00 2001 From: Lior Bondarevski Date: Tue, 16 Aug 2022 12:35:23 +0300 Subject: [PATCH 28/93] Finalize plaintext messages --- .../contract-engine/src/contract_operations.rs | 18 +++++++++++++++++- .../enclaves/shared/contract-engine/src/io.rs | 18 +++++++++--------- 2 files changed, 26 insertions(+), 10 deletions(-) diff --git a/cosmwasm/enclaves/shared/contract-engine/src/contract_operations.rs b/cosmwasm/enclaves/shared/contract-engine/src/contract_operations.rs index 958dc2021..33a88a2b7 100644 --- a/cosmwasm/enclaves/shared/contract-engine/src/contract_operations.rs +++ b/cosmwasm/enclaves/shared/contract-engine/src/contract_operations.rs @@ -30,7 +30,7 @@ use super::contract_validation::{ verify_params, ContractKey, }; use super::gas::WasmCosts; -use super::io::encrypt_output; +use super::io::{encrypt_output, finalize_raw_output, RawWasmOutput}; use super::module_cache::create_module_instance; use super::types::{IoNonce, SecretMessage}; use super::wasm::{ContractInstance, ContractOperation, Engine}; @@ -851,6 +851,22 @@ pub fn handle( &canonical_sender_address, false, )?; + } else { + let raw_output: RawWasmOutput = serde_json::from_slice(&output).map_err(|err| { + warn!("got an error while trying to deserialize output bytes into json"); + trace!("output: {:?} error: {:?}", output, err); + EnclaveError::FailedToDeserialize + })?; + + let finalized_output = finalize_raw_output(raw_output, false); + + output = serde_json::to_vec(&finalized_output).map_err(|err| { + debug!( + "got an error while trying to serialize output json into bytes {:?}: {}", + finalized_output, err + ); + EnclaveError::FailedToSerialize + })?; } Ok(output) diff --git a/cosmwasm/enclaves/shared/contract-engine/src/io.rs b/cosmwasm/enclaves/shared/contract-engine/src/io.rs index edc64a5f1..539847227 100644 --- a/cosmwasm/enclaves/shared/contract-engine/src/io.rs +++ b/cosmwasm/enclaves/shared/contract-engine/src/io.rs @@ -25,7 +25,7 @@ use sha2::Digest; /// b. Authenticate the reply. #[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] #[serde(untagged)] -enum RawWasmOutput { +pub enum RawWasmOutput { Err { #[serde(rename = "Err")] err: Value, @@ -67,7 +67,7 @@ enum RawWasmOutput { } #[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] -struct V010WasmOutput { +pub struct V010WasmOutput { #[serde(rename = "Ok")] pub ok: Option, #[serde(rename = "Err")] @@ -75,7 +75,7 @@ struct V010WasmOutput { } #[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] -struct V1WasmOutput { +pub struct V1WasmOutput { #[serde(rename = "Ok")] pub ok: Option, #[serde(rename = "Err")] @@ -83,7 +83,7 @@ struct V1WasmOutput { } #[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] -struct IBCOutput { +pub struct IBCOutput { #[serde(rename = "Ok")] pub ok: Option, #[serde(rename = "Err")] @@ -91,7 +91,7 @@ struct IBCOutput { } #[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] -struct IBCReceiveOutput { +pub struct IBCReceiveOutput { #[serde(rename = "Ok")] pub ok: Option, #[serde(rename = "Err")] @@ -99,7 +99,7 @@ struct IBCReceiveOutput { } #[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] -struct QueryOutput { +pub struct QueryOutput { #[serde(rename = "Ok")] pub ok: Option, #[serde(rename = "Err")] @@ -107,7 +107,7 @@ struct QueryOutput { } #[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] -struct WasmOutput { +pub struct WasmOutput { pub v010: Option, pub v1: Option, pub ibc: Option, @@ -184,7 +184,7 @@ fn b64_encode(data: &[u8]) -> String { base64::encode(data) } -pub fn finalize_raw_output(raw_output: RawWasmOutput) -> WasmOutput { +pub fn finalize_raw_output(raw_output: RawWasmOutput, is_query_output: bool) -> WasmOutput { return match raw_output { RawWasmOutput::Err { err, @@ -782,7 +782,7 @@ pub fn encrypt_output( } }; - let final_output = finalize_raw_output(output); + let final_output = finalize_raw_output(output, is_query_output); trace!("WasmOutput: {:?}", final_output); let encrypted_output = serde_json::to_vec(&final_output).map_err(|err| { From cc236c7a123969f59e0c64e65f9bcae58f2e6781 Mon Sep 17 00:00:00 2001 From: Lior Bondarevski Date: Wed, 17 Aug 2022 12:15:51 +0300 Subject: [PATCH 29/93] Support plaintext execute messages --- .../src/contract_operations.rs | 62 +++--- .../enclaves/shared/contract-engine/src/io.rs | 195 +++--------------- go-cosmwasm/lib.go | 69 ++----- go-cosmwasm/types/v1/ibc.go | 2 - x/compute/internal/keeper/relay.go | 2 +- 5 files changed, 80 insertions(+), 250 deletions(-) diff --git a/cosmwasm/enclaves/shared/contract-engine/src/contract_operations.rs b/cosmwasm/enclaves/shared/contract-engine/src/contract_operations.rs index 33a88a2b7..4572797a2 100644 --- a/cosmwasm/enclaves/shared/contract-engine/src/contract_operations.rs +++ b/cosmwasm/enclaves/shared/contract-engine/src/contract_operations.rs @@ -179,7 +179,6 @@ pub fn init( pub struct ParsedMessage { pub should_validate_sig_info: bool, pub was_msg_encrypted: bool, - pub is_ibc_msg: bool, pub secret_msg: SecretMessage, pub decrypted_msg: Vec, pub contract_hash_for_validation: Option>, @@ -313,9 +312,8 @@ where } Ok(ParsedMessage { - should_validate_sig_info: true, + should_validate_sig_info: false, was_msg_encrypted: true, - is_ibc_msg: true, secret_msg: orig_secret_msg, decrypted_msg: serde_json::to_vec(&parsed_encrypted_ibc_packet).map_err(|err| { warn!( @@ -331,7 +329,7 @@ where // assume packet is not encrypted, continue in plaintext mode trace!( - "{} input is not encrypted: {:?}", + "{} input was plaintext: {:?}", function_name, base64::encode(&message) ); @@ -341,7 +339,6 @@ where Ok(ParsedMessage { should_validate_sig_info: false, was_msg_encrypted: false, - is_ibc_msg: true, secret_msg: orig_secret_msg, decrypted_msg, contract_hash_for_validation: None, @@ -357,23 +354,39 @@ pub fn parse_message( handle_type: &HandleType, ) -> Result { return match handle_type { - HandleType::HANDLE_TYPE_EXECUTE => { - let orig_secret_msg = SecretMessage::from_slice(message)?; + HandleType::HANDLE_TYPE_EXECUTE => match try_get_decrypted_secret_msg(message) { + Some(decrypted_secret_msg) => { + trace!( + "execute input before decryption: {:?}", + base64::encode(&message) + ); - trace!( - "execute input before decryption: {:?}", - base64::encode(&message) - ); - let decrypted_msg = orig_secret_msg.decrypt()?; - Ok(ParsedMessage { - should_validate_sig_info: true, - was_msg_encrypted: true, - is_ibc_msg: false, - secret_msg: orig_secret_msg, - decrypted_msg, - contract_hash_for_validation: None, - }) - } + Ok(ParsedMessage { + should_validate_sig_info: true, + was_msg_encrypted: true, + secret_msg: decrypted_secret_msg.secret_msg, + decrypted_msg: decrypted_secret_msg.decrypted_msg, + contract_hash_for_validation: None, + }) + } + None => { + trace!( + "execute input was plaintext: {:?}", + base64::encode(&message) + ); + + let secret_msg = get_secret_msg(message); + let decrypted_msg = secret_msg.msg.clone(); + + Ok(ParsedMessage { + should_validate_sig_info: true, + was_msg_encrypted: false, + secret_msg, + decrypted_msg, + contract_hash_for_validation: None, + }) + } + }, HandleType::HANDLE_TYPE_REPLY => { let orig_secret_msg = SecretMessage::from_slice(message)?; @@ -441,7 +454,6 @@ pub fn parse_message( return Ok(ParsedMessage { should_validate_sig_info: false, was_msg_encrypted: false, - is_ibc_msg: false, secret_msg: reply_secret_msg, decrypted_msg: serialized_reply, contract_hash_for_validation: None, @@ -546,7 +558,6 @@ pub fn parse_message( Ok(ParsedMessage { should_validate_sig_info: true, was_msg_encrypted: true, - is_ibc_msg: false, secret_msg: reply_secret_msg, decrypted_msg: decrypted_reply_as_vec, contract_hash_for_validation: Some( @@ -640,7 +651,6 @@ pub fn parse_message( Ok(ParsedMessage { should_validate_sig_info: true, was_msg_encrypted: true, - is_ibc_msg: false, secret_msg: reply_secret_msg, decrypted_msg: decrypted_reply_as_vec, contract_hash_for_validation: Some( @@ -670,7 +680,6 @@ pub fn parse_message( Ok(ParsedMessage { should_validate_sig_info: false, was_msg_encrypted: false, - is_ibc_msg: true, secret_msg: scrt_msg, decrypted_msg, contract_hash_for_validation: None, @@ -773,7 +782,6 @@ pub fn handle( let ParsedMessage { should_validate_sig_info, was_msg_encrypted, - is_ibc_msg, secret_msg, decrypted_msg, contract_hash_for_validation, @@ -841,7 +849,7 @@ pub fn handle( secret_msg.nonce, secret_msg.user_public_key ); - if !is_ibc_msg || was_msg_encrypted { + if was_msg_encrypted { output = encrypt_output( output, &secret_msg, diff --git a/cosmwasm/enclaves/shared/contract-engine/src/io.rs b/cosmwasm/enclaves/shared/contract-engine/src/io.rs index 539847227..3ef7b0cdb 100644 --- a/cosmwasm/enclaves/shared/contract-engine/src/io.rs +++ b/cosmwasm/enclaves/shared/contract-engine/src/io.rs @@ -52,17 +52,13 @@ pub enum RawWasmOutput { internal_reply_enclave_sig: Option, internal_msg_id: Option, }, - OkIBC { + OkIBCBasic { #[serde(rename = "Ok")] ok: enclave_cosmwasm_v1_types::ibc::IbcBasicResponse, - internal_reply_enclave_sig: Option, - internal_msg_id: Option, }, - OkIBCReceive { + OkIBCPacketReceive { #[serde(rename = "Ok")] ok: enclave_cosmwasm_v1_types::ibc::IbcReceiveResponse, - internal_reply_enclave_sig: Option, - internal_msg_id: Option, }, } @@ -110,8 +106,8 @@ pub struct QueryOutput { pub struct WasmOutput { pub v010: Option, pub v1: Option, - pub ibc: Option, - pub ibc_receive: Option, + pub ibc_basic: Option, + pub ibc_packet_receive: Option, pub query: Option, pub internal_reply_enclave_sig: Option, pub internal_msg_id: Option, @@ -195,8 +191,8 @@ pub fn finalize_raw_output(raw_output: RawWasmOutput, is_query_output: bool) -> WasmOutput { v010: None, v1: None, - ibc: None, - ibc_receive: None, + ibc_basic: None, + ibc_packet_receive: None, query: Some(QueryOutput { ok: None, err: Some(err), @@ -211,8 +207,8 @@ pub fn finalize_raw_output(raw_output: RawWasmOutput, is_query_output: bool) -> ok: None, }), v1: None, - ibc: None, - ibc_receive: None, + ibc_basic: None, + ibc_packet_receive: None, query: None, internal_reply_enclave_sig, internal_msg_id, @@ -229,8 +225,8 @@ pub fn finalize_raw_output(raw_output: RawWasmOutput, is_query_output: bool) -> ok: Some(ok), }), v1: None, - ibc: None, - ibc_receive: None, + ibc_basic: None, + ibc_packet_receive: None, query: None, internal_reply_enclave_sig, internal_msg_id, @@ -245,8 +241,8 @@ pub fn finalize_raw_output(raw_output: RawWasmOutput, is_query_output: bool) -> err: None, ok: Some(ok), }), - ibc: None, - ibc_receive: None, + ibc_basic: None, + ibc_packet_receive: None, query: None, internal_reply_enclave_sig, internal_msg_id, @@ -254,8 +250,8 @@ pub fn finalize_raw_output(raw_output: RawWasmOutput, is_query_output: bool) -> RawWasmOutput::QueryOkV010 { ok } | RawWasmOutput::QueryOkV1 { ok } => WasmOutput { v010: None, v1: None, - ibc: None, - ibc_receive: None, + ibc_basic: None, + ibc_packet_receive: None, query: Some(QueryOutput { ok: Some(ok), err: None, @@ -263,37 +259,29 @@ pub fn finalize_raw_output(raw_output: RawWasmOutput, is_query_output: bool) -> internal_reply_enclave_sig: None, internal_msg_id: None, }, - RawWasmOutput::OkIBC { - ok, - internal_reply_enclave_sig, - internal_msg_id, - } => WasmOutput { + RawWasmOutput::OkIBCBasic { ok } => WasmOutput { v010: None, v1: None, - ibc: Some(IBCOutput { + ibc_basic: Some(IBCOutput { err: None, ok: Some(ok), }), - ibc_receive: None, + ibc_packet_receive: None, query: None, - internal_reply_enclave_sig, - internal_msg_id, + internal_reply_enclave_sig: None, + internal_msg_id: None, }, - RawWasmOutput::OkIBCReceive { - ok, - internal_reply_enclave_sig, - internal_msg_id, - } => WasmOutput { + RawWasmOutput::OkIBCPacketReceive { ok } => WasmOutput { v010: None, v1: None, - ibc: None, - ibc_receive: Some(IBCReceiveOutput { + ibc_basic: None, + ibc_packet_receive: Some(IBCReceiveOutput { err: None, ok: Some(ok), }), query: None, - internal_reply_enclave_sig, - internal_msg_id, + internal_reply_enclave_sig: None, + internal_msg_id: None, }, }; } @@ -573,11 +561,7 @@ pub fn encrypt_output( None => None, // Not a reply, we don't need enclave sig } } - RawWasmOutput::OkIBC { - ok, - internal_reply_enclave_sig, - internal_msg_id, - } => { + RawWasmOutput::OkIBCBasic { ok } => { for sub_msg in &mut ok.messages { if let enclave_cosmwasm_v1_types::results::CosmosMsg::Wasm(wasm_msg) = &mut sub_msg.msg @@ -611,72 +595,8 @@ pub fn encrypt_output( attr.value = encrypt_preserialized_string(&encryption_key, &attr.value, &None)?; } } - - let msg_id = match reply_params { - Some(ref r) => { - let encrypted_id = Binary::from_base64(&encrypt_preserialized_string( - &encryption_key, - &r.sub_msg_id.to_string(), - &reply_params, - )?)?; - - Some(encrypted_id) - } - None => None, - }; - - *internal_msg_id = msg_id.clone(); - - *internal_reply_enclave_sig = match reply_params { - Some(_) => { - let mut events: Vec = vec![]; - - if ok.attributes.len() > 0 { - events.push(Event { - ty: "wasm".to_string(), - attributes: ok.attributes.clone(), - }) - } - - events.extend_from_slice(&ok.events.clone().as_slice()); - let custom_contract_event_prefix: String = "wasm-".to_string(); - for event in events.iter_mut() { - if event.ty != "wasm" { - event.ty = custom_contract_event_prefix.clone() + event.ty.as_str(); - } - } - - let reply = Reply { - id: msg_id.unwrap(), - result: SubMsgResult::Ok(SubMsgResponse { events, data: None }), - }; - - let reply_as_vec = serde_json::to_vec(&reply).map_err(|err| { - warn!( - "got an error while trying to serialize reply into bytes for internal_reply_enclave_sig {:?}: {}", - reply, err - ); - EnclaveError::FailedToSerialize - })?; - - let tmp_secret_msg = SecretMessage { - nonce: secret_msg.nonce, - user_public_key: secret_msg.user_public_key, - msg: reply_as_vec, - }; - - Some(Binary::from( - create_callback_signature(sender_addr, &tmp_secret_msg, &[]).as_slice(), - )) - } - None => None, // Not a reply, we don't need enclave sig - } } - RawWasmOutput::OkIBCReceive { - ok, - internal_reply_enclave_sig, - internal_msg_id, - } => { + RawWasmOutput::OkIBCPacketReceive { ok } => { for sub_msg in &mut ok.messages { if let enclave_cosmwasm_v1_types::results::CosmosMsg::Wasm(wasm_msg) = &mut sub_msg.msg @@ -716,69 +636,6 @@ pub fn encrypt_output( &ok.acknowledgement, &reply_params, )?)?; - - let msg_id = match reply_params { - Some(ref r) => { - let encrypted_id = Binary::from_base64(&encrypt_preserialized_string( - &encryption_key, - &r.sub_msg_id.to_string(), - &reply_params, - )?)?; - - Some(encrypted_id) - } - None => None, - }; - - *internal_msg_id = msg_id.clone(); - - *internal_reply_enclave_sig = match reply_params { - Some(_) => { - let mut events: Vec = vec![]; - - if ok.attributes.len() > 0 { - events.push(Event { - ty: "wasm".to_string(), - attributes: ok.attributes.clone(), - }) - } - - events.extend_from_slice(&ok.events.clone().as_slice()); - let custom_contract_event_prefix: String = "wasm-".to_string(); - for event in events.iter_mut() { - if event.ty != "wasm" { - event.ty = custom_contract_event_prefix.clone() + event.ty.as_str(); - } - } - - let reply = Reply { - id: msg_id.unwrap(), - result: SubMsgResult::Ok(SubMsgResponse { - events, - data: Some(ok.acknowledgement.clone()), - }), - }; - - let reply_as_vec = serde_json::to_vec(&reply).map_err(|err| { - warn!( - "got an error while trying to serialize reply into bytes for internal_reply_enclave_sig {:?}: {}", - reply, err - ); - EnclaveError::FailedToSerialize - })?; - - let tmp_secret_msg = SecretMessage { - nonce: secret_msg.nonce, - user_public_key: secret_msg.user_public_key, - msg: reply_as_vec, - }; - - Some(Binary::from( - create_callback_signature(sender_addr, &tmp_secret_msg, &[]).as_slice(), - )) - } - None => None, // Not a reply, we don't need enclave sig - } } }; diff --git a/go-cosmwasm/lib.go b/go-cosmwasm/lib.go index 0809da070..970da2127 100644 --- a/go-cosmwasm/lib.go +++ b/go-cosmwasm/lib.go @@ -86,13 +86,12 @@ func (w *Wasmer) GetCode(code CodeID) (WasmCode, error) { // This struct helps us to distinguish between v0.10 contract response and v1 contract response type ContractExecResponse struct { - V1 *V1ContractExecResponse `json:"v1,omitempty"` - V010 *V010ContractExecResponse `json:"v010,omitempty"` - InternaReplyEnclaveSig []byte `json:"internal_reply_enclave_sig"` - InternalMsgId []byte `json:"internal_msg_id"` - IBCChannelOpen *v1types.IBCChannelOpenResult `json:"ibc_channel_open,omitempty"` - IBC *v1types.IBCBasicResult `json:"ibc,omitempty"` - IBCReceive *v1types.IBCReceiveResult `json:"ibc_receive,omitempty"` + V1 *V1ContractExecResponse `json:"v1,omitempty"` + V010 *V010ContractExecResponse `json:"v010,omitempty"` + InternaReplyEnclaveSig []byte `json:"internal_reply_enclave_sig"` + InternalMsgId []byte `json:"internal_msg_id"` + IBCBasic *v1types.IBCBasicResult `json:"ibc_basic,omitempty"` + IBCPacketReceive *v1types.IBCReceiveResult `json:"ibc_packet_receive,omitempty"` } type V010ContractExecResponse struct { @@ -315,55 +314,23 @@ func (w *Wasmer) Execute( } } - // handle IBCChannelOpen response - if resp.IBCChannelOpen != nil { - if resp.IBCChannelOpen.Err != "" { - return nil, gasUsed, fmt.Errorf("%s", resp.IBCChannelOpen.Err) - } else if resp.IBCChannelOpen.Ok != nil { - return resp.IBCChannelOpen.Ok, gasUsed, nil - } else { - return nil, gasUsed, fmt.Errorf("cannot parse IBCChannelOpen response: %+v", resp) - } - } - - // handle IBCChannelConnect response - if resp.IBC != nil { - if resp.IBC.Err != nil { - return v1types.DataWithInternalReplyInfo{ - InternalMsgId: resp.InternalMsgId, - InternaReplyEnclaveSig: resp.InternaReplyEnclaveSig, - Data: []byte(resp.IBC.Err.GenericErr.Msg), - }, gasUsed, fmt.Errorf("%+v", resp.IBC.Err) - } else if resp.IBC.Ok != nil { - if isOutputAddressedToReply { - resp.IBC.Ok.InternalData, err = AppendReplyInternalDataToData([]byte{}, resp.InternaReplyEnclaveSig, resp.InternalMsgId) - if err != nil { - return nil, gasUsed, fmt.Errorf("cannot serialize v1 DataWithInternalReplyInfo into binary : %w", err) - } - } - return resp.V1.Ok, gasUsed, nil + if resp.IBCBasic != nil { + if resp.IBCBasic.Err != nil { + return nil, gasUsed, fmt.Errorf("%+v", resp.IBCBasic.Err) + } else if resp.IBCBasic.Ok != nil { + return resp.IBCBasic.Ok, gasUsed, nil } else { - return nil, gasUsed, fmt.Errorf("cannot parse v1 handle response: %+v", resp) + return nil, gasUsed, fmt.Errorf("cannot parse IBCBasic response: %+v", resp) } } - if resp.IBCReceive != nil { - if resp.IBCReceive.Err != nil { - return v1types.DataWithInternalReplyInfo{ - InternalMsgId: resp.InternalMsgId, - InternaReplyEnclaveSig: resp.InternaReplyEnclaveSig, - Data: []byte(resp.IBCReceive.Err.GenericErr.Msg), - }, gasUsed, fmt.Errorf("%+v", resp.IBCReceive.Err) - } else if resp.IBCReceive.Ok != nil { - if isOutputAddressedToReply { - resp.IBCReceive.Ok.Acknowledgement, err = AppendReplyInternalDataToData(resp.IBCReceive.Ok.Acknowledgement, resp.InternaReplyEnclaveSig, resp.InternalMsgId) - if err != nil { - return nil, gasUsed, fmt.Errorf("cannot serialize v1 DataWithInternalReplyInfo into binary : %w", err) - } - } - return resp.V1.Ok, gasUsed, nil + if resp.IBCPacketReceive != nil { + if resp.IBCPacketReceive.Err != nil { + return nil, gasUsed, fmt.Errorf("%+v", resp.IBCPacketReceive.Err) + } else if resp.IBCPacketReceive.Ok != nil { + return resp.IBCPacketReceive.Ok, gasUsed, nil } else { - return nil, gasUsed, fmt.Errorf("cannot parse v1 handle response: %+v", resp) + return nil, gasUsed, fmt.Errorf("cannot parse IBCPacketReceive response: %+v", resp) } } diff --git a/go-cosmwasm/types/v1/ibc.go b/go-cosmwasm/types/v1/ibc.go index d98c6826b..efe2a462d 100644 --- a/go-cosmwasm/types/v1/ibc.go +++ b/go-cosmwasm/types/v1/ibc.go @@ -228,8 +228,6 @@ type IBCBasicResult struct { // IBCBasicResponse defines the return value on a successful processing. // This is the counterpart of [IbcBasicResponse](https://github.com/CosmWasm/cosmwasm/blob/v0.14.0-beta1/packages/std/src/ibc.rs#L194-L216). type IBCBasicResponse struct { - // Used for internal purposes - InternalData []byte `json:"internal_data,omitempty"` // Messages comes directly from the contract and is its request for action. // If the ReplyOn value matches the result, the runtime will invoke this // contract's `reply` entry point after execution. Otherwise, this is all diff --git a/x/compute/internal/keeper/relay.go b/x/compute/internal/keeper/relay.go index 776f3e52d..a60a928e0 100644 --- a/x/compute/internal/keeper/relay.go +++ b/x/compute/internal/keeper/relay.go @@ -287,6 +287,6 @@ func (k Keeper) OnTimeoutPacket( func (k Keeper) handleIBCBasicContractResponse(ctx sdk.Context, addr sdk.AccAddress, ibcPortID string, inputMsg []byte, res *v1types.IBCBasicResponse) error { verificationInfo := types.NewVerificationInfo([]byte{}, sdktxsigning.SignMode_SIGN_MODE_UNSPECIFIED, []byte{}, []byte{}, []byte{}, nil) - _, err := k.handleContractResponse(ctx, addr, ibcPortID, res.Messages, res.Attributes, res.Events, res.InternalData, inputMsg, verificationInfo, wasmTypes.CosmosMsgVersionV1) + _, err := k.handleContractResponse(ctx, addr, ibcPortID, res.Messages, res.Attributes, res.Events, nil, inputMsg, verificationInfo, wasmTypes.CosmosMsgVersionV1) return err } From 28a412ac7fa14c640968eb8227105b1988d6b2a7 Mon Sep 17 00:00:00 2001 From: Lior Bondarevski Date: Wed, 17 Aug 2022 13:10:05 +0300 Subject: [PATCH 30/93] Correct errors for replies --- x/compute/internal/keeper/keeper.go | 8 ++++---- x/compute/internal/types/errors.go | 3 +++ 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/x/compute/internal/keeper/keeper.go b/x/compute/internal/keeper/keeper.go index 115bd8e54..9fd58eb6e 100644 --- a/x/compute/internal/keeper/keeper.go +++ b/x/compute/internal/keeper/keeper.go @@ -1066,12 +1066,12 @@ func (k Keeper) reply(ctx sdk.Context, contractAddress sdk.AccAddress, reply v1w consumeGas(ctx, gasUsed) if execErr != nil { - return nil, sdkerrors.Wrap(types.ErrExecuteFailed, execErr.Error()) + return nil, sdkerrors.Wrap(types.ErrReplyFailed, execErr.Error()) } switch res := response.(type) { case *v010wasmTypes.HandleResponse: - return nil, sdkerrors.Wrap(types.ErrExecuteFailed, fmt.Sprintf("response of reply should always be a CosmWasm v1 response type: %+v", res)) + return nil, sdkerrors.Wrap(types.ErrReplyFailed, fmt.Sprintf("response of reply should always be a CosmWasm v1 response type: %+v", res)) case *v1wasmTypes.Response: consumeGas(ctx, gasUsed) @@ -1082,11 +1082,11 @@ func (k Keeper) reply(ctx sdk.Context, contractAddress sdk.AccAddress, reply v1w data, err := k.handleContractResponse(ctx, contractAddress, contractInfo.IBCPortID, res.Messages, res.Attributes, res.Events, res.Data, ogTx, ogSigInfo, wasmTypes.CosmosMsgVersionV1) if err != nil { - return nil, sdkerrors.Wrap(types.ErrExecuteFailed, err.Error()) + return nil, sdkerrors.Wrap(types.ErrReplyFailed, err.Error()) } return data, nil default: - return nil, sdkerrors.Wrap(types.ErrExecuteFailed, fmt.Sprintf("cannot detect response type: %+v", res)) + return nil, sdkerrors.Wrap(types.ErrReplyFailed, fmt.Sprintf("cannot detect response type: %+v", res)) } } diff --git a/x/compute/internal/types/errors.go b/x/compute/internal/types/errors.go index 1cd214613..7c7dfff50 100644 --- a/x/compute/internal/types/errors.go +++ b/x/compute/internal/types/errors.go @@ -64,6 +64,9 @@ var ( // ErrUnknownMsg error by a message handler to show that it is not responsible for this message type ErrUnknownMsg = sdkErrors.Register(DefaultCodespace, 18, "unknown message from the contract") + // ErrReplyFailed error for rust execution contract failure + ErrReplyFailed = sdkErrors.Register(DefaultCodespace, 19, "reply to contract failed") + // ErrInvalidEvent error if an attribute/event from the contract is invalid ErrInvalidEvent = sdkErrors.Register(DefaultCodespace, 21, "invalid event") ) From 214101ab891f5486d054fa2e03bf93d5a2ec6ae7 Mon Sep 17 00:00:00 2001 From: Assaf Morami Date: Wed, 17 Aug 2022 18:02:41 +0300 Subject: [PATCH 31/93] Wire up StargateQuery --- app/app.go | 4 +- go-cosmwasm/types/queries.go | 13 ++ x/compute/alias.go | 2 +- x/compute/internal/keeper/handler_plugin.go | 95 ++++--------- x/compute/internal/keeper/keeper.go | 18 +-- x/compute/internal/keeper/query_plugins.go | 149 ++++++++++++++++++-- x/compute/internal/keeper/test_common.go | 3 +- 7 files changed, 191 insertions(+), 93 deletions(-) diff --git a/app/app.go b/app/app.go index 326fddf9f..02afe6789 100644 --- a/app/app.go +++ b/app/app.go @@ -399,7 +399,6 @@ func NewSecretNetworkApp( AddRoute(ibcclienttypes.RouterKey, ibcclient.NewClientProposalHandler(app.ibcKeeper.ClientKeeper)) // Just re-use the full router - do we want to limit this more? - computeRouter := app.Router() regRouter := app.Router() // Replace with bootstrap flag when we figure out how to test properly and everything works @@ -435,7 +434,8 @@ func NewSecretNetworkApp( app.ibcKeeper.PortKeeper, app.transferKeeper, app.ibcKeeper.ChannelKeeper, - computeRouter, + app.MsgServiceRouter(), + app.GRPCQueryRouter(), computeDir, computeConfig, supportedFeatures, diff --git a/go-cosmwasm/types/queries.go b/go-cosmwasm/types/queries.go index 90519e2a4..d3909c6d5 100644 --- a/go-cosmwasm/types/queries.go +++ b/go-cosmwasm/types/queries.go @@ -242,6 +242,19 @@ type DistQuery struct { type GovQuery struct { Proposals *ProposalsQuery `json:"proposals,omitempty"` } + +// StargateQuery is encoded the same way as abci_query, with path and protobuf encoded request data. +// The format is defined in [ADR-21](https://github.com/cosmos/cosmos-sdk/blob/master/docs/architecture/adr-021-protobuf-query-encoding.md). +// The response is protobuf encoded data directly without a JSON response wrapper. +// The caller is responsible for compiling the proper protobuf definitions for both requests and responses. +type StargateQuery struct { + // this is the fully qualified service path used for routing, + // eg. custom/cosmos_sdk.x.bank.v1.Query/QueryBalance + Path string `json:"path"` + // this is the expected protobuf message type (not any), binary encoded + Data []byte `json:"data"` +} + type MintQuery struct { Inflation *MintingInflationQuery `json:"inflation,omitempty"` BondedRatio *MintingBondedRatioQuery `json:"bonded_ratio,omitempty"` diff --git a/x/compute/alias.go b/x/compute/alias.go index 47f42e992..ea3beec23 100644 --- a/x/compute/alias.go +++ b/x/compute/alias.go @@ -117,7 +117,7 @@ type ( CreatedAt = types.AbsoluteTxPosition WasmConfig = types.WasmConfig CodeInfoResponse = types.CodeInfoResponse - MessageHandler = keeper.MessageHandler + MessageHandler = keeper.SDKMessageHandler BankEncoder = keeper.BankEncoder CustomEncoder = keeper.CustomEncoder StakingEncoder = keeper.StakingEncoder diff --git a/x/compute/internal/keeper/handler_plugin.go b/x/compute/internal/keeper/handler_plugin.go index f557fcffc..a6357b0bb 100644 --- a/x/compute/internal/keeper/handler_plugin.go +++ b/x/compute/internal/keeper/handler_plugin.go @@ -14,7 +14,6 @@ import ( host "github.com/cosmos/ibc-go/v3/modules/core/24-host" v1wasmTypes "github.com/enigmampc/SecretNetwork/go-cosmwasm/types/v1" - "github.com/cosmos/cosmos-sdk/x/auth/legacy/legacytx" banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" distrtypes "github.com/cosmos/cosmos-sdk/x/distribution/types" govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" @@ -34,13 +33,14 @@ type MessageHandlerChain struct { handlers []Messenger } -type MessageHandler struct { - router sdk.Router +// SDKMessageHandler can handles messages that can be encoded into sdk.Message types and routed. +type SDKMessageHandler struct { + router MessageRouter encoders MessageEncoders } -func NewSDKMessageHandler(router sdk.Router, encoders MessageEncoders) MessageHandler { - return MessageHandler{ +func NewSDKMessageHandler(router MessageRouter, encoders MessageEncoders) SDKMessageHandler { + return SDKMessageHandler{ router: router, encoders: encoders, } @@ -67,7 +67,7 @@ func NewMessageHandlerChain(first Messenger, others ...Messenger) *MessageHandle } func NewMessageHandler( - router sdk.Router, + msgRouter MessageRouter, customEncoders *MessageEncoders, channelKeeper channelkeeper.Keeper, capabilityKeeper capabilitykeeper.ScopedKeeper, @@ -76,7 +76,7 @@ func NewMessageHandler( ) Messenger { encoders := DefaultEncoders(portSource, unpacker).Merge(customEncoders) return NewMessageHandlerChain( - NewSDKMessageHandler(router, encoders), + NewSDKMessageHandler(msgRouter, encoders), NewIBCRawPacketHandler(channelKeeper, capabilityKeeper), ) } @@ -515,7 +515,7 @@ func EncodeWasmMsg(sender sdk.AccAddress, msg *v1wasmTypes.WasmMsg) ([]sdk.Msg, } } -func (h MessageHandler) DispatchMsg(ctx sdk.Context, contractAddr sdk.AccAddress, contractIBCPortID string, msg v1wasmTypes.CosmosMsg, ogMessageVersion wasmTypes.CosmosMsgVersion) ([]sdk.Event, [][]byte, error) { +func (h SDKMessageHandler) DispatchMsg(ctx sdk.Context, contractAddr sdk.AccAddress, contractIBCPortID string, msg v1wasmTypes.CosmosMsg, ogMessageVersion wasmTypes.CosmosMsgVersion) ([]sdk.Event, [][]byte, error) { sdkMsgs, err := h.encoders.Encode(ctx, contractAddr, contractIBCPortID, msg) if err != nil { return nil, nil, err @@ -526,81 +526,46 @@ func (h MessageHandler) DispatchMsg(ctx sdk.Context, contractAddr sdk.AccAddress data [][]byte ) for _, sdkMsg := range sdkMsgs { - sdkEvents, sdkData, err := h.handleSdkMessage(ctx, contractAddr, sdkMsg) + res, err := h.handleSdkMessage(ctx, contractAddr, sdkMsg) if err != nil { - data = append(data, sdkData) - return nil, data, err + return nil, nil, err } // append data - data = append(data, sdkData) + data = append(data, res.Data) + // append events + sdkEvents := make([]sdk.Event, len(res.Events)) + for i := range res.Events { + sdkEvents[i] = sdk.Event(res.Events[i]) + } events = append(events, sdkEvents...) } return events, data, nil - - // return nil, nil, sdkerrors.Wrap(types.ErrInvalidMsg, "Unknown variant of CosmosMsgVersion") } -func (h MessageHandler) handleSdkMessage(ctx sdk.Context, contractAddr sdk.Address, msg sdk.Msg) (sdk.Events, []byte, error) { +func (h SDKMessageHandler) handleSdkMessage(ctx sdk.Context, contractAddr sdk.Address, msg sdk.Msg) (*sdk.Result, error) { if err := msg.ValidateBasic(); err != nil { - return nil, nil, err + return nil, err } - // make sure this account can send it for _, acct := range msg.GetSigners() { if !acct.Equals(contractAddr) { - return nil, nil, sdkerrors.Wrap(sdkerrors.ErrUnauthorized, "contract doesn't have permission") - } - } - - var res *sdk.Result - var err error - if legacyMsg, ok := msg.(legacytx.LegacyMsg); ok { - msgRoute := legacyMsg.Route() - handler := h.router.Route(ctx, msgRoute) - if handler == nil { - return nil, nil, sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "unrecognized message route: %s", msgRoute) - } - - res, err = handler(ctx, msg) - if err != nil { - var errData []byte - errData = nil - if res != nil { - errData = make([]byte, len(res.Data)) - copy(errData, res.Data) - } - - return nil, errData, err + return nil, sdkerrors.Wrap(sdkerrors.ErrUnauthorized, "contract doesn't have permission") } - } else { - return nil, nil, sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "unrecognized legacy message route: %s", sdk.MsgTypeURL(msg)) - - // todo: grpc routing - //handler := k.serviceRouter.Handler(msg) - //if handler == nil { - // return nil, nil, sdkerrors.Wrap(sdkerrors.ErrUnknownRequest, sdk.MsgTypeURL(msg)) - //} - //res, err := handler(ctx, msg) - //if err != nil { - // return nil, nil, err - //} } - var events []sdk.Event - data := make([]byte, len(res.Data)) - copy(data, res.Data) - // - // convert Tendermint.Events to sdk.Event - sdkEvents := make(sdk.Events, len(res.Events)) - for i := range res.Events { - sdkEvents[i] = sdk.Event(res.Events[i]) + // find the handler and execute it + if handler := h.router.Handler(msg); handler != nil { + // ADR 031 request type routing + msgResult, err := handler(ctx, msg) + return msgResult, err } - - // append message action attribute - events = append(events, sdkEvents...) - - return events, data, nil + // legacy sdk.Msg routing + // Assuming that the app developer has migrated all their Msgs to + // proto messages and has registered all `Msg services`, then this + // path should never be called, because all those Msgs should be + // registered within the `msgServiceRouter` already. + return nil, sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "can't route message %+v", msg) } // convertWasmIBCTimeoutHeightToCosmosHeight converts a wasm type ibc timeout height to ibc module type height diff --git a/x/compute/internal/keeper/keeper.go b/x/compute/internal/keeper/keeper.go index 808d18abd..c1627e869 100644 --- a/x/compute/internal/keeper/keeper.go +++ b/x/compute/internal/keeper/keeper.go @@ -72,20 +72,19 @@ type Keeper struct { messenger Messenger // queryGasLimit is the max wasm gas that can be spent on executing a query with a contract queryGasLimit uint64 - serviceRouter MsgServiceRouter // authZPolicy AuthorizationPolicy // paramSpace subspace.Subspace } -// MsgServiceRouter expected MsgServiceRouter interface -type MsgServiceRouter interface { - Handler(msg sdk.Msg) baseapp.MsgServiceHandler -} - func moduleLogger(ctx sdk.Context) log.Logger { return ctx.Logger().With("module", fmt.Sprintf("x/%s", types.ModuleName)) } +// MessageRouter ADR 031 request type routing +type MessageRouter interface { + Handler(msg sdk.Msg) baseapp.MsgServiceHandler +} + func NewKeeper( cdc codec.Codec, legacyAmino codec.LegacyAmino, @@ -100,7 +99,8 @@ func NewKeeper( portKeeper portkeeper.Keeper, portSource types.ICS20TransferPortSource, channelKeeper channelkeeper.Keeper, - router sdk.Router, + msgRouter MessageRouter, + queryRouter GRPCQueryRouter, homeDir string, wasmConfig *types.WasmConfig, supportedFeatures string, @@ -128,10 +128,10 @@ func NewKeeper( bankKeeper: bankKeeper, portKeeper: portKeeper, capabilityKeeper: capabilityKeeper, - messenger: NewMessageHandler(router, customEncoders, channelKeeper, capabilityKeeper, portSource, cdc), + messenger: NewMessageHandler(msgRouter, customEncoders, channelKeeper, capabilityKeeper, portSource, cdc), queryGasLimit: wasmConfig.SmartQueryGasLimit, } - keeper.queryPlugins = DefaultQueryPlugins(govKeeper, distKeeper, mintKeeper, bankKeeper, stakingKeeper, &keeper).Merge(customPlugins) + keeper.queryPlugins = DefaultQueryPlugins(govKeeper, distKeeper, mintKeeper, bankKeeper, stakingKeeper, queryRouter, &keeper).Merge(customPlugins) return keeper } diff --git a/x/compute/internal/keeper/query_plugins.go b/x/compute/internal/keeper/query_plugins.go index 66d201222..1f21db699 100644 --- a/x/compute/internal/keeper/query_plugins.go +++ b/x/compute/internal/keeper/query_plugins.go @@ -2,10 +2,12 @@ package keeper import ( "encoding/json" + "fmt" "strings" "github.com/enigmampc/SecretNetwork/x/compute/internal/types" + "github.com/cosmos/cosmos-sdk/baseapp" "github.com/cosmos/cosmos-sdk/codec" bankkeeper "github.com/cosmos/cosmos-sdk/x/bank/keeper" distrkeeper "github.com/cosmos/cosmos-sdk/x/distribution/keeper" @@ -22,6 +24,10 @@ import ( abci "github.com/tendermint/tendermint/abci/types" ) +type GRPCQueryRouter interface { + Route(path string) baseapp.GRPCQueryHandler +} + type QueryHandler struct { Ctx sdk.Context Plugins QueryPlugins @@ -71,24 +77,26 @@ func (q QueryHandler) GasConsumed() uint64 { type CustomQuerier func(ctx sdk.Context, request json.RawMessage) ([]byte, error) type QueryPlugins struct { - Bank func(ctx sdk.Context, request *wasmTypes.BankQuery) ([]byte, error) - Custom CustomQuerier - Staking func(ctx sdk.Context, request *wasmTypes.StakingQuery) ([]byte, error) - Wasm func(ctx sdk.Context, request *wasmTypes.WasmQuery) ([]byte, error) - Dist func(ctx sdk.Context, request *wasmTypes.DistQuery) ([]byte, error) - Mint func(ctx sdk.Context, request *wasmTypes.MintQuery) ([]byte, error) - Gov func(ctx sdk.Context, request *wasmTypes.GovQuery) ([]byte, error) + Bank func(ctx sdk.Context, request *wasmTypes.BankQuery) ([]byte, error) + Custom CustomQuerier + Staking func(ctx sdk.Context, request *wasmTypes.StakingQuery) ([]byte, error) + Wasm func(ctx sdk.Context, request *wasmTypes.WasmQuery) ([]byte, error) + Dist func(ctx sdk.Context, request *wasmTypes.DistQuery) ([]byte, error) + Mint func(ctx sdk.Context, request *wasmTypes.MintQuery) ([]byte, error) + Stargate func(ctx sdk.Context, request *wasmTypes.StargateQuery) ([]byte, error) + Gov func(ctx sdk.Context, request *wasmTypes.GovQuery) ([]byte, error) } -func DefaultQueryPlugins(gov govkeeper.Keeper, dist distrkeeper.Keeper, mint mintkeeper.Keeper, bank bankkeeper.Keeper, staking stakingkeeper.Keeper, wasm *Keeper) QueryPlugins { +func DefaultQueryPlugins(gov govkeeper.Keeper, dist distrkeeper.Keeper, mint mintkeeper.Keeper, bank bankkeeper.Keeper, staking stakingkeeper.Keeper, stargateQueryRouter GRPCQueryRouter, wasm *Keeper) QueryPlugins { return QueryPlugins{ - Bank: BankQuerier(bank), - Custom: NoCustomQuerier, - Staking: StakingQuerier(staking, dist), - Wasm: WasmQuerier(wasm), - Dist: DistQuerier(dist), - Mint: MintQuerier(mint), - Gov: GovQuerier(gov), + Bank: BankQuerier(bank), + Custom: NoCustomQuerier, + Staking: StakingQuerier(staking, dist), + Wasm: WasmQuerier(wasm), + Dist: DistQuerier(dist), + Mint: MintQuerier(mint), + Gov: GovQuerier(gov), + Stargate: StargateQuerier(stargateQueryRouter), } } @@ -121,6 +129,117 @@ func (e QueryPlugins) Merge(o *QueryPlugins) QueryPlugins { return e } +// Assaf: stargateQueryAllowlist is a list of all safe and efficient queries +// +// excluded from this list (should be safe, but needs a clear use case): +// - /secret.registration.* +// - /ibc.core.* +// - /secret.intertx.* +// - /cosmos.evidence.* +// - /cosmos.upgrade.* +// +// we reserve the right to add/remove queries in future chain upgrades +// +// used this to find all query paths: +// find -name query.proto | sort | xargs grep -Poin 'package [a-z0-9.]+;|rpc [a-zA-Z]+\(' +var stargateQueryAllowlist = map[string]bool{ + "/cosmos.auth.v1beta1.Query.Account": true, + "/cosmos.auth.v1beta1.Query.Accounts": true, + "/cosmos.auth.v1beta1.Query.Params": true, + + "/cosmos.authz.v1beta1.Query.Grants": true, + "/cosmos.authz.v1beta1.Query.GranterGrants": true, + "/cosmos.authz.v1beta1.Query.GranteeGrants": true, + + "/cosmos.bank.v1beta1.Query.Balance": true, + "/cosmos.bank.v1beta1.Query.AllBalances": true, + "/cosmos.bank.v1beta1.Query.SpendableBalances": true, + "/cosmos.bank.v1beta1.Query.TotalSupply": true, + "/cosmos.bank.v1beta1.Query.SupplyOf": true, + "/cosmos.bank.v1beta1.Query.Params": true, + "/cosmos.bank.v1beta1.Query.DenomMetadata": true, + "/cosmos.bank.v1beta1.Query.DenomsMetadata": true, + + "/cosmos.distribution.v1beta1.Query.Params": true, + "/cosmos.distribution.v1beta1.Query.ValidatorOutstandingRewards": true, + "/cosmos.distribution.v1beta1.Query.ValidatorCommission": true, + "/cosmos.distribution.v1beta1.Query.ValidatorSlashes": true, + "/cosmos.distribution.v1beta1.Query.DelegationRewards": true, + "/cosmos.distribution.v1beta1.Query.DelegationTotalRewards": true, + "/cosmos.distribution.v1beta1.Query.DelegatorValidators": true, + "/cosmos.distribution.v1beta1.Query.DelegatorWithdrawAddress": true, + "/cosmos.distribution.v1beta1.Query.CommunityPool": true, + "/cosmos.distribution.v1beta1.Query.FoundationTax": true, + + "/cosmos.feegrant.v1beta1.Query.Allowance": true, + "/cosmos.feegrant.v1beta1.Query.Allowances": true, + + "/cosmos.gov.v1beta1.Query.Proposal": true, + "/cosmos.gov.v1beta1.Query.Proposals": true, + "/cosmos.gov.v1beta1.Query.Vote": true, + "/cosmos.gov.v1beta1.Query.Votes": true, + "/cosmos.gov.v1beta1.Query.Params": true, + "/cosmos.gov.v1beta1.Query.Deposit": true, + "/cosmos.gov.v1beta1.Query.Deposits": true, + "/cosmos.gov.v1beta1.Query.TallyResult": true, + + "/cosmos.mint.v1beta1.Query.Params": true, + "/cosmos.mint.v1beta1.Query.Inflation": true, + "/cosmos.mint.v1beta1.Query.AnnualProvisions": true, + + "/cosmos.params.v1beta1.Query.Params": true, + + "/cosmos.slashing.v1beta1.Query.Params": true, + "/cosmos.slashing.v1beta1.Query.SigningInfo": true, + "/cosmos.slashing.v1beta1.Query.SigningInfos": true, + + "/cosmos.staking.v1beta1.Query.Validators": true, + "/cosmos.staking.v1beta1.Query.Validator": true, + "/cosmos.staking.v1beta1.Query.ValidatorDelegations": true, + "/cosmos.staking.v1beta1.Query.ValidatorUnbondingDelegations": true, + "/cosmos.staking.v1beta1.Query.Delegation": true, + "/cosmos.staking.v1beta1.Query.UnbondingDelegation": true, + "/cosmos.staking.v1beta1.Query.DelegatorDelegations": true, + "/cosmos.staking.v1beta1.Query.DelegatorUnbondingDelegations": true, + "/cosmos.staking.v1beta1.Query.Redelegations": true, + "/cosmos.staking.v1beta1.Query.DelegatorValidators": true, + "/cosmos.staking.v1beta1.Query.DelegatorValidator": true, + "/cosmos.staking.v1beta1.Query.HistoricalInfo": true, + "/cosmos.staking.v1beta1.Query.Pool": true, + "/cosmos.staking.v1beta1.Query.Params": true, + + "/ibc.applications.transfer.v1.Query.DenomTrace": true, + "/ibc.applications.transfer.v1.Query.DenomTraces": true, + "/ibc.applications.transfer.v1.Query.Params": true, + "/ibc.applications.transfer.v1.Query.DenomHash": true, + + "/secret.compute.v1beta1.Query.ContractInfo": true, + "/secret.compute.v1beta1.Query.ContractsByCode": true, + "/secret.compute.v1beta1.Query.Codes": true, +} + +func StargateQuerier(queryRouter GRPCQueryRouter) func(ctx sdk.Context, request *wasmTypes.StargateQuery) ([]byte, error) { + return func(ctx sdk.Context, msg *wasmTypes.StargateQuery) ([]byte, error) { + if !stargateQueryAllowlist[msg.Path] { + return nil, wasmTypes.UnsupportedRequest{Kind: fmt.Sprintf("query path '%s' is not allowed from the contract", msg.Path)} + } + + route := queryRouter.Route(msg.Path) + if route == nil { + return nil, wasmTypes.UnsupportedRequest{Kind: fmt.Sprintf("No route to query path '%s'", msg.Path)} + } + req := abci.RequestQuery{ + Data: msg.Data, + Path: msg.Path, + } + res, err := route(ctx, req) + if err != nil { + return nil, err + } + return res.Value, nil + } +} + func GovQuerier(keeper govkeeper.Keeper) func(ctx sdk.Context, request *wasmTypes.GovQuery) ([]byte, error) { return func(ctx sdk.Context, request *wasmTypes.GovQuery) ([]byte, error) { if request.Proposals != nil { diff --git a/x/compute/internal/keeper/test_common.go b/x/compute/internal/keeper/test_common.go index c4269232b..cb68b3bc9 100644 --- a/x/compute/internal/keeper/test_common.go +++ b/x/compute/internal/keeper/test_common.go @@ -420,7 +420,8 @@ func CreateTestInput(t *testing.T, isCheckTx bool, supportedFeatures string, enc ibcKeeper.PortKeeper, MockIBCTransferKeeper{}, ibcKeeper.ChannelKeeper, - router, + baseapp.NewMsgServiceRouter(), + baseapp.NewGRPCQueryRouter(), tempDir, wasmConfig, supportedFeatures, From 94b816a7e0be6b8ecc33944c64d18de04dea8554 Mon Sep 17 00:00:00 2001 From: Lior Bondarevski Date: Thu, 18 Aug 2022 12:24:24 +0300 Subject: [PATCH 32/93] parse the message correctly --- .../src/contract_operations.rs | 107 +++++++----------- 1 file changed, 43 insertions(+), 64 deletions(-) diff --git a/cosmwasm/enclaves/shared/contract-engine/src/contract_operations.rs b/cosmwasm/enclaves/shared/contract-engine/src/contract_operations.rs index 5f3bb724c..03839d239 100644 --- a/cosmwasm/enclaves/shared/contract-engine/src/contract_operations.rs +++ b/cosmwasm/enclaves/shared/contract-engine/src/contract_operations.rs @@ -254,91 +254,73 @@ pub fn try_get_decrypted_secret_msg(message: &[u8]) -> Option( - _t: T, - message: &[u8], - orig_secret_msg: SecretMessage, - function_name: &str, -) -> Result +pub fn parse_ibc_packet(_t: T, message: &[u8], function_name: &str) -> ParsedMessage where T: IbcPacketTrait + Serialize + DeserializeOwned + Debug, { - let mut parsed_encrypted_ibc_packet: T = - serde_json::from_slice(&orig_secret_msg.msg.as_slice().to_vec()).map_err(|err| { - warn!( + let mut parsed_encrypted_ibc_packet: T = serde_json::from_slice(&message.as_slice().to_vec()) + .map_err(|err| { + warn!( "{} msg got an error while trying to deserialize msg input bytes into json {:?}: {}", function_name, String::from_utf8_lossy(&orig_secret_msg.msg), err ); - EnclaveError::FailedToDeserialize - })?; + EnclaveError::FailedToDeserialize + })?; - let tmp_secret_data = SecretMessage { - nonce: orig_secret_msg.nonce, - user_public_key: orig_secret_msg.user_public_key, - msg: parsed_encrypted_ibc_packet.get_packet().as_slice().to_vec(), - }; + let tmp_secret_data = get_secret_msg(parsed_encrypted_ibc_packet.get_packet().as_slice()); + let was_msg_encrypted = false; + let orig_secret_msg = tmp_secret_data; match tmp_secret_data.decrypt() { Ok(decrypted_msg) => { // IBC packet was encrypted trace!( - "{} input before decryption: {:?}", + "{} data before decryption: {:?}", function_name, base64::encode(&message) ); parsed_encrypted_ibc_packet.set_packet(decrypted_msg.as_slice().into()); - - match parsed_encrypted_ibc_packet.get_ack() { - Some(ack_data) => { - let tmp_secret_ack_data = SecretMessage { - nonce: orig_secret_msg.nonce, - user_public_key: orig_secret_msg.user_public_key, - msg: ack_data.as_slice().to_vec(), - }; - - parsed_encrypted_ibc_packet - .set_ack(tmp_secret_ack_data.decrypt()?.as_slice().into()); - } - None => {} - } - - Ok(ParsedMessage { - should_validate_sig_info: false, - was_msg_encrypted: true, - secret_msg: orig_secret_msg, - decrypted_msg: serde_json::to_vec(&parsed_encrypted_ibc_packet).map_err(|err| { - warn!( - "got an error while trying to serialize {} msg into bytes {:?}: {}", - function_name, parsed_encrypted_ibc_packet, err - ); - EnclaveError::FailedToSerialize - })?, - contract_hash_for_validation: None, - }) + was_msg_encrypted = true; } Err(_) => { - // assume packet is not encrypted, continue in plaintext mode + // assume data is not encrypted trace!( - "{} input was plaintext: {:?}", + "{} data was plaintext: {:?}", function_name, base64::encode(&message) ); + } + } - let decrypted_msg = orig_secret_msg.msg.clone(); + let tmp_secret_ack = get_secret_msg(parsed_encrypted_ibc_packet.get_ack().as_slice()); - Ok(ParsedMessage { - should_validate_sig_info: false, - was_msg_encrypted: false, - secret_msg: orig_secret_msg, - decrypted_msg, - contract_hash_for_validation: None, - }) + match tmp_secret_ack.decrypt() { + Ok(ack_data) => { + parsed_encrypted_ibc_packet.set_ack(ack_data.as_slice().into()); + was_msg_encrypted = true; + + orig_secret_msg = tmp_secret_ack; } + Err(_) => {} + } + + ParsedMessage { + should_validate_sig_info: false, + was_msg_encrypted, + secret_msg: orig_secret_msg, + decrypted_msg: serde_json::to_vec(&parsed_encrypted_ibc_packet).map_err(|err| { + warn!( + "got an error while trying to serialize {} msg into bytes {:?}: {}", + function_name, parsed_encrypted_ibc_packet, err + ); + EnclaveError::FailedToSerialize + })?, + contract_hash_for_validation: None, } } @@ -683,32 +665,29 @@ pub fn parse_message( HandleType::HANDLE_TYPE_IBC_PACKET_RECEIVE => { // LIORRR TODO: Maybe mark whether the message was encrypted or not. let orig_secret_msg = get_secret_msg(message); - parse_ibc_packet( + Ok(parse_ibc_packet( IbcPacketReceiveMsg::default(), message, - orig_secret_msg, "ibc_packet_receive", - ) + )) } HandleType::HANDLE_TYPE_IBC_PACKET_ACK => { // LIORRR TODO: Maybe mark whether the message was encrypted or not. let orig_secret_msg = get_secret_msg(message); - parse_ibc_packet( + Ok(parse_ibc_packet( IbcPacketAckMsg::default(), message, - orig_secret_msg, "ibc_packet_receive", - ) + )) } HandleType::HANDLE_TYPE_IBC_PACKET_TIMEOUT => { // LIORRR TODO: Maybe mark whether the message was encrypted or not. let orig_secret_msg = get_secret_msg(message); - parse_ibc_packet( + Ok(parse_ibc_packet( IbcPacketTimeoutMsg::default(), message, - orig_secret_msg, "ibc_packet_timeout", - ) + )) } }; } From 18abe47270a59088dc49e3fef0a712601241dd20 Mon Sep 17 00:00:00 2001 From: Lior Bondarevski Date: Fri, 19 Aug 2022 20:06:42 +0300 Subject: [PATCH 33/93] Create IBC tests suite --- x/compute/internal/keeper/ibc_test.go | 332 +++++++++++++++++++++++ x/compute/internal/keeper/test_common.go | 38 ++- 2 files changed, 358 insertions(+), 12 deletions(-) create mode 100644 x/compute/internal/keeper/ibc_test.go diff --git a/x/compute/internal/keeper/ibc_test.go b/x/compute/internal/keeper/ibc_test.go new file mode 100644 index 000000000..9092290b1 --- /dev/null +++ b/x/compute/internal/keeper/ibc_test.go @@ -0,0 +1,332 @@ +package keeper + +import ( + "encoding/hex" + "testing" + + crypto "github.com/cosmos/cosmos-sdk/crypto/types" + sdk "github.com/cosmos/cosmos-sdk/types" + cosmwasm "github.com/enigmampc/SecretNetwork/go-cosmwasm/types" + v1types "github.com/enigmampc/SecretNetwork/go-cosmwasm/types/v1" + "github.com/enigmampc/SecretNetwork/x/compute/internal/types" + "github.com/stretchr/testify/require" + "github.com/tendermint/tendermint/libs/log" +) + +func ibcChannelConnectHelper( + t *testing.T, keeper Keeper, ctx sdk.Context, + contractAddr sdk.AccAddress, creatorPrivKey crypto.PrivKey, msg string, + gas uint64, shouldSendOpenAck bool, channel v1types.IBCChannel, +) cosmwasm.StdError { + // create new ctx with the same storage and a gas limit + // this is to reset the event manager, so we won't get + // events from past calls + gasMeter := &WasmCounterGasMeter{0, sdk.NewGasMeter(gas)} + ctx = sdk.NewContext( + ctx.MultiStore(), + ctx.BlockHeader(), + ctx.IsCheckTx(), + log.NewNopLogger(), + ).WithGasMeter(gasMeter) + + var ibcChannelConnectMsg v1types.IBCChannelConnectMsg + if shouldSendOpenAck { + ibcChannelConnectMsg = v1types.IBCChannelConnectMsg{ + OpenAck: &v1types.IBCOpenAck{ + Channel: channel, + CounterpartyVersion: "", + }, + OpenConfirm: nil, + } + } else { + ibcChannelConnectMsg = v1types.IBCChannelConnectMsg{ + OpenAck: nil, + OpenConfirm: &v1types.IBCOpenConfirm{ + Channel: channel, + }, + } + } + + err := keeper.OnConnectChannel(ctx, contractAddr, ibcChannelConnectMsg) + + require.NotZero(t, gasMeter.GetWasmCounter(), err) + + if err != nil { + return cosmwasm.StdError{GenericErr: &cosmwasm.GenericErr{Msg: err.Error()}} + } + + return cosmwasm.StdError{} +} + +func ibcChannelOpenHelper( + t *testing.T, keeper Keeper, ctx sdk.Context, + contractAddr sdk.AccAddress, creatorPrivKey crypto.PrivKey, msg string, + gas uint64, shouldSendOpenTry bool, channel v1types.IBCChannel, +) (string, cosmwasm.StdError) { + // create new ctx with the same storage and a gas limit + // this is to reset the event manager, so we won't get + // events from past calls + gasMeter := &WasmCounterGasMeter{0, sdk.NewGasMeter(gas)} + ctx = sdk.NewContext( + ctx.MultiStore(), + ctx.BlockHeader(), + ctx.IsCheckTx(), + log.NewNopLogger(), + ).WithGasMeter(gasMeter) + + var ibcChannelOpenMsg v1types.IBCChannelOpenMsg + if shouldSendOpenTry { + ibcChannelOpenMsg = v1types.IBCChannelOpenMsg{ + OpenTry: &v1types.IBCOpenTry{ + Channel: channel, + CounterpartyVersion: "", + }, + OpenInit: nil, + } + } else { + ibcChannelOpenMsg = v1types.IBCChannelOpenMsg{ + OpenTry: nil, + OpenInit: &v1types.IBCOpenInit{ + Channel: channel, + }, + } + } + + res, err := keeper.OnOpenChannel(ctx, contractAddr, ibcChannelOpenMsg) + + require.NotZero(t, gasMeter.GetWasmCounter(), err) + + if err != nil { + return "", cosmwasm.StdError{GenericErr: &cosmwasm.GenericErr{Msg: err.Error()}} + } + + return res, cosmwasm.StdError{} +} + +func ibcChannelCloseHelper( + t *testing.T, keeper Keeper, ctx sdk.Context, + contractAddr sdk.AccAddress, creatorPrivKey crypto.PrivKey, msg string, + gas uint64, shouldSendCloseConfirn bool, channel v1types.IBCChannel, +) cosmwasm.StdError { + // create new ctx with the same storage and a gas limit + // this is to reset the event manager, so we won't get + // events from past calls + gasMeter := &WasmCounterGasMeter{0, sdk.NewGasMeter(gas)} + ctx = sdk.NewContext( + ctx.MultiStore(), + ctx.BlockHeader(), + ctx.IsCheckTx(), + log.NewNopLogger(), + ).WithGasMeter(gasMeter) + + var ibcChannelCloseMsg v1types.IBCChannelCloseMsg + if shouldSendCloseConfirn { + ibcChannelCloseMsg = v1types.IBCChannelCloseMsg{ + CloseConfirm: &v1types.IBCCloseConfirm{ + Channel: channel, + }, + CloseInit: nil, + } + } else { + ibcChannelCloseMsg = v1types.IBCChannelCloseMsg{ + CloseConfirm: nil, + CloseInit: &v1types.IBCCloseInit{ + Channel: channel, + }, + } + } + + err := keeper.OnCloseChannel(ctx, contractAddr, ibcChannelCloseMsg) + + require.NotZero(t, gasMeter.GetWasmCounter(), err) + + if err != nil { + return cosmwasm.StdError{GenericErr: &cosmwasm.GenericErr{Msg: err.Error()}} + } + + return cosmwasm.StdError{} +} + +func createIBCEndpoint(port string, channel string) v1types.IBCEndpoint { + return v1types.IBCEndpoint{ + PortID: port, + ChannelID: channel, + } +} + +func createIBCTimeout(timeout uint64) v1types.IBCTimeout { + return v1types.IBCTimeout{ + Block: nil, + Timestamp: timeout, + } +} + +func createIBCPacket(src v1types.IBCEndpoint, dest v1types.IBCEndpoint, sequence uint64, timeout v1types.IBCTimeout, data []byte) v1types.IBCPacket { + return v1types.IBCPacket{ + Data: data, + Src: src, + Dest: dest, + Sequence: sequence, + Timeout: timeout, + } +} + +func ibcPacketReceiveHelper( + t *testing.T, keeper Keeper, ctx sdk.Context, + contractAddr sdk.AccAddress, creatorPrivKey crypto.PrivKey, msg string, + shouldEncryptMsg bool, gas uint64, packet v1types.IBCPacket, +) ([]byte, cosmwasm.StdError) { + var nonce []byte + internalPacket := packet + + if shouldEncryptMsg { + hashStr := hex.EncodeToString(keeper.GetContractHash(ctx, contractAddr)) + + msg := types.SecretMsg{ + CodeHash: []byte(hashStr), + Msg: packet.Data, + } + + dataBz, err := wasmCtx.Encrypt(msg.Serialize()) + require.NoError(t, err) + nonce = dataBz[0:32] + internalPacket.Data = dataBz + } + + // create new ctx with the same storage and a gas limit + // this is to reset the event manager, so we won't get + // events from past calls + gasMeter := &WasmCounterGasMeter{0, sdk.NewGasMeter(gas)} + ctx = sdk.NewContext( + ctx.MultiStore(), + ctx.BlockHeader(), + ctx.IsCheckTx(), + log.NewNopLogger(), + ).WithGasMeter(gasMeter) + + ibcPacketReceiveMsg := v1types.IBCPacketReceiveMsg{ + Packet: internalPacket, + Relayer: "relayer", + } + + res, err := keeper.OnRecvPacket(ctx, contractAddr, ibcPacketReceiveMsg) + + require.NotZero(t, gasMeter.GetWasmCounter(), err) + + if err != nil { + if shouldEncryptMsg { + return nil, extractInnerError(t, err, nonce, true, true) + } + + return nil, cosmwasm.StdError{GenericErr: &cosmwasm.GenericErr{Msg: err.Error()}} + } + + return res, cosmwasm.StdError{} +} + +func ibcPacketAckHelper( + t *testing.T, keeper Keeper, ctx sdk.Context, + contractAddr sdk.AccAddress, creatorPrivKey crypto.PrivKey, msg string, + shouldEncryptMsg bool, gas uint64, originalPacket v1types.IBCPacket, ack []byte, +) cosmwasm.StdError { + var nonce []byte + + if shouldEncryptMsg { + hashStr := hex.EncodeToString(keeper.GetContractHash(ctx, contractAddr)) + + msg := types.SecretMsg{ + CodeHash: []byte(hashStr), + Msg: ack, + } + + ackBz, err := wasmCtx.Encrypt(msg.Serialize()) + require.NoError(t, err) + nonce = ackBz[0:32] + ack = ackBz + } + + // create new ctx with the same storage and a gas limit + // this is to reset the event manager, so we won't get + // events from past calls + gasMeter := &WasmCounterGasMeter{0, sdk.NewGasMeter(gas)} + ctx = sdk.NewContext( + ctx.MultiStore(), + ctx.BlockHeader(), + ctx.IsCheckTx(), + log.NewNopLogger(), + ).WithGasMeter(gasMeter) + + ibcPacketAckMsg := v1types.IBCPacketAckMsg{ + Acknowledgement: v1types.IBCAcknowledgement{ + Data: ack, + }, + OriginalPacket: originalPacket, + Relayer: "relayer", + } + + err := keeper.OnAckPacket(ctx, contractAddr, ibcPacketAckMsg) + + require.NotZero(t, gasMeter.GetWasmCounter(), err) + + if err != nil { + if shouldEncryptMsg { + return extractInnerError(t, err, nonce, true, true) + } + + return cosmwasm.StdError{GenericErr: &cosmwasm.GenericErr{Msg: err.Error()}} + } + + return cosmwasm.StdError{} +} + +func ibcPacketTimeoutHelper( + t *testing.T, keeper Keeper, ctx sdk.Context, + contractAddr sdk.AccAddress, creatorPrivKey crypto.PrivKey, msg string, + shouldEncryptMsg bool, gas uint64, originalPacket v1types.IBCPacket, +) cosmwasm.StdError { + var nonce []byte + + if shouldEncryptMsg { + hashStr := hex.EncodeToString(keeper.GetContractHash(ctx, contractAddr)) + + msg := types.SecretMsg{ + CodeHash: []byte(hashStr), + Msg: originalPacket.Data, + } + + dataBz, err := wasmCtx.Encrypt(msg.Serialize()) + require.NoError(t, err) + nonce = dataBz[0:32] + originalPacket.Data = dataBz + } + + // create new ctx with the same storage and a gas limit + // this is to reset the event manager, so we won't get + // events from past calls + gasMeter := &WasmCounterGasMeter{0, sdk.NewGasMeter(gas)} + ctx = sdk.NewContext( + ctx.MultiStore(), + ctx.BlockHeader(), + ctx.IsCheckTx(), + log.NewNopLogger(), + ).WithGasMeter(gasMeter) + + ibcPacketTimeoutMsg := v1types.IBCPacketTimeoutMsg{ + Packet: originalPacket, + Relayer: "relayer", + } + + err := keeper.OnTimeoutPacket(ctx, contractAddr, ibcPacketTimeoutMsg) + + require.NotZero(t, gasMeter.GetWasmCounter(), err) + + if err != nil { + if shouldEncryptMsg { + return extractInnerError(t, err, nonce, true, true) + } + + return cosmwasm.StdError{GenericErr: &cosmwasm.GenericErr{Msg: err.Error()}} + } + + return cosmwasm.StdError{} +} diff --git a/x/compute/internal/keeper/test_common.go b/x/compute/internal/keeper/test_common.go index c4269232b..bb47de2dd 100644 --- a/x/compute/internal/keeper/test_common.go +++ b/x/compute/internal/keeper/test_common.go @@ -2,6 +2,7 @@ package keeper import ( "encoding/binary" + "encoding/json" "fmt" "io/ioutil" "os" @@ -89,6 +90,7 @@ import ( "github.com/cosmos/cosmos-sdk/x/upgrade" upgradeclient "github.com/cosmos/cosmos-sdk/x/upgrade/client" + v1types "github.com/enigmampc/SecretNetwork/go-cosmwasm/types/v1" wasmtypes "github.com/enigmampc/SecretNetwork/x/compute/internal/types" "github.com/enigmampc/SecretNetwork/x/registration" ) @@ -494,20 +496,13 @@ func handleExecute(ctx sdk.Context, k Keeper, msg *wasmtypes.MsgExecuteContract) return res, nil } -func PrepareInitSignedTx(t *testing.T, keeper Keeper, ctx sdk.Context, creator sdk.AccAddress, privKey crypto.PrivKey, encMsg []byte, codeID uint64, funds sdk.Coins) sdk.Context { - creatorAcc, err := ante.GetSignerAcc(ctx, keeper.accountKeeper, creator) - require.NoError(t, err) - - initMsg := wasmtypes.MsgInstantiateContract{ - Sender: creator, - CodeID: codeID, - Label: "demo contract 1", - InitMsg: encMsg, - InitFunds: funds, +func PrepareIBCOpenAck(t *testing.T, keeper Keeper, ctx sdk.Context, ibcOpenAck v1types.IBCOpenAck, ibcOpenConfirm v1types.IBCOpenConfirm) sdk.Context { + channelConnectMsg := v1types.IBCChannelConnectMsg{ + OpenAck: &ibcOpenAck, + OpenConfirm: &ibcOpenConfirm, } - tx := NewTestTx(&initMsg, creatorAcc, privKey) - txBytes, err := tx.Marshal() + txBytes, err := json.Marshal(channelConnectMsg) require.NoError(t, err) return ctx.WithTxBytes(txBytes) @@ -531,6 +526,25 @@ func PrepareExecSignedTx(t *testing.T, keeper Keeper, ctx sdk.Context, sender sd return ctx.WithTxBytes(txBytes) } +func PrepareInitSignedTx(t *testing.T, keeper Keeper, ctx sdk.Context, creator sdk.AccAddress, privKey crypto.PrivKey, encMsg []byte, codeID uint64, funds sdk.Coins) sdk.Context { + creatorAcc, err := ante.GetSignerAcc(ctx, keeper.accountKeeper, creator) + require.NoError(t, err) + + initMsg := wasmtypes.MsgInstantiateContract{ + Sender: creator, + CodeID: codeID, + Label: "demo contract 1", + InitMsg: encMsg, + InitFunds: funds, + } + tx := NewTestTx(&initMsg, creatorAcc, privKey) + + txBytes, err := tx.Marshal() + require.NoError(t, err) + + return ctx.WithTxBytes(txBytes) +} + func NewTestTx(msg sdk.Msg, creatorAcc authtypes.AccountI, privKey crypto.PrivKey) *sdktx.Tx { return NewTestTxMultiple([]sdk.Msg{msg}, []authtypes.AccountI{creatorAcc}, []crypto.PrivKey{privKey}) } From 215237373764a14bf51e6884310bdd2d9a1ae290 Mon Sep 17 00:00:00 2001 From: Lior Bondarevski Date: Sun, 21 Aug 2022 00:14:15 +0300 Subject: [PATCH 34/93] Fix compilation --- .../src/contract_operations.rs | 48 +++++++++---------- 1 file changed, 23 insertions(+), 25 deletions(-) diff --git a/cosmwasm/enclaves/shared/contract-engine/src/contract_operations.rs b/cosmwasm/enclaves/shared/contract-engine/src/contract_operations.rs index 03839d239..7231f010a 100644 --- a/cosmwasm/enclaves/shared/contract-engine/src/contract_operations.rs +++ b/cosmwasm/enclaves/shared/contract-engine/src/contract_operations.rs @@ -254,26 +254,30 @@ pub fn try_get_decrypted_secret_msg(message: &[u8]) -> Option(_t: T, message: &[u8], function_name: &str) -> ParsedMessage +pub fn parse_ibc_packet( + _t: T, + message: &[u8], + function_name: &str, +) -> Result where T: IbcPacketTrait + Serialize + DeserializeOwned + Debug, { - let mut parsed_encrypted_ibc_packet: T = serde_json::from_slice(&message.as_slice().to_vec()) - .map_err(|err| { - warn!( + let mut parsed_encrypted_ibc_packet: T = + serde_json::from_slice(&message.to_vec()).map_err(|err| { + warn!( "{} msg got an error while trying to deserialize msg input bytes into json {:?}: {}", function_name, - String::from_utf8_lossy(&orig_secret_msg.msg), + String::from_utf8_lossy(&message), err ); - EnclaveError::FailedToDeserialize - })?; + EnclaveError::FailedToDeserialize + })?; let tmp_secret_data = get_secret_msg(parsed_encrypted_ibc_packet.get_packet().as_slice()); - let was_msg_encrypted = false; - let orig_secret_msg = tmp_secret_data; + let mut was_msg_encrypted = false; + let mut orig_secret_msg = tmp_secret_data; - match tmp_secret_data.decrypt() { + match orig_secret_msg.decrypt() { Ok(decrypted_msg) => { // IBC packet was encrypted @@ -297,7 +301,8 @@ where } } - let tmp_secret_ack = get_secret_msg(parsed_encrypted_ibc_packet.get_ack().as_slice()); + let ack = parsed_encrypted_ibc_packet.get_ack(); + let tmp_secret_ack = get_secret_msg(ack.unwrap_or(Binary::from(vec![].as_slice())).as_slice()); match tmp_secret_ack.decrypt() { Ok(ack_data) => { @@ -309,7 +314,7 @@ where Err(_) => {} } - ParsedMessage { + Ok(ParsedMessage { should_validate_sig_info: false, was_msg_encrypted, secret_msg: orig_secret_msg, @@ -321,7 +326,7 @@ where EnclaveError::FailedToSerialize })?, contract_hash_for_validation: None, - } + }) } // Parse the message that was passed to handle (Based on the assumption that it might be a reply or IBC as well) @@ -664,30 +669,23 @@ pub fn parse_message( } HandleType::HANDLE_TYPE_IBC_PACKET_RECEIVE => { // LIORRR TODO: Maybe mark whether the message was encrypted or not. - let orig_secret_msg = get_secret_msg(message); - Ok(parse_ibc_packet( + parse_ibc_packet( IbcPacketReceiveMsg::default(), message, "ibc_packet_receive", - )) + ) } HandleType::HANDLE_TYPE_IBC_PACKET_ACK => { // LIORRR TODO: Maybe mark whether the message was encrypted or not. - let orig_secret_msg = get_secret_msg(message); - Ok(parse_ibc_packet( - IbcPacketAckMsg::default(), - message, - "ibc_packet_receive", - )) + parse_ibc_packet(IbcPacketAckMsg::default(), message, "ibc_packet_receive") } HandleType::HANDLE_TYPE_IBC_PACKET_TIMEOUT => { // LIORRR TODO: Maybe mark whether the message was encrypted or not. - let orig_secret_msg = get_secret_msg(message); - Ok(parse_ibc_packet( + parse_ibc_packet( IbcPacketTimeoutMsg::default(), message, "ibc_packet_timeout", - )) + ) } }; } From a359a8e0bfcd713f22cf537adedb53990294b932 Mon Sep 17 00:00:00 2001 From: Assaf Morami Date: Mon, 22 Aug 2022 10:37:29 +0300 Subject: [PATCH 35/93] Fix debugger for go-tests --- .vscode/launch.json | 1 + .vscode/settings.json | 1 - x/compute/internal/keeper/gov_test.go | 3 +-- x/compute/internal/keeper/test_common.go | 9 +++++++-- 4 files changed, 9 insertions(+), 5 deletions(-) diff --git a/.vscode/launch.json b/.vscode/launch.json index cf316bbde..17ec80ded 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -10,6 +10,7 @@ "request": "launch", "mode": "debug", "program": "${file}", + "cwd": "${workspaceFolder}/x/compute/internal/keeper", "env": { "SGX_MODE": "SW", "RUST_BACKTRACE": "1" }, "args": [ "test", diff --git a/.vscode/settings.json b/.vscode/settings.json index 0b900924e..6e0c34527 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -20,7 +20,6 @@ "go.useLanguageServer": true, "go.lintTool": "golangci-lint", "go.lintOnSave": "workspace", - "go.buildTags": "secretcli", "gopls": { "formatting.gofumpt": true }, diff --git a/x/compute/internal/keeper/gov_test.go b/x/compute/internal/keeper/gov_test.go index a12d35272..58605d73c 100644 --- a/x/compute/internal/keeper/gov_test.go +++ b/x/compute/internal/keeper/gov_test.go @@ -104,8 +104,7 @@ func TestGovQueryProposals(t *testing.T) { // an active proposal and checking that there is 1 active func TestGovVote(t *testing.T) { encodingConfig := MakeEncodingConfig() - var transferPortSource wasmTypes.ICS20TransferPortSource - transferPortSource = MockIBCTransferKeeper{GetPortFn: func(ctx sdk.Context) string { + transferPortSource := MockIBCTransferKeeper{GetPortFn: func(ctx sdk.Context) string { return "myTransferPort" }} encoders := DefaultEncoders(transferPortSource, encodingConfig.Marshaler) diff --git a/x/compute/internal/keeper/test_common.go b/x/compute/internal/keeper/test_common.go index cb68b3bc9..d5812e124 100644 --- a/x/compute/internal/keeper/test_common.go +++ b/x/compute/internal/keeper/test_common.go @@ -405,6 +405,11 @@ func CreateTestInput(t *testing.T, isCheckTx bool, supportedFeatures string, enc // stakingtypes.RegisterMsgServer(serviceRouter, stakingMsgServer) // distrtypes.RegisterMsgServer(serviceRouter, distrMsgServer) + queryRouter := baseapp.NewGRPCQueryRouter() + queryRouter.SetInterfaceRegistry(encodingConfig.InterfaceRegistry) + msgRouter := baseapp.NewMsgServiceRouter() + msgRouter.SetInterfaceRegistry(encodingConfig.InterfaceRegistry) + keeper := NewKeeper( encodingConfig.Marshaler, *encodingConfig.Amino, @@ -420,8 +425,8 @@ func CreateTestInput(t *testing.T, isCheckTx bool, supportedFeatures string, enc ibcKeeper.PortKeeper, MockIBCTransferKeeper{}, ibcKeeper.ChannelKeeper, - baseapp.NewMsgServiceRouter(), - baseapp.NewGRPCQueryRouter(), + msgRouter, + queryRouter, tempDir, wasmConfig, supportedFeatures, From 60616404603ff4174680802222f78018baa55621 Mon Sep 17 00:00:00 2001 From: Assaf Morami Date: Mon, 22 Aug 2022 12:54:08 +0300 Subject: [PATCH 36/93] Add integration tests, enable stargate feature --- .vscode/settings.json | 10 +- app/app.go | 2 +- go-cosmwasm/cmd/main.go | 2 +- integration-tests/Makefile | 2 + integration-tests/contract-v0.10/.gitignore | 13 + integration-tests/contract-v0.10/Cargo.lock | 295 + integration-tests/contract-v0.10/Cargo.toml | 43 + integration-tests/contract-v0.10/Makefile | 26 + integration-tests/contract-v0.10/README.md | 1 + integration-tests/contract-v0.10/build.rs | 3 + .../contract-v0.10/src/contract.rs | 1829 ++ integration-tests/contract-v0.10/src/lib.rs | 38 + integration-tests/contract-v1/.gitignore | 13 + integration-tests/contract-v1/Cargo.lock | 614 + integration-tests/contract-v1/Cargo.toml | 39 + integration-tests/contract-v1/Makefile | 8 + integration-tests/contract-v1/rust-toolchain | 1 + integration-tests/contract-v1/src/contract.rs | 37 + integration-tests/contract-v1/src/lib.rs | 2 + integration-tests/contract-v1/src/msg.rs | 30 + integration-tests/jest.config.js | 13 + integration-tests/package.json | 19 + integration-tests/test.ts | 248 + integration-tests/tsconfig.json | 6 + integration-tests/yarn.lock | 2763 ++ package-lock.json | 23858 ---------------- package.json | 10 - x/compute/internal/keeper/keeper_test.go | 126 +- 28 files changed, 6114 insertions(+), 23937 deletions(-) create mode 100644 integration-tests/Makefile create mode 100644 integration-tests/contract-v0.10/.gitignore create mode 100644 integration-tests/contract-v0.10/Cargo.lock create mode 100644 integration-tests/contract-v0.10/Cargo.toml create mode 100644 integration-tests/contract-v0.10/Makefile create mode 100644 integration-tests/contract-v0.10/README.md create mode 100644 integration-tests/contract-v0.10/build.rs create mode 100644 integration-tests/contract-v0.10/src/contract.rs create mode 100644 integration-tests/contract-v0.10/src/lib.rs create mode 100644 integration-tests/contract-v1/.gitignore create mode 100644 integration-tests/contract-v1/Cargo.lock create mode 100644 integration-tests/contract-v1/Cargo.toml create mode 100644 integration-tests/contract-v1/Makefile create mode 100644 integration-tests/contract-v1/rust-toolchain create mode 100644 integration-tests/contract-v1/src/contract.rs create mode 100644 integration-tests/contract-v1/src/lib.rs create mode 100644 integration-tests/contract-v1/src/msg.rs create mode 100644 integration-tests/jest.config.js create mode 100644 integration-tests/package.json create mode 100644 integration-tests/test.ts create mode 100644 integration-tests/tsconfig.json create mode 100644 integration-tests/yarn.lock delete mode 100644 package-lock.json delete mode 100644 package.json diff --git a/.vscode/settings.json b/.vscode/settings.json index 6e0c34527..576d88a73 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,9 +1,11 @@ { "rust-analyzer.linkedProjects": [ - "./cosmwasm/Cargo.toml", - "./cosmwasm/enclaves/Cargo.toml", - "./x/compute/internal/keeper/testdata/v1-sanity-contract/Cargo.toml", - "./x/compute/internal/keeper/testdata/test-contract/Cargo.toml" + "cosmwasm/Cargo.toml", + "cosmwasm/enclaves/Cargo.toml", + "x/compute/internal/keeper/testdata/v1-sanity-contract/Cargo.toml", + "x/compute/internal/keeper/testdata/test-contract/Cargo.toml", + "integration-tests/contract-v1/Cargo.toml", + "go-cosmwasm/Cargo.toml" ], "rust-analyzer.diagnostics.experimental.enable": true, "rust-analyzer.rustfmt.rangeFormatting.enable": true, diff --git a/app/app.go b/app/app.go index 02afe6789..65eefd6f6 100644 --- a/app/app.go +++ b/app/app.go @@ -418,7 +418,7 @@ func NewSecretNetworkApp( // The last arguments can contain custom message handlers, and custom query handlers, // if we want to allow any custom callbacks - supportedFeatures := "staking" + supportedFeatures := "staking,stargate" app.computeKeeper = compute.NewKeeper( appCodec, diff --git a/go-cosmwasm/cmd/main.go b/go-cosmwasm/cmd/main.go index 149d3ccf4..d1f06fa75 100644 --- a/go-cosmwasm/cmd/main.go +++ b/go-cosmwasm/cmd/main.go @@ -19,7 +19,7 @@ func main() { fmt.Println("Loaded!") os.MkdirAll("tmp", 0o755) - wasmer, err := wasm.NewWasmer("tmp", "staking", 0, 15) + wasmer, err := wasm.NewWasmer("tmp", "staking,stargate", 0, 15) if err != nil { panic(err) } diff --git a/integration-tests/Makefile b/integration-tests/Makefile new file mode 100644 index 000000000..e4944e836 --- /dev/null +++ b/integration-tests/Makefile @@ -0,0 +1,2 @@ +all: + $(MAKE) -C contract-v1 \ No newline at end of file diff --git a/integration-tests/contract-v0.10/.gitignore b/integration-tests/contract-v0.10/.gitignore new file mode 100644 index 000000000..0e24e33d5 --- /dev/null +++ b/integration-tests/contract-v0.10/.gitignore @@ -0,0 +1,13 @@ +# Build results +/target +*.wasm + +# Text file backups +**/*.rs.bk + +# macOS +.DS_Store + +# IDEs +*.iml +.idea diff --git a/integration-tests/contract-v0.10/Cargo.lock b/integration-tests/contract-v0.10/Cargo.lock new file mode 100644 index 000000000..7400d17f0 --- /dev/null +++ b/integration-tests/contract-v0.10/Cargo.lock @@ -0,0 +1,295 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "addr2line" +version = "0.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9ecd88a8c8378ca913a680cd98f0f13ac67383d35993f86c90a70e3f137816b" +dependencies = [ + "gimli", +] + +[[package]] +name = "adler" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" + +[[package]] +name = "backtrace" +version = "0.3.66" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cab84319d616cfb654d03394f38ab7e6f0919e181b1b57e1fd15e7fb4077d9a7" +dependencies = [ + "addr2line", + "cc", + "cfg-if", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", +] + +[[package]] +name = "base64" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b41b7ea54a0c9d92199de89e20e58d49f02f8e699814ef3fdf266f6f748d15c7" + +[[package]] +name = "cc" +version = "1.0.73" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2fff2a6927b3bb87f9595d67196a70493f627687a71d87a0d692242c33f58c11" + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "doc-comment" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fea41bba32d969b513997752735605054bc0dfa92b4c56bf1189f2e174be7a10" + +[[package]] +name = "gimli" +version = "0.26.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78cc372d058dcf6d5ecd98510e7fbc9e5aec4d21de70f65fea8fecebcd881bd4" + +[[package]] +name = "itoa" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "112c678d4050afce233f4f2852bb2eb519230b3cf12f33585275537d7e41578d" + +[[package]] +name = "libc" +version = "0.2.126" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "349d5a591cd28b49e1d1037471617a32ddcda5731b99419008085f72d5a53836" + +[[package]] +name = "memchr" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" + +[[package]] +name = "miniz_oxide" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f5c75688da582b8ffc1f1799e9db273f32133c49e048f614d22ec3256773ccc" +dependencies = [ + "adler", +] + +[[package]] +name = "object" +version = "0.29.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "21158b2c33aa6d4561f1c0a6ea283ca92bc54802a93b263e910746d679a7eb53" +dependencies = [ + "memchr", +] + +[[package]] +name = "proc-macro2" +version = "1.0.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd96a1e8ed2596c337f8eae5f24924ec83f5ad5ab21ea8e455d3566c69fbcaf7" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3bcdf212e9776fbcb2d23ab029360416bb1706b1aea2d1a5ba002727cbcab804" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rustc-demangle" +version = "0.1.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ef03e0a2b150c7a90d01faf6254c9c48a41e95fb2a8c2ac1c6f0d2b9aefc342" + +[[package]] +name = "ryu" +version = "1.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3f6f92acf49d1b98f7a81226834412ada05458b7364277387724a237f062695" + +[[package]] +name = "schemars" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be77ed66abed6954aabf6a3e31a84706bedbf93750d267e92ef4a6d90bbd6a61" +dependencies = [ + "schemars_derive", + "serde", + "serde_json", +] + +[[package]] +name = "schemars_derive" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11af7a475c9ee266cfaa9e303a47c830ebe072bf3101ab907a7b7b9d816fa01d" +dependencies = [ + "proc-macro2", + "quote", + "serde_derive_internals", + "syn", +] + +[[package]] +name = "secp256k1" +version = "0.20.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97d03ceae636d0fed5bae6a7f4f664354c5f4fcedf6eef053fef17e49f837d0a" +dependencies = [ + "secp256k1-sys", +] + +[[package]] +name = "secp256k1-sys" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "957da2573cde917463ece3570eab4a0b3f19de6f1646cde62e6fd3868f566036" +dependencies = [ + "cc", +] + +[[package]] +name = "secret-cosmwasm-std" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f5d4b8fed972d924458d9c3c0e6c9fbf6c4c5e30655571e3d2b78be056d316e9" +dependencies = [ + "base64", + "schemars", + "serde", + "serde-json-wasm", + "snafu", +] + +[[package]] +name = "secret-cosmwasm-storage" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffee3243bb13c02ddcdc15458526288d36ec23422ec43681ac5d48e7325d8327" +dependencies = [ + "secret-cosmwasm-std", + "serde", +] + +[[package]] +name = "serde" +version = "1.0.138" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1578c6245786b9d168c5447eeacfb96856573ca56c9d68fdcf394be134882a47" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde-json-wasm" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "120bad73306616e91acd7ceed522ba96032a51cffeef3cc813de7f367df71e37" +dependencies = [ + "serde", +] + +[[package]] +name = "serde_derive" +version = "1.0.138" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "023e9b1467aef8a10fb88f25611870ada9800ef7e22afce356bb0d2387b6f27c" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_derive_internals" +version = "0.25.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1dbab34ca63057a1f15280bdf3c39f2b1eb1b54c17e98360e511637aef7418c6" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_json" +version = "1.0.82" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "82c2c1fdcd807d1098552c5b9a36e425e42e9fbd7c6a37a8425f390f781f7fa7" +dependencies = [ + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "snafu" +version = "0.6.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eab12d3c261b2308b0d80c26fffb58d17eba81a4be97890101f416b478c79ca7" +dependencies = [ + "backtrace", + "doc-comment", + "snafu-derive", +] + +[[package]] +name = "snafu-derive" +version = "0.6.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1508efa03c362e23817f96cde18abed596a25219a8b2c66e8db33c03543d315b" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "syn" +version = "1.0.98" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c50aef8a904de4c23c788f104b7dddc7d6f79c647c7c8ce4cc8f73eb0ca773dd" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "test-contract" +version = "0.0.1" +dependencies = [ + "schemars", + "secp256k1", + "secret-cosmwasm-std", + "secret-cosmwasm-storage", + "serde", + "serde-json-wasm", +] + +[[package]] +name = "unicode-ident" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5bd2fe26506023ed7b5e1e315add59d6f584c621d037f9368fea9cfb988f368c" diff --git a/integration-tests/contract-v0.10/Cargo.toml b/integration-tests/contract-v0.10/Cargo.toml new file mode 100644 index 000000000..36251d8b3 --- /dev/null +++ b/integration-tests/contract-v0.10/Cargo.toml @@ -0,0 +1,43 @@ +[package] +name = "test-contract" +version = "0.0.1" +authors = ["Enigma "] +edition = "2018" +description = "A Test contract intended to use in system tests for the Secret Netowrk" +license = "MIT" +exclude = [ + # Those files are cosmwasm-opt artifacts. You might want to commit them for convenience but they should not be part of the source code publication. + "contract.wasm", + "hash.txt", +] + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html +[lib] +crate-type = ["cdylib", "rlib"] + +[profile.release] +opt-level = 3 +debug = false +rpath = false +lto = true +debug-assertions = false +codegen-units = 1 +panic = 'abort' +incremental = false +overflow-checks = true + +[features] +default = ["backtraces"] +backtraces = ["cosmwasm-std/backtraces"] +with_floats = [] + +[dependencies] +cosmwasm-std = { package = "secret-cosmwasm-std", version = "0.10.1" } +cosmwasm-storage = { package = "secret-cosmwasm-storage", version = "0.10.0" } +schemars = "0.7" +serde = { version = "1.0.114", default-features = false, features = [ + "derive", + "alloc" +] } +serde-json-wasm = "0.2.1" +secp256k1 = "0.20.3" diff --git a/integration-tests/contract-v0.10/Makefile b/integration-tests/contract-v0.10/Makefile new file mode 100644 index 000000000..cbabda449 --- /dev/null +++ b/integration-tests/contract-v0.10/Makefile @@ -0,0 +1,26 @@ +all: src/contract.rs src/lib.rs Cargo.toml Cargo.lock + rustup target add wasm32-unknown-unknown + + RUSTFLAGS='-C link-arg=-s' cargo build --release --target wasm32-unknown-unknown + cp ./target/wasm32-unknown-unknown/release/test_contract.wasm ./contract.wasm + + # Compile with floats + RUSTFLAGS='-C link-arg=-s' cargo build --release --target wasm32-unknown-unknown --features with_floats + cp ./target/wasm32-unknown-unknown/release/test_contract.wasm ./contract_with_floats.wasm + + # Create a wasm with more than 192 memory pages (fails in init, handle & query, this is our limit) + # https://github.com/enigmampc/SecretNetwork/blob/9eef8591b2c04c586ceee12f424b92062598123e/cosmwasm/packages/wasmi-runtime/src/wasm/memory.rs#L39 + wasm2wat ./contract.wasm | perl -pe 's/\(memory \(;0;\) 17\)/(memory (;0;) 193)/' > /tmp/too-high-initial-memory.wat + wat2wasm /tmp/too-high-initial-memory.wat -o ./too-high-initial-memory.wasm + + # Create a wasm with more than 512 memory pages (fails in store, this is cosmwasm's limit) + # https://github.com/enigmampc/SecretNetwork/blob/9eef8591b2c04c586ceee12f424b92062598123e/cosmwasm/packages/sgx-vm/src/compatability.rs#L36 + wasm2wat ./contract.wasm | perl -pe 's/\(memory \(;0;\) 17\)/(memory (;0;) 513)/' > /tmp/static-too-high-initial-memory.wat + wat2wasm /tmp/static-too-high-initial-memory.wat -o ./static-too-high-initial-memory.wasm + +setup: + apt-get install wabt + +clean: + cargo clean + -rm -f ./contract.wasm \ No newline at end of file diff --git a/integration-tests/contract-v0.10/README.md b/integration-tests/contract-v0.10/README.md new file mode 100644 index 000000000..6f604781c --- /dev/null +++ b/integration-tests/contract-v0.10/README.md @@ -0,0 +1 @@ +Just `make`. :rainbow: diff --git a/integration-tests/contract-v0.10/build.rs b/integration-tests/contract-v0.10/build.rs new file mode 100644 index 000000000..88fb06f33 --- /dev/null +++ b/integration-tests/contract-v0.10/build.rs @@ -0,0 +1,3 @@ +fn main() { + println!("cargo:rerun-if-changed=./src/contract.rs"); +} diff --git a/integration-tests/contract-v0.10/src/contract.rs b/integration-tests/contract-v0.10/src/contract.rs new file mode 100644 index 000000000..3419e4d16 --- /dev/null +++ b/integration-tests/contract-v0.10/src/contract.rs @@ -0,0 +1,1829 @@ +use cosmwasm_storage::{PrefixedStorage, ReadonlySingleton, Singleton}; + +use cosmwasm_std::{ + log, plaintext_log, to_binary, Api, BankMsg, Binary, Coin, CosmosMsg, Empty, Env, Extern, + HandleResponse, HandleResult, HumanAddr, InitResponse, InitResult, Querier, QueryRequest, + QueryResult, ReadonlyStorage, StdError, StdResult, Storage, Uint128, WasmMsg, WasmQuery, +}; +use secp256k1::Secp256k1; + +/////////////////////////////// Messages /////////////////////////////// + +use core::time; +use mem::MaybeUninit; +use schemars::JsonSchema; +use serde::{Deserialize, Serialize}; +use std::{mem, thread}; + +//// consts + +const REALLY_LONG: &[u8] = b"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"; + +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] +#[serde(rename_all = "snake_case")] +pub enum InitMsg { + WasmMsg { + ty: String, + }, + Nop {}, + Callback { + contract_addr: HumanAddr, + code_hash: String, + }, + CallbackContractError { + contract_addr: HumanAddr, + code_hash: String, + }, + ContractError { + error_type: String, + }, + NoLogs {}, + CallbackToInit { + code_id: u64, + code_hash: String, + }, + CallbackBadParams { + contract_addr: HumanAddr, + code_hash: String, + }, + Panic {}, + SendExternalQueryDepthCounter { + to: HumanAddr, + depth: u8, + code_hash: String, + }, + SendExternalQueryRecursionLimit { + to: HumanAddr, + depth: u8, + code_hash: String, + }, + CallToInit { + code_id: u64, + code_hash: String, + label: String, + msg: String, + }, + CallToExec { + addr: HumanAddr, + code_hash: String, + msg: String, + }, + CallToQuery { + addr: HumanAddr, + code_hash: String, + msg: String, + }, + InitFromV1 { + counter: u64, + }, + Counter { + counter: u64, + }, + AddAttributes {}, + AddAttributesWithSubmessage {}, + AddPlaintextAttributes {}, + AddPlaintextAttributesWithSubmessage {}, + AddMixedEventsAndAttributesFromV1 { + addr: HumanAddr, + code_hash: String, + }, + BankMsgSend { + amount: Vec, + to: HumanAddr, + from: Option, + }, + CosmosMsgCustom {}, +} + +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] +#[serde(rename_all = "snake_case")] +pub enum HandleMsg { + WasmMsg { + ty: String, + }, + A { + contract_addr: HumanAddr, + code_hash: String, + x: u8, + y: u8, + }, + B { + contract_addr: HumanAddr, + code_hash: String, + x: u8, + y: u8, + }, + C { + x: u8, + y: u8, + }, + UnicodeData {}, + EmptyLogKeyValue {}, + EmptyData {}, + NoData {}, + ContractError { + error_type: String, + }, + NoLogs {}, + CallbackToInit { + code_id: u64, + code_hash: String, + }, + CallbackContractError { + contract_addr: HumanAddr, + code_hash: String, + }, + CallbackBadParams { + contract_addr: HumanAddr, + code_hash: String, + }, + SetState { + key: String, + value: String, + }, + GetState { + key: String, + }, + RemoveState { + key: String, + }, + TestCanonicalizeAddressErrors {}, + Panic {}, + AllocateOnHeap { + bytes: u32, + }, + PassNullPointerToImportsShouldThrow { + pass_type: String, + }, + SendExternalQuery { + to: HumanAddr, + code_hash: String, + }, + SendExternalQueryPanic { + to: HumanAddr, + code_hash: String, + }, + SendExternalQueryError { + to: HumanAddr, + code_hash: String, + }, + SendExternalQueryBadAbi { + to: HumanAddr, + code_hash: String, + }, + SendExternalQueryBadAbiReceiver { + to: HumanAddr, + code_hash: String, + }, + LogMsgSender {}, + CallbackToLogMsgSender { + to: HumanAddr, + code_hash: String, + }, + DepositToContract {}, + SendFunds { + amount: u32, + denom: String, + to: HumanAddr, + from: HumanAddr, + }, + BankMsgSend { + amount: Vec, + to: HumanAddr, + from: Option, + }, + SendFundsToInitCallback { + amount: u32, + denom: String, + code_id: u64, + code_hash: String, + }, + SendFundsToExecCallback { + amount: u32, + denom: String, + to: HumanAddr, + code_hash: String, + }, + Sleep { + ms: u64, + }, + SendExternalQueryDepthCounter { + to: HumanAddr, + code_hash: String, + depth: u8, + }, + SendExternalQueryRecursionLimit { + to: HumanAddr, + code_hash: String, + depth: u8, + }, + WithFloats { + x: u8, + y: u8, + }, + CallToInit { + code_id: u64, + code_hash: String, + label: String, + msg: String, + }, + CallToExec { + addr: HumanAddr, + code_hash: String, + msg: String, + }, + CallToQuery { + addr: HumanAddr, + code_hash: String, + msg: String, + }, + StoreReallyLongKey {}, + StoreReallyShortKey {}, + StoreReallyLongValue {}, + Secp256k1Verify { + pubkey: Binary, + sig: Binary, + msg_hash: Binary, + iterations: u32, + }, + Secp256k1VerifyFromCrate { + pubkey: Binary, + sig: Binary, + msg_hash: Binary, + iterations: u32, + }, + Ed25519Verify { + pubkey: Binary, + sig: Binary, + msg: Binary, + iterations: u32, + }, + Ed25519BatchVerify { + pubkeys: Vec, + sigs: Vec, + msgs: Vec, + iterations: u32, + }, + Secp256k1RecoverPubkey { + msg_hash: Binary, + sig: Binary, + recovery_param: u8, + iterations: u32, + }, + Secp256k1Sign { + msg: Binary, + privkey: Binary, + iterations: u32, + }, + Ed25519Sign { + msg: Binary, + privkey: Binary, + iterations: u32, + }, + ExecuteFromV1 { + counter: u64, + }, + IncrementFromV1 { + addition: u64, + }, + AddAttributes {}, + AddAttributesWithSubmessage {}, + AddMoreAttributes {}, + AddPlaintextAttributes {}, + AddPlaintextAttributesWithSubmessage {}, + AddMorePlaintextAttributes {}, + AddMixedEventsAndAttributesFromV1 { + addr: HumanAddr, + code_hash: String, + }, + CosmosMsgCustom {}, + InitNewContract {}, +} + +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] +#[serde(rename_all = "snake_case")] +pub enum QueryMsg { + ContractError { + error_type: String, + }, + Panic {}, + ReceiveExternalQuery { + num: u8, + }, + SendExternalQueryInfiniteLoop { + to: HumanAddr, + code_hash: String, + }, + WriteToStorage {}, + RemoveFromStorage {}, + SendExternalQueryDepthCounter { + to: HumanAddr, + depth: u8, + code_hash: String, + }, + SendExternalQueryRecursionLimit { + to: HumanAddr, + depth: u8, + code_hash: String, + }, + CallToQuery { + addr: HumanAddr, + code_hash: String, + msg: String, + }, + GetCountFromV1 {}, + Get {}, + GetContractVersion {}, +} + +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] +#[serde(rename_all = "snake_case")] +pub enum QueryRes { + Get { count: u64 }, +} + +/////////////////////////////// Init /////////////////////////////// + +pub fn init( + deps: &mut Extern, + env: Env, + msg: InitMsg, +) -> InitResult { + match msg { + InitMsg::WasmMsg { ty } => { + if ty == "success" { + return Ok(InitResponse::default()); + } else if ty == "err" { + return Err(StdError::generic_err("custom error")); + } else if ty == "panic" { + panic!() + } + + return Err(StdError::generic_err("custom error")); + } + InitMsg::Nop {} => Ok(InitResponse { + messages: vec![], + log: vec![log("init", "🌈")], + }), + InitMsg::Callback { + contract_addr, + code_hash, + } => Ok(init_with_callback(deps, env, contract_addr, code_hash)), + InitMsg::ContractError { error_type } => Err(map_string_to_error(error_type)), + InitMsg::NoLogs {} => Ok(InitResponse::default()), + InitMsg::CallbackToInit { code_id, code_hash } => { + Ok(init_callback_to_init(deps, env, code_id, code_hash)) + } + InitMsg::CallbackContractError { + contract_addr, + code_hash, + } => Ok(init_with_callback_contract_error(contract_addr, code_hash)), + InitMsg::CallbackBadParams { + contract_addr, + code_hash, + } => Ok(init_callback_bad_params(contract_addr, code_hash)), + InitMsg::Panic {} => panic!("panic in init"), + InitMsg::SendExternalQueryDepthCounter { + to, + depth, + code_hash, + } => Ok(InitResponse { + messages: vec![], + log: vec![log( + format!( + "{}", + send_external_query_depth_counter(deps, to, depth, code_hash) + ), + "", + )], + }), + InitMsg::SendExternalQueryRecursionLimit { + to, + depth, + code_hash, + } => Ok(InitResponse { + messages: vec![], + log: vec![log( + "message", + send_external_query_recursion_limit(deps, to, depth, code_hash)?, + )], + }), + InitMsg::CallToInit { + code_id, + code_hash, + label, + msg, + } => Ok(InitResponse { + messages: vec![CosmosMsg::Wasm(WasmMsg::Instantiate { + code_id, + callback_code_hash: code_hash, + msg: Binary(msg.as_bytes().into()), + send: vec![], + label: label, + })], + log: vec![log("a", "a")], + }), + InitMsg::CallToExec { + addr, + code_hash, + msg, + } => Ok(InitResponse { + messages: vec![CosmosMsg::Wasm(WasmMsg::Execute { + contract_addr: addr, + callback_code_hash: code_hash, + msg: Binary(msg.as_bytes().into()), + send: vec![], + })], + log: vec![log("b", "b")], + }), + InitMsg::CallToQuery { + addr, + code_hash, + msg, + } => { + let answer: u32 = deps + .querier + .query(&QueryRequest::Wasm(WasmQuery::Smart { + contract_addr: addr, + callback_code_hash: code_hash, + msg: Binary::from(msg.as_bytes().to_vec()), + })) + .map_err(|err| { + StdError::generic_err(format!("Got an error from query: {:?}", err)) + })?; + + Ok(InitResponse { + messages: vec![], + log: vec![log("c", format!("{}", answer))], + }) + } + InitMsg::InitFromV1 { counter } => { + count(&mut deps.storage).save(&counter)?; + + Ok(InitResponse { + messages: vec![], + log: vec![], + }) + } + InitMsg::Counter { counter } => { + count(&mut deps.storage).save(&counter)?; + + Ok(InitResponse { + messages: vec![], + log: vec![], + }) + } + InitMsg::AddAttributes {} => Ok(InitResponse { + messages: vec![], + log: vec![log("attr1", "🦄"), log("attr2", "🌈")], + }), + InitMsg::AddAttributesWithSubmessage {} => Ok(InitResponse { + messages: vec![CosmosMsg::Wasm(WasmMsg::Execute { + contract_addr: env.contract.address, + callback_code_hash: env.contract_code_hash, + msg: Binary::from(r#"{"add_more_attributes":{}}"#.as_bytes().to_vec()), + send: vec![], + })], + log: vec![log("attr1", "🦄"), log("attr2", "🌈")], + }), + InitMsg::AddPlaintextAttributes {} => Ok(InitResponse { + messages: vec![], + log: vec![plaintext_log("attr1", "🦄"), plaintext_log("attr2", "🌈")], + }), + InitMsg::AddPlaintextAttributesWithSubmessage {} => Ok(InitResponse { + messages: vec![CosmosMsg::Wasm(WasmMsg::Execute { + contract_addr: env.contract.address, + callback_code_hash: env.contract_code_hash, + msg: Binary::from(r#"{"add_more_plaintext_attributes":{}}"#.as_bytes().to_vec()), + send: vec![], + })], + log: vec![plaintext_log("attr1", "🦄"), plaintext_log("attr2", "🌈")], + }), + InitMsg::AddMixedEventsAndAttributesFromV1 { addr, code_hash } => Ok(InitResponse { + messages: vec![CosmosMsg::Wasm(WasmMsg::Execute { + contract_addr: addr, + callback_code_hash: code_hash, + msg: Binary::from( + r#"{"add_more_mixed_attributes_and_events":{}}"#.as_bytes().to_vec(), + ), + send: vec![], + })], + log: vec![plaintext_log("attr1", "🦄"), plaintext_log("attr2", "🌈")], + }), + InitMsg::BankMsgSend { + to, + amount: coins, + from, + } => Ok(InitResponse { + messages: vec![CosmosMsg::Bank(BankMsg::Send { + from_address: from.unwrap_or(env.contract.address), + to_address: to, + amount: coins, + })], + log: vec![], + }), + InitMsg::CosmosMsgCustom {} => Ok(InitResponse { + messages: vec![CosmosMsg::Custom(Empty {})], + log: vec![], + }), + } +} + +pub const COUNT_KEY: &[u8] = b"count"; + +pub fn count(storage: &mut S) -> Singleton { + Singleton::new(storage, COUNT_KEY) +} + +pub fn count_read(storage: &S) -> ReadonlySingleton { + ReadonlySingleton::new(storage, COUNT_KEY) +} + +fn map_string_to_error(error_type: String) -> StdError { + let as_str: &str = &error_type[..]; + match as_str { + "generic_err" => StdError::generic_err("la la 🤯"), + "invalid_base64" => StdError::invalid_base64("ra ra 🤯"), + "invalid_utf8" => StdError::invalid_utf8("ka ka 🤯"), + "not_found" => StdError::not_found("za za 🤯"), + "parse_err" => StdError::parse_err("na na 🤯", "pa pa 🤯"), + "serialize_err" => StdError::serialize_err("ba ba 🤯", "ga ga 🤯"), + "unauthorized" => StdError::unauthorized(), + "underflow" => StdError::underflow("minuend 🤯", "subtrahend 🤯"), + _ => StdError::generic_err("catch-all 🤯"), + } +} + +fn init_with_callback_contract_error(contract_addr: HumanAddr, code_hash: String) -> InitResponse { + InitResponse { + messages: vec![CosmosMsg::Wasm(WasmMsg::Execute { + contract_addr: contract_addr.clone(), + callback_code_hash: code_hash, + msg: Binary::from(r#"{"contract_error":{"error_type":"generic_err"}}"#.as_bytes()), + send: vec![], + })], + log: vec![log("init with a callback with contract error", "🤷‍♀️")], + } +} + +fn init_callback_bad_params(contract_addr: HumanAddr, code_hash: String) -> InitResponse { + InitResponse { + messages: vec![CosmosMsg::Wasm(WasmMsg::Execute { + contract_addr: contract_addr.clone(), + callback_code_hash: code_hash, + msg: Binary::from(r#"{"c":{"x":"banana","y":3}}"#.as_bytes().to_vec()), + send: vec![], + })], + log: vec![], + } +} + +fn init_with_callback( + _deps: &mut Extern, + _env: Env, + contract_addr: HumanAddr, + code_hash: String, +) -> InitResponse { + InitResponse { + messages: vec![CosmosMsg::Wasm(WasmMsg::Execute { + callback_code_hash: code_hash, + contract_addr: contract_addr.clone(), + msg: Binary::from("{\"c\":{\"x\":0,\"y\":13}}".as_bytes().to_vec()), + send: vec![], + })], + log: vec![log("init with a callback", "🦄")], + } +} + +pub fn init_callback_to_init( + _deps: &mut Extern, + _env: Env, + code_id: u64, + code_hash: String, +) -> InitResponse { + InitResponse { + messages: vec![CosmosMsg::Wasm(WasmMsg::Instantiate { + code_id, + msg: Binary::from("{\"nop\":{}}".as_bytes().to_vec()), + callback_code_hash: code_hash, + send: vec![], + label: String::from("fi"), + })], + log: vec![log("instantiating a new contract from init!", "🐙")], + } +} + +/////////////////////////////// Handle /////////////////////////////// + +pub fn handle( + deps: &mut Extern, + env: Env, + msg: HandleMsg, +) -> HandleResult { + match msg { + HandleMsg::WasmMsg { ty } => { + if ty == "success" { + return Ok(HandleResponse::default()); + } else if ty == "err" { + return Err(StdError::generic_err("custom error")); + } else if ty == "panic" { + panic!() + } + + return Err(StdError::generic_err("custom error")); + } + HandleMsg::A { + contract_addr, + code_hash, + x, + y, + } => Ok(a(deps, env, contract_addr, code_hash, x, y)), + HandleMsg::B { + contract_addr, + code_hash, + x, + y, + } => Ok(b(deps, env, contract_addr, code_hash, x, y)), + HandleMsg::C { x, y } => Ok(c(deps, env, x, y)), + HandleMsg::UnicodeData {} => Ok(unicode_data(deps, env)), + HandleMsg::EmptyLogKeyValue {} => Ok(empty_log_key_value(deps, env)), + HandleMsg::EmptyData {} => Ok(empty_data(deps, env)), + HandleMsg::NoData {} => Ok(no_data(deps, env)), + HandleMsg::ContractError { error_type } => Err(map_string_to_error(error_type)), + HandleMsg::NoLogs {} => Ok(HandleResponse::default()), + HandleMsg::CallbackToInit { code_id, code_hash } => { + Ok(exec_callback_to_init(deps, env, code_id, code_hash)) + } + HandleMsg::CallbackBadParams { + contract_addr, + code_hash, + } => Ok(exec_callback_bad_params(contract_addr, code_hash)), + HandleMsg::CallbackContractError { + contract_addr, + code_hash, + } => Ok(exec_with_callback_contract_error(contract_addr, code_hash)), + HandleMsg::SetState { key, value } => Ok(set_state(deps, key, value)), + HandleMsg::GetState { key } => Ok(get_state(deps, key)), + HandleMsg::RemoveState { key } => Ok(remove_state(deps, key)), + HandleMsg::TestCanonicalizeAddressErrors {} => test_canonicalize_address_errors(deps), + HandleMsg::Panic {} => panic!("panic in exec"), + HandleMsg::AllocateOnHeap { bytes } => Ok(allocate_on_heap(bytes as usize)), + HandleMsg::PassNullPointerToImportsShouldThrow { pass_type } => { + Ok(pass_null_pointer_to_imports_should_throw(deps, pass_type)) + } + HandleMsg::SendExternalQuery { to, code_hash } => Ok(HandleResponse { + messages: vec![], + log: vec![], + data: Some(vec![send_external_query(deps, to, code_hash)].into()), + }), + HandleMsg::SendExternalQueryDepthCounter { + to, + code_hash, + depth, + } => Ok(HandleResponse { + messages: vec![], + log: vec![], + data: Some( + vec![send_external_query_depth_counter( + deps, to, depth, code_hash, + )] + .into(), + ), + }), + HandleMsg::SendExternalQueryRecursionLimit { + to, + code_hash, + depth, + } => Ok(HandleResponse { + messages: vec![], + log: vec![], + data: Some(to_binary(&send_external_query_recursion_limit( + deps, to, depth, code_hash, + )?)?), + }), + HandleMsg::SendExternalQueryPanic { to, code_hash } => { + send_external_query_panic(deps, to, code_hash) + } + HandleMsg::SendExternalQueryError { to, code_hash } => { + send_external_query_stderror(deps, to, code_hash) + } + HandleMsg::SendExternalQueryBadAbi { to, code_hash } => { + send_external_query_bad_abi(deps, to, code_hash) + } + HandleMsg::SendExternalQueryBadAbiReceiver { to, code_hash } => { + send_external_query_bad_abi_receiver(deps, to, code_hash) + } + HandleMsg::LogMsgSender {} => Ok(HandleResponse { + messages: vec![], + log: vec![log("msg.sender", env.message.sender.to_string())], + data: None, + }), + HandleMsg::CallbackToLogMsgSender { to, code_hash } => Ok(HandleResponse { + messages: vec![CosmosMsg::Wasm(WasmMsg::Execute { + contract_addr: to.clone(), + callback_code_hash: code_hash, + msg: Binary::from(r#"{"log_msg_sender":{}}"#.as_bytes().to_vec()), + send: vec![], + })], + log: vec![log("hi", "hey")], + data: None, + }), + HandleMsg::DepositToContract {} => Ok(HandleResponse { + messages: vec![], + log: vec![], + data: Some(to_binary(&env.message.sent_funds).unwrap()), + }), + HandleMsg::SendFunds { + amount, + from, + to, + denom, + } => Ok(HandleResponse { + messages: vec![CosmosMsg::Bank(BankMsg::Send { + from_address: from, + to_address: to, + amount: vec![Coin { + amount: Uint128(amount as u128), + denom: denom, + }], + })], + log: vec![], + data: None, + }), + HandleMsg::BankMsgSend { to, amount, from } => Ok(HandleResponse { + messages: vec![CosmosMsg::Bank(BankMsg::Send { + from_address: from.unwrap_or(env.contract.address), + to_address: to, + amount, + })], + log: vec![], + data: None, + }), + HandleMsg::CosmosMsgCustom {} => Ok(HandleResponse { + messages: vec![CosmosMsg::Custom(Empty {})], + log: vec![], + data: None, + }), + HandleMsg::SendFundsToInitCallback { + amount, + denom, + code_id, + code_hash, + } => Ok(HandleResponse { + messages: vec![CosmosMsg::Wasm(WasmMsg::Instantiate { + msg: Binary("{\"nop\":{}}".as_bytes().to_vec()), + code_id: code_id, + callback_code_hash: code_hash, + label: String::from("yo"), + send: vec![Coin { + amount: Uint128(amount as u128), + denom: denom, + }], + })], + log: vec![], + data: None, + }), + HandleMsg::SendFundsToExecCallback { + amount, + denom, + to, + code_hash, + } => Ok(HandleResponse { + messages: vec![CosmosMsg::Wasm(WasmMsg::Execute { + msg: Binary("{\"no_data\":{}}".as_bytes().to_vec()), + contract_addr: to, + callback_code_hash: code_hash, + send: vec![Coin { + amount: Uint128(amount as u128), + denom: denom, + }], + })], + log: vec![], + data: None, + }), + HandleMsg::Sleep { ms } => { + thread::sleep(time::Duration::from_millis(ms)); + + Ok(HandleResponse { + messages: vec![], + log: vec![], + data: None, + }) + } + HandleMsg::WithFloats { x, y } => Ok(HandleResponse { + messages: vec![], + log: vec![], + data: Some(use_floats(x, y)), + }), + HandleMsg::CallToInit { + code_id, + code_hash, + label, + msg, + } => Ok(HandleResponse { + messages: vec![CosmosMsg::Wasm(WasmMsg::Instantiate { + code_id, + callback_code_hash: code_hash, + msg: Binary(msg.as_bytes().into()), + send: vec![], + label: label, + })], + log: vec![log("a", "a")], + data: None, + }), + HandleMsg::CallToExec { + addr, + code_hash, + msg, + } => Ok(HandleResponse { + messages: vec![CosmosMsg::Wasm(WasmMsg::Execute { + contract_addr: addr, + callback_code_hash: code_hash, + msg: Binary(msg.as_bytes().into()), + send: vec![], + })], + log: vec![log("b", "b")], + data: None, + }), + HandleMsg::CallToQuery { + addr, + code_hash, + msg, + } => { + let answer: u32 = deps + .querier + .query(&QueryRequest::Wasm(WasmQuery::Smart { + contract_addr: addr, + callback_code_hash: code_hash, + msg: Binary::from(msg.as_bytes().to_vec()), + })) + .map_err(|err| { + StdError::generic_err(format!("Got an error from query: {:?}", err)) + })?; + + Ok(HandleResponse { + messages: vec![], + log: vec![log("c", format!("{}", answer))], + data: None, + }) + } + HandleMsg::StoreReallyLongKey {} => { + let mut store = PrefixedStorage::new(b"my_prefix", &mut deps.storage); + store.set(REALLY_LONG, b"hello"); + Ok(HandleResponse::default()) + } + HandleMsg::StoreReallyShortKey {} => { + let mut store = PrefixedStorage::new(b"my_prefix", &mut deps.storage); + store.set(b"a", b"hello"); + Ok(HandleResponse::default()) + } + HandleMsg::StoreReallyLongValue {} => { + let mut store = PrefixedStorage::new(b"my_prefix", &mut deps.storage); + store.set(b"hello", REALLY_LONG); + Ok(HandleResponse::default()) + } + HandleMsg::Secp256k1Verify { + pubkey, + sig, + msg_hash, + iterations, + } => { + let mut res: HandleResult = Ok(HandleResponse { + messages: vec![], + log: vec![], + data: None, + }); + + // loop for benchmarking + for _ in 0..iterations { + res = match deps.api.secp256k1_verify( + msg_hash.as_slice(), + sig.as_slice(), + pubkey.as_slice(), + ) { + Ok(result) => Ok(HandleResponse { + messages: vec![], + log: vec![log("result", format!("{}", result))], + data: None, + }), + Err(err) => Err(StdError::generic_err(format!("{:?}", err))), + }; + } + + return res; + } + HandleMsg::Secp256k1VerifyFromCrate { + pubkey, + sig, + msg_hash, + iterations, + } => { + let mut res: HandleResult = Ok(HandleResponse { + messages: vec![], + log: vec![], + data: None, + }); + + // loop for benchmarking + for _ in 0..iterations { + let secp256k1_verifier = Secp256k1::verification_only(); + + let secp256k1_signature = + secp256k1::Signature::from_compact(&sig.0).map_err(|err| { + StdError::generic_err(format!("Malformed signature: {:?}", err)) + })?; + let secp256k1_pubkey = secp256k1::PublicKey::from_slice(pubkey.0.as_slice()) + .map_err(|err| StdError::generic_err(format!("Malformed pubkey: {:?}", err)))?; + let secp256k1_msg = + secp256k1::Message::from_slice(&msg_hash.as_slice()).map_err(|err| { + StdError::generic_err(format!( + "Failed to create a secp256k1 message from signed_bytes: {:?}", + err + )) + })?; + + res = match secp256k1_verifier.verify( + &secp256k1_msg, + &secp256k1_signature, + &secp256k1_pubkey, + ) { + Ok(()) => Ok(HandleResponse { + messages: vec![], + log: vec![log("result", "true")], + data: None, + }), + Err(_err) => Ok(HandleResponse { + messages: vec![], + log: vec![log("result", "false")], + data: None, + }), + }; + } + + return res; + } + HandleMsg::Ed25519Verify { + pubkey, + sig, + msg, + iterations, + } => { + let mut res: HandleResult = Ok(HandleResponse { + messages: vec![], + log: vec![], + data: None, + }); + + // loop for benchmarking + for _ in 0..iterations { + res = + match deps + .api + .ed25519_verify(msg.as_slice(), sig.as_slice(), pubkey.as_slice()) + { + Ok(result) => Ok(HandleResponse { + messages: vec![], + log: vec![log("result", format!("{}", result))], + data: None, + }), + Err(err) => Err(StdError::generic_err(format!("{:?}", err))), + }; + } + + return res; + } + HandleMsg::Ed25519BatchVerify { + pubkeys, + sigs, + msgs, + iterations, + } => { + let mut res: HandleResult = Ok(HandleResponse { + messages: vec![], + log: vec![], + data: None, + }); + + // loop for benchmarking + for _ in 0..iterations { + res = match deps.api.ed25519_batch_verify( + msgs.iter() + .map(|m| m.as_slice()) + .collect::>() + .as_slice(), + sigs.iter() + .map(|s| s.as_slice()) + .collect::>() + .as_slice(), + pubkeys + .iter() + .map(|p| p.as_slice()) + .collect::>() + .as_slice(), + ) { + Ok(result) => Ok(HandleResponse { + messages: vec![], + log: vec![log("result", format!("{}", result))], + data: None, + }), + Err(err) => Err(StdError::generic_err(format!("{:?}", err))), + }; + } + + return res; + } + HandleMsg::Secp256k1RecoverPubkey { + msg_hash, + sig, + recovery_param, + iterations, + } => { + let mut res: HandleResult = Ok(HandleResponse { + messages: vec![], + log: vec![], + data: None, + }); + + // loop for benchmarking + for _ in 0..iterations { + res = match deps.api.secp256k1_recover_pubkey( + msg_hash.as_slice(), + sig.as_slice(), + recovery_param, + ) { + Ok(result) => Ok(HandleResponse { + messages: vec![], + log: vec![log("result", format!("{}", Binary(result).to_base64()))], + data: None, + }), + Err(err) => Err(StdError::generic_err(format!("{:?}", err))), + }; + } + + return res; + } + HandleMsg::Secp256k1Sign { + msg, + privkey, + iterations, + } => { + let mut res: HandleResult = Ok(HandleResponse { + messages: vec![], + log: vec![], + data: None, + }); + + // loop for benchmarking + for _ in 0..iterations { + res = match deps.api.secp256k1_sign(msg.as_slice(), privkey.as_slice()) { + Ok(result) => Ok(HandleResponse { + messages: vec![], + log: vec![log("result", format!("{}", Binary(result).to_base64()))], + data: None, + }), + Err(err) => Err(StdError::generic_err(format!("{:?}", err))), + }; + } + + return res; + } + HandleMsg::Ed25519Sign { + msg, + privkey, + iterations, + } => { + let mut res: HandleResult = Ok(HandleResponse { + messages: vec![], + log: vec![], + data: None, + }); + + // loop for benchmarking + for _ in 0..iterations { + res = match deps.api.ed25519_sign(msg.as_slice(), privkey.as_slice()) { + Ok(result) => Ok(HandleResponse { + messages: vec![], + log: vec![log("result", format!("{}", Binary(result).to_base64()))], + data: None, + }), + Err(err) => Err(StdError::generic_err(format!("{:?}", err))), + }; + } + + return res; + } + HandleMsg::ExecuteFromV1 { counter } => { + count(&mut deps.storage).save(&counter)?; + + let mut resp = HandleResponse::default(); + resp.data = Some( + (count_read(&deps.storage).load()? as u32) + .to_be_bytes() + .into(), + ); + + Ok(resp) + } + HandleMsg::IncrementFromV1 { addition } => { + if addition == 0 { + return Err(StdError::generic_err("got wrong counter")); + } + + let new_count = count(&mut deps.storage).load()? + addition; + count(&mut deps.storage).save(&new_count)?; + + let mut resp = HandleResponse::default(); + resp.data = Some((new_count as u32).to_be_bytes().into()); + + Ok(resp) + } + HandleMsg::AddAttributes {} => Ok(HandleResponse { + messages: vec![], + log: vec![log("attr1", "🦄"), log("attr2", "🌈")], + data: None, + }), + HandleMsg::AddMoreAttributes {} => Ok(HandleResponse { + messages: vec![], + log: vec![log("attr3", "🍉"), log("attr4", "🥝")], + data: None, + }), + HandleMsg::AddAttributesWithSubmessage {} => Ok(HandleResponse { + messages: vec![CosmosMsg::Wasm(WasmMsg::Execute { + contract_addr: env.contract.address, + callback_code_hash: env.contract_code_hash, + msg: Binary::from(r#"{"add_more_attributes":{}}"#.as_bytes().to_vec()), + send: vec![], + })], + log: vec![log("attr1", "🦄"), log("attr2", "🌈")], + data: None, + }), + HandleMsg::AddPlaintextAttributes {} => Ok(HandleResponse { + messages: vec![], + log: vec![plaintext_log("attr1", "🦄"), plaintext_log("attr2", "🌈")], + data: None, + }), + HandleMsg::AddMorePlaintextAttributes {} => Ok(HandleResponse { + messages: vec![], + log: vec![plaintext_log("attr3", "🍉"), plaintext_log("attr4", "🥝")], + data: None, + }), + HandleMsg::AddPlaintextAttributesWithSubmessage {} => Ok(HandleResponse { + messages: vec![CosmosMsg::Wasm(WasmMsg::Execute { + contract_addr: env.contract.address, + callback_code_hash: env.contract_code_hash, + msg: Binary::from(r#"{"add_more_plaintext_attributes":{}}"#.as_bytes().to_vec()), + send: vec![], + })], + log: vec![plaintext_log("attr1", "🦄"), plaintext_log("attr2", "🌈")], + data: None, + }), + HandleMsg::AddMixedEventsAndAttributesFromV1 { addr, code_hash } => Ok(HandleResponse { + messages: vec![CosmosMsg::Wasm(WasmMsg::Execute { + contract_addr: addr, + callback_code_hash: code_hash, + msg: Binary::from( + r#"{"add_more_mixed_attributes_and_events":{}}"#.as_bytes().to_vec(), + ), + send: vec![], + })], + log: vec![plaintext_log("attr1", "🦄"), plaintext_log("attr2", "🌈")], + data: None, + }), + HandleMsg::InitNewContract {} => Ok(HandleResponse { + messages: vec![CosmosMsg::Wasm(WasmMsg::Instantiate { + code_id: 1, + msg: Binary::from( + "{\"counter\":{\"counter\":150, \"expires\":100}}" + .as_bytes() + .to_vec(), + ), + callback_code_hash: env.contract_code_hash, + send: vec![], + label: String::from("fi"), + })], + log: vec![], + data: None, + }), + } +} + +#[cfg(feature = "with_floats")] +fn use_floats(x: u8, y: u8) -> Binary { + let res: f64 = (x as f64) / (y as f64); + to_binary(&format!("{}", res)).unwrap() +} + +#[cfg(not(feature = "with_floats"))] +fn use_floats(x: u8, y: u8) -> Binary { + Binary(vec![x, y]) +} + +fn send_external_query( + deps: &Extern, + contract_addr: HumanAddr, + code_hash: String, +) -> u8 { + let answer: u8 = deps + .querier + .query(&QueryRequest::Wasm(WasmQuery::Smart { + contract_addr, + callback_code_hash: code_hash, + msg: Binary::from(r#"{"receive_external_query":{"num":2}}"#.as_bytes().to_vec()), + })) + .unwrap(); + answer +} + +fn send_external_query_depth_counter( + deps: &Extern, + contract_addr: HumanAddr, + depth: u8, + code_hash: String, +) -> u8 { + if depth == 0 { + return 0; + } + + let answer: u8 = deps + .querier + .query(&QueryRequest::Wasm(WasmQuery::Smart { + contract_addr: contract_addr.clone(), + callback_code_hash: code_hash.clone(), + msg: Binary( + format!( + r#"{{"send_external_query_depth_counter":{{"to":"{}","code_hash":"{}","depth":{}}}}}"#, + contract_addr.clone().to_string(), + code_hash.clone().to_string(), + depth - 1 + ) + .into(), + ), + })) + .unwrap(); + + answer + 1 +} + +fn send_external_query_recursion_limit( + deps: &Extern, + contract_addr: HumanAddr, + depth: u8, + code_hash: String, +) -> StdResult { + let result = deps + .querier + .query(&QueryRequest::Wasm(WasmQuery::Smart { + contract_addr: contract_addr.clone(), + callback_code_hash: code_hash.clone(), + msg: Binary( + format!( + r#"{{"send_external_query_recursion_limit":{{"to":"{}","code_hash":"{}","depth":{}}}}}"#, + contract_addr.clone().to_string(), + code_hash.clone().to_string(), + depth + 1 + ) + .into_bytes(), + ), + })); + + // 10 is the current recursion limit. + if depth != 10 { + result + } else { + match result { + Err(StdError::GenericErr { msg, .. }) + if msg == "Querier system error: Query recursion limit exceeded" => + { + Ok(String::from("Recursion limit was correctly enforced")) + } + _ => Err(StdError::generic_err( + "Recursion limit was bypassed! this is a bug!", + )), + } + } +} + +fn send_external_query_panic( + deps: &mut Extern, + contract_addr: HumanAddr, + code_hash: String, +) -> HandleResult { + let err = deps + .querier + .query::(&QueryRequest::Wasm(WasmQuery::Smart { + contract_addr, + msg: Binary::from(r#"{"panic":{}}"#.as_bytes().to_vec()), + callback_code_hash: code_hash, + })) + .unwrap_err(); + + Err(err) +} + +fn send_external_query_stderror( + deps: &mut Extern, + contract_addr: HumanAddr, + code_hash: String, +) -> HandleResult { + let answer = deps + .querier + .query::(&QueryRequest::Wasm(WasmQuery::Smart { + contract_addr, + msg: Binary::from( + r#"{"contract_error":{"error_type":"generic_err"}}"# + .as_bytes() + .to_vec(), + ), + callback_code_hash: code_hash, + })); + + match answer { + Ok(wtf) => Ok(HandleResponse { + messages: vec![], + log: vec![], + data: Some(wtf), + }), + Err(e) => Err(e), + } +} + +fn send_external_query_bad_abi( + deps: &mut Extern, + contract_addr: HumanAddr, + code_hash: String, +) -> HandleResult { + let answer = deps + .querier + .query::(&QueryRequest::Wasm(WasmQuery::Smart { + contract_addr, + callback_code_hash: code_hash, + msg: Binary::from( + r#""contract_error":{"error_type":"generic_err"}}"#.as_bytes().to_vec(), + ), + })); + + match answer { + Ok(wtf) => Ok(HandleResponse { + messages: vec![], + log: vec![], + data: Some(wtf), + }), + Err(e) => Err(e), + } +} + +fn send_external_query_bad_abi_receiver( + deps: &mut Extern, + contract_addr: HumanAddr, + code_hash: String, +) -> HandleResult { + let answer = deps + .querier + .query::(&QueryRequest::Wasm(WasmQuery::Smart { + contract_addr, + msg: Binary::from(r#"{"receive_external_query":{"num":25}}"#.as_bytes().to_vec()), + callback_code_hash: code_hash, + })); + + match answer { + Ok(wtf) => Ok(HandleResponse { + messages: vec![], + log: vec![log("wtf", wtf)], + data: None, + }), + Err(e) => Err(e), + } +} + +fn exec_callback_bad_params(contract_addr: HumanAddr, code_hash: String) -> HandleResponse { + HandleResponse { + messages: vec![CosmosMsg::Wasm(WasmMsg::Execute { + contract_addr: contract_addr.clone(), + callback_code_hash: code_hash, + msg: Binary::from(r#"{"c":{"x":"banana","y":3}}"#.as_bytes().to_vec()), + send: vec![], + })], + log: vec![], + data: None, + } +} + +pub fn a( + _deps: &mut Extern, + _env: Env, + contract_addr: HumanAddr, + code_hash: String, + x: u8, + y: u8, +) -> HandleResponse { + HandleResponse { + messages: vec![CosmosMsg::Wasm(WasmMsg::Execute { + contract_addr: contract_addr.clone(), + callback_code_hash: code_hash.clone(), + msg: Binary::from(format!( + "{{\"b\":{{\"x\":{} ,\"y\": {},\"contract_addr\": \"{}\",\"code_hash\": \"{}\" }}}}", + x, + y, + contract_addr.as_str(), + &code_hash + ) + .as_bytes() + .to_vec()), + send: vec![], + })], + log: vec![log("banana", "🍌")], + data: Some(Binary(vec![x, y])), + } +} + +pub fn b( + _deps: &mut Extern, + _env: Env, + contract_addr: HumanAddr, + code_hash: String, + x: u8, + y: u8, +) -> HandleResponse { + HandleResponse { + messages: vec![CosmosMsg::Wasm(WasmMsg::Execute { + contract_addr: contract_addr.clone(), + callback_code_hash: code_hash, + msg: Binary::from( + format!("{{\"c\":{{\"x\":{} ,\"y\": {} }}}}", x + 1, y + 1) + .as_bytes() + .to_vec(), + ), + send: vec![], + })], + log: vec![log("kiwi", "🥝")], + data: Some(Binary(vec![x + y])), + } +} + +pub fn c( + _deps: &mut Extern, + _env: Env, + x: u8, + y: u8, +) -> HandleResponse { + HandleResponse { + messages: vec![], + log: vec![log("watermelon", "🍉")], + data: Some(Binary(vec![x + y])), + } +} + +pub fn empty_log_key_value( + _deps: &mut Extern, + _env: Env, +) -> HandleResponse { + HandleResponse { + messages: vec![], + log: vec![log("my value is empty", ""), log("", "my key is empty")], + data: None, + } +} + +pub fn empty_data( + _deps: &mut Extern, + _env: Env, +) -> HandleResponse { + HandleResponse { + messages: vec![], + log: vec![], + data: Some(Binary(vec![])), + } +} + +pub fn unicode_data( + _deps: &mut Extern, + _env: Env, +) -> HandleResponse { + HandleResponse { + messages: vec![], + log: vec![], + data: Some(Binary("🍆🥑🍄".as_bytes().to_vec())), + } +} + +pub fn no_data( + _deps: &mut Extern, + _env: Env, +) -> HandleResponse { + HandleResponse { + messages: vec![], + log: vec![], + data: None, + } +} + +pub fn exec_callback_to_init( + _deps: &mut Extern, + _env: Env, + code_id: u64, + code_hash: String, +) -> HandleResponse { + HandleResponse { + messages: vec![CosmosMsg::Wasm(WasmMsg::Instantiate { + code_id, + msg: Binary::from("{\"nop\":{}}".as_bytes().to_vec()), + callback_code_hash: code_hash, + send: vec![], + label: String::from("hi"), + })], + log: vec![log("instantiating a new contract", "🪂")], + data: None, + } +} + +fn exec_with_callback_contract_error( + contract_addr: HumanAddr, + code_hash: String, +) -> HandleResponse { + HandleResponse { + messages: vec![CosmosMsg::Wasm(WasmMsg::Execute { + contract_addr: contract_addr.clone(), + callback_code_hash: code_hash, + msg: Binary::from( + r#"{"contract_error":{"error_type":"generic_err"}}"# + .as_bytes() + .to_vec(), + ), + send: vec![], + })], + log: vec![log("exec with a callback with contract error", "🤷‍♂️")], + data: None, + } +} + +fn allocate_on_heap(bytes: usize) -> HandleResponse { + let mut values: Vec = vec![0; bytes]; + values[bytes - 1] = 1; + + HandleResponse { + data: Some(Binary("😅".as_bytes().to_vec())), + log: vec![], + messages: vec![], + } +} + +fn get_state( + deps: &mut Extern, + key: String, +) -> HandleResponse { + let store = PrefixedStorage::new(b"my_prefix", &mut deps.storage); + + match store.get(key.as_bytes()) { + Some(value) => HandleResponse { + data: Some(Binary(value)), + log: vec![], + messages: vec![], + }, + None => HandleResponse::default(), + } +} + +fn set_state( + deps: &mut Extern, + key: String, + value: String, +) -> HandleResponse { + let mut store = PrefixedStorage::new(b"my_prefix", &mut deps.storage); + store.set(key.as_bytes(), value.as_bytes()); + HandleResponse::default() +} + +fn remove_state( + deps: &mut Extern, + key: String, +) -> HandleResponse { + let mut store = PrefixedStorage::new(b"my_prefix", &mut deps.storage); + store.remove(key.as_bytes()); + HandleResponse::default() +} + +#[allow(invalid_value)] +#[allow(unused_must_use)] +fn pass_null_pointer_to_imports_should_throw( + deps: &mut Extern, + pass_type: String, +) -> HandleResponse { + let null_ptr_slice: &[u8] = unsafe { MaybeUninit::zeroed().assume_init() }; + + match &pass_type[..] { + "read_db_key" => { + deps.storage.get(null_ptr_slice); + } + "write_db_key" => { + deps.storage.set(null_ptr_slice, b"write value"); + } + "write_db_value" => { + deps.storage.set(b"write key", null_ptr_slice); + } + "remove_db_key" => { + deps.storage.remove(null_ptr_slice); + } + "canonicalize_address_input" => { + deps.api + .canonical_address(unsafe { MaybeUninit::zeroed().assume_init() }); + } + "canonicalize_address_output" => { /* TODO */ } + "humanize_address_input" => { + deps.api + .human_address(unsafe { MaybeUninit::zeroed().assume_init() }); + } + "humanize_address_output" => { /* TODO */ } + _ => {} + }; + + HandleResponse::default() +} + +fn test_canonicalize_address_errors( + deps: &mut Extern, +) -> HandleResult { + match deps.api.canonical_address(&HumanAddr(String::from(""))) { + Err(StdError::GenericErr { msg, backtrace: _ }) => { + if msg != String::from("canonicalize_address errored: input is empty") { + return Err(StdError::generic_err( + "empty address should have failed with 'canonicalize_address errored: input is empty'", + )); + } + // all is good, continue + } + _ => return Err(StdError::generic_err( + "empty address should have failed with 'canonicalize_address errored: input is empty'", + )), + } + + match deps.api.canonical_address(&HumanAddr(String::from(" "))) { + Err(StdError::GenericErr { msg, backtrace: _ }) => { + if msg != String::from("canonicalize_address errored: input is empty") { + return Err(StdError::generic_err( + "empty trimmed address should have failed with 'canonicalize_address errored: input is empty'", + )); + } + // all is good, continue + } + _ => { + return Err(StdError::generic_err( + "empty trimmed address should have failed with 'canonicalize_address errored: input is empty'", + )) + } + } + + match deps + .api + .canonical_address(&HumanAddr(String::from("cosmos1h99hrcc54ms9lxxxx"))) + { + Err(StdError::GenericErr { msg, backtrace: _ }) => { + if msg != String::from("canonicalize_address errored: invalid checksum") { + return Err(StdError::generic_err( + "bad bech32 should have failed with 'canonicalize_address errored: invalid checksum'", + )); + } + // all is good, continue + } + _ => return Err(StdError::generic_err( + "bad bech32 should have failed with 'canonicalize_address errored: invalid checksum'", + )), + } + + match deps.api.canonical_address(&HumanAddr(String::from( + "cosmos1h99hrcc54ms9luwpex9kw0rwdt7etvfdyxh6gu", + ))) { + Err(StdError::GenericErr { msg, backtrace: _ }) => { + if msg != String::from("canonicalize_address errored: wrong address prefix: \"cosmos\"") + { + return Err(StdError::generic_err( + "bad prefix should have failed with 'canonicalize_address errored: wrong address prefix: \"cosmos\"'", + )); + } + // all is good, continue + } + _ => { + return Err(StdError::generic_err( + "bad prefix should have failed with 'canonicalize_address errored: wrong address prefix: \"cosmos\"'", + )) + } + } + + Ok(HandleResponse { + data: Some(Binary("🤟".as_bytes().to_vec())), + log: vec![], + messages: vec![], + }) +} + +/////////////////////////////// Query /////////////////////////////// + +pub fn query( + deps: &Extern, + _msg: QueryMsg, +) -> QueryResult { + match _msg { + QueryMsg::ContractError { error_type } => Err(map_string_to_error(error_type)), + QueryMsg::Panic {} => panic!("panic in query"), + QueryMsg::ReceiveExternalQuery { num } => { + Ok(Binary(serde_json_wasm::to_vec(&(num + 1)).unwrap())) + } + QueryMsg::SendExternalQueryInfiniteLoop { to, code_hash } => { + send_external_query_infinite_loop(deps, to, code_hash) + } + QueryMsg::WriteToStorage {} => write_to_storage_in_query(deps), + QueryMsg::RemoveFromStorage {} => remove_from_storage_in_query(deps), + QueryMsg::SendExternalQueryDepthCounter { + to, + depth, + code_hash, + } => Ok(to_binary(&send_external_query_depth_counter( + deps, to, depth, code_hash, + )) + .unwrap()), + QueryMsg::SendExternalQueryRecursionLimit { + to, + depth, + code_hash, + } => to_binary(&send_external_query_recursion_limit( + deps, to, depth, code_hash, + )?), + QueryMsg::CallToQuery { + addr, + code_hash, + msg, + } => { + let answer: u32 = deps + .querier + .query(&QueryRequest::Wasm(WasmQuery::Smart { + contract_addr: addr, + callback_code_hash: code_hash, + msg: Binary::from(msg.as_bytes().to_vec()), + })) + .map_err(|err| { + StdError::generic_err(format!("Got an error from query: {:?}", err)) + })?; + return Ok(to_binary(&answer)?); + } + QueryMsg::GetCountFromV1 {} => { + let count = count_read(&deps.storage).load()?; + + Ok(to_binary(&QueryRes::Get { count })?) + } + QueryMsg::Get {} => { + let count = count_read(&deps.storage).load()?; + + Ok(to_binary(&QueryRes::Get { count })?) + } + QueryMsg::GetContractVersion {} => { + let answer: u8 = 10; + return Ok(to_binary(&answer)?); + } + } +} + +fn send_external_query_infinite_loop( + deps: &Extern, + contract_addr: HumanAddr, + code_hash: String, +) -> QueryResult { + let answer = deps + .querier + .query::(&QueryRequest::Wasm(WasmQuery::Smart { + contract_addr: contract_addr.clone(), + callback_code_hash: code_hash.clone(), + msg: Binary::from( + format!( + r#"{{"send_external_query_infinite_loop":{{"to":"{}", "code_hash":"{}"}}}}"#, + contract_addr.clone().to_string(), + &code_hash + ) + .as_bytes() + .to_vec(), + ), + })); + + match answer { + Ok(wtf) => Ok(Binary(wtf.into())), + Err(e) => Err(e), + } +} + +fn write_to_storage_in_query( + deps: &Extern, +) -> StdResult { + #[allow(clippy::cast_ref_to_mut)] + let deps = unsafe { &mut *(deps as *const _ as *mut Extern) }; + deps.storage.set(b"abcd", b"dcba"); + + Ok(Binary(vec![])) +} + +fn remove_from_storage_in_query( + deps: &Extern, +) -> StdResult { + #[allow(clippy::cast_ref_to_mut)] + let deps = unsafe { &mut *(deps as *const _ as *mut Extern) }; + deps.storage.remove(b"abcd"); + + Ok(Binary(vec![])) +} diff --git a/integration-tests/contract-v0.10/src/lib.rs b/integration-tests/contract-v0.10/src/lib.rs new file mode 100644 index 000000000..4d128dcb3 --- /dev/null +++ b/integration-tests/contract-v0.10/src/lib.rs @@ -0,0 +1,38 @@ +pub mod contract; + +#[cfg(target_arch = "wasm32")] +mod wasm { + use super::contract; + use cosmwasm_std::{ + do_handle, do_init, do_query, ExternalApi, ExternalQuerier, ExternalStorage, + }; + + #[no_mangle] + extern "C" fn init(env_ptr: u32, msg_ptr: u32) -> u32 { + do_init( + &contract::init::, + env_ptr, + msg_ptr, + ) + } + + #[no_mangle] + extern "C" fn handle(env_ptr: u32, msg_ptr: u32) -> u32 { + do_handle( + &contract::handle::, + env_ptr, + msg_ptr, + ) + } + + #[no_mangle] + extern "C" fn query(msg_ptr: u32) -> u32 { + do_query( + &contract::query::, + msg_ptr, + ) + } + + // Other C externs like cosmwasm_vm_version_1, allocate, deallocate are available + // automatically because we `use cosmwasm_std`. +} diff --git a/integration-tests/contract-v1/.gitignore b/integration-tests/contract-v1/.gitignore new file mode 100644 index 000000000..0e24e33d5 --- /dev/null +++ b/integration-tests/contract-v1/.gitignore @@ -0,0 +1,13 @@ +# Build results +/target +*.wasm + +# Text file backups +**/*.rs.bk + +# macOS +.DS_Store + +# IDEs +*.iml +.idea diff --git a/integration-tests/contract-v1/Cargo.lock b/integration-tests/contract-v1/Cargo.lock new file mode 100644 index 000000000..283ca7e5e --- /dev/null +++ b/integration-tests/contract-v1/Cargo.lock @@ -0,0 +1,614 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "base16ct" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "349a06037c7bf932dd7e7d1f653678b2038b9ad46a74102f1fc7bd7872678cce" + +[[package]] +name = "base64" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd" + +[[package]] +name = "base64ct" +version = "1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3bdca834647821e0b13d9539a8634eb62d3501b6b6c2cec1722786ee6671b851" + +[[package]] +name = "block-buffer" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" +dependencies = [ + "generic-array", +] + +[[package]] +name = "byteorder" +version = "1.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "const-oid" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e4c78c047431fee22c1a7bb92e00ad095a02a983affe4d8a72e2a2c62c1b94f3" + +[[package]] +name = "contract-v1" +version = "0.0.1" +dependencies = [ + "cosmwasm-std", + "cosmwasm-storage", + "schemars", + "serde", + "serde-json-wasm 0.2.3", +] + +[[package]] +name = "cosmwasm-crypto" +version = "1.0.0" +source = "git+https://github.com/scrtlabs/cosmwasm?branch=secret#e69869a8565e4e2318bdbfd3711fd1ceda0db209" +dependencies = [ + "digest", + "ed25519-zebra", + "k256", + "rand_core 0.6.3", + "thiserror", +] + +[[package]] +name = "cosmwasm-derive" +version = "1.0.0" +source = "git+https://github.com/scrtlabs/cosmwasm?branch=secret#e69869a8565e4e2318bdbfd3711fd1ceda0db209" +dependencies = [ + "syn", +] + +[[package]] +name = "cosmwasm-std" +version = "1.0.0" +source = "git+https://github.com/scrtlabs/cosmwasm?branch=secret#e69869a8565e4e2318bdbfd3711fd1ceda0db209" +dependencies = [ + "base64", + "cosmwasm-crypto", + "cosmwasm-derive", + "forward_ref", + "schemars", + "serde", + "serde-json-wasm 0.4.1", + "thiserror", + "uint", +] + +[[package]] +name = "cosmwasm-storage" +version = "1.0.0" +source = "git+https://github.com/scrtlabs/cosmwasm?branch=secret#e69869a8565e4e2318bdbfd3711fd1ceda0db209" +dependencies = [ + "cosmwasm-std", + "serde", +] + +[[package]] +name = "cpufeatures" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59a6001667ab124aebae2a495118e11d30984c3a653e99d86d58971708cf5e4b" +dependencies = [ + "libc", +] + +[[package]] +name = "crunchy" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" + +[[package]] +name = "crypto-bigint" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03c6a1d5fa1de37e071642dfa44ec552ca5b299adb128fab16138e24b548fd21" +dependencies = [ + "generic-array", + "rand_core 0.6.3", + "subtle", + "zeroize", +] + +[[package]] +name = "crypto-mac" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1d1a86f49236c215f271d40892d5fc950490551400b02ef360692c29815c714" +dependencies = [ + "generic-array", + "subtle", +] + +[[package]] +name = "curve25519-dalek" +version = "3.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90f9d052967f590a76e62eb387bd0bbb1b000182c3cefe5364db6b7211651bc0" +dependencies = [ + "byteorder", + "digest", + "rand_core 0.5.1", + "subtle", + "zeroize", +] + +[[package]] +name = "der" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6919815d73839e7ad218de758883aae3a257ba6759ce7a9992501efbb53d705c" +dependencies = [ + "const-oid", +] + +[[package]] +name = "digest" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" +dependencies = [ + "generic-array", +] + +[[package]] +name = "dyn-clone" +version = "1.0.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d07a982d1fb29db01e5a59b1918e03da4df7297eaeee7686ac45542fd4e59c8" + +[[package]] +name = "ecdsa" +version = "0.13.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0d69ae62e0ce582d56380743515fefaf1a8c70cec685d9677636d7e30ae9dc9" +dependencies = [ + "der", + "elliptic-curve", + "rfc6979", + "signature", +] + +[[package]] +name = "ed25519-zebra" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "403ef3e961ab98f0ba902771d29f842058578bb1ce7e3c59dad5a6a93e784c69" +dependencies = [ + "curve25519-dalek", + "hex", + "rand_core 0.6.3", + "serde", + "sha2", + "thiserror", + "zeroize", +] + +[[package]] +name = "elliptic-curve" +version = "0.11.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25b477563c2bfed38a3b7a60964c49e058b2510ad3f12ba3483fd8f62c2306d6" +dependencies = [ + "base16ct", + "crypto-bigint", + "der", + "ff", + "generic-array", + "group", + "rand_core 0.6.3", + "sec1", + "subtle", + "zeroize", +] + +[[package]] +name = "ff" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "131655483be284720a17d74ff97592b8e76576dc25563148601df2d7c9080924" +dependencies = [ + "rand_core 0.6.3", + "subtle", +] + +[[package]] +name = "forward_ref" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8cbd1169bd7b4a0a20d92b9af7a7e0422888bd38a6f5ec29c1fd8c1558a272e" + +[[package]] +name = "generic-array" +version = "0.14.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd48d33ec7f05fbfa152300fdad764757cbded343c1aa1cff2fbaf4134851803" +dependencies = [ + "typenum", + "version_check", +] + +[[package]] +name = "getrandom" +version = "0.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce" +dependencies = [ + "cfg-if", + "libc", + "wasi 0.9.0+wasi-snapshot-preview1", +] + +[[package]] +name = "getrandom" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4eb1a864a501629691edf6c15a593b7a51eebaa1e8468e9ddc623de7c9b58ec6" +dependencies = [ + "cfg-if", + "libc", + "wasi 0.11.0+wasi-snapshot-preview1", +] + +[[package]] +name = "group" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc5ac374b108929de78460075f3dc439fa66df9d8fc77e8f12caa5165fcf0c89" +dependencies = [ + "ff", + "rand_core 0.6.3", + "subtle", +] + +[[package]] +name = "hex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" + +[[package]] +name = "hmac" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a2a2320eb7ec0ebe8da8f744d7812d9fc4cb4d09344ac01898dbcb6a20ae69b" +dependencies = [ + "crypto-mac", + "digest", +] + +[[package]] +name = "itoa" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "112c678d4050afce233f4f2852bb2eb519230b3cf12f33585275537d7e41578d" + +[[package]] +name = "k256" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19c3a5e0a0b8450278feda242592512e09f61c72e018b8cd5c859482802daf2d" +dependencies = [ + "cfg-if", + "ecdsa", + "elliptic-curve", + "sec1", + "sha2", +] + +[[package]] +name = "libc" +version = "0.2.126" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "349d5a591cd28b49e1d1037471617a32ddcda5731b99419008085f72d5a53836" + +[[package]] +name = "opaque-debug" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" + +[[package]] +name = "pkcs8" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7cabda3fb821068a9a4fab19a683eac3af12edf0f34b94a8be53c4972b8149d0" +dependencies = [ + "der", + "spki", + "zeroize", +] + +[[package]] +name = "proc-macro2" +version = "1.0.42" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c278e965f1d8cf32d6e0e96de3d3e79712178ae67986d9cf9151f51e95aac89b" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3bcdf212e9776fbcb2d23ab029360416bb1706b1aea2d1a5ba002727cbcab804" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rand_core" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" +dependencies = [ + "getrandom 0.1.16", +] + +[[package]] +name = "rand_core" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7" +dependencies = [ + "getrandom 0.2.7", +] + +[[package]] +name = "rfc6979" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96ef608575f6392792f9ecf7890c00086591d29a83910939d430753f7c050525" +dependencies = [ + "crypto-bigint", + "hmac", + "zeroize", +] + +[[package]] +name = "ryu" +version = "1.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3f6f92acf49d1b98f7a81226834412ada05458b7364277387724a237f062695" + +[[package]] +name = "schemars" +version = "0.8.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1847b767a3d62d95cbf3d8a9f0e421cf57a0d8aa4f411d4b16525afb0284d4ed" +dependencies = [ + "dyn-clone", + "schemars_derive", + "serde", + "serde_json", +] + +[[package]] +name = "schemars_derive" +version = "0.8.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af4d7e1b012cb3d9129567661a63755ea4b8a7386d339dc945ae187e403c6743" +dependencies = [ + "proc-macro2", + "quote", + "serde_derive_internals", + "syn", +] + +[[package]] +name = "sec1" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08da66b8b0965a5555b6bd6639e68ccba85e1e2506f5fbb089e93f8a04e1a2d1" +dependencies = [ + "der", + "generic-array", + "pkcs8", + "subtle", + "zeroize", +] + +[[package]] +name = "serde" +version = "1.0.140" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc855a42c7967b7c369eb5860f7164ef1f6f81c20c7cc1141f2a604e18723b03" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde-json-wasm" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "120bad73306616e91acd7ceed522ba96032a51cffeef3cc813de7f367df71e37" +dependencies = [ + "serde", +] + +[[package]] +name = "serde-json-wasm" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "479b4dbc401ca13ee8ce902851b834893251404c4f3c65370a49e047a6be09a5" +dependencies = [ + "serde", +] + +[[package]] +name = "serde_derive" +version = "1.0.140" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f2122636b9fe3b81f1cb25099fcf2d3f542cdb1d45940d56c713158884a05da" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_derive_internals" +version = "0.26.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85bf8229e7920a9f636479437026331ce11aa132b4dde37d121944a44d6e5f3c" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_json" +version = "1.0.82" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "82c2c1fdcd807d1098552c5b9a36e425e42e9fbd7c6a37a8425f390f781f7fa7" +dependencies = [ + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "sha2" +version = "0.9.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d58a1e1bf39749807d89cf2d98ac2dfa0ff1cb3faa38fbb64dd88ac8013d800" +dependencies = [ + "block-buffer", + "cfg-if", + "cpufeatures", + "digest", + "opaque-debug", +] + +[[package]] +name = "signature" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "02658e48d89f2bec991f9a78e69cfa4c316f8d6a6c4ec12fae1aeb263d486788" +dependencies = [ + "digest", + "rand_core 0.6.3", +] + +[[package]] +name = "spki" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44d01ac02a6ccf3e07db148d2be087da624fea0221a16152ed01f0496a6b0a27" +dependencies = [ + "base64ct", + "der", +] + +[[package]] +name = "static_assertions" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" + +[[package]] +name = "subtle" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" + +[[package]] +name = "syn" +version = "1.0.98" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c50aef8a904de4c23c788f104b7dddc7d6f79c647c7c8ce4cc8f73eb0ca773dd" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "thiserror" +version = "1.0.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd829fe32373d27f76265620b5309d0340cb8550f523c1dda251d6298069069a" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0396bc89e626244658bef819e22d0cc459e795a5ebe878e6ec336d1674a8d79a" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "typenum" +version = "1.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dcf81ac59edc17cc8697ff311e8f5ef2d99fcbd9817b34cec66f90b6c3dfd987" + +[[package]] +name = "uint" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "12f03af7ccf01dd611cc450a0d10dbc9b745770d096473e2faf0ca6e2d66d1e0" +dependencies = [ + "byteorder", + "crunchy", + "hex", + "static_assertions", +] + +[[package]] +name = "unicode-ident" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "15c61ba63f9235225a22310255a29b806b907c9b8c964bcbd0a2c70f3f2deea7" + +[[package]] +name = "version_check" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" + +[[package]] +name = "wasi" +version = "0.9.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[package]] +name = "zeroize" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4756f7db3f7b5574938c3eb1c117038b8e07f95ee6718c0efad4ac21508f1efd" diff --git a/integration-tests/contract-v1/Cargo.toml b/integration-tests/contract-v1/Cargo.toml new file mode 100644 index 000000000..ecec318c2 --- /dev/null +++ b/integration-tests/contract-v1/Cargo.toml @@ -0,0 +1,39 @@ +[package] +name = "contract-v1" +version = "0.0.1" +authors = ["SCRT Labs "] +edition = "2018" +description = "A Test contract intended to use in integration tests for the Secret Netowrk" +license = "MIT" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html +[lib] +crate-type = ["cdylib", "rlib"] + +[profile.release] +opt-level = 3 +debug = false +rpath = false +lto = true +debug-assertions = false +codegen-units = 1 +panic = 'abort' +incremental = false +overflow-checks = true + +[features] +default = [] +backtraces = ["cosmwasm-std/backtraces"] +with_floats = [] + +[dependencies] +cosmwasm-std = { git = "https://github.com/scrtlabs/cosmwasm", branch = "secret", features = [ + "stargate" +] } +cosmwasm-storage = { git = "https://github.com/scrtlabs/cosmwasm", branch = "secret" } +schemars = "0.8.1" +serde = { version = "1.0.114", default-features = false, features = [ + "derive", + "alloc" +] } +serde-json-wasm = "0.2.1" diff --git a/integration-tests/contract-v1/Makefile b/integration-tests/contract-v1/Makefile new file mode 100644 index 000000000..61a463623 --- /dev/null +++ b/integration-tests/contract-v1/Makefile @@ -0,0 +1,8 @@ +all: src/contract.rs src/lib.rs src/msg.rs Cargo.toml Cargo.lock + rustup target add wasm32-unknown-unknown + RUSTFLAGS='-C link-arg=-s' cargo build --release --target wasm32-unknown-unknown + cp ./target/wasm32-unknown-unknown/release/contract_v1.wasm ./contract.wasm + +clean: + cargo clean + -rm -f ./contract.wasm \ No newline at end of file diff --git a/integration-tests/contract-v1/rust-toolchain b/integration-tests/contract-v1/rust-toolchain new file mode 100644 index 000000000..a7efc46ca --- /dev/null +++ b/integration-tests/contract-v1/rust-toolchain @@ -0,0 +1 @@ +1.61 \ No newline at end of file diff --git a/integration-tests/contract-v1/src/contract.rs b/integration-tests/contract-v1/src/contract.rs new file mode 100644 index 000000000..21e622b82 --- /dev/null +++ b/integration-tests/contract-v1/src/contract.rs @@ -0,0 +1,37 @@ +use cosmwasm_std::{ + entry_point, BankMsg, Binary, CosmosMsg, Deps, DepsMut, Env, MessageInfo, Response, StdResult, +}; + +use crate::msg::{ExecuteMsg, InstantiateMsg, QueryMsg}; + +#[entry_point] +pub fn instantiate( + _deps: DepsMut, + _env: Env, + _info: MessageInfo, + _msg: InstantiateMsg, +) -> StdResult { + Ok(Response::new()) +} + +#[entry_point] +pub fn execute( + _deps: DepsMut, + _env: Env, + _info: MessageInfo, + msg: ExecuteMsg, +) -> StdResult { + match msg { + ExecuteMsg::BankMsg { to_address, amount } => { + Ok(Response::new().add_message(CosmosMsg::Bank(BankMsg::Send { to_address, amount }))) + } + ExecuteMsg::StargateMsg { type_url, value } => { + Ok(Response::new().add_message(CosmosMsg::Stargate { type_url, value })) + } + } +} + +#[entry_point] +pub fn query(_deps: Deps, _env: Env, _msg: QueryMsg) -> StdResult { + Ok(Binary(vec![])) +} diff --git a/integration-tests/contract-v1/src/lib.rs b/integration-tests/contract-v1/src/lib.rs new file mode 100644 index 000000000..112ecadc8 --- /dev/null +++ b/integration-tests/contract-v1/src/lib.rs @@ -0,0 +1,2 @@ +pub mod contract; +pub mod msg; diff --git a/integration-tests/contract-v1/src/msg.rs b/integration-tests/contract-v1/src/msg.rs new file mode 100644 index 000000000..f477637eb --- /dev/null +++ b/integration-tests/contract-v1/src/msg.rs @@ -0,0 +1,30 @@ +use cosmwasm_std::{Binary, Coin}; +use schemars::JsonSchema; +use serde::{Deserialize, Serialize}; + +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] +#[serde(rename_all = "snake_case")] +pub enum InstantiateMsg { + Nop {}, +} + +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] +#[serde(rename_all = "snake_case")] +pub enum ExecuteMsg { + BankMsg { + to_address: String, + amount: Vec, + }, + StargateMsg { + type_url: String, + value: Binary, + }, +} + +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] +#[serde(rename_all = "snake_case")] +pub enum QueryMsg {} + +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] +#[serde(rename_all = "snake_case")] +pub enum QueryRes {} diff --git a/integration-tests/jest.config.js b/integration-tests/jest.config.js new file mode 100644 index 000000000..877497a25 --- /dev/null +++ b/integration-tests/jest.config.js @@ -0,0 +1,13 @@ +/** @type {import('ts-jest/dist/types').InitialOptionsTsJest} */ +module.exports = { + preset: "ts-jest", + testEnvironment: "node", + testTimeout: 60_000, + // modulePathIgnorePatterns: ["dist", "scripts"], + // globalSetup: "/test/globalSetup.ts", + // globalTeardown: "/test/globalTeardown.js", + // setupFilesAfterEnv: ["/test/setup.ts"], + globals: { + TEST_ACCOUNTS: {}, + }, +}; diff --git a/integration-tests/package.json b/integration-tests/package.json new file mode 100644 index 000000000..b06e6fc36 --- /dev/null +++ b/integration-tests/package.json @@ -0,0 +1,19 @@ +{ + "name": "integration-tests", + "version": "1.4.0", + "license": "MIT", + "scripts": { + "test": "make && jest" + }, + "devDependencies": { + "@noble/hashes": "1.1.2", + "@types/jest": "28.1.7", + "@types/node": "18.7.9", + "jest": "28.1.3", + "prettier": "2.7.1", + "secretjs": "1.3.0-beta.23", + "ts-jest": "28.0.8", + "ts-node": "10.9.1", + "typescript": "4.7.4" + } +} diff --git a/integration-tests/test.ts b/integration-tests/test.ts new file mode 100644 index 000000000..1b5d0f781 --- /dev/null +++ b/integration-tests/test.ts @@ -0,0 +1,248 @@ +import { SecretNetworkClient, toBase64, toHex, Wallet } from "secretjs"; +import { MsgSend } from "secretjs/dist/protobuf_stuff/cosmos/bank/v1beta1/tx"; +import { sha256 } from "@noble/hashes/sha256"; +import * as fs from "fs"; + +// @ts-ignore +const accounts: { + a: SecretNetworkClient; + b: SecretNetworkClient; + c: SecretNetworkClient; + d: SecretNetworkClient; +} = {}; + +let v1CodeID: number; +let v1Address: string; +let v1CodeHash: string; + +beforeAll(async () => { + accounts.a = await SecretNetworkClient.create({ + chainId: "secretdev-1", + grpcWebUrl: "http://localhost:9091", + wallet: new Wallet( + "grant rice replace explain federal release fix clever romance raise often wild taxi quarter soccer fiber love must tape steak together observe swap guitar" + ), + walletAddress: "secret1ap26qrlp8mcq2pg6r47w43l0y8zkqm8a450s03", + }); + + accounts.b = await SecretNetworkClient.create({ + chainId: "secretdev-1", + grpcWebUrl: "http://localhost:9091", + wallet: new Wallet( + "jelly shadow frog dirt dragon use armed praise universe win jungle close inmate rain oil canvas beauty pioneer chef soccer icon dizzy thunder meadow" + ), + walletAddress: "secret1fc3fzy78ttp0lwuujw7e52rhspxn8uj52zfyne", + }); + + accounts.c = await SecretNetworkClient.create({ + chainId: "secretdev-1", + grpcWebUrl: "http://localhost:9091", + wallet: new Wallet( + "chair love bleak wonder skirt permit say assist aunt credit roast size obtain minute throw sand usual age smart exact enough room shadow charge" + ), + walletAddress: "secret1ajz54hz8azwuy34qwy9fkjnfcrvf0dzswy0lqq", + }); + + accounts.d = await SecretNetworkClient.create({ + chainId: "secretdev-1", + grpcWebUrl: "http://localhost:9091", + wallet: new Wallet( + "word twist toast cloth movie predict advance crumble escape whale sail such angry muffin balcony keen move employ cook valve hurt glimpse breeze brick" + ), + walletAddress: "secret1ldjxljw7v4vk6zhyduywh04hpj0jdwxsmrlatf", + }); + + console.log("Waiting for LocalSecret to start..."); + await waitForBlocks(); + + const v1Wasm = fs.readFileSync( + `${__dirname}/contract-v1/contract.wasm` + ) as Uint8Array; + v1CodeHash = toHex(sha256(v1Wasm)); + + let tx = await accounts.a.tx.compute.storeCode( + { + sender: accounts.a.address, + wasmByteCode: v1Wasm, + source: "", + builder: "", + }, + { gasLimit: 5_000_000 } + ); + if (tx.code !== 0) { + console.log(tx.rawLog); + } + expect(tx.code).toBe(0); + + v1CodeID = Number(tx.arrayLog.find((x) => x.key === "code_id").value); + + tx = await accounts.a.tx.compute.instantiateContract( + { + sender: accounts.a.address, + codeId: v1CodeID, + codeHash: v1CodeHash, + initMsg: { nop: {} }, + label: `v1-${Math.random()}`, + }, + { gasLimit: 100_000 } + ); + if (tx.code !== 0) { + console.log(tx.rawLog); + } + expect(tx.code).toBe(0); + + v1Address = tx.arrayLog.find((x) => x.key === "contract_address").value; +}); + +async function sleep(ms: number) { + return new Promise((resolve) => setTimeout(resolve, ms)); +} +async function waitForBlocks() { + while (true) { + const secretjs = await SecretNetworkClient.create({ + grpcWebUrl: "http://localhost:9091", + chainId: "secretdev-1", + }); + + try { + const { block } = await secretjs.query.tendermint.getLatestBlock({}); + + if (Number(block?.header?.height) >= 1) { + break; + } + } catch (e) { + // console.error(e); + } + await sleep(250); + } +} + +describe("BankMsg::Send", () => { + test("v1", async () => { + const tx = await accounts.a.tx.compute.executeContract( + { + sender: accounts.a.address, + contractAddress: v1Address, + codeHash: v1CodeHash, + msg: { + bank_msg: { + to_address: accounts.b.address, + amount: [{ amount: "1", denom: "uscrt" }], + }, + }, + sentFunds: [{ amount: "1", denom: "uscrt" }], + }, + { gasLimit: 250_000 } + ); + if (tx.code !== 0) { + console.log(tx.rawLog); + } + expect(tx.code).toBe(0); + expect(tx.arrayLog.filter((x) => x.type === "coin_spent")).toStrictEqual([ + { + key: "spender", + msg: 0, + type: "coin_spent", + value: accounts.a.address, + }, + { key: "amount", msg: 0, type: "coin_spent", value: "1uscrt" }, + { + key: "spender", + msg: 0, + type: "coin_spent", + value: v1Address, + }, + { key: "amount", msg: 0, type: "coin_spent", value: "1uscrt" }, + ]); + expect(tx.arrayLog.filter((x) => x.type === "coin_received")).toStrictEqual( + [ + { + key: "receiver", + msg: 0, + type: "coin_received", + value: v1Address, + }, + { key: "amount", msg: 0, type: "coin_received", value: "1uscrt" }, + { + key: "receiver", + msg: 0, + type: "coin_received", + value: accounts.b.address, + }, + { key: "amount", msg: 0, type: "coin_received", value: "1uscrt" }, + ] + ); + }); + + test("v0.10", async () => { + // TODO + }); +}); + +describe("StargateMsg", () => { + test("v1", async () => { + const tx = await accounts.a.tx.compute.executeContract( + { + sender: accounts.a.address, + contractAddress: v1Address, + codeHash: v1CodeHash, + msg: { + stargate_msg: { + type_url: "/cosmos.bank.v1beta1.MsgSend", + value: toBase64( + MsgSend.encode({ + fromAddress: v1Address, + toAddress: accounts.b.address, + amount: [{ amount: "1", denom: "uscrt" }], + }).finish() + ), + }, + }, + sentFunds: [{ amount: "1", denom: "uscrt" }], + }, + { gasLimit: 250_000 } + ); + if (tx.code !== 0) { + console.log(tx.rawLog); + } + expect(tx.code).toBe(0); + expect(tx.arrayLog.filter((x) => x.type === "coin_spent")).toStrictEqual([ + { + key: "spender", + msg: 0, + type: "coin_spent", + value: accounts.a.address, + }, + { key: "amount", msg: 0, type: "coin_spent", value: "1uscrt" }, + { + key: "spender", + msg: 0, + type: "coin_spent", + value: v1Address, + }, + { key: "amount", msg: 0, type: "coin_spent", value: "1uscrt" }, + ]); + expect(tx.arrayLog.filter((x) => x.type === "coin_received")).toStrictEqual( + [ + { + key: "receiver", + msg: 0, + type: "coin_received", + value: v1Address, + }, + { key: "amount", msg: 0, type: "coin_received", value: "1uscrt" }, + { + key: "receiver", + msg: 0, + type: "coin_received", + value: accounts.b.address, + }, + { key: "amount", msg: 0, type: "coin_received", value: "1uscrt" }, + ] + ); + }); + + test("v0.10", async () => { + // TODO + }); +}); diff --git a/integration-tests/tsconfig.json b/integration-tests/tsconfig.json new file mode 100644 index 000000000..b6105b83d --- /dev/null +++ b/integration-tests/tsconfig.json @@ -0,0 +1,6 @@ +{ + "compilerOptions": { + "types": ["jest", "node"], + "esModuleInterop": true + } +} diff --git a/integration-tests/yarn.lock b/integration-tests/yarn.lock new file mode 100644 index 000000000..eade28849 --- /dev/null +++ b/integration-tests/yarn.lock @@ -0,0 +1,2763 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +"@ampproject/remapping@^2.1.0": + version "2.2.0" + resolved "https://registry.yarnpkg.com/@ampproject/remapping/-/remapping-2.2.0.tgz#56c133824780de3174aed5ab6834f3026790154d" + integrity sha512-qRmjj8nj9qmLTQXXmaR1cck3UXSRMPrbsLJAasZpF+t3riI71BXed5ebIOYwQntykeZuhjsdweEc9BxH5Jc26w== + dependencies: + "@jridgewell/gen-mapping" "^0.1.0" + "@jridgewell/trace-mapping" "^0.3.9" + +"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.12.13", "@babel/code-frame@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.18.6.tgz#3b25d38c89600baa2dcc219edfa88a74eb2c427a" + integrity sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q== + dependencies: + "@babel/highlight" "^7.18.6" + +"@babel/compat-data@^7.18.8": + version "7.18.8" + resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.18.8.tgz#2483f565faca607b8535590e84e7de323f27764d" + integrity sha512-HSmX4WZPPK3FUxYp7g2T6EyO8j96HlZJlxmKPSh6KAcqwyDrfx7hKjXpAW/0FhFfTJsR0Yt4lAjLI2coMptIHQ== + +"@babel/core@^7.11.6", "@babel/core@^7.12.3": + version "7.18.10" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.18.10.tgz#39ad504991d77f1f3da91be0b8b949a5bc466fb8" + integrity sha512-JQM6k6ENcBFKVtWvLavlvi/mPcpYZ3+R+2EySDEMSMbp7Mn4FexlbbJVrx2R7Ijhr01T8gyqrOaABWIOgxeUyw== + dependencies: + "@ampproject/remapping" "^2.1.0" + "@babel/code-frame" "^7.18.6" + "@babel/generator" "^7.18.10" + "@babel/helper-compilation-targets" "^7.18.9" + "@babel/helper-module-transforms" "^7.18.9" + "@babel/helpers" "^7.18.9" + "@babel/parser" "^7.18.10" + "@babel/template" "^7.18.10" + "@babel/traverse" "^7.18.10" + "@babel/types" "^7.18.10" + convert-source-map "^1.7.0" + debug "^4.1.0" + gensync "^1.0.0-beta.2" + json5 "^2.2.1" + semver "^6.3.0" + +"@babel/generator@^7.18.10", "@babel/generator@^7.7.2": + version "7.18.12" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.18.12.tgz#fa58daa303757bd6f5e4bbca91b342040463d9f4" + integrity sha512-dfQ8ebCN98SvyL7IxNMCUtZQSq5R7kxgN+r8qYTGDmmSion1hX2C0zq2yo1bsCDhXixokv1SAWTZUMYbO/V5zg== + dependencies: + "@babel/types" "^7.18.10" + "@jridgewell/gen-mapping" "^0.3.2" + jsesc "^2.5.1" + +"@babel/helper-compilation-targets@^7.18.9": + version "7.18.9" + resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.18.9.tgz#69e64f57b524cde3e5ff6cc5a9f4a387ee5563bf" + integrity sha512-tzLCyVmqUiFlcFoAPLA/gL9TeYrF61VLNtb+hvkuVaB5SUjW7jcfrglBIX1vUIoT7CLP3bBlIMeyEsIl2eFQNg== + dependencies: + "@babel/compat-data" "^7.18.8" + "@babel/helper-validator-option" "^7.18.6" + browserslist "^4.20.2" + semver "^6.3.0" + +"@babel/helper-environment-visitor@^7.18.9": + version "7.18.9" + resolved "https://registry.yarnpkg.com/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.9.tgz#0c0cee9b35d2ca190478756865bb3528422f51be" + integrity sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg== + +"@babel/helper-function-name@^7.18.9": + version "7.18.9" + resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.18.9.tgz#940e6084a55dee867d33b4e487da2676365e86b0" + integrity sha512-fJgWlZt7nxGksJS9a0XdSaI4XvpExnNIgRP+rVefWh5U7BL8pPuir6SJUmFKRfjWQ51OtWSzwOxhaH/EBWWc0A== + dependencies: + "@babel/template" "^7.18.6" + "@babel/types" "^7.18.9" + +"@babel/helper-hoist-variables@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.18.6.tgz#d4d2c8fb4baeaa5c68b99cc8245c56554f926678" + integrity sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q== + dependencies: + "@babel/types" "^7.18.6" + +"@babel/helper-module-imports@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.18.6.tgz#1e3ebdbbd08aad1437b428c50204db13c5a3ca6e" + integrity sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA== + dependencies: + "@babel/types" "^7.18.6" + +"@babel/helper-module-transforms@^7.18.9": + version "7.18.9" + resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.18.9.tgz#5a1079c005135ed627442df31a42887e80fcb712" + integrity sha512-KYNqY0ICwfv19b31XzvmI/mfcylOzbLtowkw+mfvGPAQ3kfCnMLYbED3YecL5tPd8nAYFQFAd6JHp2LxZk/J1g== + dependencies: + "@babel/helper-environment-visitor" "^7.18.9" + "@babel/helper-module-imports" "^7.18.6" + "@babel/helper-simple-access" "^7.18.6" + "@babel/helper-split-export-declaration" "^7.18.6" + "@babel/helper-validator-identifier" "^7.18.6" + "@babel/template" "^7.18.6" + "@babel/traverse" "^7.18.9" + "@babel/types" "^7.18.9" + +"@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.10.4", "@babel/helper-plugin-utils@^7.12.13", "@babel/helper-plugin-utils@^7.14.5", "@babel/helper-plugin-utils@^7.18.6", "@babel/helper-plugin-utils@^7.8.0": + version "7.18.9" + resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.18.9.tgz#4b8aea3b069d8cb8a72cdfe28ddf5ceca695ef2f" + integrity sha512-aBXPT3bmtLryXaoJLyYPXPlSD4p1ld9aYeR+sJNOZjJJGiOpb+fKfh3NkcCu7J54nUJwCERPBExCCpyCOHnu/w== + +"@babel/helper-simple-access@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.18.6.tgz#d6d8f51f4ac2978068df934b569f08f29788c7ea" + integrity sha512-iNpIgTgyAvDQpDj76POqg+YEt8fPxx3yaNBg3S30dxNKm2SWfYhD0TGrK/Eu9wHpUW63VQU894TsTg+GLbUa1g== + dependencies: + "@babel/types" "^7.18.6" + +"@babel/helper-split-export-declaration@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.18.6.tgz#7367949bc75b20c6d5a5d4a97bba2824ae8ef075" + integrity sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA== + dependencies: + "@babel/types" "^7.18.6" + +"@babel/helper-string-parser@^7.18.10": + version "7.18.10" + resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.18.10.tgz#181f22d28ebe1b3857fa575f5c290b1aaf659b56" + integrity sha512-XtIfWmeNY3i4t7t4D2t02q50HvqHybPqW2ki1kosnvWCwuCMeo81Jf0gwr85jy/neUdg5XDdeFE/80DXiO+njw== + +"@babel/helper-validator-identifier@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.18.6.tgz#9c97e30d31b2b8c72a1d08984f2ca9b574d7a076" + integrity sha512-MmetCkz9ej86nJQV+sFCxoGGrUbU3q02kgLciwkrt9QqEB7cP39oKEY0PakknEO0Gu20SskMRi+AYZ3b1TpN9g== + +"@babel/helper-validator-option@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.18.6.tgz#bf0d2b5a509b1f336099e4ff36e1a63aa5db4db8" + integrity sha512-XO7gESt5ouv/LRJdrVjkShckw6STTaB7l9BrpBaAHDeF5YZT+01PCwmR0SJHnkW6i8OwW/EVWRShfi4j2x+KQw== + +"@babel/helpers@^7.18.9": + version "7.18.9" + resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.18.9.tgz#4bef3b893f253a1eced04516824ede94dcfe7ff9" + integrity sha512-Jf5a+rbrLoR4eNdUmnFu8cN5eNJT6qdTdOg5IHIzq87WwyRw9PwguLFOWYgktN/60IP4fgDUawJvs7PjQIzELQ== + dependencies: + "@babel/template" "^7.18.6" + "@babel/traverse" "^7.18.9" + "@babel/types" "^7.18.9" + +"@babel/highlight@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.18.6.tgz#81158601e93e2563795adcbfbdf5d64be3f2ecdf" + integrity sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g== + dependencies: + "@babel/helper-validator-identifier" "^7.18.6" + chalk "^2.0.0" + js-tokens "^4.0.0" + +"@babel/parser@^7.1.0", "@babel/parser@^7.14.7", "@babel/parser@^7.18.10", "@babel/parser@^7.18.11": + version "7.18.11" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.18.11.tgz#68bb07ab3d380affa9a3f96728df07969645d2d9" + integrity sha512-9JKn5vN+hDt0Hdqn1PiJ2guflwP+B6Ga8qbDuoF0PzzVhrzsKIJo8yGqVk6CmMHiMei9w1C1Bp9IMJSIK+HPIQ== + +"@babel/plugin-syntax-async-generators@^7.8.4": + version "7.8.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz#a983fb1aeb2ec3f6ed042a210f640e90e786fe0d" + integrity sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-bigint@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz#4c9a6f669f5d0cdf1b90a1671e9a146be5300cea" + integrity sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-class-properties@^7.8.3": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz#b5c987274c4a3a82b89714796931a6b53544ae10" + integrity sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA== + dependencies: + "@babel/helper-plugin-utils" "^7.12.13" + +"@babel/plugin-syntax-import-meta@^7.8.3": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz#ee601348c370fa334d2207be158777496521fd51" + integrity sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + +"@babel/plugin-syntax-json-strings@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz#01ca21b668cd8218c9e640cb6dd88c5412b2c96a" + integrity sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-logical-assignment-operators@^7.8.3": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz#ca91ef46303530448b906652bac2e9fe9941f699" + integrity sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + +"@babel/plugin-syntax-nullish-coalescing-operator@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz#167ed70368886081f74b5c36c65a88c03b66d1a9" + integrity sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-numeric-separator@^7.8.3": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz#b9b070b3e33570cd9fd07ba7fa91c0dd37b9af97" + integrity sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + +"@babel/plugin-syntax-object-rest-spread@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz#60e225edcbd98a640332a2e72dd3e66f1af55871" + integrity sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-optional-catch-binding@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz#6111a265bcfb020eb9efd0fdfd7d26402b9ed6c1" + integrity sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-optional-chaining@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz#4f69c2ab95167e0180cd5336613f8c5788f7d48a" + integrity sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-top-level-await@^7.8.3": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz#c1cfdadc35a646240001f06138247b741c34d94c" + integrity sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw== + dependencies: + "@babel/helper-plugin-utils" "^7.14.5" + +"@babel/plugin-syntax-typescript@^7.7.2": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.18.6.tgz#1c09cd25795c7c2b8a4ba9ae49394576d4133285" + integrity sha512-mAWAuq4rvOepWCBid55JuRNvpTNf2UGVgoz4JV0fXEKolsVZDzsa4NqCef758WZJj/GDu0gVGItjKFiClTAmZA== + dependencies: + "@babel/helper-plugin-utils" "^7.18.6" + +"@babel/runtime@^7.18.3": + version "7.18.9" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.18.9.tgz#b4fcfce55db3d2e5e080d2490f608a3b9f407f4a" + integrity sha512-lkqXDcvlFT5rvEjiu6+QYO+1GXrEHRo2LOtS7E4GtX5ESIZOgepqsZBVIj6Pv+a6zqsya9VCgiK1KAK4BvJDAw== + dependencies: + regenerator-runtime "^0.13.4" + +"@babel/template@^7.18.10", "@babel/template@^7.18.6", "@babel/template@^7.3.3": + version "7.18.10" + resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.18.10.tgz#6f9134835970d1dbf0835c0d100c9f38de0c5e71" + integrity sha512-TI+rCtooWHr3QJ27kJxfjutghu44DLnasDMwpDqCXVTal9RLp3RSYNh4NdBrRP2cQAoG9A8juOQl6P6oZG4JxA== + dependencies: + "@babel/code-frame" "^7.18.6" + "@babel/parser" "^7.18.10" + "@babel/types" "^7.18.10" + +"@babel/traverse@^7.18.10", "@babel/traverse@^7.18.9", "@babel/traverse@^7.7.2": + version "7.18.11" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.18.11.tgz#3d51f2afbd83ecf9912bcbb5c4d94e3d2ddaa16f" + integrity sha512-TG9PiM2R/cWCAy6BPJKeHzNbu4lPzOSZpeMfeNErskGpTJx6trEvFaVCbDvpcxwy49BKWmEPwiW8mrysNiDvIQ== + dependencies: + "@babel/code-frame" "^7.18.6" + "@babel/generator" "^7.18.10" + "@babel/helper-environment-visitor" "^7.18.9" + "@babel/helper-function-name" "^7.18.9" + "@babel/helper-hoist-variables" "^7.18.6" + "@babel/helper-split-export-declaration" "^7.18.6" + "@babel/parser" "^7.18.11" + "@babel/types" "^7.18.10" + debug "^4.1.0" + globals "^11.1.0" + +"@babel/types@^7.0.0", "@babel/types@^7.18.10", "@babel/types@^7.18.6", "@babel/types@^7.18.9", "@babel/types@^7.3.0", "@babel/types@^7.3.3": + version "7.18.10" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.18.10.tgz#4908e81b6b339ca7c6b7a555a5fc29446f26dde6" + integrity sha512-MJvnbEiiNkpjo+LknnmRrqbY1GPUUggjv+wQVjetM/AONoupqRALB7I6jGqNUAZsKcRIEu2J6FRFvsczljjsaQ== + dependencies: + "@babel/helper-string-parser" "^7.18.10" + "@babel/helper-validator-identifier" "^7.18.6" + to-fast-properties "^2.0.0" + +"@bcoe/v8-coverage@^0.2.3": + version "0.2.3" + resolved "https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39" + integrity sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw== + +"@cosmjs/encoding@0.27.1": + version "0.27.1" + resolved "https://registry.yarnpkg.com/@cosmjs/encoding/-/encoding-0.27.1.tgz#3cd5bc0af743485eb2578cdb08cfa84c86d610e1" + integrity sha512-rayLsA0ojHeniaRfWWcqSsrE/T1rl1gl0OXVNtXlPwLJifKBeLEefGbOUiAQaT0wgJ8VNGBazVtAZBpJidfDhw== + dependencies: + base64-js "^1.3.0" + bech32 "^1.1.4" + readonly-date "^1.0.0" + +"@cosmjs/math@0.27.1": + version "0.27.1" + resolved "https://registry.yarnpkg.com/@cosmjs/math/-/math-0.27.1.tgz#be78857b008ffc6b1ed6fecaa1c4cd5bc38c07d7" + integrity sha512-cHWVjmfIjtRc7f80n7x+J5k8pe+vTVTQ0lA82tIxUgqUvgS6rogPP/TmGtTiZ4+NxWxd11DUISY6gVpr18/VNQ== + dependencies: + bn.js "^5.2.0" + +"@cspotcode/source-map-support@^0.8.0": + version "0.8.1" + resolved "https://registry.yarnpkg.com/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz#00629c35a688e05a88b1cda684fb9d5e73f000a1" + integrity sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw== + dependencies: + "@jridgewell/trace-mapping" "0.3.9" + +"@improbable-eng/grpc-web-node-http-transport@0.15.0": + version "0.15.0" + resolved "https://registry.yarnpkg.com/@improbable-eng/grpc-web-node-http-transport/-/grpc-web-node-http-transport-0.15.0.tgz#5a064472ef43489cbd075a91fb831c2abeb09d68" + integrity sha512-HLgJfVolGGpjc9DWPhmMmXJx8YGzkek7jcCFO1YYkSOoO81MWRZentPOd/JiKiZuU08wtc4BG+WNuGzsQB5jZA== + +"@improbable-eng/grpc-web@0.15.0": + version "0.15.0" + resolved "https://registry.yarnpkg.com/@improbable-eng/grpc-web/-/grpc-web-0.15.0.tgz#3e47e9fdd90381a74abd4b7d26e67422a2a04bef" + integrity sha512-ERft9/0/8CmYalqOVnJnpdDry28q+j+nAlFFARdjyxXDJ+Mhgv9+F600QC8BR9ygOfrXRlAk6CvST2j+JCpQPg== + dependencies: + browser-headers "^0.4.1" + +"@istanbuljs/load-nyc-config@^1.0.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz#fd3db1d59ecf7cf121e80650bb86712f9b55eced" + integrity sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ== + dependencies: + camelcase "^5.3.1" + find-up "^4.1.0" + get-package-type "^0.1.0" + js-yaml "^3.13.1" + resolve-from "^5.0.0" + +"@istanbuljs/schema@^0.1.2": + version "0.1.3" + resolved "https://registry.yarnpkg.com/@istanbuljs/schema/-/schema-0.1.3.tgz#e45e384e4b8ec16bce2fd903af78450f6bf7ec98" + integrity sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA== + +"@jest/console@^28.1.3": + version "28.1.3" + resolved "https://registry.yarnpkg.com/@jest/console/-/console-28.1.3.tgz#2030606ec03a18c31803b8a36382762e447655df" + integrity sha512-QPAkP5EwKdK/bxIr6C1I4Vs0rm2nHiANzj/Z5X2JQkrZo6IqvC4ldZ9K95tF0HdidhA8Bo6egxSzUFPYKcEXLw== + dependencies: + "@jest/types" "^28.1.3" + "@types/node" "*" + chalk "^4.0.0" + jest-message-util "^28.1.3" + jest-util "^28.1.3" + slash "^3.0.0" + +"@jest/core@^28.1.3": + version "28.1.3" + resolved "https://registry.yarnpkg.com/@jest/core/-/core-28.1.3.tgz#0ebf2bd39840f1233cd5f2d1e6fc8b71bd5a1ac7" + integrity sha512-CIKBrlaKOzA7YG19BEqCw3SLIsEwjZkeJzf5bdooVnW4bH5cktqe3JX+G2YV1aK5vP8N9na1IGWFzYaTp6k6NA== + dependencies: + "@jest/console" "^28.1.3" + "@jest/reporters" "^28.1.3" + "@jest/test-result" "^28.1.3" + "@jest/transform" "^28.1.3" + "@jest/types" "^28.1.3" + "@types/node" "*" + ansi-escapes "^4.2.1" + chalk "^4.0.0" + ci-info "^3.2.0" + exit "^0.1.2" + graceful-fs "^4.2.9" + jest-changed-files "^28.1.3" + jest-config "^28.1.3" + jest-haste-map "^28.1.3" + jest-message-util "^28.1.3" + jest-regex-util "^28.0.2" + jest-resolve "^28.1.3" + jest-resolve-dependencies "^28.1.3" + jest-runner "^28.1.3" + jest-runtime "^28.1.3" + jest-snapshot "^28.1.3" + jest-util "^28.1.3" + jest-validate "^28.1.3" + jest-watcher "^28.1.3" + micromatch "^4.0.4" + pretty-format "^28.1.3" + rimraf "^3.0.0" + slash "^3.0.0" + strip-ansi "^6.0.0" + +"@jest/environment@^28.1.3": + version "28.1.3" + resolved "https://registry.yarnpkg.com/@jest/environment/-/environment-28.1.3.tgz#abed43a6b040a4c24fdcb69eab1f97589b2d663e" + integrity sha512-1bf40cMFTEkKyEf585R9Iz1WayDjHoHqvts0XFYEqyKM3cFWDpeMoqKKTAF9LSYQModPUlh8FKptoM2YcMWAXA== + dependencies: + "@jest/fake-timers" "^28.1.3" + "@jest/types" "^28.1.3" + "@types/node" "*" + jest-mock "^28.1.3" + +"@jest/expect-utils@^28.1.3": + version "28.1.3" + resolved "https://registry.yarnpkg.com/@jest/expect-utils/-/expect-utils-28.1.3.tgz#58561ce5db7cd253a7edddbc051fb39dda50f525" + integrity sha512-wvbi9LUrHJLn3NlDW6wF2hvIMtd4JUl2QNVrjq+IBSHirgfrR3o9RnVtxzdEGO2n9JyIWwHnLfby5KzqBGg2YA== + dependencies: + jest-get-type "^28.0.2" + +"@jest/expect@^28.1.3": + version "28.1.3" + resolved "https://registry.yarnpkg.com/@jest/expect/-/expect-28.1.3.tgz#9ac57e1d4491baca550f6bdbd232487177ad6a72" + integrity sha512-lzc8CpUbSoE4dqT0U+g1qODQjBRHPpCPXissXD4mS9+sWQdmmpeJ9zSH1rS1HEkrsMN0fb7nKrJ9giAR1d3wBw== + dependencies: + expect "^28.1.3" + jest-snapshot "^28.1.3" + +"@jest/fake-timers@^28.1.3": + version "28.1.3" + resolved "https://registry.yarnpkg.com/@jest/fake-timers/-/fake-timers-28.1.3.tgz#230255b3ad0a3d4978f1d06f70685baea91c640e" + integrity sha512-D/wOkL2POHv52h+ok5Oj/1gOG9HSywdoPtFsRCUmlCILXNn5eIWmcnd3DIiWlJnpGvQtmajqBP95Ei0EimxfLw== + dependencies: + "@jest/types" "^28.1.3" + "@sinonjs/fake-timers" "^9.1.2" + "@types/node" "*" + jest-message-util "^28.1.3" + jest-mock "^28.1.3" + jest-util "^28.1.3" + +"@jest/globals@^28.1.3": + version "28.1.3" + resolved "https://registry.yarnpkg.com/@jest/globals/-/globals-28.1.3.tgz#a601d78ddc5fdef542728309894895b4a42dc333" + integrity sha512-XFU4P4phyryCXu1pbcqMO0GSQcYe1IsalYCDzRNyhetyeyxMcIxa11qPNDpVNLeretItNqEmYYQn1UYz/5x1NA== + dependencies: + "@jest/environment" "^28.1.3" + "@jest/expect" "^28.1.3" + "@jest/types" "^28.1.3" + +"@jest/reporters@^28.1.3": + version "28.1.3" + resolved "https://registry.yarnpkg.com/@jest/reporters/-/reporters-28.1.3.tgz#9adf6d265edafc5fc4a434cfb31e2df5a67a369a" + integrity sha512-JuAy7wkxQZVNU/V6g9xKzCGC5LVXx9FDcABKsSXp5MiKPEE2144a/vXTEDoyzjUpZKfVwp08Wqg5A4WfTMAzjg== + dependencies: + "@bcoe/v8-coverage" "^0.2.3" + "@jest/console" "^28.1.3" + "@jest/test-result" "^28.1.3" + "@jest/transform" "^28.1.3" + "@jest/types" "^28.1.3" + "@jridgewell/trace-mapping" "^0.3.13" + "@types/node" "*" + chalk "^4.0.0" + collect-v8-coverage "^1.0.0" + exit "^0.1.2" + glob "^7.1.3" + graceful-fs "^4.2.9" + istanbul-lib-coverage "^3.0.0" + istanbul-lib-instrument "^5.1.0" + istanbul-lib-report "^3.0.0" + istanbul-lib-source-maps "^4.0.0" + istanbul-reports "^3.1.3" + jest-message-util "^28.1.3" + jest-util "^28.1.3" + jest-worker "^28.1.3" + slash "^3.0.0" + string-length "^4.0.1" + strip-ansi "^6.0.0" + terminal-link "^2.0.0" + v8-to-istanbul "^9.0.1" + +"@jest/schemas@^28.1.3": + version "28.1.3" + resolved "https://registry.yarnpkg.com/@jest/schemas/-/schemas-28.1.3.tgz#ad8b86a66f11f33619e3d7e1dcddd7f2d40ff905" + integrity sha512-/l/VWsdt/aBXgjshLWOFyFt3IVdYypu5y2Wn2rOO1un6nkqIn8SLXzgIMYXFyYsRWDyF5EthmKJMIdJvk08grg== + dependencies: + "@sinclair/typebox" "^0.24.1" + +"@jest/source-map@^28.1.2": + version "28.1.2" + resolved "https://registry.yarnpkg.com/@jest/source-map/-/source-map-28.1.2.tgz#7fe832b172b497d6663cdff6c13b0a920e139e24" + integrity sha512-cV8Lx3BeStJb8ipPHnqVw/IM2VCMWO3crWZzYodSIkxXnRcXJipCdx1JCK0K5MsJJouZQTH73mzf4vgxRaH9ww== + dependencies: + "@jridgewell/trace-mapping" "^0.3.13" + callsites "^3.0.0" + graceful-fs "^4.2.9" + +"@jest/test-result@^28.1.3": + version "28.1.3" + resolved "https://registry.yarnpkg.com/@jest/test-result/-/test-result-28.1.3.tgz#5eae945fd9f4b8fcfce74d239e6f725b6bf076c5" + integrity sha512-kZAkxnSE+FqE8YjW8gNuoVkkC9I7S1qmenl8sGcDOLropASP+BkcGKwhXoyqQuGOGeYY0y/ixjrd/iERpEXHNg== + dependencies: + "@jest/console" "^28.1.3" + "@jest/types" "^28.1.3" + "@types/istanbul-lib-coverage" "^2.0.0" + collect-v8-coverage "^1.0.0" + +"@jest/test-sequencer@^28.1.3": + version "28.1.3" + resolved "https://registry.yarnpkg.com/@jest/test-sequencer/-/test-sequencer-28.1.3.tgz#9d0c283d906ac599c74bde464bc0d7e6a82886c3" + integrity sha512-NIMPEqqa59MWnDi1kvXXpYbqsfQmSJsIbnd85mdVGkiDfQ9WQQTXOLsvISUfonmnBT+w85WEgneCigEEdHDFxw== + dependencies: + "@jest/test-result" "^28.1.3" + graceful-fs "^4.2.9" + jest-haste-map "^28.1.3" + slash "^3.0.0" + +"@jest/transform@^28.1.3": + version "28.1.3" + resolved "https://registry.yarnpkg.com/@jest/transform/-/transform-28.1.3.tgz#59d8098e50ab07950e0f2fc0fc7ec462371281b0" + integrity sha512-u5dT5di+oFI6hfcLOHGTAfmUxFRrjK+vnaP0kkVow9Md/M7V/MxqQMOz/VV25UZO8pzeA9PjfTpOu6BDuwSPQA== + dependencies: + "@babel/core" "^7.11.6" + "@jest/types" "^28.1.3" + "@jridgewell/trace-mapping" "^0.3.13" + babel-plugin-istanbul "^6.1.1" + chalk "^4.0.0" + convert-source-map "^1.4.0" + fast-json-stable-stringify "^2.0.0" + graceful-fs "^4.2.9" + jest-haste-map "^28.1.3" + jest-regex-util "^28.0.2" + jest-util "^28.1.3" + micromatch "^4.0.4" + pirates "^4.0.4" + slash "^3.0.0" + write-file-atomic "^4.0.1" + +"@jest/types@^28.1.3": + version "28.1.3" + resolved "https://registry.yarnpkg.com/@jest/types/-/types-28.1.3.tgz#b05de80996ff12512bc5ceb1d208285a7d11748b" + integrity sha512-RyjiyMUZrKz/c+zlMFO1pm70DcIlST8AeWTkoUdZevew44wcNZQHsEVOiCVtgVnlFFD82FPaXycys58cf2muVQ== + dependencies: + "@jest/schemas" "^28.1.3" + "@types/istanbul-lib-coverage" "^2.0.0" + "@types/istanbul-reports" "^3.0.0" + "@types/node" "*" + "@types/yargs" "^17.0.8" + chalk "^4.0.0" + +"@jridgewell/gen-mapping@^0.1.0": + version "0.1.1" + resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.1.1.tgz#e5d2e450306a9491e3bd77e323e38d7aff315996" + integrity sha512-sQXCasFk+U8lWYEe66WxRDOE9PjVz4vSM51fTu3Hw+ClTpUSQb718772vH3pyS5pShp6lvQM7SxgIDXXXmOX7w== + dependencies: + "@jridgewell/set-array" "^1.0.0" + "@jridgewell/sourcemap-codec" "^1.4.10" + +"@jridgewell/gen-mapping@^0.3.2": + version "0.3.2" + resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz#c1aedc61e853f2bb9f5dfe6d4442d3b565b253b9" + integrity sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A== + dependencies: + "@jridgewell/set-array" "^1.0.1" + "@jridgewell/sourcemap-codec" "^1.4.10" + "@jridgewell/trace-mapping" "^0.3.9" + +"@jridgewell/resolve-uri@^3.0.3": + version "3.1.0" + resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz#2203b118c157721addfe69d47b70465463066d78" + integrity sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w== + +"@jridgewell/set-array@^1.0.0", "@jridgewell/set-array@^1.0.1": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@jridgewell/set-array/-/set-array-1.1.2.tgz#7c6cf998d6d20b914c0a55a91ae928ff25965e72" + integrity sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw== + +"@jridgewell/sourcemap-codec@^1.4.10": + version "1.4.14" + resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz#add4c98d341472a289190b424efbdb096991bb24" + integrity sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw== + +"@jridgewell/trace-mapping@0.3.9": + version "0.3.9" + resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz#6534fd5933a53ba7cbf3a17615e273a0d1273ff9" + integrity sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ== + dependencies: + "@jridgewell/resolve-uri" "^3.0.3" + "@jridgewell/sourcemap-codec" "^1.4.10" + +"@jridgewell/trace-mapping@^0.3.12", "@jridgewell/trace-mapping@^0.3.13", "@jridgewell/trace-mapping@^0.3.9": + version "0.3.15" + resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.15.tgz#aba35c48a38d3fd84b37e66c9c0423f9744f9774" + integrity sha512-oWZNOULl+UbhsgB51uuZzglikfIKSUBO/M9W2OfEjn7cmqoAiCgmv9lyACTUacZwBz0ITnJ2NqjU8Tx0DHL88g== + dependencies: + "@jridgewell/resolve-uri" "^3.0.3" + "@jridgewell/sourcemap-codec" "^1.4.10" + +"@noble/hashes@1.0.0": + version "1.0.0" + resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.0.0.tgz#d5e38bfbdaba174805a4e649f13be9a9ed3351ae" + integrity sha512-DZVbtY62kc3kkBtMHqwCOfXrT/hnoORy5BJ4+HU1IR59X0KWAOqsfzQPcUl/lQLlG7qXbe/fZ3r/emxtAl+sqg== + +"@noble/hashes@1.1.2": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.1.2.tgz#e9e035b9b166ca0af657a7848eb2718f0f22f183" + integrity sha512-KYRCASVTv6aeUi1tsF8/vpyR7zpfs3FUzy2Jqm+MU+LmUKhQ0y2FpfwqkCcxSg2ua4GALJd8k2R76WxwZGbQpA== + +"@noble/secp256k1@1.6.3": + version "1.6.3" + resolved "https://registry.yarnpkg.com/@noble/secp256k1/-/secp256k1-1.6.3.tgz#7eed12d9f4404b416999d0c87686836c4c5c9b94" + integrity sha512-T04e4iTurVy7I8Sw4+c5OSN9/RkPlo1uKxAomtxQNLq8j1uPAqnsqG1bqvY3Jv7c13gyr6dui0zmh/I3+f/JaQ== + +"@osmonauts/helpers@0.3.8": + version "0.3.8" + resolved "https://registry.yarnpkg.com/@osmonauts/helpers/-/helpers-0.3.8.tgz#77a57cdd20922cd477f21de9662a403620e2c848" + integrity sha512-6xM/DGjLctziRVT2DuR7/MQ/HqfHAcqOaGF4z77Jeh3RWQ78zWiaRVxBefRQdKaqrh5LhXL6VebUdiy9IGwTTA== + dependencies: + "@babel/runtime" "^7.18.3" + long "^5.2.0" + protobufjs "^6.11.3" + +"@protobufjs/aspromise@^1.1.1", "@protobufjs/aspromise@^1.1.2": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@protobufjs/aspromise/-/aspromise-1.1.2.tgz#9b8b0cc663d669a7d8f6f5d0893a14d348f30fbf" + integrity sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ== + +"@protobufjs/base64@^1.1.2": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@protobufjs/base64/-/base64-1.1.2.tgz#4c85730e59b9a1f1f349047dbf24296034bb2735" + integrity sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg== + +"@protobufjs/codegen@^2.0.4": + version "2.0.4" + resolved "https://registry.yarnpkg.com/@protobufjs/codegen/-/codegen-2.0.4.tgz#7ef37f0d010fb028ad1ad59722e506d9262815cb" + integrity sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg== + +"@protobufjs/eventemitter@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz#355cbc98bafad5978f9ed095f397621f1d066b70" + integrity sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q== + +"@protobufjs/fetch@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@protobufjs/fetch/-/fetch-1.1.0.tgz#ba99fb598614af65700c1619ff06d454b0d84c45" + integrity sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ== + dependencies: + "@protobufjs/aspromise" "^1.1.1" + "@protobufjs/inquire" "^1.1.0" + +"@protobufjs/float@^1.0.2": + version "1.0.2" + resolved "https://registry.yarnpkg.com/@protobufjs/float/-/float-1.0.2.tgz#5e9e1abdcb73fc0a7cb8b291df78c8cbd97b87d1" + integrity sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ== + +"@protobufjs/inquire@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@protobufjs/inquire/-/inquire-1.1.0.tgz#ff200e3e7cf2429e2dcafc1140828e8cc638f089" + integrity sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q== + +"@protobufjs/path@^1.1.2": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@protobufjs/path/-/path-1.1.2.tgz#6cc2b20c5c9ad6ad0dccfd21ca7673d8d7fbf68d" + integrity sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA== + +"@protobufjs/pool@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@protobufjs/pool/-/pool-1.1.0.tgz#09fd15f2d6d3abfa9b65bc366506d6ad7846ff54" + integrity sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw== + +"@protobufjs/utf8@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@protobufjs/utf8/-/utf8-1.1.0.tgz#a777360b5b39a1a2e5106f8e858f2fd2d060c570" + integrity sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw== + +"@sinclair/typebox@^0.24.1": + version "0.24.28" + resolved "https://registry.yarnpkg.com/@sinclair/typebox/-/typebox-0.24.28.tgz#15aa0b416f82c268b1573ab653e4413c965fe794" + integrity sha512-dgJd3HLOkLmz4Bw50eZx/zJwtBq65nms3N9VBYu5LTjJ883oBFkTyXRlCB/ZGGwqYpJJHA5zW2Ibhl5ngITfow== + +"@sinonjs/commons@^1.7.0": + version "1.8.3" + resolved "https://registry.yarnpkg.com/@sinonjs/commons/-/commons-1.8.3.tgz#3802ddd21a50a949b6721ddd72da36e67e7f1b2d" + integrity sha512-xkNcLAn/wZaX14RPlwizcKicDk9G3F8m2nU3L7Ukm5zBgTwiT0wsoFAHx9Jq56fJA1z/7uKGtCRu16sOUCLIHQ== + dependencies: + type-detect "4.0.8" + +"@sinonjs/fake-timers@^9.1.2": + version "9.1.2" + resolved "https://registry.yarnpkg.com/@sinonjs/fake-timers/-/fake-timers-9.1.2.tgz#4eaab737fab77332ab132d396a3c0d364bd0ea8c" + integrity sha512-BPS4ynJW/o92PUR4wgriz2Ud5gpST5vz6GQfMixEDK0Z8ZCUv2M7SkBLykH56T++Xs+8ln9zTGbOvNGIe02/jw== + dependencies: + "@sinonjs/commons" "^1.7.0" + +"@tsconfig/node10@^1.0.7": + version "1.0.9" + resolved "https://registry.yarnpkg.com/@tsconfig/node10/-/node10-1.0.9.tgz#df4907fc07a886922637b15e02d4cebc4c0021b2" + integrity sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA== + +"@tsconfig/node12@^1.0.7": + version "1.0.11" + resolved "https://registry.yarnpkg.com/@tsconfig/node12/-/node12-1.0.11.tgz#ee3def1f27d9ed66dac6e46a295cffb0152e058d" + integrity sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag== + +"@tsconfig/node14@^1.0.0": + version "1.0.3" + resolved "https://registry.yarnpkg.com/@tsconfig/node14/-/node14-1.0.3.tgz#e4386316284f00b98435bf40f72f75a09dabf6c1" + integrity sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow== + +"@tsconfig/node16@^1.0.2": + version "1.0.3" + resolved "https://registry.yarnpkg.com/@tsconfig/node16/-/node16-1.0.3.tgz#472eaab5f15c1ffdd7f8628bd4c4f753995ec79e" + integrity sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ== + +"@types/babel__core@^7.1.14": + version "7.1.19" + resolved "https://registry.yarnpkg.com/@types/babel__core/-/babel__core-7.1.19.tgz#7b497495b7d1b4812bdb9d02804d0576f43ee460" + integrity sha512-WEOTgRsbYkvA/KCsDwVEGkd7WAr1e3g31VHQ8zy5gul/V1qKullU/BU5I68X5v7V3GnB9eotmom4v5a5gjxorw== + dependencies: + "@babel/parser" "^7.1.0" + "@babel/types" "^7.0.0" + "@types/babel__generator" "*" + "@types/babel__template" "*" + "@types/babel__traverse" "*" + +"@types/babel__generator@*": + version "7.6.4" + resolved "https://registry.yarnpkg.com/@types/babel__generator/-/babel__generator-7.6.4.tgz#1f20ce4c5b1990b37900b63f050182d28c2439b7" + integrity sha512-tFkciB9j2K755yrTALxD44McOrk+gfpIpvC3sxHjRawj6PfnQxrse4Clq5y/Rq+G3mrBurMax/lG8Qn2t9mSsg== + dependencies: + "@babel/types" "^7.0.0" + +"@types/babel__template@*": + version "7.4.1" + resolved "https://registry.yarnpkg.com/@types/babel__template/-/babel__template-7.4.1.tgz#3d1a48fd9d6c0edfd56f2ff578daed48f36c8969" + integrity sha512-azBFKemX6kMg5Io+/rdGT0dkGreboUVR0Cdm3fz9QJWpaQGJRQXl7C+6hOTCZcMll7KFyEQpgbYI2lHdsS4U7g== + dependencies: + "@babel/parser" "^7.1.0" + "@babel/types" "^7.0.0" + +"@types/babel__traverse@*", "@types/babel__traverse@^7.0.6": + version "7.18.0" + resolved "https://registry.yarnpkg.com/@types/babel__traverse/-/babel__traverse-7.18.0.tgz#8134fd78cb39567465be65b9fdc16d378095f41f" + integrity sha512-v4Vwdko+pgymgS+A2UIaJru93zQd85vIGWObM5ekZNdXCKtDYqATlEYnWgfo86Q6I1Lh0oXnksDnMU1cwmlPDw== + dependencies: + "@babel/types" "^7.3.0" + +"@types/graceful-fs@^4.1.3": + version "4.1.5" + resolved "https://registry.yarnpkg.com/@types/graceful-fs/-/graceful-fs-4.1.5.tgz#21ffba0d98da4350db64891f92a9e5db3cdb4e15" + integrity sha512-anKkLmZZ+xm4p8JWBf4hElkM4XR+EZeA2M9BAkkTldmcyDY4mbdIJnRghDJH3Ov5ooY7/UAoENtmdMSkaAd7Cw== + dependencies: + "@types/node" "*" + +"@types/istanbul-lib-coverage@*", "@types/istanbul-lib-coverage@^2.0.0", "@types/istanbul-lib-coverage@^2.0.1": + version "2.0.4" + resolved "https://registry.yarnpkg.com/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.4.tgz#8467d4b3c087805d63580480890791277ce35c44" + integrity sha512-z/QT1XN4K4KYuslS23k62yDIDLwLFkzxOuMplDtObz0+y7VqJCaO2o+SPwHCvLFZh7xazvvoor2tA/hPz9ee7g== + +"@types/istanbul-lib-report@*": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz#c14c24f18ea8190c118ee7562b7ff99a36552686" + integrity sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg== + dependencies: + "@types/istanbul-lib-coverage" "*" + +"@types/istanbul-reports@^3.0.0": + version "3.0.1" + resolved "https://registry.yarnpkg.com/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz#9153fe98bba2bd565a63add9436d6f0d7f8468ff" + integrity sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw== + dependencies: + "@types/istanbul-lib-report" "*" + +"@types/jest@28.1.7": + version "28.1.7" + resolved "https://registry.yarnpkg.com/@types/jest/-/jest-28.1.7.tgz#a680c5d05b69634c2d54a63cb106d7fb1adaba16" + integrity sha512-acDN4VHD40V24tgu0iC44jchXavRNVFXQ/E6Z5XNsswgoSO/4NgsXoEYmPUGookKldlZQyIpmrEXsHI9cA3ZTA== + dependencies: + expect "^28.0.0" + pretty-format "^28.0.0" + +"@types/long@^4.0.1": + version "4.0.2" + resolved "https://registry.yarnpkg.com/@types/long/-/long-4.0.2.tgz#b74129719fc8d11c01868010082d483b7545591a" + integrity sha512-MqTGEo5bj5t157U6fA/BiDynNkn0YknVdh48CMPkTSpFTVmvao5UQmm7uEF6xBEo7qIMAlY/JSleYaE6VOdpaA== + +"@types/node@*", "@types/node@18.7.9", "@types/node@>=13.7.0": + version "18.7.9" + resolved "https://registry.yarnpkg.com/@types/node/-/node-18.7.9.tgz#180bfc495c91dc62573967edf047e15dbdce1491" + integrity sha512-0N5Y1XAdcl865nDdjbO0m3T6FdmQ4ijE89/urOHLREyTXbpMWbSafx9y7XIsgWGtwUP2iYTinLyyW3FatAxBLQ== + +"@types/node@10.12.18": + version "10.12.18" + resolved "https://registry.yarnpkg.com/@types/node/-/node-10.12.18.tgz#1d3ca764718915584fcd9f6344621b7672665c67" + integrity sha512-fh+pAqt4xRzPfqA6eh3Z2y6fyZavRIumvjhaCL753+TVkGKGhpPeyrJG2JftD0T9q4GF00KjefsQ+PQNDdWQaQ== + +"@types/node@11.11.6": + version "11.11.6" + resolved "https://registry.yarnpkg.com/@types/node/-/node-11.11.6.tgz#df929d1bb2eee5afdda598a41930fe50b43eaa6a" + integrity sha512-Exw4yUWMBXM3X+8oqzJNRqZSwUAaS4+7NdvHqQuFi/d+synz++xmX3QIf+BFqneW8N31R8Ky+sikfZUXq07ggQ== + +"@types/prettier@^2.1.5": + version "2.7.0" + resolved "https://registry.yarnpkg.com/@types/prettier/-/prettier-2.7.0.tgz#ea03e9f0376a4446f44797ca19d9c46c36e352dc" + integrity sha512-RI1L7N4JnW5gQw2spvL7Sllfuf1SaHdrZpCHiBlCXjIlufi1SMNnbu2teze3/QE67Fg2tBlH7W+mi4hVNk4p0A== + +"@types/stack-utils@^2.0.0": + version "2.0.1" + resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-2.0.1.tgz#20f18294f797f2209b5f65c8e3b5c8e8261d127c" + integrity sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw== + +"@types/yargs-parser@*": + version "21.0.0" + resolved "https://registry.yarnpkg.com/@types/yargs-parser/-/yargs-parser-21.0.0.tgz#0c60e537fa790f5f9472ed2776c2b71ec117351b" + integrity sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA== + +"@types/yargs@^17.0.8": + version "17.0.11" + resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-17.0.11.tgz#5e10ca33e219807c0eee0f08b5efcba9b6a42c06" + integrity sha512-aB4y9UDUXTSMxmM4MH+YnuR0g5Cph3FLQBoWoMB21DSvFVAxRVEHEMx3TLh+zUZYMCQtKiqazz0Q4Rre31f/OA== + dependencies: + "@types/yargs-parser" "*" + +acorn-walk@^8.1.1: + version "8.2.0" + resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-8.2.0.tgz#741210f2e2426454508853a2f44d0ab83b7f69c1" + integrity sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA== + +acorn@^8.4.1: + version "8.8.0" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.8.0.tgz#88c0187620435c7f6015803f5539dae05a9dbea8" + integrity sha512-QOxyigPVrpZ2GXT+PFyZTl6TtOFc5egxHIP9IlQ+RbupQuX4RkT/Bee4/kQuC02Xkzg84JcT7oLYtDIQxp+v7w== + +ansi-escapes@^4.2.1: + version "4.3.2" + resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-4.3.2.tgz#6b2291d1db7d98b6521d5f1efa42d0f3a9feb65e" + integrity sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ== + dependencies: + type-fest "^0.21.3" + +ansi-regex@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" + integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== + +ansi-styles@^3.2.1: + version "3.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" + integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== + dependencies: + color-convert "^1.9.0" + +ansi-styles@^4.0.0, ansi-styles@^4.1.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937" + integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== + dependencies: + color-convert "^2.0.1" + +ansi-styles@^5.0.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-5.2.0.tgz#07449690ad45777d1924ac2abb2fc8895dba836b" + integrity sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA== + +anymatch@^3.0.3: + version "3.1.2" + resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.2.tgz#c0557c096af32f106198f4f4e2a383537e378716" + integrity sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg== + dependencies: + normalize-path "^3.0.0" + picomatch "^2.0.4" + +arg@^4.1.0: + version "4.1.3" + resolved "https://registry.yarnpkg.com/arg/-/arg-4.1.3.tgz#269fc7ad5b8e42cb63c896d5666017261c144089" + integrity sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA== + +argparse@^1.0.7: + version "1.0.10" + resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" + integrity sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg== + dependencies: + sprintf-js "~1.0.2" + +babel-jest@^28.1.3: + version "28.1.3" + resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-28.1.3.tgz#c1187258197c099072156a0a121c11ee1e3917d5" + integrity sha512-epUaPOEWMk3cWX0M/sPvCHHCe9fMFAa/9hXEgKP8nFfNl/jlGkE9ucq9NqkZGXLDduCJYS0UvSlPUwC0S+rH6Q== + dependencies: + "@jest/transform" "^28.1.3" + "@types/babel__core" "^7.1.14" + babel-plugin-istanbul "^6.1.1" + babel-preset-jest "^28.1.3" + chalk "^4.0.0" + graceful-fs "^4.2.9" + slash "^3.0.0" + +babel-plugin-istanbul@^6.1.1: + version "6.1.1" + resolved "https://registry.yarnpkg.com/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz#fa88ec59232fd9b4e36dbbc540a8ec9a9b47da73" + integrity sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + "@istanbuljs/load-nyc-config" "^1.0.0" + "@istanbuljs/schema" "^0.1.2" + istanbul-lib-instrument "^5.0.4" + test-exclude "^6.0.0" + +babel-plugin-jest-hoist@^28.1.3: + version "28.1.3" + resolved "https://registry.yarnpkg.com/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-28.1.3.tgz#1952c4d0ea50f2d6d794353762278d1d8cca3fbe" + integrity sha512-Ys3tUKAmfnkRUpPdpa98eYrAR0nV+sSFUZZEGuQ2EbFd1y4SOLtD5QDNHAq+bb9a+bbXvYQC4b+ID/THIMcU6Q== + dependencies: + "@babel/template" "^7.3.3" + "@babel/types" "^7.3.3" + "@types/babel__core" "^7.1.14" + "@types/babel__traverse" "^7.0.6" + +babel-preset-current-node-syntax@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.1.tgz#b4399239b89b2a011f9ddbe3e4f401fc40cff73b" + integrity sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ== + dependencies: + "@babel/plugin-syntax-async-generators" "^7.8.4" + "@babel/plugin-syntax-bigint" "^7.8.3" + "@babel/plugin-syntax-class-properties" "^7.8.3" + "@babel/plugin-syntax-import-meta" "^7.8.3" + "@babel/plugin-syntax-json-strings" "^7.8.3" + "@babel/plugin-syntax-logical-assignment-operators" "^7.8.3" + "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.3" + "@babel/plugin-syntax-numeric-separator" "^7.8.3" + "@babel/plugin-syntax-object-rest-spread" "^7.8.3" + "@babel/plugin-syntax-optional-catch-binding" "^7.8.3" + "@babel/plugin-syntax-optional-chaining" "^7.8.3" + "@babel/plugin-syntax-top-level-await" "^7.8.3" + +babel-preset-jest@^28.1.3: + version "28.1.3" + resolved "https://registry.yarnpkg.com/babel-preset-jest/-/babel-preset-jest-28.1.3.tgz#5dfc20b99abed5db994406c2b9ab94c73aaa419d" + integrity sha512-L+fupJvlWAHbQfn74coNX3zf60LXMJsezNvvx8eIh7iOR1luJ1poxYgQk1F8PYtNq/6QODDHCqsSnTFSWC491A== + dependencies: + babel-plugin-jest-hoist "^28.1.3" + babel-preset-current-node-syntax "^1.0.0" + +balanced-match@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" + integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== + +base-x@^3.0.2: + version "3.0.9" + resolved "https://registry.yarnpkg.com/base-x/-/base-x-3.0.9.tgz#6349aaabb58526332de9f60995e548a53fe21320" + integrity sha512-H7JU6iBHTal1gp56aKoaa//YUxEaAOUiydvrV/pILqIHXTtqxSkATOnDA2u+jZ/61sD+L/412+7kzXRtWukhpQ== + dependencies: + safe-buffer "^5.0.1" + +base64-js@^1.3.0: + version "1.5.1" + resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a" + integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== + +bech32@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/bech32/-/bech32-2.0.0.tgz#078d3686535075c8c79709f054b1b226a133b355" + integrity sha512-LcknSilhIGatDAsY1ak2I8VtGaHNhgMSYVxFrGLXv+xLHytaKZKcaUJJUE7qmBr7h33o5YQwP55pMI0xmkpJwg== + +bech32@^1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/bech32/-/bech32-1.1.4.tgz#e38c9f37bf179b8eb16ae3a772b40c356d4832e9" + integrity sha512-s0IrSOzLlbvX7yp4WBfPITzpAU8sqQcpsmwXDiKwrG4r491vwCO/XpejasRNl0piBMe/DvP4Tz0mIS/X1DPJBQ== + +bignumber.js@9.0.2: + version "9.0.2" + resolved "https://registry.yarnpkg.com/bignumber.js/-/bignumber.js-9.0.2.tgz#71c6c6bed38de64e24a65ebe16cfcf23ae693673" + integrity sha512-GAcQvbpsM0pUb0zw1EI0KhQEZ+lRwR5fYaAp3vPOYuP7aDvGy6cVN6XHLauvF8SOga2y0dcLcjt3iQDTSEliyw== + +bindings@^1.3.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/bindings/-/bindings-1.5.0.tgz#10353c9e945334bc0511a6d90b38fbc7c9c504df" + integrity sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ== + dependencies: + file-uri-to-path "1.0.0" + +bip32@2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/bip32/-/bip32-2.0.6.tgz#6a81d9f98c4cd57d05150c60d8f9e75121635134" + integrity sha512-HpV5OMLLGTjSVblmrtYRfFFKuQB+GArM0+XP8HGWfJ5vxYBqo+DesvJwOdC2WJ3bCkZShGf0QIfoIpeomVzVdA== + dependencies: + "@types/node" "10.12.18" + bs58check "^2.1.1" + create-hash "^1.2.0" + create-hmac "^1.1.7" + tiny-secp256k1 "^1.1.3" + typeforce "^1.11.5" + wif "^2.0.6" + +bip39@3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/bip39/-/bip39-3.0.4.tgz#5b11fed966840b5e1b8539f0f54ab6392969b2a0" + integrity sha512-YZKQlb752TrUWqHWj7XAwCSjYEgGAk+/Aas3V7NyjQeZYsztO8JnQUaCWhcnL4T+jL8nvB8typ2jRPzTlgugNw== + dependencies: + "@types/node" "11.11.6" + create-hash "^1.1.0" + pbkdf2 "^3.0.9" + randombytes "^2.0.1" + +bn.js@^4.11.8, bn.js@^4.11.9: + version "4.12.0" + resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.12.0.tgz#775b3f278efbb9718eec7361f483fb36fbbfea88" + integrity sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA== + +bn.js@^5.2.0: + version "5.2.1" + resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-5.2.1.tgz#0bc527a6a0d18d0aa8d5b0538ce4a77dccfa7b70" + integrity sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ== + +brace-expansion@^1.1.7: + version "1.1.11" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" + integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== + dependencies: + balanced-match "^1.0.0" + concat-map "0.0.1" + +braces@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" + integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== + dependencies: + fill-range "^7.0.1" + +brorand@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/brorand/-/brorand-1.1.0.tgz#12c25efe40a45e3c323eb8675a0a0ce57b22371f" + integrity sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w== + +browser-headers@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/browser-headers/-/browser-headers-0.4.1.tgz#4308a7ad3b240f4203dbb45acedb38dc2d65dd02" + integrity sha512-CA9hsySZVo9371qEHjHZtYxV2cFtVj5Wj/ZHi8ooEsrtm4vOnl9Y9HmyYWk9q+05d7K3rdoAE0j3MVEFVvtQtg== + +browserslist@^4.20.2: + version "4.21.3" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.21.3.tgz#5df277694eb3c48bc5c4b05af3e8b7e09c5a6d1a" + integrity sha512-898rgRXLAyRkM1GryrrBHGkqA5hlpkV5MhtZwg9QXeiyLUYs2k00Un05aX5l2/yJIOObYKOpS2JNo8nJDE7fWQ== + dependencies: + caniuse-lite "^1.0.30001370" + electron-to-chromium "^1.4.202" + node-releases "^2.0.6" + update-browserslist-db "^1.0.5" + +bs-logger@0.x: + version "0.2.6" + resolved "https://registry.yarnpkg.com/bs-logger/-/bs-logger-0.2.6.tgz#eb7d365307a72cf974cc6cda76b68354ad336bd8" + integrity sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog== + dependencies: + fast-json-stable-stringify "2.x" + +bs58@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/bs58/-/bs58-4.0.1.tgz#be161e76c354f6f788ae4071f63f34e8c4f0a42a" + integrity sha512-Ok3Wdf5vOIlBrgCvTq96gBkJw+JUEzdBgyaza5HLtPm7yTHkjRy8+JzNyHF7BHa0bNWOQIp3m5YF0nnFcOIKLw== + dependencies: + base-x "^3.0.2" + +bs58check@<3.0.0, bs58check@^2.1.1: + version "2.1.2" + resolved "https://registry.yarnpkg.com/bs58check/-/bs58check-2.1.2.tgz#53b018291228d82a5aa08e7d796fdafda54aebfc" + integrity sha512-0TS1jicxdU09dwJMNZtVAfzPi6Q6QeN0pM1Fkzrjn+XYHvzMKPU3pHVpva+769iNVSfIYWf7LJ6WR+BuuMf8cA== + dependencies: + bs58 "^4.0.0" + create-hash "^1.1.0" + safe-buffer "^5.1.2" + +bser@2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/bser/-/bser-2.1.1.tgz#e6787da20ece9d07998533cfd9de6f5c38f4bc05" + integrity sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ== + dependencies: + node-int64 "^0.4.0" + +buffer-from@^1.0.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5" + integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ== + +callsites@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" + integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ== + +camelcase@^5.3.1: + version "5.3.1" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320" + integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg== + +camelcase@^6.2.0: + version "6.3.0" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.3.0.tgz#5685b95eb209ac9c0c177467778c9c84df58ba9a" + integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA== + +caniuse-lite@^1.0.30001370: + version "1.0.30001381" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001381.tgz#e62955310e6e69cdf4b40bc5bc0895aa24bc4b8b" + integrity sha512-fEnkDOKpvp6qc+olg7+NzE1SqyfiyKf4uci7fAU38M3zxs0YOyKOxW/nMZ2l9sJbt7KZHcDIxUnbI0Iime7V4w== + +chalk@^2.0.0: + version "2.4.2" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" + integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== + dependencies: + ansi-styles "^3.2.1" + escape-string-regexp "^1.0.5" + supports-color "^5.3.0" + +chalk@^4.0.0: + version "4.1.2" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" + integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== + dependencies: + ansi-styles "^4.1.0" + supports-color "^7.1.0" + +char-regex@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/char-regex/-/char-regex-1.0.2.tgz#d744358226217f981ed58f479b1d6bcc29545dcf" + integrity sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw== + +ci-info@^3.2.0: + version "3.3.2" + resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-3.3.2.tgz#6d2967ffa407466481c6c90b6e16b3098f080128" + integrity sha512-xmDt/QIAdeZ9+nfdPsaBCpMvHNLFiLdjj59qjqn+6iPe6YmHGQ35sBnQ8uslRBXFmXkiZQOJRjvQeoGppoTjjg== + +cipher-base@^1.0.1, cipher-base@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/cipher-base/-/cipher-base-1.0.4.tgz#8760e4ecc272f4c363532f926d874aae2c1397de" + integrity sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q== + dependencies: + inherits "^2.0.1" + safe-buffer "^5.0.1" + +cjs-module-lexer@^1.0.0: + version "1.2.2" + resolved "https://registry.yarnpkg.com/cjs-module-lexer/-/cjs-module-lexer-1.2.2.tgz#9f84ba3244a512f3a54e5277e8eef4c489864e40" + integrity sha512-cOU9usZw8/dXIXKtwa8pM0OTJQuJkxMN6w30csNRUerHfeQ5R6U3kkU/FtJeIf3M202OHfY2U8ccInBG7/xogA== + +cliui@^7.0.2: + version "7.0.4" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-7.0.4.tgz#a0265ee655476fc807aea9df3df8df7783808b4f" + integrity sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ== + dependencies: + string-width "^4.2.0" + strip-ansi "^6.0.0" + wrap-ansi "^7.0.0" + +co@^4.6.0: + version "4.6.0" + resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184" + integrity sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ== + +collect-v8-coverage@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/collect-v8-coverage/-/collect-v8-coverage-1.0.1.tgz#cc2c8e94fc18bbdffe64d6534570c8a673b27f59" + integrity sha512-iBPtljfCNcTKNAto0KEtDfZ3qzjJvqE3aTGZsbhjSBlorqpXJlaWWtPO35D+ZImoC3KWejX64o+yPGxhWSTzfg== + +color-convert@^1.9.0: + version "1.9.3" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" + integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== + dependencies: + color-name "1.1.3" + +color-convert@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" + integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== + dependencies: + color-name "~1.1.4" + +color-name@1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" + integrity sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw== + +color-name@~1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" + integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== + +concat-map@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" + integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg== + +convert-source-map@^1.4.0, convert-source-map@^1.6.0, convert-source-map@^1.7.0: + version "1.8.0" + resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.8.0.tgz#f3373c32d21b4d780dd8004514684fb791ca4369" + integrity sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA== + dependencies: + safe-buffer "~5.1.1" + +create-hash@^1.1.0, create-hash@^1.1.2, create-hash@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/create-hash/-/create-hash-1.2.0.tgz#889078af11a63756bcfb59bd221996be3a9ef196" + integrity sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg== + dependencies: + cipher-base "^1.0.1" + inherits "^2.0.1" + md5.js "^1.3.4" + ripemd160 "^2.0.1" + sha.js "^2.4.0" + +create-hmac@^1.1.4, create-hmac@^1.1.7: + version "1.1.7" + resolved "https://registry.yarnpkg.com/create-hmac/-/create-hmac-1.1.7.tgz#69170c78b3ab957147b2b8b04572e47ead2243ff" + integrity sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg== + dependencies: + cipher-base "^1.0.3" + create-hash "^1.1.0" + inherits "^2.0.1" + ripemd160 "^2.0.0" + safe-buffer "^5.0.1" + sha.js "^2.4.8" + +create-require@^1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/create-require/-/create-require-1.1.1.tgz#c1d7e8f1e5f6cfc9ff65f9cd352d37348756c333" + integrity sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ== + +cross-spawn@^7.0.3: + version "7.0.3" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" + integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== + dependencies: + path-key "^3.1.0" + shebang-command "^2.0.0" + which "^2.0.1" + +curve25519-js@0.0.4: + version "0.0.4" + resolved "https://registry.yarnpkg.com/curve25519-js/-/curve25519-js-0.0.4.tgz#e6ad967e8cd284590d657bbfc90d8b50e49ba060" + integrity sha512-axn2UMEnkhyDUPWOwVKBMVIzSQy2ejH2xRGy1wq81dqRwApXfIzfbE3hIX0ZRFBIihf/KDqK158DLwESu4AK1w== + +debug@^4.1.0, debug@^4.1.1: + version "4.3.4" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" + integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== + dependencies: + ms "2.1.2" + +dedent@^0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/dedent/-/dedent-0.7.0.tgz#2495ddbaf6eb874abb0e1be9df22d2e5a544326c" + integrity sha512-Q6fKUPqnAHAyhiUgFU7BUzLiv0kd8saH9al7tnu5Q/okj6dnupxyTgFIBjVzJATdfIAm9NAsvXNzjaKa+bxVyA== + +deepmerge@^4.2.2: + version "4.2.2" + resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-4.2.2.tgz#44d2ea3679b8f4d4ffba33f03d865fc1e7bf4955" + integrity sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg== + +detect-newline@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/detect-newline/-/detect-newline-3.1.0.tgz#576f5dfc63ae1a192ff192d8ad3af6308991b651" + integrity sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA== + +diff-sequences@^28.1.1: + version "28.1.1" + resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-28.1.1.tgz#9989dc731266dc2903457a70e996f3a041913ac6" + integrity sha512-FU0iFaH/E23a+a718l8Qa/19bF9p06kgE0KipMOMadwa3SjnaElKzPaUC0vnibs6/B/9ni97s61mcejk8W1fQw== + +diff@^4.0.1: + version "4.0.2" + resolved "https://registry.yarnpkg.com/diff/-/diff-4.0.2.tgz#60f3aecb89d5fae520c11aa19efc2bb982aade7d" + integrity sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A== + +electron-to-chromium@^1.4.202: + version "1.4.225" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.225.tgz#3e27bdd157cbaf19768141f2e0f0f45071e52338" + integrity sha512-ICHvGaCIQR3P88uK8aRtx8gmejbVJyC6bB4LEC3anzBrIzdzC7aiZHY4iFfXhN4st6I7lMO0x4sgBHf/7kBvRw== + +elliptic@^6.4.0: + version "6.5.4" + resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.5.4.tgz#da37cebd31e79a1367e941b592ed1fbebd58abbb" + integrity sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ== + dependencies: + bn.js "^4.11.9" + brorand "^1.1.0" + hash.js "^1.0.0" + hmac-drbg "^1.0.1" + inherits "^2.0.4" + minimalistic-assert "^1.0.1" + minimalistic-crypto-utils "^1.0.1" + +emittery@^0.10.2: + version "0.10.2" + resolved "https://registry.yarnpkg.com/emittery/-/emittery-0.10.2.tgz#902eec8aedb8c41938c46e9385e9db7e03182933" + integrity sha512-aITqOwnLanpHLNXZJENbOgjUBeHocD+xsSJmNrjovKBW5HbSpW3d1pEls7GFQPUWXiwG9+0P4GtHfEqC/4M0Iw== + +emoji-regex@^8.0.0: + version "8.0.0" + resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" + integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== + +error-ex@^1.3.1: + version "1.3.2" + resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf" + integrity sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g== + dependencies: + is-arrayish "^0.2.1" + +escalade@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40" + integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw== + +escape-string-regexp@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" + integrity sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg== + +escape-string-regexp@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz#a30304e99daa32e23b2fd20f51babd07cffca344" + integrity sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w== + +esprima@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" + integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== + +execa@^5.0.0: + version "5.1.1" + resolved "https://registry.yarnpkg.com/execa/-/execa-5.1.1.tgz#f80ad9cbf4298f7bd1d4c9555c21e93741c411dd" + integrity sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg== + dependencies: + cross-spawn "^7.0.3" + get-stream "^6.0.0" + human-signals "^2.1.0" + is-stream "^2.0.0" + merge-stream "^2.0.0" + npm-run-path "^4.0.1" + onetime "^5.1.2" + signal-exit "^3.0.3" + strip-final-newline "^2.0.0" + +exit@^0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/exit/-/exit-0.1.2.tgz#0632638f8d877cc82107d30a0fff1a17cba1cd0c" + integrity sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ== + +expect@^28.0.0, expect@^28.1.3: + version "28.1.3" + resolved "https://registry.yarnpkg.com/expect/-/expect-28.1.3.tgz#90a7c1a124f1824133dd4533cce2d2bdcb6603ec" + integrity sha512-eEh0xn8HlsuOBxFgIss+2mX85VAS4Qy3OSkjV7rlBWljtA4oWH37glVGyOZSZvErDT/yBywZdPGwCXuTvSG85g== + dependencies: + "@jest/expect-utils" "^28.1.3" + jest-get-type "^28.0.2" + jest-matcher-utils "^28.1.3" + jest-message-util "^28.1.3" + jest-util "^28.1.3" + +fast-json-stable-stringify@2.x, fast-json-stable-stringify@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" + integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== + +fb-watchman@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/fb-watchman/-/fb-watchman-2.0.1.tgz#fc84fb39d2709cf3ff6d743706157bb5708a8a85" + integrity sha512-DkPJKQeY6kKwmuMretBhr7G6Vodr7bFwDYTXIkfG1gjvNpaxBTQV3PbXg6bR1c1UP4jPOX0jHUbbHANL9vRjVg== + dependencies: + bser "2.1.1" + +file-uri-to-path@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz#553a7b8446ff6f684359c445f1e37a05dacc33dd" + integrity sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw== + +fill-range@^7.0.1: + version "7.0.1" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40" + integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ== + dependencies: + to-regex-range "^5.0.1" + +find-up@^4.0.0, find-up@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-4.1.0.tgz#97afe7d6cdc0bc5928584b7c8d7b16e8a9aa5d19" + integrity sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw== + dependencies: + locate-path "^5.0.0" + path-exists "^4.0.0" + +fs.realpath@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" + integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw== + +fsevents@^2.3.2: + version "2.3.2" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a" + integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA== + +function-bind@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" + integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== + +gensync@^1.0.0-beta.2: + version "1.0.0-beta.2" + resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.2.tgz#32a6ee76c3d7f52d46b2b1ae5d93fea8580a25e0" + integrity sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg== + +get-caller-file@^2.0.5: + version "2.0.5" + resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" + integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== + +get-package-type@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/get-package-type/-/get-package-type-0.1.0.tgz#8de2d803cff44df3bc6c456e6668b36c3926e11a" + integrity sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q== + +get-stream@^6.0.0: + version "6.0.1" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-6.0.1.tgz#a262d8eef67aced57c2852ad6167526a43cbf7b7" + integrity sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg== + +glob@^7.1.3, glob@^7.1.4: + version "7.2.3" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.3.tgz#b8df0fb802bbfa8e89bd1d938b4e16578ed44f2b" + integrity sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.1.1" + once "^1.3.0" + path-is-absolute "^1.0.0" + +globals@^11.1.0: + version "11.12.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e" + integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA== + +graceful-fs@^4.2.9: + version "4.2.10" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.10.tgz#147d3a006da4ca3ce14728c7aefc287c367d7a6c" + integrity sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA== + +has-flag@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" + integrity sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw== + +has-flag@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" + integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== + +has@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" + integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== + dependencies: + function-bind "^1.1.1" + +hash-base@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/hash-base/-/hash-base-3.1.0.tgz#55c381d9e06e1d2997a883b4a3fddfe7f0d3af33" + integrity sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA== + dependencies: + inherits "^2.0.4" + readable-stream "^3.6.0" + safe-buffer "^5.2.0" + +hash.js@^1.0.0, hash.js@^1.0.3: + version "1.1.7" + resolved "https://registry.yarnpkg.com/hash.js/-/hash.js-1.1.7.tgz#0babca538e8d4ee4a0f8988d68866537a003cf42" + integrity sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA== + dependencies: + inherits "^2.0.3" + minimalistic-assert "^1.0.1" + +hmac-drbg@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/hmac-drbg/-/hmac-drbg-1.0.1.tgz#d2745701025a6c775a6c545793ed502fc0c649a1" + integrity sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg== + dependencies: + hash.js "^1.0.3" + minimalistic-assert "^1.0.0" + minimalistic-crypto-utils "^1.0.1" + +html-escaper@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/html-escaper/-/html-escaper-2.0.2.tgz#dfd60027da36a36dfcbe236262c00a5822681453" + integrity sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg== + +human-signals@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-2.1.0.tgz#dc91fcba42e4d06e4abaed33b3e7a3c02f514ea0" + integrity sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw== + +import-local@^3.0.2: + version "3.1.0" + resolved "https://registry.yarnpkg.com/import-local/-/import-local-3.1.0.tgz#b4479df8a5fd44f6cdce24070675676063c95cb4" + integrity sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg== + dependencies: + pkg-dir "^4.2.0" + resolve-cwd "^3.0.0" + +imurmurhash@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" + integrity sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA== + +inflight@^1.0.4: + version "1.0.6" + resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" + integrity sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA== + dependencies: + once "^1.3.0" + wrappy "1" + +inherits@2, inherits@^2.0.1, inherits@^2.0.3, inherits@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" + integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== + +is-arrayish@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" + integrity sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg== + +is-core-module@^2.9.0: + version "2.10.0" + resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.10.0.tgz#9012ede0a91c69587e647514e1d5277019e728ed" + integrity sha512-Erxj2n/LDAZ7H8WNJXd9tw38GYM3dv8rk8Zcs+jJuxYTW7sozH+SS8NtrSjVL1/vpLvWi1hxy96IzjJ3EHTJJg== + dependencies: + has "^1.0.3" + +is-fullwidth-code-point@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" + integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== + +is-generator-fn@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-generator-fn/-/is-generator-fn-2.1.0.tgz#7d140adc389aaf3011a8f2a2a4cfa6faadffb118" + integrity sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ== + +is-gzip@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-gzip/-/is-gzip-2.0.0.tgz#f4fed2bbd9f96bf2cb39e19262797fdb15aad933" + integrity sha512-jtO4Njg6q58zDo/Pu4027beSZ0VdsZlt8/5Moco6yAg+DIxb5BK/xUYqYG2+MD4+piKldXJNHxRkhEYI2fvrxA== + +is-number@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" + integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== + +is-stream@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.1.tgz#fac1e3d53b97ad5a9d0ae9cef2389f5810a5c077" + integrity sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg== + +isexe@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" + integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw== + +istanbul-lib-coverage@^3.0.0, istanbul-lib-coverage@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz#189e7909d0a39fa5a3dfad5b03f71947770191d3" + integrity sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw== + +istanbul-lib-instrument@^5.0.4, istanbul-lib-instrument@^5.1.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.0.tgz#31d18bdd127f825dd02ea7bfdfd906f8ab840e9f" + integrity sha512-6Lthe1hqXHBNsqvgDzGO6l03XNeu3CrG4RqQ1KM9+l5+jNGpEJfIELx1NS3SEHmJQA8np/u+E4EPRKRiu6m19A== + dependencies: + "@babel/core" "^7.12.3" + "@babel/parser" "^7.14.7" + "@istanbuljs/schema" "^0.1.2" + istanbul-lib-coverage "^3.2.0" + semver "^6.3.0" + +istanbul-lib-report@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz#7518fe52ea44de372f460a76b5ecda9ffb73d8a6" + integrity sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw== + dependencies: + istanbul-lib-coverage "^3.0.0" + make-dir "^3.0.0" + supports-color "^7.1.0" + +istanbul-lib-source-maps@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz#895f3a709fcfba34c6de5a42939022f3e4358551" + integrity sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw== + dependencies: + debug "^4.1.1" + istanbul-lib-coverage "^3.0.0" + source-map "^0.6.1" + +istanbul-reports@^3.1.3: + version "3.1.5" + resolved "https://registry.yarnpkg.com/istanbul-reports/-/istanbul-reports-3.1.5.tgz#cc9a6ab25cb25659810e4785ed9d9fb742578bae" + integrity sha512-nUsEMa9pBt/NOHqbcbeJEgqIlY/K7rVWUX6Lql2orY5e9roQOthbR3vtY4zzf2orPELg80fnxxk9zUyPlgwD1w== + dependencies: + html-escaper "^2.0.0" + istanbul-lib-report "^3.0.0" + +jest-changed-files@^28.1.3: + version "28.1.3" + resolved "https://registry.yarnpkg.com/jest-changed-files/-/jest-changed-files-28.1.3.tgz#d9aeee6792be3686c47cb988a8eaf82ff4238831" + integrity sha512-esaOfUWJXk2nfZt9SPyC8gA1kNfdKLkQWyzsMlqq8msYSlNKfmZxfRgZn4Cd4MGVUF+7v6dBs0d5TOAKa7iIiA== + dependencies: + execa "^5.0.0" + p-limit "^3.1.0" + +jest-circus@^28.1.3: + version "28.1.3" + resolved "https://registry.yarnpkg.com/jest-circus/-/jest-circus-28.1.3.tgz#d14bd11cf8ee1a03d69902dc47b6bd4634ee00e4" + integrity sha512-cZ+eS5zc79MBwt+IhQhiEp0OeBddpc1n8MBo1nMB8A7oPMKEO+Sre+wHaLJexQUj9Ya/8NOBY0RESUgYjB6fow== + dependencies: + "@jest/environment" "^28.1.3" + "@jest/expect" "^28.1.3" + "@jest/test-result" "^28.1.3" + "@jest/types" "^28.1.3" + "@types/node" "*" + chalk "^4.0.0" + co "^4.6.0" + dedent "^0.7.0" + is-generator-fn "^2.0.0" + jest-each "^28.1.3" + jest-matcher-utils "^28.1.3" + jest-message-util "^28.1.3" + jest-runtime "^28.1.3" + jest-snapshot "^28.1.3" + jest-util "^28.1.3" + p-limit "^3.1.0" + pretty-format "^28.1.3" + slash "^3.0.0" + stack-utils "^2.0.3" + +jest-cli@^28.1.3: + version "28.1.3" + resolved "https://registry.yarnpkg.com/jest-cli/-/jest-cli-28.1.3.tgz#558b33c577d06de55087b8448d373b9f654e46b2" + integrity sha512-roY3kvrv57Azn1yPgdTebPAXvdR2xfezaKKYzVxZ6It/5NCxzJym6tUI5P1zkdWhfUYkxEI9uZWcQdaFLo8mJQ== + dependencies: + "@jest/core" "^28.1.3" + "@jest/test-result" "^28.1.3" + "@jest/types" "^28.1.3" + chalk "^4.0.0" + exit "^0.1.2" + graceful-fs "^4.2.9" + import-local "^3.0.2" + jest-config "^28.1.3" + jest-util "^28.1.3" + jest-validate "^28.1.3" + prompts "^2.0.1" + yargs "^17.3.1" + +jest-config@^28.1.3: + version "28.1.3" + resolved "https://registry.yarnpkg.com/jest-config/-/jest-config-28.1.3.tgz#e315e1f73df3cac31447eed8b8740a477392ec60" + integrity sha512-MG3INjByJ0J4AsNBm7T3hsuxKQqFIiRo/AUqb1q9LRKI5UU6Aar9JHbr9Ivn1TVwfUD9KirRoM/T6u8XlcQPHQ== + dependencies: + "@babel/core" "^7.11.6" + "@jest/test-sequencer" "^28.1.3" + "@jest/types" "^28.1.3" + babel-jest "^28.1.3" + chalk "^4.0.0" + ci-info "^3.2.0" + deepmerge "^4.2.2" + glob "^7.1.3" + graceful-fs "^4.2.9" + jest-circus "^28.1.3" + jest-environment-node "^28.1.3" + jest-get-type "^28.0.2" + jest-regex-util "^28.0.2" + jest-resolve "^28.1.3" + jest-runner "^28.1.3" + jest-util "^28.1.3" + jest-validate "^28.1.3" + micromatch "^4.0.4" + parse-json "^5.2.0" + pretty-format "^28.1.3" + slash "^3.0.0" + strip-json-comments "^3.1.1" + +jest-diff@^28.1.3: + version "28.1.3" + resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-28.1.3.tgz#948a192d86f4e7a64c5264ad4da4877133d8792f" + integrity sha512-8RqP1B/OXzjjTWkqMX67iqgwBVJRgCyKD3L9nq+6ZqJMdvjE8RgHktqZ6jNrkdMT+dJuYNI3rhQpxaz7drJHfw== + dependencies: + chalk "^4.0.0" + diff-sequences "^28.1.1" + jest-get-type "^28.0.2" + pretty-format "^28.1.3" + +jest-docblock@^28.1.1: + version "28.1.1" + resolved "https://registry.yarnpkg.com/jest-docblock/-/jest-docblock-28.1.1.tgz#6f515c3bf841516d82ecd57a62eed9204c2f42a8" + integrity sha512-3wayBVNiOYx0cwAbl9rwm5kKFP8yHH3d/fkEaL02NPTkDojPtheGB7HZSFY4wzX+DxyrvhXz0KSCVksmCknCuA== + dependencies: + detect-newline "^3.0.0" + +jest-each@^28.1.3: + version "28.1.3" + resolved "https://registry.yarnpkg.com/jest-each/-/jest-each-28.1.3.tgz#bdd1516edbe2b1f3569cfdad9acd543040028f81" + integrity sha512-arT1z4sg2yABU5uogObVPvSlSMQlDA48owx07BDPAiasW0yYpYHYOo4HHLz9q0BVzDVU4hILFjzJw0So9aCL/g== + dependencies: + "@jest/types" "^28.1.3" + chalk "^4.0.0" + jest-get-type "^28.0.2" + jest-util "^28.1.3" + pretty-format "^28.1.3" + +jest-environment-node@^28.1.3: + version "28.1.3" + resolved "https://registry.yarnpkg.com/jest-environment-node/-/jest-environment-node-28.1.3.tgz#7e74fe40eb645b9d56c0c4b70ca4357faa349be5" + integrity sha512-ugP6XOhEpjAEhGYvp5Xj989ns5cB1K6ZdjBYuS30umT4CQEETaxSiPcZ/E1kFktX4GkrcM4qu07IIlDYX1gp+A== + dependencies: + "@jest/environment" "^28.1.3" + "@jest/fake-timers" "^28.1.3" + "@jest/types" "^28.1.3" + "@types/node" "*" + jest-mock "^28.1.3" + jest-util "^28.1.3" + +jest-get-type@^28.0.2: + version "28.0.2" + resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-28.0.2.tgz#34622e628e4fdcd793d46db8a242227901fcf203" + integrity sha512-ioj2w9/DxSYHfOm5lJKCdcAmPJzQXmbM/Url3rhlghrPvT3tt+7a/+oXc9azkKmLvoiXjtV83bEWqi+vs5nlPA== + +jest-haste-map@^28.1.3: + version "28.1.3" + resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-28.1.3.tgz#abd5451129a38d9841049644f34b034308944e2b" + integrity sha512-3S+RQWDXccXDKSWnkHa/dPwt+2qwA8CJzR61w3FoYCvoo3Pn8tvGcysmMF0Bj0EX5RYvAI2EIvC57OmotfdtKA== + dependencies: + "@jest/types" "^28.1.3" + "@types/graceful-fs" "^4.1.3" + "@types/node" "*" + anymatch "^3.0.3" + fb-watchman "^2.0.0" + graceful-fs "^4.2.9" + jest-regex-util "^28.0.2" + jest-util "^28.1.3" + jest-worker "^28.1.3" + micromatch "^4.0.4" + walker "^1.0.8" + optionalDependencies: + fsevents "^2.3.2" + +jest-leak-detector@^28.1.3: + version "28.1.3" + resolved "https://registry.yarnpkg.com/jest-leak-detector/-/jest-leak-detector-28.1.3.tgz#a6685d9b074be99e3adee816ce84fd30795e654d" + integrity sha512-WFVJhnQsiKtDEo5lG2mM0v40QWnBM+zMdHHyJs8AWZ7J0QZJS59MsyKeJHWhpBZBH32S48FOVvGyOFT1h0DlqA== + dependencies: + jest-get-type "^28.0.2" + pretty-format "^28.1.3" + +jest-matcher-utils@^28.1.3: + version "28.1.3" + resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-28.1.3.tgz#5a77f1c129dd5ba3b4d7fc20728806c78893146e" + integrity sha512-kQeJ7qHemKfbzKoGjHHrRKH6atgxMk8Enkk2iPQ3XwO6oE/KYD8lMYOziCkeSB9G4adPM4nR1DE8Tf5JeWH6Bw== + dependencies: + chalk "^4.0.0" + jest-diff "^28.1.3" + jest-get-type "^28.0.2" + pretty-format "^28.1.3" + +jest-message-util@^28.1.3: + version "28.1.3" + resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-28.1.3.tgz#232def7f2e333f1eecc90649b5b94b0055e7c43d" + integrity sha512-PFdn9Iewbt575zKPf1286Ht9EPoJmYT7P0kY+RibeYZ2XtOr53pDLEFoTWXbd1h4JiGiWpTBC84fc8xMXQMb7g== + dependencies: + "@babel/code-frame" "^7.12.13" + "@jest/types" "^28.1.3" + "@types/stack-utils" "^2.0.0" + chalk "^4.0.0" + graceful-fs "^4.2.9" + micromatch "^4.0.4" + pretty-format "^28.1.3" + slash "^3.0.0" + stack-utils "^2.0.3" + +jest-mock@^28.1.3: + version "28.1.3" + resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-28.1.3.tgz#d4e9b1fc838bea595c77ab73672ebf513ab249da" + integrity sha512-o3J2jr6dMMWYVH4Lh/NKmDXdosrsJgi4AviS8oXLujcjpCMBb1FMsblDnOXKZKfSiHLxYub1eS0IHuRXsio9eA== + dependencies: + "@jest/types" "^28.1.3" + "@types/node" "*" + +jest-pnp-resolver@^1.2.2: + version "1.2.2" + resolved "https://registry.yarnpkg.com/jest-pnp-resolver/-/jest-pnp-resolver-1.2.2.tgz#b704ac0ae028a89108a4d040b3f919dfddc8e33c" + integrity sha512-olV41bKSMm8BdnuMsewT4jqlZ8+3TCARAXjZGT9jcoSnrfUnRCqnMoF9XEeoWjbzObpqF9dRhHQj0Xb9QdF6/w== + +jest-regex-util@^28.0.2: + version "28.0.2" + resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-28.0.2.tgz#afdc377a3b25fb6e80825adcf76c854e5bf47ead" + integrity sha512-4s0IgyNIy0y9FK+cjoVYoxamT7Zeo7MhzqRGx7YDYmaQn1wucY9rotiGkBzzcMXTtjrCAP/f7f+E0F7+fxPNdw== + +jest-resolve-dependencies@^28.1.3: + version "28.1.3" + resolved "https://registry.yarnpkg.com/jest-resolve-dependencies/-/jest-resolve-dependencies-28.1.3.tgz#8c65d7583460df7275c6ea2791901fa975c1fe66" + integrity sha512-qa0QO2Q0XzQoNPouMbCc7Bvtsem8eQgVPNkwn9LnS+R2n8DaVDPL/U1gngC0LTl1RYXJU0uJa2BMC2DbTfFrHA== + dependencies: + jest-regex-util "^28.0.2" + jest-snapshot "^28.1.3" + +jest-resolve@^28.1.3: + version "28.1.3" + resolved "https://registry.yarnpkg.com/jest-resolve/-/jest-resolve-28.1.3.tgz#cfb36100341ddbb061ec781426b3c31eb51aa0a8" + integrity sha512-Z1W3tTjE6QaNI90qo/BJpfnvpxtaFTFw5CDgwpyE/Kz8U/06N1Hjf4ia9quUhCh39qIGWF1ZuxFiBiJQwSEYKQ== + dependencies: + chalk "^4.0.0" + graceful-fs "^4.2.9" + jest-haste-map "^28.1.3" + jest-pnp-resolver "^1.2.2" + jest-util "^28.1.3" + jest-validate "^28.1.3" + resolve "^1.20.0" + resolve.exports "^1.1.0" + slash "^3.0.0" + +jest-runner@^28.1.3: + version "28.1.3" + resolved "https://registry.yarnpkg.com/jest-runner/-/jest-runner-28.1.3.tgz#5eee25febd730b4713a2cdfd76bdd5557840f9a1" + integrity sha512-GkMw4D/0USd62OVO0oEgjn23TM+YJa2U2Wu5zz9xsQB1MxWKDOlrnykPxnMsN0tnJllfLPinHTka61u0QhaxBA== + dependencies: + "@jest/console" "^28.1.3" + "@jest/environment" "^28.1.3" + "@jest/test-result" "^28.1.3" + "@jest/transform" "^28.1.3" + "@jest/types" "^28.1.3" + "@types/node" "*" + chalk "^4.0.0" + emittery "^0.10.2" + graceful-fs "^4.2.9" + jest-docblock "^28.1.1" + jest-environment-node "^28.1.3" + jest-haste-map "^28.1.3" + jest-leak-detector "^28.1.3" + jest-message-util "^28.1.3" + jest-resolve "^28.1.3" + jest-runtime "^28.1.3" + jest-util "^28.1.3" + jest-watcher "^28.1.3" + jest-worker "^28.1.3" + p-limit "^3.1.0" + source-map-support "0.5.13" + +jest-runtime@^28.1.3: + version "28.1.3" + resolved "https://registry.yarnpkg.com/jest-runtime/-/jest-runtime-28.1.3.tgz#a57643458235aa53e8ec7821949e728960d0605f" + integrity sha512-NU+881ScBQQLc1JHG5eJGU7Ui3kLKrmwCPPtYsJtBykixrM2OhVQlpMmFWJjMyDfdkGgBMNjXCGB/ebzsgNGQw== + dependencies: + "@jest/environment" "^28.1.3" + "@jest/fake-timers" "^28.1.3" + "@jest/globals" "^28.1.3" + "@jest/source-map" "^28.1.2" + "@jest/test-result" "^28.1.3" + "@jest/transform" "^28.1.3" + "@jest/types" "^28.1.3" + chalk "^4.0.0" + cjs-module-lexer "^1.0.0" + collect-v8-coverage "^1.0.0" + execa "^5.0.0" + glob "^7.1.3" + graceful-fs "^4.2.9" + jest-haste-map "^28.1.3" + jest-message-util "^28.1.3" + jest-mock "^28.1.3" + jest-regex-util "^28.0.2" + jest-resolve "^28.1.3" + jest-snapshot "^28.1.3" + jest-util "^28.1.3" + slash "^3.0.0" + strip-bom "^4.0.0" + +jest-snapshot@^28.1.3: + version "28.1.3" + resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-28.1.3.tgz#17467b3ab8ddb81e2f605db05583d69388fc0668" + integrity sha512-4lzMgtiNlc3DU/8lZfmqxN3AYD6GGLbl+72rdBpXvcV+whX7mDrREzkPdp2RnmfIiWBg1YbuFSkXduF2JcafJg== + dependencies: + "@babel/core" "^7.11.6" + "@babel/generator" "^7.7.2" + "@babel/plugin-syntax-typescript" "^7.7.2" + "@babel/traverse" "^7.7.2" + "@babel/types" "^7.3.3" + "@jest/expect-utils" "^28.1.3" + "@jest/transform" "^28.1.3" + "@jest/types" "^28.1.3" + "@types/babel__traverse" "^7.0.6" + "@types/prettier" "^2.1.5" + babel-preset-current-node-syntax "^1.0.0" + chalk "^4.0.0" + expect "^28.1.3" + graceful-fs "^4.2.9" + jest-diff "^28.1.3" + jest-get-type "^28.0.2" + jest-haste-map "^28.1.3" + jest-matcher-utils "^28.1.3" + jest-message-util "^28.1.3" + jest-util "^28.1.3" + natural-compare "^1.4.0" + pretty-format "^28.1.3" + semver "^7.3.5" + +jest-util@^28.0.0, jest-util@^28.1.3: + version "28.1.3" + resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-28.1.3.tgz#f4f932aa0074f0679943220ff9cbba7e497028b0" + integrity sha512-XdqfpHwpcSRko/C35uLYFM2emRAltIIKZiJ9eAmhjsj0CqZMa0p1ib0R5fWIqGhn1a103DebTbpqIaP1qCQ6tQ== + dependencies: + "@jest/types" "^28.1.3" + "@types/node" "*" + chalk "^4.0.0" + ci-info "^3.2.0" + graceful-fs "^4.2.9" + picomatch "^2.2.3" + +jest-validate@^28.1.3: + version "28.1.3" + resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-28.1.3.tgz#e322267fd5e7c64cea4629612c357bbda96229df" + integrity sha512-SZbOGBWEsaTxBGCOpsRWlXlvNkvTkY0XxRfh7zYmvd8uL5Qzyg0CHAXiXKROflh801quA6+/DsT4ODDthOC/OA== + dependencies: + "@jest/types" "^28.1.3" + camelcase "^6.2.0" + chalk "^4.0.0" + jest-get-type "^28.0.2" + leven "^3.1.0" + pretty-format "^28.1.3" + +jest-watcher@^28.1.3: + version "28.1.3" + resolved "https://registry.yarnpkg.com/jest-watcher/-/jest-watcher-28.1.3.tgz#c6023a59ba2255e3b4c57179fc94164b3e73abd4" + integrity sha512-t4qcqj9hze+jviFPUN3YAtAEeFnr/azITXQEMARf5cMwKY2SMBRnCQTXLixTl20OR6mLh9KLMrgVJgJISym+1g== + dependencies: + "@jest/test-result" "^28.1.3" + "@jest/types" "^28.1.3" + "@types/node" "*" + ansi-escapes "^4.2.1" + chalk "^4.0.0" + emittery "^0.10.2" + jest-util "^28.1.3" + string-length "^4.0.1" + +jest-worker@^28.1.3: + version "28.1.3" + resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-28.1.3.tgz#7e3c4ce3fa23d1bb6accb169e7f396f98ed4bb98" + integrity sha512-CqRA220YV/6jCo8VWvAt1KKx6eek1VIHMPeLEbpcfSfkEeWyBNppynM/o6q+Wmw+sOhos2ml34wZbSX3G13//g== + dependencies: + "@types/node" "*" + merge-stream "^2.0.0" + supports-color "^8.0.0" + +jest@28.1.3: + version "28.1.3" + resolved "https://registry.yarnpkg.com/jest/-/jest-28.1.3.tgz#e9c6a7eecdebe3548ca2b18894a50f45b36dfc6b" + integrity sha512-N4GT5on8UkZgH0O5LUavMRV1EDEhNTL0KEfRmDIeZHSV7p2XgLoY9t9VDUgL6o+yfdgYHVxuz81G8oB9VG5uyA== + dependencies: + "@jest/core" "^28.1.3" + "@jest/types" "^28.1.3" + import-local "^3.0.2" + jest-cli "^28.1.3" + +js-tokens@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" + integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== + +js-yaml@^3.13.1: + version "3.14.1" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.14.1.tgz#dae812fdb3825fa306609a8717383c50c36a0537" + integrity sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g== + dependencies: + argparse "^1.0.7" + esprima "^4.0.0" + +jsesc@^2.5.1: + version "2.5.2" + resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-2.5.2.tgz#80564d2e483dacf6e8ef209650a67df3f0c283a4" + integrity sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA== + +json-parse-even-better-errors@^2.3.0: + version "2.3.1" + resolved "https://registry.yarnpkg.com/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz#7c47805a94319928e05777405dc12e1f7a4ee02d" + integrity sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w== + +json5@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.1.tgz#655d50ed1e6f95ad1a3caababd2b0efda10b395c" + integrity sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA== + +kleur@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/kleur/-/kleur-3.0.3.tgz#a79c9ecc86ee1ce3fa6206d1216c501f147fc07e" + integrity sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w== + +leven@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/leven/-/leven-3.1.0.tgz#77891de834064cccba82ae7842bb6b14a13ed7f2" + integrity sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A== + +lines-and-columns@^1.1.6: + version "1.2.4" + resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.2.4.tgz#eca284f75d2965079309dc0ad9255abb2ebc1632" + integrity sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg== + +locate-path@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-5.0.0.tgz#1afba396afd676a6d42504d0a67a3a7eb9f62aa0" + integrity sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g== + dependencies: + p-locate "^4.1.0" + +lodash.memoize@4.x: + version "4.1.2" + resolved "https://registry.yarnpkg.com/lodash.memoize/-/lodash.memoize-4.1.2.tgz#bcc6c49a42a2840ed997f323eada5ecd182e0bfe" + integrity sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag== + +long@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/long/-/long-4.0.0.tgz#9a7b71cfb7d361a194ea555241c92f7468d5bf28" + integrity sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA== + +long@^5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/long/-/long-5.2.0.tgz#2696dadf4b4da2ce3f6f6b89186085d94d52fd61" + integrity sha512-9RTUNjK60eJbx3uz+TEGF7fUr29ZDxR5QzXcyDpeSfeH28S9ycINflOgOlppit5U+4kNTe83KQnMEerw7GmE8w== + +lru-cache@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" + integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== + dependencies: + yallist "^4.0.0" + +make-dir@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-3.1.0.tgz#415e967046b3a7f1d185277d84aa58203726a13f" + integrity sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw== + dependencies: + semver "^6.0.0" + +make-error@1.x, make-error@^1.1.1: + version "1.3.6" + resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.6.tgz#2eb2e37ea9b67c4891f684a1394799af484cf7a2" + integrity sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw== + +makeerror@1.0.12: + version "1.0.12" + resolved "https://registry.yarnpkg.com/makeerror/-/makeerror-1.0.12.tgz#3e5dd2079a82e812e983cc6610c4a2cb0eaa801a" + integrity sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg== + dependencies: + tmpl "1.0.5" + +md5.js@^1.3.4: + version "1.3.5" + resolved "https://registry.yarnpkg.com/md5.js/-/md5.js-1.3.5.tgz#b5d07b8e3216e3e27cd728d72f70d1e6a342005f" + integrity sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg== + dependencies: + hash-base "^3.0.0" + inherits "^2.0.1" + safe-buffer "^5.1.2" + +merge-stream@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60" + integrity sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w== + +micromatch@^4.0.4: + version "4.0.5" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.5.tgz#bc8999a7cbbf77cdc89f132f6e467051b49090c6" + integrity sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA== + dependencies: + braces "^3.0.2" + picomatch "^2.3.1" + +mimic-fn@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" + integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== + +minimalistic-assert@^1.0.0, minimalistic-assert@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7" + integrity sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A== + +minimalistic-crypto-utils@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz#f6c00c1c0b082246e5c4d99dfb8c7c083b2b582a" + integrity sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg== + +minimatch@^3.0.4, minimatch@^3.1.1: + version "3.1.2" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" + integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== + dependencies: + brace-expansion "^1.1.7" + +miscreant@0.3.2: + version "0.3.2" + resolved "https://registry.yarnpkg.com/miscreant/-/miscreant-0.3.2.tgz#a91c046566cca70bd6b5e9fbdd3f67617fa85034" + integrity sha512-fL9KxsQz9BJB2KGPMHFrReioywkiomBiuaLk6EuChijK0BsJsIKJXdVomR+/bPj5mvbFD6wM0CM3bZio9g7OHA== + +ms@2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" + integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== + +nan@^2.13.2: + version "2.16.0" + resolved "https://registry.yarnpkg.com/nan/-/nan-2.16.0.tgz#664f43e45460fb98faf00edca0bb0d7b8dce7916" + integrity sha512-UdAqHyFngu7TfQKsCBgAA6pWDkT8MAO7d0jyOecVhN5354xbLqdn8mV9Tat9gepAupm0bt2DbeaSC8vS52MuFA== + +natural-compare@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" + integrity sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw== + +node-int64@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/node-int64/-/node-int64-0.4.0.tgz#87a9065cdb355d3182d8f94ce11188b825c68a3b" + integrity sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw== + +node-releases@^2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.6.tgz#8a7088c63a55e493845683ebf3c828d8c51c5503" + integrity sha512-PiVXnNuFm5+iYkLBNeq5211hvO38y63T0i2KKh2KnUs3RpzJ+JtODFjkD8yjLwnDkTYF1eKXheUwdssR+NRZdg== + +normalize-path@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" + integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== + +npm-run-path@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-4.0.1.tgz#b7ecd1e5ed53da8e37a55e1c2269e0b97ed748ea" + integrity sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw== + dependencies: + path-key "^3.0.0" + +once@^1.3.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" + integrity sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w== + dependencies: + wrappy "1" + +onetime@^5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/onetime/-/onetime-5.1.2.tgz#d0e96ebb56b07476df1dd9c4806e5237985ca45e" + integrity sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg== + dependencies: + mimic-fn "^2.1.0" + +p-limit@^2.2.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.3.0.tgz#3dd33c647a214fdfffd835933eb086da0dc21db1" + integrity sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w== + dependencies: + p-try "^2.0.0" + +p-limit@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-3.1.0.tgz#e1daccbe78d0d1388ca18c64fea38e3e57e3706b" + integrity sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ== + dependencies: + yocto-queue "^0.1.0" + +p-locate@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-4.1.0.tgz#a3428bb7088b3a60292f66919278b7c297ad4f07" + integrity sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A== + dependencies: + p-limit "^2.2.0" + +p-try@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6" + integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== + +pako@2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/pako/-/pako-2.0.4.tgz#6cebc4bbb0b6c73b0d5b8d7e8476e2b2fbea576d" + integrity sha512-v8tweI900AUkZN6heMU/4Uy4cXRc2AYNRggVmTR+dEncawDJgCdLMximOVA2p4qO57WMynangsfGRb5WD6L1Bg== + +parse-json@^5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-5.2.0.tgz#c76fc66dee54231c962b22bcc8a72cf2f99753cd" + integrity sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg== + dependencies: + "@babel/code-frame" "^7.0.0" + error-ex "^1.3.1" + json-parse-even-better-errors "^2.3.0" + lines-and-columns "^1.1.6" + +path-exists@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3" + integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w== + +path-is-absolute@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" + integrity sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg== + +path-key@^3.0.0, path-key@^3.1.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" + integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== + +path-parse@^1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" + integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== + +pbkdf2@^3.0.9: + version "3.1.2" + resolved "https://registry.yarnpkg.com/pbkdf2/-/pbkdf2-3.1.2.tgz#dd822aa0887580e52f1a039dc3eda108efae3075" + integrity sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA== + dependencies: + create-hash "^1.1.2" + create-hmac "^1.1.4" + ripemd160 "^2.0.1" + safe-buffer "^5.0.1" + sha.js "^2.4.8" + +picocolors@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c" + integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ== + +picomatch@^2.0.4, picomatch@^2.2.3, picomatch@^2.3.1: + version "2.3.1" + resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" + integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== + +pirates@^4.0.4: + version "4.0.5" + resolved "https://registry.yarnpkg.com/pirates/-/pirates-4.0.5.tgz#feec352ea5c3268fb23a37c702ab1699f35a5f3b" + integrity sha512-8V9+HQPupnaXMA23c5hvl69zXvTwTzyAYasnkb0Tts4XvO4CliqONMOnvlq26rkhLC3nWDFBJf73LU1e1VZLaQ== + +pkg-dir@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-4.2.0.tgz#f099133df7ede422e81d1d8448270eeb3e4261f3" + integrity sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ== + dependencies: + find-up "^4.0.0" + +prettier@2.7.1: + version "2.7.1" + resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.7.1.tgz#e235806850d057f97bb08368a4f7d899f7760c64" + integrity sha512-ujppO+MkdPqoVINuDFDRLClm7D78qbDt0/NR+wp5FqEZOoTNAjPHWj17QRhu7geIHJfcNhRk1XVQmF8Bp3ye+g== + +pretty-format@^28.0.0, pretty-format@^28.1.3: + version "28.1.3" + resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-28.1.3.tgz#c9fba8cedf99ce50963a11b27d982a9ae90970d5" + integrity sha512-8gFb/To0OmxHR9+ZTb14Df2vNxdGCX8g1xWGUTqUw5TiZvcQf5sHKObd5UcPyLLyowNwDAMTF3XWOG1B6mxl1Q== + dependencies: + "@jest/schemas" "^28.1.3" + ansi-regex "^5.0.1" + ansi-styles "^5.0.0" + react-is "^18.0.0" + +prompts@^2.0.1: + version "2.4.2" + resolved "https://registry.yarnpkg.com/prompts/-/prompts-2.4.2.tgz#7b57e73b3a48029ad10ebd44f74b01722a4cb069" + integrity sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q== + dependencies: + kleur "^3.0.3" + sisteransi "^1.0.5" + +protobufjs@6.11.3, protobufjs@^6.11.3: + version "6.11.3" + resolved "https://registry.yarnpkg.com/protobufjs/-/protobufjs-6.11.3.tgz#637a527205a35caa4f3e2a9a4a13ddffe0e7af74" + integrity sha512-xL96WDdCZYdU7Slin569tFX712BxsxslWwAfAhCYjQKGTq7dAU91Lomy6nLLhh/dyGhk/YH4TwTSRxTzhuHyZg== + dependencies: + "@protobufjs/aspromise" "^1.1.2" + "@protobufjs/base64" "^1.1.2" + "@protobufjs/codegen" "^2.0.4" + "@protobufjs/eventemitter" "^1.1.0" + "@protobufjs/fetch" "^1.1.0" + "@protobufjs/float" "^1.0.2" + "@protobufjs/inquire" "^1.1.0" + "@protobufjs/path" "^1.1.2" + "@protobufjs/pool" "^1.1.0" + "@protobufjs/utf8" "^1.1.0" + "@types/long" "^4.0.1" + "@types/node" ">=13.7.0" + long "^4.0.0" + +randombytes@^2.0.1: + version "2.1.0" + resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a" + integrity sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ== + dependencies: + safe-buffer "^5.1.0" + +react-is@^18.0.0: + version "18.2.0" + resolved "https://registry.yarnpkg.com/react-is/-/react-is-18.2.0.tgz#199431eeaaa2e09f86427efbb4f1473edb47609b" + integrity sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w== + +readable-stream@^3.6.0: + version "3.6.0" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.0.tgz#337bbda3adc0706bd3e024426a286d4b4b2c9198" + integrity sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA== + dependencies: + inherits "^2.0.3" + string_decoder "^1.1.1" + util-deprecate "^1.0.1" + +readonly-date@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/readonly-date/-/readonly-date-1.0.0.tgz#5af785464d8c7d7c40b9d738cbde8c646f97dcd9" + integrity sha512-tMKIV7hlk0h4mO3JTmmVuIlJVXjKk3Sep9Bf5OH0O+758ruuVkUy2J9SttDLm91IEX/WHlXPSpxMGjPj4beMIQ== + +regenerator-runtime@^0.13.4: + version "0.13.9" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz#8925742a98ffd90814988d7566ad30ca3b263b52" + integrity sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA== + +require-directory@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" + integrity sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q== + +resolve-cwd@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/resolve-cwd/-/resolve-cwd-3.0.0.tgz#0f0075f1bb2544766cf73ba6a6e2adfebcb13f2d" + integrity sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg== + dependencies: + resolve-from "^5.0.0" + +resolve-from@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-5.0.0.tgz#c35225843df8f776df21c57557bc087e9dfdfc69" + integrity sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw== + +resolve.exports@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/resolve.exports/-/resolve.exports-1.1.0.tgz#5ce842b94b05146c0e03076985d1d0e7e48c90c9" + integrity sha512-J1l+Zxxp4XK3LUDZ9m60LRJF/mAe4z6a4xyabPHk7pvK5t35dACV32iIjJDFeWZFfZlO29w6SZ67knR0tHzJtQ== + +resolve@^1.20.0: + version "1.22.1" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.1.tgz#27cb2ebb53f91abb49470a928bba7558066ac177" + integrity sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw== + dependencies: + is-core-module "^2.9.0" + path-parse "^1.0.7" + supports-preserve-symlinks-flag "^1.0.0" + +rimraf@^3.0.0: + version "3.0.2" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" + integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== + dependencies: + glob "^7.1.3" + +ripemd160@^2.0.0, ripemd160@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/ripemd160/-/ripemd160-2.0.2.tgz#a1c1a6f624751577ba5d07914cbc92850585890c" + integrity sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA== + dependencies: + hash-base "^3.0.0" + inherits "^2.0.1" + +safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.2, safe-buffer@^5.2.0, safe-buffer@~5.2.0: + version "5.2.1" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" + integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== + +safe-buffer@~5.1.1: + version "5.1.2" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" + integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== + +secretjs@1.3.0-beta.23: + version "1.3.0-beta.23" + resolved "https://registry.yarnpkg.com/secretjs/-/secretjs-1.3.0-beta.23.tgz#b956d2479cc6b06c1fed3623ae19a8ba7c540f8a" + integrity sha512-zXL0t1h68it1+77+kobAq4JcIWV7EUtHfP2W2Vpc9MpAGLUeJ5XgfSNs6uO4IYq7viIEL7idTTls/7ljWBb8xw== + dependencies: + "@cosmjs/encoding" "0.27.1" + "@cosmjs/math" "0.27.1" + "@improbable-eng/grpc-web" "0.15.0" + "@improbable-eng/grpc-web-node-http-transport" "0.15.0" + "@noble/hashes" "1.0.0" + "@noble/secp256k1" "1.6.3" + "@osmonauts/helpers" "0.3.8" + bech32 "2.0.0" + bignumber.js "9.0.2" + bip32 "2.0.6" + bip39 "3.0.4" + curve25519-js "0.0.4" + is-gzip "2.0.0" + miscreant "0.3.2" + pako "2.0.4" + protobufjs "6.11.3" + secure-random "1.1.2" + +secure-random@1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/secure-random/-/secure-random-1.1.2.tgz#ed103b460a851632d420d46448b2a900a41e7f7c" + integrity sha512-H2bdSKERKdBV1SwoqYm6C0y+9EA94v6SUBOWO8kDndc4NoUih7Dv6Tsgma7zO1lv27wIvjlD0ZpMQk7um5dheQ== + +semver@7.x, semver@^7.3.5: + version "7.3.7" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.7.tgz#12c5b649afdbf9049707796e22a4028814ce523f" + integrity sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g== + dependencies: + lru-cache "^6.0.0" + +semver@^6.0.0, semver@^6.3.0: + version "6.3.0" + resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" + integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== + +sha.js@^2.4.0, sha.js@^2.4.8: + version "2.4.11" + resolved "https://registry.yarnpkg.com/sha.js/-/sha.js-2.4.11.tgz#37a5cf0b81ecbc6943de109ba2960d1b26584ae7" + integrity sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ== + dependencies: + inherits "^2.0.1" + safe-buffer "^5.0.1" + +shebang-command@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" + integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA== + dependencies: + shebang-regex "^3.0.0" + +shebang-regex@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" + integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== + +signal-exit@^3.0.3, signal-exit@^3.0.7: + version "3.0.7" + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9" + integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ== + +sisteransi@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/sisteransi/-/sisteransi-1.0.5.tgz#134d681297756437cc05ca01370d3a7a571075ed" + integrity sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg== + +slash@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634" + integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q== + +source-map-support@0.5.13: + version "0.5.13" + resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.13.tgz#31b24a9c2e73c2de85066c0feb7d44767ed52932" + integrity sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w== + dependencies: + buffer-from "^1.0.0" + source-map "^0.6.0" + +source-map@^0.6.0, source-map@^0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" + integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== + +sprintf-js@~1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" + integrity sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g== + +stack-utils@^2.0.3: + version "2.0.5" + resolved "https://registry.yarnpkg.com/stack-utils/-/stack-utils-2.0.5.tgz#d25265fca995154659dbbfba3b49254778d2fdd5" + integrity sha512-xrQcmYhOsn/1kX+Vraq+7j4oE2j/6BFscZ0etmYg81xuM8Gq0022Pxb8+IqgOFUIaxHs0KaSb7T1+OegiNrNFA== + dependencies: + escape-string-regexp "^2.0.0" + +string-length@^4.0.1: + version "4.0.2" + resolved "https://registry.yarnpkg.com/string-length/-/string-length-4.0.2.tgz#a8a8dc7bd5c1a82b9b3c8b87e125f66871b6e57a" + integrity sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ== + dependencies: + char-regex "^1.0.2" + strip-ansi "^6.0.0" + +string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: + version "4.2.3" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" + integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== + dependencies: + emoji-regex "^8.0.0" + is-fullwidth-code-point "^3.0.0" + strip-ansi "^6.0.1" + +string_decoder@^1.1.1: + version "1.3.0" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e" + integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== + dependencies: + safe-buffer "~5.2.0" + +strip-ansi@^6.0.0, strip-ansi@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" + integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== + dependencies: + ansi-regex "^5.0.1" + +strip-bom@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-4.0.0.tgz#9c3505c1db45bcedca3d9cf7a16f5c5aa3901878" + integrity sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w== + +strip-final-newline@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-2.0.0.tgz#89b852fb2fcbe936f6f4b3187afb0a12c1ab58ad" + integrity sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA== + +strip-json-comments@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" + integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== + +supports-color@^5.3.0: + version "5.5.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" + integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== + dependencies: + has-flag "^3.0.0" + +supports-color@^7.0.0, supports-color@^7.1.0: + version "7.2.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da" + integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== + dependencies: + has-flag "^4.0.0" + +supports-color@^8.0.0: + version "8.1.1" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-8.1.1.tgz#cd6fc17e28500cff56c1b86c0a7fd4a54a73005c" + integrity sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q== + dependencies: + has-flag "^4.0.0" + +supports-hyperlinks@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/supports-hyperlinks/-/supports-hyperlinks-2.2.0.tgz#4f77b42488765891774b70c79babd87f9bd594bb" + integrity sha512-6sXEzV5+I5j8Bmq9/vUphGRM/RJNT9SCURJLjwfOg51heRtguGWDzcaBlgAzKhQa0EVNpPEKzQuBwZ8S8WaCeQ== + dependencies: + has-flag "^4.0.0" + supports-color "^7.0.0" + +supports-preserve-symlinks-flag@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09" + integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w== + +terminal-link@^2.0.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/terminal-link/-/terminal-link-2.1.1.tgz#14a64a27ab3c0df933ea546fba55f2d078edc994" + integrity sha512-un0FmiRUQNr5PJqy9kP7c40F5BOfpGlYTrxonDChEZB7pzZxRNp/bt+ymiy9/npwXya9KH99nJ/GXFIiUkYGFQ== + dependencies: + ansi-escapes "^4.2.1" + supports-hyperlinks "^2.0.0" + +test-exclude@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/test-exclude/-/test-exclude-6.0.0.tgz#04a8698661d805ea6fa293b6cb9e63ac044ef15e" + integrity sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w== + dependencies: + "@istanbuljs/schema" "^0.1.2" + glob "^7.1.4" + minimatch "^3.0.4" + +tiny-secp256k1@^1.1.3: + version "1.1.6" + resolved "https://registry.yarnpkg.com/tiny-secp256k1/-/tiny-secp256k1-1.1.6.tgz#7e224d2bee8ab8283f284e40e6b4acb74ffe047c" + integrity sha512-FmqJZGduTyvsr2cF3375fqGHUovSwDi/QytexX1Se4BPuPZpTE5Ftp5fg+EFSuEf3lhZqgCRjEG3ydUQ/aNiwA== + dependencies: + bindings "^1.3.0" + bn.js "^4.11.8" + create-hmac "^1.1.7" + elliptic "^6.4.0" + nan "^2.13.2" + +tmpl@1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/tmpl/-/tmpl-1.0.5.tgz#8683e0b902bb9c20c4f726e3c0b69f36518c07cc" + integrity sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw== + +to-fast-properties@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e" + integrity sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog== + +to-regex-range@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" + integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== + dependencies: + is-number "^7.0.0" + +ts-jest@28.0.8: + version "28.0.8" + resolved "https://registry.yarnpkg.com/ts-jest/-/ts-jest-28.0.8.tgz#cd204b8e7a2f78da32cf6c95c9a6165c5b99cc73" + integrity sha512-5FaG0lXmRPzApix8oFG8RKjAz4ehtm8yMKOTy5HX3fY6W8kmvOrmcY0hKDElW52FJov+clhUbrKAqofnj4mXTg== + dependencies: + bs-logger "0.x" + fast-json-stable-stringify "2.x" + jest-util "^28.0.0" + json5 "^2.2.1" + lodash.memoize "4.x" + make-error "1.x" + semver "7.x" + yargs-parser "^21.0.1" + +ts-node@10.9.1: + version "10.9.1" + resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-10.9.1.tgz#e73de9102958af9e1f0b168a6ff320e25adcff4b" + integrity sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw== + dependencies: + "@cspotcode/source-map-support" "^0.8.0" + "@tsconfig/node10" "^1.0.7" + "@tsconfig/node12" "^1.0.7" + "@tsconfig/node14" "^1.0.0" + "@tsconfig/node16" "^1.0.2" + acorn "^8.4.1" + acorn-walk "^8.1.1" + arg "^4.1.0" + create-require "^1.1.0" + diff "^4.0.1" + make-error "^1.1.1" + v8-compile-cache-lib "^3.0.1" + yn "3.1.1" + +type-detect@4.0.8: + version "4.0.8" + resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-4.0.8.tgz#7646fb5f18871cfbb7749e69bd39a6388eb7450c" + integrity sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g== + +type-fest@^0.21.3: + version "0.21.3" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.21.3.tgz#d260a24b0198436e133fa26a524a6d65fa3b2e37" + integrity sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w== + +typeforce@^1.11.5: + version "1.18.0" + resolved "https://registry.yarnpkg.com/typeforce/-/typeforce-1.18.0.tgz#d7416a2c5845e085034d70fcc5b6cc4a90edbfdc" + integrity sha512-7uc1O8h1M1g0rArakJdf0uLRSSgFcYexrVoKo+bzJd32gd4gDy2L/Z+8/FjPnU9ydY3pEnVPtr9FyscYY60K1g== + +typescript@4.7.4: + version "4.7.4" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.7.4.tgz#1a88596d1cf47d59507a1bcdfb5b9dfe4d488235" + integrity sha512-C0WQT0gezHuw6AdY1M2jxUO83Rjf0HP7Sk1DtXj6j1EwkQNZrHAg2XPWlq62oqEhYvONq5pkC2Y9oPljWToLmQ== + +update-browserslist-db@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.0.5.tgz#be06a5eedd62f107b7c19eb5bcefb194411abf38" + integrity sha512-dteFFpCyvuDdr9S/ff1ISkKt/9YZxKjI9WlRR99c180GaztJtRa/fn18FdxGVKVsnPY7/a/FDN68mcvUmP4U7Q== + dependencies: + escalade "^3.1.1" + picocolors "^1.0.0" + +util-deprecate@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" + integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw== + +v8-compile-cache-lib@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz#6336e8d71965cb3d35a1bbb7868445a7c05264bf" + integrity sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg== + +v8-to-istanbul@^9.0.1: + version "9.0.1" + resolved "https://registry.yarnpkg.com/v8-to-istanbul/-/v8-to-istanbul-9.0.1.tgz#b6f994b0b5d4ef255e17a0d17dc444a9f5132fa4" + integrity sha512-74Y4LqY74kLE6IFyIjPtkSTWzUZmj8tdHT9Ii/26dvQ6K9Dl2NbEfj0XgU2sHCtKgt5VupqhlO/5aWuqS+IY1w== + dependencies: + "@jridgewell/trace-mapping" "^0.3.12" + "@types/istanbul-lib-coverage" "^2.0.1" + convert-source-map "^1.6.0" + +walker@^1.0.8: + version "1.0.8" + resolved "https://registry.yarnpkg.com/walker/-/walker-1.0.8.tgz#bd498db477afe573dc04185f011d3ab8a8d7653f" + integrity sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ== + dependencies: + makeerror "1.0.12" + +which@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" + integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== + dependencies: + isexe "^2.0.0" + +wif@^2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/wif/-/wif-2.0.6.tgz#08d3f52056c66679299726fade0d432ae74b4704" + integrity sha512-HIanZn1zmduSF+BQhkE+YXIbEiH0xPr1012QbFEGB0xsKqJii0/SqJjyn8dFv6y36kOznMgMB+LGcbZTJ1xACQ== + dependencies: + bs58check "<3.0.0" + +wrap-ansi@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" + integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== + dependencies: + ansi-styles "^4.0.0" + string-width "^4.1.0" + strip-ansi "^6.0.0" + +wrappy@1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" + integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ== + +write-file-atomic@^4.0.1: + version "4.0.2" + resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-4.0.2.tgz#a9df01ae5b77858a027fd2e80768ee433555fcfd" + integrity sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg== + dependencies: + imurmurhash "^0.1.4" + signal-exit "^3.0.7" + +y18n@^5.0.5: + version "5.0.8" + resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55" + integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA== + +yallist@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" + integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== + +yargs-parser@^21.0.0, yargs-parser@^21.0.1: + version "21.1.1" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-21.1.1.tgz#9096bceebf990d21bb31fa9516e0ede294a77d35" + integrity sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw== + +yargs@^17.3.1: + version "17.5.1" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-17.5.1.tgz#e109900cab6fcb7fd44b1d8249166feb0b36e58e" + integrity sha512-t6YAJcxDkNX7NFYiVtKvWUz8l+PaKTLiL63mJYWR2GnHq2gjEWISzsLp9wg3aY36dY1j+gfIEL3pIF+XlJJfbA== + dependencies: + cliui "^7.0.2" + escalade "^3.1.1" + get-caller-file "^2.0.5" + require-directory "^2.1.1" + string-width "^4.2.3" + y18n "^5.0.5" + yargs-parser "^21.0.0" + +yn@3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/yn/-/yn-3.1.1.tgz#1e87401a09d767c1d5eab26a6e4c185182d2eb50" + integrity sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q== + +yocto-queue@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b" + integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q== diff --git a/package-lock.json b/package-lock.json deleted file mode 100644 index b659b5c44..000000000 --- a/package-lock.json +++ /dev/null @@ -1,23858 +0,0 @@ -{ - "name": "SecretNetwork", - "lockfileVersion": 2, - "requires": true, - "packages": { - "": { - "license": "AGPL-3.0-or-later", - "devDependencies": { - "vuepress": "^1.5.1" - } - }, - "node_modules/@babel/code-frame": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.1.tgz", - "integrity": "sha512-IGhtTmpjGbYzcEDOw7DcQtbQSXcG9ftmAXtWTu9V936vDye4xjjekktFAtgZsWpzTj/X01jocB46mTywm/4SZw==", - "dev": true, - "dependencies": { - "@babel/highlight": "^7.10.1" - } - }, - "node_modules/@babel/compat-data": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.10.1.tgz", - "integrity": "sha512-CHvCj7So7iCkGKPRFUfryXIkU2gSBw7VSZFYLsqVhrS47269VK2Hfi9S/YcublPMW8k1u2bQBlbDruoQEm4fgw==", - "dev": true, - "dependencies": { - "browserslist": "^4.12.0", - "invariant": "^2.2.4", - "semver": "^5.5.0" - } - }, - "node_modules/@babel/core": { - "version": "7.10.2", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.10.2.tgz", - "integrity": "sha512-KQmV9yguEjQsXqyOUGKjS4+3K8/DlOCE2pZcq4augdQmtTy5iv5EHtmMSJ7V4c1BIPjuwtZYqYLCq9Ga+hGBRQ==", - "dev": true, - "dependencies": { - "@babel/code-frame": "^7.10.1", - "@babel/generator": "^7.10.2", - "@babel/helper-module-transforms": "^7.10.1", - "@babel/helpers": "^7.10.1", - "@babel/parser": "^7.10.2", - "@babel/template": "^7.10.1", - "@babel/traverse": "^7.10.1", - "@babel/types": "^7.10.2", - "convert-source-map": "^1.7.0", - "debug": "^4.1.0", - "gensync": "^1.0.0-beta.1", - "json5": "^2.1.2", - "lodash": "^4.17.13", - "resolve": "^1.3.2", - "semver": "^5.4.1", - "source-map": "^0.5.0" - }, - "engines": { - "node": ">=6.9.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/babel" - } - }, - "node_modules/@babel/generator": { - "version": "7.10.2", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.10.2.tgz", - "integrity": "sha512-AxfBNHNu99DTMvlUPlt1h2+Hn7knPpH5ayJ8OqDWSeLld+Fi2AYBTC/IejWDM9Edcii4UzZRCsbUt0WlSDsDsA==", - "dev": true, - "dependencies": { - "@babel/types": "^7.10.2", - "jsesc": "^2.5.1", - "lodash": "^4.17.13", - "source-map": "^0.5.0" - } - }, - "node_modules/@babel/helper-annotate-as-pure": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.10.1.tgz", - "integrity": "sha512-ewp3rvJEwLaHgyWGe4wQssC2vjks3E80WiUe2BpMb0KhreTjMROCbxXcEovTrbeGVdQct5VjQfrv9EgC+xMzCw==", - "dev": true, - "dependencies": { - "@babel/types": "^7.10.1" - } - }, - "node_modules/@babel/helper-builder-binary-assignment-operator-visitor": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.10.1.tgz", - "integrity": "sha512-cQpVq48EkYxUU0xozpGCLla3wlkdRRqLWu1ksFMXA9CM5KQmyyRpSEsYXbao7JUkOw/tAaYKCaYyZq6HOFYtyw==", - "dev": true, - "dependencies": { - "@babel/helper-explode-assignable-expression": "^7.10.1", - "@babel/types": "^7.10.1" - } - }, - "node_modules/@babel/helper-compilation-targets": { - "version": "7.10.2", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.10.2.tgz", - "integrity": "sha512-hYgOhF4To2UTB4LTaZepN/4Pl9LD4gfbJx8A34mqoluT8TLbof1mhUlYuNWTEebONa8+UlCC4X0TEXu7AOUyGA==", - "dev": true, - "dependencies": { - "@babel/compat-data": "^7.10.1", - "browserslist": "^4.12.0", - "invariant": "^2.2.4", - "levenary": "^1.1.1", - "semver": "^5.5.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/helper-create-class-features-plugin": { - "version": "7.10.2", - "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.10.2.tgz", - "integrity": "sha512-5C/QhkGFh1vqcziq1vAL6SI9ymzUp8BCYjFpvYVhWP4DlATIb3u5q3iUd35mvlyGs8fO7hckkW7i0tmH+5+bvQ==", - "dev": true, - "dependencies": { - "@babel/helper-function-name": "^7.10.1", - "@babel/helper-member-expression-to-functions": "^7.10.1", - "@babel/helper-optimise-call-expression": "^7.10.1", - "@babel/helper-plugin-utils": "^7.10.1", - "@babel/helper-replace-supers": "^7.10.1", - "@babel/helper-split-export-declaration": "^7.10.1" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/helper-create-regexp-features-plugin": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.10.1.tgz", - "integrity": "sha512-Rx4rHS0pVuJn5pJOqaqcZR4XSgeF9G/pO/79t+4r7380tXFJdzImFnxMU19f83wjSrmKHq6myrM10pFHTGzkUA==", - "dev": true, - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.10.1", - "@babel/helper-regex": "^7.10.1", - "regexpu-core": "^4.7.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/helper-define-map": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/helper-define-map/-/helper-define-map-7.10.1.tgz", - "integrity": "sha512-+5odWpX+OnvkD0Zmq7panrMuAGQBu6aPUgvMzuMGo4R+jUOvealEj2hiqI6WhxgKrTpFoFj0+VdsuA8KDxHBDg==", - "dev": true, - "dependencies": { - "@babel/helper-function-name": "^7.10.1", - "@babel/types": "^7.10.1", - "lodash": "^4.17.13" - } - }, - "node_modules/@babel/helper-explode-assignable-expression": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.10.1.tgz", - "integrity": "sha512-vcUJ3cDjLjvkKzt6rHrl767FeE7pMEYfPanq5L16GRtrXIoznc0HykNW2aEYkcnP76P0isoqJ34dDMFZwzEpJg==", - "dev": true, - "dependencies": { - "@babel/traverse": "^7.10.1", - "@babel/types": "^7.10.1" - } - }, - "node_modules/@babel/helper-function-name": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.10.1.tgz", - "integrity": "sha512-fcpumwhs3YyZ/ttd5Rz0xn0TpIwVkN7X0V38B9TWNfVF42KEkhkAAuPCQ3oXmtTRtiPJrmZ0TrfS0GKF0eMaRQ==", - "dev": true, - "dependencies": { - "@babel/helper-get-function-arity": "^7.10.1", - "@babel/template": "^7.10.1", - "@babel/types": "^7.10.1" - } - }, - "node_modules/@babel/helper-get-function-arity": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.10.1.tgz", - "integrity": "sha512-F5qdXkYGOQUb0hpRaPoetF9AnsXknKjWMZ+wmsIRsp5ge5sFh4c3h1eH2pRTTuy9KKAA2+TTYomGXAtEL2fQEw==", - "dev": true, - "dependencies": { - "@babel/types": "^7.10.1" - } - }, - "node_modules/@babel/helper-hoist-variables": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.10.1.tgz", - "integrity": "sha512-vLm5srkU8rI6X3+aQ1rQJyfjvCBLXP8cAGeuw04zeAM2ItKb1e7pmVmLyHb4sDaAYnLL13RHOZPLEtcGZ5xvjg==", - "dev": true, - "dependencies": { - "@babel/types": "^7.10.1" - } - }, - "node_modules/@babel/helper-member-expression-to-functions": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.10.1.tgz", - "integrity": "sha512-u7XLXeM2n50gb6PWJ9hoO5oO7JFPaZtrh35t8RqKLT1jFKj9IWeD1zrcrYp1q1qiZTdEarfDWfTIP8nGsu0h5g==", - "dev": true, - "dependencies": { - "@babel/types": "^7.10.1" - } - }, - "node_modules/@babel/helper-module-imports": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.10.1.tgz", - "integrity": "sha512-SFxgwYmZ3HZPyZwJRiVNLRHWuW2OgE5k2nrVs6D9Iv4PPnXVffuEHy83Sfx/l4SqF+5kyJXjAyUmrG7tNm+qVg==", - "dev": true, - "dependencies": { - "@babel/types": "^7.10.1" - } - }, - "node_modules/@babel/helper-module-transforms": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.10.1.tgz", - "integrity": "sha512-RLHRCAzyJe7Q7sF4oy2cB+kRnU4wDZY/H2xJFGof+M+SJEGhZsb+GFj5j1AD8NiSaVBJ+Pf0/WObiXu/zxWpFg==", - "dev": true, - "dependencies": { - "@babel/helper-module-imports": "^7.10.1", - "@babel/helper-replace-supers": "^7.10.1", - "@babel/helper-simple-access": "^7.10.1", - "@babel/helper-split-export-declaration": "^7.10.1", - "@babel/template": "^7.10.1", - "@babel/types": "^7.10.1", - "lodash": "^4.17.13" - } - }, - "node_modules/@babel/helper-optimise-call-expression": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.10.1.tgz", - "integrity": "sha512-a0DjNS1prnBsoKx83dP2falChcs7p3i8VMzdrSbfLhuQra/2ENC4sbri34dz/rWmDADsmF1q5GbfaXydh0Jbjg==", - "dev": true, - "dependencies": { - "@babel/types": "^7.10.1" - } - }, - "node_modules/@babel/helper-plugin-utils": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.1.tgz", - "integrity": "sha512-fvoGeXt0bJc7VMWZGCAEBEMo/HAjW2mP8apF5eXK0wSqwLAVHAISCWRoLMBMUs2kqeaG77jltVqu4Hn8Egl3nA==", - "dev": true - }, - "node_modules/@babel/helper-regex": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/helper-regex/-/helper-regex-7.10.1.tgz", - "integrity": "sha512-7isHr19RsIJWWLLFn21ubFt223PjQyg1HY7CZEMRr820HttHPpVvrsIN3bUOo44DEfFV4kBXO7Abbn9KTUZV7g==", - "dev": true, - "dependencies": { - "lodash": "^4.17.13" - } - }, - "node_modules/@babel/helper-remap-async-to-generator": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.10.1.tgz", - "integrity": "sha512-RfX1P8HqsfgmJ6CwaXGKMAqbYdlleqglvVtht0HGPMSsy2V6MqLlOJVF/0Qyb/m2ZCi2z3q3+s6Pv7R/dQuZ6A==", - "dev": true, - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.10.1", - "@babel/helper-wrap-function": "^7.10.1", - "@babel/template": "^7.10.1", - "@babel/traverse": "^7.10.1", - "@babel/types": "^7.10.1" - } - }, - "node_modules/@babel/helper-replace-supers": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.10.1.tgz", - "integrity": "sha512-SOwJzEfpuQwInzzQJGjGaiG578UYmyi2Xw668klPWV5n07B73S0a9btjLk/52Mlcxa+5AdIYqws1KyXRfMoB7A==", - "dev": true, - "dependencies": { - "@babel/helper-member-expression-to-functions": "^7.10.1", - "@babel/helper-optimise-call-expression": "^7.10.1", - "@babel/traverse": "^7.10.1", - "@babel/types": "^7.10.1" - } - }, - "node_modules/@babel/helper-simple-access": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.10.1.tgz", - "integrity": "sha512-VSWpWzRzn9VtgMJBIWTZ+GP107kZdQ4YplJlCmIrjoLVSi/0upixezHCDG8kpPVTBJpKfxTH01wDhh+jS2zKbw==", - "dev": true, - "dependencies": { - "@babel/template": "^7.10.1", - "@babel/types": "^7.10.1" - } - }, - "node_modules/@babel/helper-split-export-declaration": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.10.1.tgz", - "integrity": "sha512-UQ1LVBPrYdbchNhLwj6fetj46BcFwfS4NllJo/1aJsT+1dLTEnXJL0qHqtY7gPzF8S2fXBJamf1biAXV3X077g==", - "dev": true, - "dependencies": { - "@babel/types": "^7.10.1" - } - }, - "node_modules/@babel/helper-validator-identifier": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.1.tgz", - "integrity": "sha512-5vW/JXLALhczRCWP0PnFDMCJAchlBvM7f4uk/jXritBnIa6E1KmqmtrS3yn1LAnxFBypQ3eneLuXjsnfQsgILw==", - "dev": true - }, - "node_modules/@babel/helper-wrap-function": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.10.1.tgz", - "integrity": "sha512-C0MzRGteVDn+H32/ZgbAv5r56f2o1fZSA/rj/TYo8JEJNHg+9BdSmKBUND0shxWRztWhjlT2cvHYuynpPsVJwQ==", - "dev": true, - "dependencies": { - "@babel/helper-function-name": "^7.10.1", - "@babel/template": "^7.10.1", - "@babel/traverse": "^7.10.1", - "@babel/types": "^7.10.1" - } - }, - "node_modules/@babel/helpers": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.10.1.tgz", - "integrity": "sha512-muQNHF+IdU6wGgkaJyhhEmI54MOZBKsFfsXFhboz1ybwJ1Kl7IHlbm2a++4jwrmY5UYsgitt5lfqo1wMFcHmyw==", - "dev": true, - "dependencies": { - "@babel/template": "^7.10.1", - "@babel/traverse": "^7.10.1", - "@babel/types": "^7.10.1" - } - }, - "node_modules/@babel/highlight": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.1.tgz", - "integrity": "sha512-8rMof+gVP8mxYZApLF/JgNDAkdKa+aJt3ZYxF8z6+j/hpeXL7iMsKCPHa2jNMHu/qqBwzQF4OHNoYi8dMA/rYg==", - "dev": true, - "dependencies": { - "@babel/helper-validator-identifier": "^7.10.1", - "chalk": "^2.0.0", - "js-tokens": "^4.0.0" - } - }, - "node_modules/@babel/parser": { - "version": "7.10.2", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.10.2.tgz", - "integrity": "sha512-PApSXlNMJyB4JiGVhCOlzKIif+TKFTvu0aQAhnTvfP/z3vVSN6ZypH5bfUNwFXXjRQtUEBNFd2PtmCmG2Py3qQ==", - "dev": true, - "bin": { - "parser": "bin/babel-parser.js" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@babel/plugin-proposal-async-generator-functions": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.10.1.tgz", - "integrity": "sha512-vzZE12ZTdB336POZjmpblWfNNRpMSua45EYnRigE2XsZxcXcIyly2ixnTJasJE4Zq3U7t2d8rRF7XRUuzHxbOw==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.10.1", - "@babel/helper-remap-async-to-generator": "^7.10.1", - "@babel/plugin-syntax-async-generators": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-proposal-class-properties": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.10.1.tgz", - "integrity": "sha512-sqdGWgoXlnOdgMXU+9MbhzwFRgxVLeiGBqTrnuS7LC2IBU31wSsESbTUreT2O418obpfPdGUR2GbEufZF1bpqw==", - "dev": true, - "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.10.1", - "@babel/helper-plugin-utils": "^7.10.1" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-proposal-decorators": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.10.1.tgz", - "integrity": "sha512-xBfteh352MTke2U1NpclzMDmAmCdQ2fBZjhZQQfGTjXw6qcRYMkt528sA1U8o0ThDCSeuETXIj5bOGdxN+5gkw==", - "dev": true, - "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.10.1", - "@babel/helper-plugin-utils": "^7.10.1", - "@babel/plugin-syntax-decorators": "^7.10.1" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-proposal-dynamic-import": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.10.1.tgz", - "integrity": "sha512-Cpc2yUVHTEGPlmiQzXj026kqwjEQAD9I4ZC16uzdbgWgitg/UHKHLffKNCQZ5+y8jpIZPJcKcwsr2HwPh+w3XA==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.10.1", - "@babel/plugin-syntax-dynamic-import": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-proposal-json-strings": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.10.1.tgz", - "integrity": "sha512-m8r5BmV+ZLpWPtMY2mOKN7wre6HIO4gfIiV+eOmsnZABNenrt/kzYBwrh+KOfgumSWpnlGs5F70J8afYMSJMBg==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.10.1", - "@babel/plugin-syntax-json-strings": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-proposal-nullish-coalescing-operator": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.10.1.tgz", - "integrity": "sha512-56cI/uHYgL2C8HVuHOuvVowihhX0sxb3nnfVRzUeVHTWmRHTZrKuAh/OBIMggGU/S1g/1D2CRCXqP+3u7vX7iA==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.10.1", - "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-proposal-numeric-separator": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.10.1.tgz", - "integrity": "sha512-jjfym4N9HtCiNfyyLAVD8WqPYeHUrw4ihxuAynWj6zzp2gf9Ey2f7ImhFm6ikB3CLf5Z/zmcJDri6B4+9j9RsA==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.10.1", - "@babel/plugin-syntax-numeric-separator": "^7.10.1" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-proposal-object-rest-spread": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.10.1.tgz", - "integrity": "sha512-Z+Qri55KiQkHh7Fc4BW6o+QBuTagbOp9txE+4U1i79u9oWlf2npkiDx+Rf3iK3lbcHBuNy9UOkwuR5wOMH3LIQ==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.10.1", - "@babel/plugin-syntax-object-rest-spread": "^7.8.0", - "@babel/plugin-transform-parameters": "^7.10.1" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-proposal-optional-catch-binding": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.10.1.tgz", - "integrity": "sha512-VqExgeE62YBqI3ogkGoOJp1R6u12DFZjqwJhqtKc2o5m1YTUuUWnos7bZQFBhwkxIFpWYJ7uB75U7VAPPiKETA==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.10.1", - "@babel/plugin-syntax-optional-catch-binding": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-proposal-optional-chaining": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.10.1.tgz", - "integrity": "sha512-dqQj475q8+/avvok72CF3AOSV/SGEcH29zT5hhohqqvvZ2+boQoOr7iGldBG5YXTO2qgCgc2B3WvVLUdbeMlGA==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.10.1", - "@babel/plugin-syntax-optional-chaining": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-proposal-private-methods": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.10.1.tgz", - "integrity": "sha512-RZecFFJjDiQ2z6maFprLgrdnm0OzoC23Mx89xf1CcEsxmHuzuXOdniEuI+S3v7vjQG4F5sa6YtUp+19sZuSxHg==", - "dev": true, - "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.10.1", - "@babel/helper-plugin-utils": "^7.10.1" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-proposal-unicode-property-regex": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.10.1.tgz", - "integrity": "sha512-JjfngYRvwmPwmnbRZyNiPFI8zxCZb8euzbCG/LxyKdeTb59tVciKo9GK9bi6JYKInk1H11Dq9j/zRqIH4KigfQ==", - "dev": true, - "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.10.1", - "@babel/helper-plugin-utils": "^7.10.1" - }, - "engines": { - "node": ">=4" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-async-generators": { - "version": "7.8.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", - "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-class-properties": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.10.1.tgz", - "integrity": "sha512-Gf2Yx/iRs1JREDtVZ56OrjjgFHCaldpTnuy9BHla10qyVT3YkIIGEtoDWhyop0ksu1GvNjHIoYRBqm3zoR1jyQ==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.10.1" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-decorators": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-decorators/-/plugin-syntax-decorators-7.10.1.tgz", - "integrity": "sha512-a9OAbQhKOwSle1Vr0NJu/ISg1sPfdEkfRKWpgPuzhnWWzForou2gIeUIIwjAMHRekhhpJ7eulZlYs0H14Cbi+g==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.10.1" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-dynamic-import": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz", - "integrity": "sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-json-strings": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", - "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-jsx": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.10.1.tgz", - "integrity": "sha512-+OxyOArpVFXQeXKLO9o+r2I4dIoVoy6+Uu0vKELrlweDM3QJADZj+Z+5ERansZqIZBcLj42vHnDI8Rz9BnRIuQ==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.10.1" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-nullish-coalescing-operator": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", - "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-numeric-separator": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.1.tgz", - "integrity": "sha512-uTd0OsHrpe3tH5gRPTxG8Voh99/WCU78vIm5NMRYPAqC8lR4vajt6KkCAknCHrx24vkPdd/05yfdGSB4EIY2mg==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.10.1" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-object-rest-spread": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", - "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-optional-catch-binding": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", - "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-optional-chaining": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", - "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-top-level-await": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.10.1.tgz", - "integrity": "sha512-hgA5RYkmZm8FTFT3yu2N9Bx7yVVOKYT6yEdXXo6j2JTm0wNxgqaGeQVaSHRjhfnQbX91DtjFB6McRFSlcJH3xQ==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.10.1" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-arrow-functions": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.10.1.tgz", - "integrity": "sha512-6AZHgFJKP3DJX0eCNJj01RpytUa3SOGawIxweHkNX2L6PYikOZmoh5B0d7hIHaIgveMjX990IAa/xK7jRTN8OA==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.10.1" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-async-to-generator": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.10.1.tgz", - "integrity": "sha512-XCgYjJ8TY2slj6SReBUyamJn3k2JLUIiiR5b6t1mNCMSvv7yx+jJpaewakikp0uWFQSF7ChPPoe3dHmXLpISkg==", - "dev": true, - "dependencies": { - "@babel/helper-module-imports": "^7.10.1", - "@babel/helper-plugin-utils": "^7.10.1", - "@babel/helper-remap-async-to-generator": "^7.10.1" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-block-scoped-functions": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.10.1.tgz", - "integrity": "sha512-B7K15Xp8lv0sOJrdVAoukKlxP9N59HS48V1J3U/JGj+Ad+MHq+am6xJVs85AgXrQn4LV8vaYFOB+pr/yIuzW8Q==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.10.1" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-block-scoping": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.10.1.tgz", - "integrity": "sha512-8bpWG6TtF5akdhIm/uWTyjHqENpy13Fx8chg7pFH875aNLwX8JxIxqm08gmAT+Whe6AOmaTeLPe7dpLbXt+xUw==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.10.1", - "lodash": "^4.17.13" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-classes": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.10.1.tgz", - "integrity": "sha512-P9V0YIh+ln/B3RStPoXpEQ/CoAxQIhRSUn7aXqQ+FZJ2u8+oCtjIXR3+X0vsSD8zv+mb56K7wZW1XiDTDGiDRQ==", - "dev": true, - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.10.1", - "@babel/helper-define-map": "^7.10.1", - "@babel/helper-function-name": "^7.10.1", - "@babel/helper-optimise-call-expression": "^7.10.1", - "@babel/helper-plugin-utils": "^7.10.1", - "@babel/helper-replace-supers": "^7.10.1", - "@babel/helper-split-export-declaration": "^7.10.1", - "globals": "^11.1.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-computed-properties": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.10.1.tgz", - "integrity": "sha512-mqSrGjp3IefMsXIenBfGcPXxJxweQe2hEIwMQvjtiDQ9b1IBvDUjkAtV/HMXX47/vXf14qDNedXsIiNd1FmkaQ==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.10.1" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-destructuring": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.10.1.tgz", - "integrity": "sha512-V/nUc4yGWG71OhaTH705pU8ZSdM6c1KmmLP8ys59oOYbT7RpMYAR3MsVOt6OHL0WzG7BlTU076va9fjJyYzJMA==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.10.1" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-dotall-regex": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.10.1.tgz", - "integrity": "sha512-19VIMsD1dp02RvduFUmfzj8uknaO3uiHHF0s3E1OHnVsNj8oge8EQ5RzHRbJjGSetRnkEuBYO7TG1M5kKjGLOA==", - "dev": true, - "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.10.1", - "@babel/helper-plugin-utils": "^7.10.1" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-duplicate-keys": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.10.1.tgz", - "integrity": "sha512-wIEpkX4QvX8Mo9W6XF3EdGttrIPZWozHfEaDTU0WJD/TDnXMvdDh30mzUl/9qWhnf7naicYartcEfUghTCSNpA==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.10.1" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-exponentiation-operator": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.10.1.tgz", - "integrity": "sha512-lr/przdAbpEA2BUzRvjXdEDLrArGRRPwbaF9rvayuHRvdQ7lUTTkZnhZrJ4LE2jvgMRFF4f0YuPQ20vhiPYxtA==", - "dev": true, - "dependencies": { - "@babel/helper-builder-binary-assignment-operator-visitor": "^7.10.1", - "@babel/helper-plugin-utils": "^7.10.1" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-for-of": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.10.1.tgz", - "integrity": "sha512-US8KCuxfQcn0LwSCMWMma8M2R5mAjJGsmoCBVwlMygvmDUMkTCykc84IqN1M7t+agSfOmLYTInLCHJM+RUoz+w==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.10.1" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-function-name": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.10.1.tgz", - "integrity": "sha512-//bsKsKFBJfGd65qSNNh1exBy5Y9gD9ZN+DvrJ8f7HXr4avE5POW6zB7Rj6VnqHV33+0vXWUwJT0wSHubiAQkw==", - "dev": true, - "dependencies": { - "@babel/helper-function-name": "^7.10.1", - "@babel/helper-plugin-utils": "^7.10.1" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-literals": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.10.1.tgz", - "integrity": "sha512-qi0+5qgevz1NHLZroObRm5A+8JJtibb7vdcPQF1KQE12+Y/xxl8coJ+TpPW9iRq+Mhw/NKLjm+5SHtAHCC7lAw==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.10.1" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-member-expression-literals": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.10.1.tgz", - "integrity": "sha512-UmaWhDokOFT2GcgU6MkHC11i0NQcL63iqeufXWfRy6pUOGYeCGEKhvfFO6Vz70UfYJYHwveg62GS83Rvpxn+NA==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.10.1" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-modules-amd": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.10.1.tgz", - "integrity": "sha512-31+hnWSFRI4/ACFr1qkboBbrTxoBIzj7qA69qlq8HY8p7+YCzkCT6/TvQ1a4B0z27VeWtAeJd6pr5G04dc1iHw==", - "dev": true, - "dependencies": { - "@babel/helper-module-transforms": "^7.10.1", - "@babel/helper-plugin-utils": "^7.10.1", - "babel-plugin-dynamic-import-node": "^2.3.3" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-modules-commonjs": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.10.1.tgz", - "integrity": "sha512-AQG4fc3KOah0vdITwt7Gi6hD9BtQP/8bhem7OjbaMoRNCH5Djx42O2vYMfau7QnAzQCa+RJnhJBmFFMGpQEzrg==", - "dev": true, - "dependencies": { - "@babel/helper-module-transforms": "^7.10.1", - "@babel/helper-plugin-utils": "^7.10.1", - "@babel/helper-simple-access": "^7.10.1", - "babel-plugin-dynamic-import-node": "^2.3.3" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-modules-systemjs": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.10.1.tgz", - "integrity": "sha512-ewNKcj1TQZDL3YnO85qh9zo1YF1CHgmSTlRQgHqe63oTrMI85cthKtZjAiZSsSNjPQ5NCaYo5QkbYqEw1ZBgZA==", - "dev": true, - "dependencies": { - "@babel/helper-hoist-variables": "^7.10.1", - "@babel/helper-module-transforms": "^7.10.1", - "@babel/helper-plugin-utils": "^7.10.1", - "babel-plugin-dynamic-import-node": "^2.3.3" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-modules-umd": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.10.1.tgz", - "integrity": "sha512-EIuiRNMd6GB6ulcYlETnYYfgv4AxqrswghmBRQbWLHZxN4s7mupxzglnHqk9ZiUpDI4eRWewedJJNj67PWOXKA==", - "dev": true, - "dependencies": { - "@babel/helper-module-transforms": "^7.10.1", - "@babel/helper-plugin-utils": "^7.10.1" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-named-capturing-groups-regex": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.8.3.tgz", - "integrity": "sha512-f+tF/8UVPU86TrCb06JoPWIdDpTNSGGcAtaD9mLP0aYGA0OS0j7j7DHJR0GTFrUZPUU6loZhbsVZgTh0N+Qdnw==", - "dev": true, - "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.8.3" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/plugin-transform-new-target": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.10.1.tgz", - "integrity": "sha512-MBlzPc1nJvbmO9rPr1fQwXOM2iGut+JC92ku6PbiJMMK7SnQc1rytgpopveE3Evn47gzvGYeCdgfCDbZo0ecUw==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.10.1" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-object-super": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.10.1.tgz", - "integrity": "sha512-WnnStUDN5GL+wGQrJylrnnVlFhFmeArINIR9gjhSeYyvroGhBrSAXYg/RHsnfzmsa+onJrTJrEClPzgNmmQ4Gw==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.10.1", - "@babel/helper-replace-supers": "^7.10.1" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-parameters": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.10.1.tgz", - "integrity": "sha512-tJ1T0n6g4dXMsL45YsSzzSDZCxiHXAQp/qHrucOq5gEHncTA3xDxnd5+sZcoQp+N1ZbieAaB8r/VUCG0gqseOg==", - "dev": true, - "dependencies": { - "@babel/helper-get-function-arity": "^7.10.1", - "@babel/helper-plugin-utils": "^7.10.1" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-property-literals": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.10.1.tgz", - "integrity": "sha512-Kr6+mgag8auNrgEpbfIWzdXYOvqDHZOF0+Bx2xh4H2EDNwcbRb9lY6nkZg8oSjsX+DH9Ebxm9hOqtKW+gRDeNA==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.10.1" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-regenerator": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.10.1.tgz", - "integrity": "sha512-B3+Y2prScgJ2Bh/2l9LJxKbb8C8kRfsG4AdPT+n7ixBHIxJaIG8bi8tgjxUMege1+WqSJ+7gu1YeoMVO3gPWzw==", - "dev": true, - "dependencies": { - "regenerator-transform": "^0.14.2" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-reserved-words": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.10.1.tgz", - "integrity": "sha512-qN1OMoE2nuqSPmpTqEM7OvJ1FkMEV+BjVeZZm9V9mq/x1JLKQ4pcv8riZJMNN3u2AUGl0ouOMjRr2siecvHqUQ==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.10.1" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-runtime": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.10.1.tgz", - "integrity": "sha512-4w2tcglDVEwXJ5qxsY++DgWQdNJcCCsPxfT34wCUwIf2E7dI7pMpH8JczkMBbgBTNzBX62SZlNJ9H+De6Zebaw==", - "dev": true, - "dependencies": { - "@babel/helper-module-imports": "^7.10.1", - "@babel/helper-plugin-utils": "^7.10.1", - "resolve": "^1.8.1", - "semver": "^5.5.1" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-shorthand-properties": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.10.1.tgz", - "integrity": "sha512-AR0E/lZMfLstScFwztApGeyTHJ5u3JUKMjneqRItWeEqDdHWZwAOKycvQNCasCK/3r5YXsuNG25funcJDu7Y2g==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.10.1" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-spread": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.10.1.tgz", - "integrity": "sha512-8wTPym6edIrClW8FI2IoaePB91ETOtg36dOkj3bYcNe7aDMN2FXEoUa+WrmPc4xa1u2PQK46fUX2aCb+zo9rfw==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.10.1" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-sticky-regex": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.10.1.tgz", - "integrity": "sha512-j17ojftKjrL7ufX8ajKvwRilwqTok4q+BjkknmQw9VNHnItTyMP5anPFzxFJdCQs7clLcWpCV3ma+6qZWLnGMA==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.10.1", - "@babel/helper-regex": "^7.10.1" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-template-literals": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.10.1.tgz", - "integrity": "sha512-t7B/3MQf5M1T9hPCRG28DNGZUuxAuDqLYS03rJrIk2prj/UV7Z6FOneijhQhnv/Xa039vidXeVbvjK2SK5f7Gg==", - "dev": true, - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.10.1", - "@babel/helper-plugin-utils": "^7.10.1" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-typeof-symbol": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.10.1.tgz", - "integrity": "sha512-qX8KZcmbvA23zDi+lk9s6hC1FM7jgLHYIjuLgULgc8QtYnmB3tAVIYkNoKRQ75qWBeyzcoMoK8ZQmogGtC/w0g==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.10.1" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-unicode-escapes": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.10.1.tgz", - "integrity": "sha512-zZ0Poh/yy1d4jeDWpx/mNwbKJVwUYJX73q+gyh4bwtG0/iUlzdEu0sLMda8yuDFS6LBQlT/ST1SJAR6zYwXWgw==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.10.1" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-unicode-regex": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.10.1.tgz", - "integrity": "sha512-Y/2a2W299k0VIUdbqYm9X2qS6fE0CUBhhiPpimK6byy7OJ/kORLlIX+J6UrjgNu5awvs62k+6RSslxhcvVw2Tw==", - "dev": true, - "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.10.1", - "@babel/helper-plugin-utils": "^7.10.1" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/preset-env": { - "version": "7.10.2", - "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.10.2.tgz", - "integrity": "sha512-MjqhX0RZaEgK/KueRzh+3yPSk30oqDKJ5HP5tqTSB1e2gzGS3PLy7K0BIpnp78+0anFuSwOeuCf1zZO7RzRvEA==", - "dev": true, - "dependencies": { - "@babel/compat-data": "^7.10.1", - "@babel/helper-compilation-targets": "^7.10.2", - "@babel/helper-module-imports": "^7.10.1", - "@babel/helper-plugin-utils": "^7.10.1", - "@babel/plugin-proposal-async-generator-functions": "^7.10.1", - "@babel/plugin-proposal-class-properties": "^7.10.1", - "@babel/plugin-proposal-dynamic-import": "^7.10.1", - "@babel/plugin-proposal-json-strings": "^7.10.1", - "@babel/plugin-proposal-nullish-coalescing-operator": "^7.10.1", - "@babel/plugin-proposal-numeric-separator": "^7.10.1", - "@babel/plugin-proposal-object-rest-spread": "^7.10.1", - "@babel/plugin-proposal-optional-catch-binding": "^7.10.1", - "@babel/plugin-proposal-optional-chaining": "^7.10.1", - "@babel/plugin-proposal-private-methods": "^7.10.1", - "@babel/plugin-proposal-unicode-property-regex": "^7.10.1", - "@babel/plugin-syntax-async-generators": "^7.8.0", - "@babel/plugin-syntax-class-properties": "^7.10.1", - "@babel/plugin-syntax-dynamic-import": "^7.8.0", - "@babel/plugin-syntax-json-strings": "^7.8.0", - "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.0", - "@babel/plugin-syntax-numeric-separator": "^7.10.1", - "@babel/plugin-syntax-object-rest-spread": "^7.8.0", - "@babel/plugin-syntax-optional-catch-binding": "^7.8.0", - "@babel/plugin-syntax-optional-chaining": "^7.8.0", - "@babel/plugin-syntax-top-level-await": "^7.10.1", - "@babel/plugin-transform-arrow-functions": "^7.10.1", - "@babel/plugin-transform-async-to-generator": "^7.10.1", - "@babel/plugin-transform-block-scoped-functions": "^7.10.1", - "@babel/plugin-transform-block-scoping": "^7.10.1", - "@babel/plugin-transform-classes": "^7.10.1", - "@babel/plugin-transform-computed-properties": "^7.10.1", - "@babel/plugin-transform-destructuring": "^7.10.1", - "@babel/plugin-transform-dotall-regex": "^7.10.1", - "@babel/plugin-transform-duplicate-keys": "^7.10.1", - "@babel/plugin-transform-exponentiation-operator": "^7.10.1", - "@babel/plugin-transform-for-of": "^7.10.1", - "@babel/plugin-transform-function-name": "^7.10.1", - "@babel/plugin-transform-literals": "^7.10.1", - "@babel/plugin-transform-member-expression-literals": "^7.10.1", - "@babel/plugin-transform-modules-amd": "^7.10.1", - "@babel/plugin-transform-modules-commonjs": "^7.10.1", - "@babel/plugin-transform-modules-systemjs": "^7.10.1", - "@babel/plugin-transform-modules-umd": "^7.10.1", - "@babel/plugin-transform-named-capturing-groups-regex": "^7.8.3", - "@babel/plugin-transform-new-target": "^7.10.1", - "@babel/plugin-transform-object-super": "^7.10.1", - "@babel/plugin-transform-parameters": "^7.10.1", - "@babel/plugin-transform-property-literals": "^7.10.1", - "@babel/plugin-transform-regenerator": "^7.10.1", - "@babel/plugin-transform-reserved-words": "^7.10.1", - "@babel/plugin-transform-shorthand-properties": "^7.10.1", - "@babel/plugin-transform-spread": "^7.10.1", - "@babel/plugin-transform-sticky-regex": "^7.10.1", - "@babel/plugin-transform-template-literals": "^7.10.1", - "@babel/plugin-transform-typeof-symbol": "^7.10.1", - "@babel/plugin-transform-unicode-escapes": "^7.10.1", - "@babel/plugin-transform-unicode-regex": "^7.10.1", - "@babel/preset-modules": "^0.1.3", - "@babel/types": "^7.10.2", - "browserslist": "^4.12.0", - "core-js-compat": "^3.6.2", - "invariant": "^2.2.2", - "levenary": "^1.1.1", - "semver": "^5.5.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/preset-modules": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.3.tgz", - "integrity": "sha512-Ra3JXOHBq2xd56xSF7lMKXdjBn3T772Y1Wet3yWnkDly9zHvJki029tAFzvAAK5cf4YV3yoxuP61crYRol6SVg==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.0.0", - "@babel/plugin-proposal-unicode-property-regex": "^7.4.4", - "@babel/plugin-transform-dotall-regex": "^7.4.4", - "@babel/types": "^7.4.4", - "esutils": "^2.0.2" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/runtime": { - "version": "7.10.2", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.10.2.tgz", - "integrity": "sha512-6sF3uQw2ivImfVIl62RZ7MXhO2tap69WeWK57vAaimT6AZbE4FbqjdEJIN1UqoD6wI6B+1n9UiagafH1sxjOtg==", - "dev": true, - "dependencies": { - "regenerator-runtime": "^0.13.4" - } - }, - "node_modules/@babel/template": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.10.1.tgz", - "integrity": "sha512-OQDg6SqvFSsc9A0ej6SKINWrpJiNonRIniYondK2ViKhB06i3c0s+76XUft71iqBEe9S1OKsHwPAjfHnuvnCig==", - "dev": true, - "dependencies": { - "@babel/code-frame": "^7.10.1", - "@babel/parser": "^7.10.1", - "@babel/types": "^7.10.1" - } - }, - "node_modules/@babel/traverse": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.10.1.tgz", - "integrity": "sha512-C/cTuXeKt85K+p08jN6vMDz8vSV0vZcI0wmQ36o6mjbuo++kPMdpOYw23W2XH04dbRt9/nMEfA4W3eR21CD+TQ==", - "dev": true, - "dependencies": { - "@babel/code-frame": "^7.10.1", - "@babel/generator": "^7.10.1", - "@babel/helper-function-name": "^7.10.1", - "@babel/helper-split-export-declaration": "^7.10.1", - "@babel/parser": "^7.10.1", - "@babel/types": "^7.10.1", - "debug": "^4.1.0", - "globals": "^11.1.0", - "lodash": "^4.17.13" - } - }, - "node_modules/@babel/types": { - "version": "7.10.2", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.10.2.tgz", - "integrity": "sha512-AD3AwWBSz0AWF0AkCN9VPiWrvldXq+/e3cHa4J89vo4ymjz1XwrBFFVZmkJTsQIPNk+ZVomPSXUJqq8yyjZsng==", - "dev": true, - "dependencies": { - "@babel/helper-validator-identifier": "^7.10.1", - "lodash": "^4.17.13", - "to-fast-properties": "^2.0.0" - } - }, - "node_modules/@mrmlnc/readdir-enhanced": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/@mrmlnc/readdir-enhanced/-/readdir-enhanced-2.2.1.tgz", - "integrity": "sha512-bPHp6Ji8b41szTOcaP63VlnbbO5Ny6dwAATtY6JTjh5N2OLrb5Qk/Th5cRkRQhkWCt+EJsYrNB0MiL+Gpn6e3g==", - "dev": true, - "dependencies": { - "call-me-maybe": "^1.0.1", - "glob-to-regexp": "^0.3.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@nodelib/fs.stat": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-1.1.3.tgz", - "integrity": "sha512-shAmDyaQC4H92APFoIaVDHCx5bStIocgvbwQyxPRrbUY20V1EYTbSDchWbuwlMG3V17cprZhA6+78JfB+3DTPw==", - "dev": true, - "engines": { - "node": ">= 6" - } - }, - "node_modules/@sindresorhus/is": { - "version": "0.14.0", - "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.14.0.tgz", - "integrity": "sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/@szmarczak/http-timer": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-1.1.2.tgz", - "integrity": "sha512-XIB2XbzHTN6ieIjfIMV9hlVcfPU26s2vafYWQcZHWXHOxiaRZYEDKEwdl129Zyg50+foYV2jCgtrqSA6qNuNSA==", - "dev": true, - "dependencies": { - "defer-to-connect": "^1.0.1" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/@types/color-name": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@types/color-name/-/color-name-1.1.1.tgz", - "integrity": "sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==", - "dev": true - }, - "node_modules/@types/glob": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.2.tgz", - "integrity": "sha512-VgNIkxK+j7Nz5P7jvUZlRvhuPSmsEfS03b0alKcq5V/STUKAa3Plemsn5mrQUO7am6OErJ4rhGEGJbACclrtRA==", - "dev": true, - "dependencies": { - "@types/minimatch": "*", - "@types/node": "*" - } - }, - "node_modules/@types/json-schema": { - "version": "7.0.5", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.5.tgz", - "integrity": "sha512-7+2BITlgjgDhH0vvwZU/HZJVyk+2XUlvxXe8dFMedNX/aMkaOq++rMAFXc0tM7ij15QaWlbdQASBR9dihi+bDQ==", - "dev": true - }, - "node_modules/@types/minimatch": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz", - "integrity": "sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==", - "dev": true - }, - "node_modules/@types/node": { - "version": "14.0.13", - "resolved": "https://registry.npmjs.org/@types/node/-/node-14.0.13.tgz", - "integrity": "sha512-rouEWBImiRaSJsVA+ITTFM6ZxibuAlTuNOCyxVbwreu6k6+ujs7DfnU9o+PShFhET78pMBl3eH+AGSI5eOTkPA==", - "dev": true - }, - "node_modules/@types/q": { - "version": "1.5.4", - "resolved": "https://registry.npmjs.org/@types/q/-/q-1.5.4.tgz", - "integrity": "sha512-1HcDas8SEj4z1Wc696tH56G8OlRaH/sqZOynNNB+HF0WOeXPaxTtbYzJY2oEfiUxjSKjhCKr+MvR7dCHcEelug==", - "dev": true - }, - "node_modules/@vue/babel-helper-vue-jsx-merge-props": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@vue/babel-helper-vue-jsx-merge-props/-/babel-helper-vue-jsx-merge-props-1.0.0.tgz", - "integrity": "sha512-6tyf5Cqm4m6v7buITuwS+jHzPlIPxbFzEhXR5JGZpbrvOcp1hiQKckd305/3C7C36wFekNTQSxAtgeM0j0yoUw==", - "dev": true - }, - "node_modules/@vue/babel-plugin-transform-vue-jsx": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@vue/babel-plugin-transform-vue-jsx/-/babel-plugin-transform-vue-jsx-1.1.2.tgz", - "integrity": "sha512-YfdaoSMvD1nj7+DsrwfTvTnhDXI7bsuh+Y5qWwvQXlD24uLgnsoww3qbiZvWf/EoviZMrvqkqN4CBw0W3BWUTQ==", - "dev": true, - "dependencies": { - "@babel/helper-module-imports": "^7.0.0", - "@babel/plugin-syntax-jsx": "^7.2.0", - "@vue/babel-helper-vue-jsx-merge-props": "^1.0.0", - "html-tags": "^2.0.0", - "lodash.kebabcase": "^4.1.1", - "svg-tags": "^1.0.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@vue/babel-preset-app": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/@vue/babel-preset-app/-/babel-preset-app-4.4.1.tgz", - "integrity": "sha512-VHVROEBBiW0dnuNuzlFElkncXo+zxh5Px0MZ51Th5da8UPbQodf43mnpotMnFtmCPTXAFL58tzDttu1FgrgfpQ==", - "dev": true, - "dependencies": { - "@babel/core": "^7.9.6", - "@babel/helper-compilation-targets": "^7.9.6", - "@babel/helper-module-imports": "^7.8.3", - "@babel/plugin-proposal-class-properties": "^7.8.3", - "@babel/plugin-proposal-decorators": "^7.8.3", - "@babel/plugin-syntax-dynamic-import": "^7.8.3", - "@babel/plugin-syntax-jsx": "^7.8.3", - "@babel/plugin-transform-runtime": "^7.9.6", - "@babel/preset-env": "^7.9.6", - "@babel/runtime": "^7.9.6", - "@vue/babel-preset-jsx": "^1.1.2", - "babel-plugin-dynamic-import-node": "^2.3.3", - "core-js": "^3.6.5", - "core-js-compat": "^3.6.5", - "semver": "^6.1.0" - }, - "peerDependencies": { - "@babel/core": "*", - "core-js": "^3" - }, - "peerDependenciesMeta": { - "core-js": { - "optional": true - } - } - }, - "node_modules/@vue/babel-preset-app/node_modules/semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true, - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/@vue/babel-preset-jsx": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@vue/babel-preset-jsx/-/babel-preset-jsx-1.1.2.tgz", - "integrity": "sha512-zDpVnFpeC9YXmvGIDSsKNdL7qCG2rA3gjywLYHPCKDT10erjxF4U+6ay9X6TW5fl4GsDlJp9bVfAVQAAVzxxvQ==", - "dev": true, - "dependencies": { - "@vue/babel-helper-vue-jsx-merge-props": "^1.0.0", - "@vue/babel-plugin-transform-vue-jsx": "^1.1.2", - "@vue/babel-sugar-functional-vue": "^1.1.2", - "@vue/babel-sugar-inject-h": "^1.1.2", - "@vue/babel-sugar-v-model": "^1.1.2", - "@vue/babel-sugar-v-on": "^1.1.2" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@vue/babel-sugar-functional-vue": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@vue/babel-sugar-functional-vue/-/babel-sugar-functional-vue-1.1.2.tgz", - "integrity": "sha512-YhmdJQSVEFF5ETJXzrMpj0nkCXEa39TvVxJTuVjzvP2rgKhdMmQzlJuMv/HpadhZaRVMCCF3AEjjJcK5q/cYzQ==", - "dev": true, - "dependencies": { - "@babel/plugin-syntax-jsx": "^7.2.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@vue/babel-sugar-inject-h": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@vue/babel-sugar-inject-h/-/babel-sugar-inject-h-1.1.2.tgz", - "integrity": "sha512-VRSENdTvD5htpnVp7i7DNuChR5rVMcORdXjvv5HVvpdKHzDZAYiLSD+GhnhxLm3/dMuk8pSzV+k28ECkiN5m8w==", - "dev": true, - "dependencies": { - "@babel/plugin-syntax-jsx": "^7.2.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@vue/babel-sugar-v-model": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@vue/babel-sugar-v-model/-/babel-sugar-v-model-1.1.2.tgz", - "integrity": "sha512-vLXPvNq8vDtt0u9LqFdpGM9W9IWDmCmCyJXuozlq4F4UYVleXJ2Fa+3JsnTZNJcG+pLjjfnEGHci2339Kj5sGg==", - "dev": true, - "dependencies": { - "@babel/plugin-syntax-jsx": "^7.2.0", - "@vue/babel-helper-vue-jsx-merge-props": "^1.0.0", - "@vue/babel-plugin-transform-vue-jsx": "^1.1.2", - "camelcase": "^5.0.0", - "html-tags": "^2.0.0", - "svg-tags": "^1.0.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@vue/babel-sugar-v-on": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@vue/babel-sugar-v-on/-/babel-sugar-v-on-1.1.2.tgz", - "integrity": "sha512-T8ZCwC8Jp2uRtcZ88YwZtZXe7eQrJcfRq0uTFy6ShbwYJyz5qWskRFoVsdTi9o0WEhmQXxhQUewodOSCUPVmsQ==", - "dev": true, - "dependencies": { - "@babel/plugin-syntax-jsx": "^7.2.0", - "@vue/babel-plugin-transform-vue-jsx": "^1.1.2", - "camelcase": "^5.0.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@vue/component-compiler-utils": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/@vue/component-compiler-utils/-/component-compiler-utils-3.1.2.tgz", - "integrity": "sha512-QLq9z8m79mCinpaEeSURhnNCN6djxpHw0lpP/bodMlt5kALfONpryMthvnrQOlTcIKoF+VoPi+lPHUYeDFPXug==", - "dev": true, - "dependencies": { - "consolidate": "^0.15.1", - "hash-sum": "^1.0.2", - "lru-cache": "^4.1.2", - "merge-source-map": "^1.1.0", - "postcss": "^7.0.14", - "postcss-selector-parser": "^6.0.2", - "source-map": "~0.6.1", - "vue-template-es2015-compiler": "^1.9.0" - }, - "optionalDependencies": { - "prettier": "^1.18.2" - } - }, - "node_modules/@vue/component-compiler-utils/node_modules/lru-cache": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", - "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", - "dev": true, - "dependencies": { - "pseudomap": "^1.0.2", - "yallist": "^2.1.2" - } - }, - "node_modules/@vue/component-compiler-utils/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/@vue/component-compiler-utils/node_modules/yallist": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", - "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=", - "dev": true - }, - "node_modules/@vuepress/core": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/@vuepress/core/-/core-1.5.1.tgz", - "integrity": "sha512-gLogkq6Mm8/y7SuywNNE2ny2idMAoBUnRV40TpYK1pOAjQKRlbh3C1fDck+N/nUubB7zKkZUt7uBVqzSRGk9/g==", - "dev": true, - "dependencies": { - "@babel/core": "^7.8.4", - "@vue/babel-preset-app": "^4.1.2", - "@vuepress/markdown": "1.5.1", - "@vuepress/markdown-loader": "1.5.1", - "@vuepress/plugin-last-updated": "1.5.1", - "@vuepress/plugin-register-components": "1.5.1", - "@vuepress/shared-utils": "1.5.1", - "autoprefixer": "^9.5.1", - "babel-loader": "^8.0.4", - "cache-loader": "^3.0.0", - "chokidar": "^2.0.3", - "connect-history-api-fallback": "^1.5.0", - "copy-webpack-plugin": "^5.0.2", - "core-js": "^3.6.4", - "cross-spawn": "^6.0.5", - "css-loader": "^2.1.1", - "file-loader": "^3.0.1", - "js-yaml": "^3.13.1", - "lru-cache": "^5.1.1", - "mini-css-extract-plugin": "0.6.0", - "optimize-css-assets-webpack-plugin": "^5.0.1", - "portfinder": "^1.0.13", - "postcss-loader": "^3.0.0", - "postcss-safe-parser": "^4.0.1", - "toml": "^3.0.0", - "url-loader": "^1.0.1", - "vue": "^2.6.10", - "vue-loader": "^15.7.1", - "vue-router": "^3.1.3", - "vue-server-renderer": "^2.6.10", - "vue-template-compiler": "^2.6.10", - "vuepress-html-webpack-plugin": "^3.2.0", - "vuepress-plugin-container": "^2.0.2", - "webpack": "^4.8.1", - "webpack-chain": "^6.0.0", - "webpack-dev-server": "^3.5.1", - "webpack-merge": "^4.1.2", - "webpackbar": "3.2.0" - }, - "engines": { - "node": ">=8.6" - } - }, - "node_modules/@vuepress/markdown": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/@vuepress/markdown/-/markdown-1.5.1.tgz", - "integrity": "sha512-GzlSa2stbmcnAIgdQISXzDW6qlXONp0wxdB5OFOJe6tBHW1JcSiXFk6A9bcQuYKoF+wyAZyrLExpM8FVp0qpug==", - "dev": true, - "dependencies": { - "@vuepress/shared-utils": "1.5.1", - "markdown-it": "^8.4.1", - "markdown-it-anchor": "^5.0.2", - "markdown-it-chain": "^1.3.0", - "markdown-it-emoji": "^1.4.0", - "markdown-it-table-of-contents": "^0.4.0", - "prismjs": "^1.13.0" - } - }, - "node_modules/@vuepress/markdown-loader": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/@vuepress/markdown-loader/-/markdown-loader-1.5.1.tgz", - "integrity": "sha512-yITErIhfzjNBV4KC4dALGDoe9nIF29YQcIC0UbtNtV2zlkUERkRkP+AowT3G1WMBYzY3XhtoCZqXtxxuSCDILQ==", - "dev": true, - "dependencies": { - "@vuepress/markdown": "1.5.1", - "loader-utils": "^1.1.0", - "lru-cache": "^5.1.1" - } - }, - "node_modules/@vuepress/plugin-active-header-links": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/@vuepress/plugin-active-header-links/-/plugin-active-header-links-1.5.1.tgz", - "integrity": "sha512-GGqmlJlIJ3NEkAi2Gzob6CemDL5o0cv4TRLvWzjW43H0Pj1idoOi0mbKXtWAIZ6QicrZupeJUMhy49qyipvSWQ==", - "dev": true, - "dependencies": { - "lodash.debounce": "^4.0.8" - } - }, - "node_modules/@vuepress/plugin-last-updated": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/@vuepress/plugin-last-updated/-/plugin-last-updated-1.5.1.tgz", - "integrity": "sha512-uG9P88gJ7KxmMDcTCEHbT248rJ0fZABeHxvyXodUAzSG0bDdqXjw4p34PdkzlWnHHLDiYKBIHIcEYSvKmOiRPQ==", - "dev": true, - "dependencies": { - "cross-spawn": "^6.0.5" - } - }, - "node_modules/@vuepress/plugin-nprogress": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/@vuepress/plugin-nprogress/-/plugin-nprogress-1.5.1.tgz", - "integrity": "sha512-BMoJL9Xc+XKoiVe7pSZntuVkt06u8i594J3Q4eEFkmrSRj8D+n9YFFjdRWTfae2haPMtMAvwpVeohAQ6ii61LA==", - "dev": true, - "dependencies": { - "nprogress": "^0.2.0" - } - }, - "node_modules/@vuepress/plugin-register-components": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/@vuepress/plugin-register-components/-/plugin-register-components-1.5.1.tgz", - "integrity": "sha512-pnovxJepFIQ8mx+uXg62OZ9KoFE1aOIBKxOmmtI5g9Qurx2NTVv5AWUtoi76xYbCxBpl313ffcCyvxMUfXPsrQ==", - "dev": true, - "dependencies": { - "@vuepress/shared-utils": "1.5.1" - } - }, - "node_modules/@vuepress/plugin-search": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/@vuepress/plugin-search/-/plugin-search-1.5.1.tgz", - "integrity": "sha512-JyYrTzDDZs6ANZgp7+DnuRTm3OB1LgrxUJriD5qLb7NXEDwWvJnf7noFxnp7j+yaMogCZN1IloTU0PLSLqub9A==", - "dev": true - }, - "node_modules/@vuepress/shared-utils": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/@vuepress/shared-utils/-/shared-utils-1.5.1.tgz", - "integrity": "sha512-rktTYlKa4vla6GlUZZmIiIW6Dfl+YbfcgGvkWE5A7MiIqEmJKnoqKOxJOHLPbnD+T5Ssfu71bj4FVXCG89DUmA==", - "dev": true, - "dependencies": { - "chalk": "^2.3.2", - "diacritics": "^1.3.0", - "escape-html": "^1.0.3", - "fs-extra": "^7.0.1", - "globby": "^9.2.0", - "gray-matter": "^4.0.1", - "hash-sum": "^1.0.2", - "semver": "^6.0.0", - "upath": "^1.1.0" - } - }, - "node_modules/@vuepress/shared-utils/node_modules/semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true, - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/@vuepress/theme-default": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/@vuepress/theme-default/-/theme-default-1.5.1.tgz", - "integrity": "sha512-CojJNniskrFWE/LQg7WE+4SYg7Q8xMChqXj74C4/475kCOd9dPHVeCkuvmjIpZ7NJ2m96aNlG1TvDnOTuhLCCQ==", - "dev": true, - "dependencies": { - "@vuepress/plugin-active-header-links": "1.5.1", - "@vuepress/plugin-nprogress": "1.5.1", - "@vuepress/plugin-search": "1.5.1", - "docsearch.js": "^2.5.2", - "lodash": "^4.17.15", - "stylus": "^0.54.5", - "stylus-loader": "^3.0.2", - "vuepress-plugin-container": "^2.0.2", - "vuepress-plugin-smooth-scroll": "^0.0.3" - } - }, - "node_modules/@webassemblyjs/ast": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.9.0.tgz", - "integrity": "sha512-C6wW5L+b7ogSDVqymbkkvuW9kruN//YisMED04xzeBBqjHa2FYnmvOlS6Xj68xWQRgWvI9cIglsjFowH/RJyEA==", - "dev": true, - "dependencies": { - "@webassemblyjs/helper-module-context": "1.9.0", - "@webassemblyjs/helper-wasm-bytecode": "1.9.0", - "@webassemblyjs/wast-parser": "1.9.0" - } - }, - "node_modules/@webassemblyjs/floating-point-hex-parser": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.9.0.tgz", - "integrity": "sha512-TG5qcFsS8QB4g4MhrxK5TqfdNe7Ey/7YL/xN+36rRjl/BlGE/NcBvJcqsRgCP6Z92mRE+7N50pRIi8SmKUbcQA==", - "dev": true - }, - "node_modules/@webassemblyjs/helper-api-error": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.9.0.tgz", - "integrity": "sha512-NcMLjoFMXpsASZFxJ5h2HZRcEhDkvnNFOAKneP5RbKRzaWJN36NC4jqQHKwStIhGXu5mUWlUUk7ygdtrO8lbmw==", - "dev": true - }, - "node_modules/@webassemblyjs/helper-buffer": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.9.0.tgz", - "integrity": "sha512-qZol43oqhq6yBPx7YM3m9Bv7WMV9Eevj6kMi6InKOuZxhw+q9hOkvq5e/PpKSiLfyetpaBnogSbNCfBwyB00CA==", - "dev": true - }, - "node_modules/@webassemblyjs/helper-code-frame": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-code-frame/-/helper-code-frame-1.9.0.tgz", - "integrity": "sha512-ERCYdJBkD9Vu4vtjUYe8LZruWuNIToYq/ME22igL+2vj2dQ2OOujIZr3MEFvfEaqKoVqpsFKAGsRdBSBjrIvZA==", - "dev": true, - "dependencies": { - "@webassemblyjs/wast-printer": "1.9.0" - } - }, - "node_modules/@webassemblyjs/helper-fsm": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-fsm/-/helper-fsm-1.9.0.tgz", - "integrity": "sha512-OPRowhGbshCb5PxJ8LocpdX9Kl0uB4XsAjl6jH/dWKlk/mzsANvhwbiULsaiqT5GZGT9qinTICdj6PLuM5gslw==", - "dev": true - }, - "node_modules/@webassemblyjs/helper-module-context": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-module-context/-/helper-module-context-1.9.0.tgz", - "integrity": "sha512-MJCW8iGC08tMk2enck1aPW+BE5Cw8/7ph/VGZxwyvGbJwjktKkDK7vy7gAmMDx88D7mhDTCNKAW5tED+gZ0W8g==", - "dev": true, - "dependencies": { - "@webassemblyjs/ast": "1.9.0" - } - }, - "node_modules/@webassemblyjs/helper-wasm-bytecode": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.9.0.tgz", - "integrity": "sha512-R7FStIzyNcd7xKxCZH5lE0Bqy+hGTwS3LJjuv1ZVxd9O7eHCedSdrId/hMOd20I+v8wDXEn+bjfKDLzTepoaUw==", - "dev": true - }, - "node_modules/@webassemblyjs/helper-wasm-section": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.9.0.tgz", - "integrity": "sha512-XnMB8l3ek4tvrKUUku+IVaXNHz2YsJyOOmz+MMkZvh8h1uSJpSen6vYnw3IoQ7WwEuAhL8Efjms1ZWjqh2agvw==", - "dev": true, - "dependencies": { - "@webassemblyjs/ast": "1.9.0", - "@webassemblyjs/helper-buffer": "1.9.0", - "@webassemblyjs/helper-wasm-bytecode": "1.9.0", - "@webassemblyjs/wasm-gen": "1.9.0" - } - }, - "node_modules/@webassemblyjs/ieee754": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.9.0.tgz", - "integrity": "sha512-dcX8JuYU/gvymzIHc9DgxTzUUTLexWwt8uCTWP3otys596io0L5aW02Gb1RjYpx2+0Jus1h4ZFqjla7umFniTg==", - "dev": true, - "dependencies": { - "@xtuc/ieee754": "^1.2.0" - } - }, - "node_modules/@webassemblyjs/leb128": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.9.0.tgz", - "integrity": "sha512-ENVzM5VwV1ojs9jam6vPys97B/S65YQtv/aanqnU7D8aSoHFX8GyhGg0CMfyKNIHBuAVjy3tlzd5QMMINa7wpw==", - "dev": true, - "dependencies": { - "@xtuc/long": "4.2.2" - } - }, - "node_modules/@webassemblyjs/utf8": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.9.0.tgz", - "integrity": "sha512-GZbQlWtopBTP0u7cHrEx+73yZKrQoBMpwkGEIqlacljhXCkVM1kMQge/Mf+csMJAjEdSwhOyLAS0AoR3AG5P8w==", - "dev": true - }, - "node_modules/@webassemblyjs/wasm-edit": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.9.0.tgz", - "integrity": "sha512-FgHzBm80uwz5M8WKnMTn6j/sVbqilPdQXTWraSjBwFXSYGirpkSWE2R9Qvz9tNiTKQvoKILpCuTjBKzOIm0nxw==", - "dev": true, - "dependencies": { - "@webassemblyjs/ast": "1.9.0", - "@webassemblyjs/helper-buffer": "1.9.0", - "@webassemblyjs/helper-wasm-bytecode": "1.9.0", - "@webassemblyjs/helper-wasm-section": "1.9.0", - "@webassemblyjs/wasm-gen": "1.9.0", - "@webassemblyjs/wasm-opt": "1.9.0", - "@webassemblyjs/wasm-parser": "1.9.0", - "@webassemblyjs/wast-printer": "1.9.0" - } - }, - "node_modules/@webassemblyjs/wasm-gen": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.9.0.tgz", - "integrity": "sha512-cPE3o44YzOOHvlsb4+E9qSqjc9Qf9Na1OO/BHFy4OI91XDE14MjFN4lTMezzaIWdPqHnsTodGGNP+iRSYfGkjA==", - "dev": true, - "dependencies": { - "@webassemblyjs/ast": "1.9.0", - "@webassemblyjs/helper-wasm-bytecode": "1.9.0", - "@webassemblyjs/ieee754": "1.9.0", - "@webassemblyjs/leb128": "1.9.0", - "@webassemblyjs/utf8": "1.9.0" - } - }, - "node_modules/@webassemblyjs/wasm-opt": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.9.0.tgz", - "integrity": "sha512-Qkjgm6Anhm+OMbIL0iokO7meajkzQD71ioelnfPEj6r4eOFuqm4YC3VBPqXjFyyNwowzbMD+hizmprP/Fwkl2A==", - "dev": true, - "dependencies": { - "@webassemblyjs/ast": "1.9.0", - "@webassemblyjs/helper-buffer": "1.9.0", - "@webassemblyjs/wasm-gen": "1.9.0", - "@webassemblyjs/wasm-parser": "1.9.0" - } - }, - "node_modules/@webassemblyjs/wasm-parser": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.9.0.tgz", - "integrity": "sha512-9+wkMowR2AmdSWQzsPEjFU7njh8HTO5MqO8vjwEHuM+AMHioNqSBONRdr0NQQ3dVQrzp0s8lTcYqzUdb7YgELA==", - "dev": true, - "dependencies": { - "@webassemblyjs/ast": "1.9.0", - "@webassemblyjs/helper-api-error": "1.9.0", - "@webassemblyjs/helper-wasm-bytecode": "1.9.0", - "@webassemblyjs/ieee754": "1.9.0", - "@webassemblyjs/leb128": "1.9.0", - "@webassemblyjs/utf8": "1.9.0" - } - }, - "node_modules/@webassemblyjs/wast-parser": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-parser/-/wast-parser-1.9.0.tgz", - "integrity": "sha512-qsqSAP3QQ3LyZjNC/0jBJ/ToSxfYJ8kYyuiGvtn/8MK89VrNEfwj7BPQzJVHi0jGTRK2dGdJ5PRqhtjzoww+bw==", - "dev": true, - "dependencies": { - "@webassemblyjs/ast": "1.9.0", - "@webassemblyjs/floating-point-hex-parser": "1.9.0", - "@webassemblyjs/helper-api-error": "1.9.0", - "@webassemblyjs/helper-code-frame": "1.9.0", - "@webassemblyjs/helper-fsm": "1.9.0", - "@xtuc/long": "4.2.2" - } - }, - "node_modules/@webassemblyjs/wast-printer": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.9.0.tgz", - "integrity": "sha512-2J0nE95rHXHyQ24cWjMKJ1tqB/ds8z/cyeOZxJhcb+rW+SQASVjuznUSmdz5GpVJTzU8JkhYut0D3siFDD6wsA==", - "dev": true, - "dependencies": { - "@webassemblyjs/ast": "1.9.0", - "@webassemblyjs/wast-parser": "1.9.0", - "@xtuc/long": "4.2.2" - } - }, - "node_modules/@xtuc/ieee754": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", - "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", - "dev": true - }, - "node_modules/@xtuc/long": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", - "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", - "dev": true - }, - "node_modules/abbrev": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", - "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", - "dev": true - }, - "node_modules/accepts": { - "version": "1.3.7", - "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz", - "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==", - "dev": true, - "dependencies": { - "mime-types": "~2.1.24", - "negotiator": "0.6.2" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/acorn": { - "version": "6.4.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.1.tgz", - "integrity": "sha512-ZVA9k326Nwrj3Cj9jlh3wGFutC2ZornPNARZwsNYqQYgN0EsV2d53w5RN/co65Ohn4sUAUtb1rSUAOD6XN9idA==", - "dev": true, - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/agentkeepalive": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-2.2.0.tgz", - "integrity": "sha1-xdG9SxKQCPEWPyNvhuX66iAm4u8=", - "dev": true, - "engines": { - "node": ">= 0.10.0" - } - }, - "node_modules/ajv": { - "version": "6.12.2", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.2.tgz", - "integrity": "sha512-k+V+hzjm5q/Mr8ef/1Y9goCmlsK4I6Sm74teeyGvFk1XrOsbsKLjEdrvny42CZ+a8sXbk8KWpY/bDwS+FLL2UQ==", - "dev": true, - "dependencies": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - } - }, - "node_modules/ajv-errors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/ajv-errors/-/ajv-errors-1.0.1.tgz", - "integrity": "sha512-DCRfO/4nQ+89p/RK43i8Ezd41EqdGIU4ld7nGF8OQ14oc/we5rEntLCUa7+jrn3nn83BosfwZA0wb4pon2o8iQ==", - "dev": true, - "peerDependencies": { - "ajv": ">=5.0.0" - } - }, - "node_modules/ajv-keywords": { - "version": "3.4.1", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.4.1.tgz", - "integrity": "sha512-RO1ibKvd27e6FEShVFfPALuHI3WjSVNeK5FIsmme/LYRNxjKuNj+Dt7bucLa6NdSv3JcVTyMlm9kGR84z1XpaQ==", - "dev": true, - "peerDependencies": { - "ajv": "^6.9.1" - } - }, - "node_modules/algoliasearch": { - "version": "3.35.1", - "resolved": "https://registry.npmjs.org/algoliasearch/-/algoliasearch-3.35.1.tgz", - "integrity": "sha512-K4yKVhaHkXfJ/xcUnil04xiSrB8B8yHZoFEhWNpXg23eiCnqvTZw1tn/SqvdsANlYHLJlKl0qi3I/Q2Sqo7LwQ==", - "dev": true, - "dependencies": { - "agentkeepalive": "^2.2.0", - "debug": "^2.6.9", - "envify": "^4.0.0", - "es6-promise": "^4.1.0", - "events": "^1.1.0", - "foreach": "^2.0.5", - "global": "^4.3.2", - "inherits": "^2.0.1", - "isarray": "^2.0.1", - "load-script": "^1.0.0", - "object-keys": "^1.0.11", - "querystring-es3": "^0.2.1", - "reduce": "^1.0.1", - "semver": "^5.1.0", - "tunnel-agent": "^0.6.0" - }, - "engines": { - "node": ">=0.8" - } - }, - "node_modules/algoliasearch/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/algoliasearch/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - }, - "node_modules/alphanum-sort": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/alphanum-sort/-/alphanum-sort-1.0.2.tgz", - "integrity": "sha1-l6ERlkmyEa0zaR2fn0hqjsn74KM=", - "dev": true - }, - "node_modules/ansi-align": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-3.0.0.tgz", - "integrity": "sha512-ZpClVKqXN3RGBmKibdfWzqCY4lnjEuoNzU5T0oEFpfd/z5qJHVarukridD4juLO2FXMiwUQxr9WqQtaYa8XRYw==", - "dev": true, - "dependencies": { - "string-width": "^3.0.0" - } - }, - "node_modules/ansi-align/node_modules/ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/ansi-align/node_modules/emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", - "dev": true - }, - "node_modules/ansi-align/node_modules/is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/ansi-align/node_modules/string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, - "dependencies": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/ansi-align/node_modules/strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "dependencies": { - "ansi-regex": "^4.1.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/ansi-colors": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.4.tgz", - "integrity": "sha512-hHUXGagefjN2iRrID63xckIvotOXOojhQKWIPUZ4mNUZ9nLZW+7FMNoE1lOkEhNWYsx/7ysGIuJYCiMAA9FnrA==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/ansi-escapes": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.1.tgz", - "integrity": "sha512-JWF7ocqNrp8u9oqpgV+wH5ftbt+cfvv+PTjOvKLT3AdYly/LmORARfEVT1iyjwN+4MqE5UmVKoAdIBqeoCHgLA==", - "dev": true, - "dependencies": { - "type-fest": "^0.11.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/ansi-escapes/node_modules/type-fest": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.11.0.tgz", - "integrity": "sha512-OdjXJxnCN1AvyLSzeKIgXTXxV+99ZuXl3Hpo9XpJAv9MBcHrrJOQ5kV7ypXOuQie+AmWG25hLbiKdwYTifzcfQ==", - "dev": true, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/ansi-html": { - "version": "0.0.7", - "resolved": "https://registry.npmjs.org/ansi-html/-/ansi-html-0.0.7.tgz", - "integrity": "sha1-gTWEAhliqenm/QOflA0S9WynhZ4=", - "dev": true, - "engines": [ - "node >= 0.8.0" - ], - "bin": { - "ansi-html": "bin/ansi-html" - } - }, - "node_modules/ansi-regex": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", - "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/anymatch": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", - "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", - "dev": true, - "dependencies": { - "micromatch": "^3.1.4", - "normalize-path": "^2.1.1" - } - }, - "node_modules/anymatch/node_modules/normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", - "dev": true, - "dependencies": { - "remove-trailing-separator": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/aproba": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", - "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==", - "dev": true - }, - "node_modules/argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "dev": true, - "dependencies": { - "sprintf-js": "~1.0.2" - } - }, - "node_modules/arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/arr-flatten": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", - "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/arr-union": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", - "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/array-flatten": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-2.1.2.tgz", - "integrity": "sha512-hNfzcOV8W4NdualtqBFPyVO+54DSJuZGY9qT4pRroB6S9e3iiido2ISIC5h9R2sPJ8H3FHCIiEnsv1lPXO3KtQ==", - "dev": true - }, - "node_modules/array-union": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", - "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=", - "dev": true, - "dependencies": { - "array-uniq": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/array-uniq": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", - "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/asn1": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", - "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", - "dev": true, - "dependencies": { - "safer-buffer": "~2.1.0" - } - }, - "node_modules/asn1.js": { - "version": "4.10.1", - "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-4.10.1.tgz", - "integrity": "sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw==", - "dev": true, - "dependencies": { - "bn.js": "^4.0.0", - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0" - } - }, - "node_modules/asn1.js/node_modules/bn.js": { - "version": "4.11.9", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz", - "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==", - "dev": true - }, - "node_modules/assert": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/assert/-/assert-1.5.0.tgz", - "integrity": "sha512-EDsgawzwoun2CZkCgtxJbv392v4nbk9XDD06zI+kQYoBM/3RBWLlEyJARDOmhAAosBjWACEkKL6S+lIZtcAubA==", - "dev": true, - "dependencies": { - "object-assign": "^4.1.1", - "util": "0.10.3" - } - }, - "node_modules/assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", - "dev": true, - "engines": { - "node": ">=0.8" - } - }, - "node_modules/assert/node_modules/inherits": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", - "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=", - "dev": true - }, - "node_modules/assert/node_modules/util": { - "version": "0.10.3", - "resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz", - "integrity": "sha1-evsa/lCAUkZInj23/g7TeTNqwPk=", - "dev": true, - "dependencies": { - "inherits": "2.0.1" - } - }, - "node_modules/assign-symbols": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", - "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/async": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/async/-/async-2.6.3.tgz", - "integrity": "sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==", - "dev": true, - "dependencies": { - "lodash": "^4.17.14" - } - }, - "node_modules/async-each": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.3.tgz", - "integrity": "sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ==", - "dev": true - }, - "node_modules/async-limiter": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz", - "integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==", - "dev": true - }, - "node_modules/asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", - "dev": true - }, - "node_modules/atob": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", - "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==", - "dev": true, - "bin": { - "atob": "bin/atob.js" - }, - "engines": { - "node": ">= 4.5.0" - } - }, - "node_modules/autocomplete.js": { - "version": "0.36.0", - "resolved": "https://registry.npmjs.org/autocomplete.js/-/autocomplete.js-0.36.0.tgz", - "integrity": "sha512-jEwUXnVMeCHHutUt10i/8ZiRaCb0Wo+ZyKxeGsYwBDtw6EJHqEeDrq4UwZRD8YBSvp3g6klP678il2eeiVXN2Q==", - "dev": true, - "dependencies": { - "immediate": "^3.2.3" - } - }, - "node_modules/autoprefixer": { - "version": "9.8.0", - "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-9.8.0.tgz", - "integrity": "sha512-D96ZiIHXbDmU02dBaemyAg53ez+6F5yZmapmgKcjm35yEe1uVDYI8hGW3VYoGRaG290ZFf91YxHrR518vC0u/A==", - "dev": true, - "dependencies": { - "browserslist": "^4.12.0", - "caniuse-lite": "^1.0.30001061", - "chalk": "^2.4.2", - "normalize-range": "^0.1.2", - "num2fraction": "^1.2.2", - "postcss": "^7.0.30", - "postcss-value-parser": "^4.1.0" - }, - "bin": { - "autoprefixer": "bin/autoprefixer" - }, - "engines": { - "node": ">=6.0.0" - }, - "funding": { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/autoprefixer" - } - }, - "node_modules/aws-sign2": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", - "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=", - "dev": true, - "engines": { - "node": "*" - } - }, - "node_modules/aws4": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.10.0.tgz", - "integrity": "sha512-3YDiu347mtVtjpyV3u5kVqQLP242c06zwDOgpeRnybmXlYYsLbtTrUBUm8i8srONt+FWobl5aibnU1030PeeuA==", - "dev": true - }, - "node_modules/babel-loader": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-8.1.0.tgz", - "integrity": "sha512-7q7nC1tYOrqvUrN3LQK4GwSk/TQorZSOlO9C+RZDZpODgyN4ZlCqE5q9cDsyWOliN+aU9B4JX01xK9eJXowJLw==", - "dev": true, - "dependencies": { - "find-cache-dir": "^2.1.0", - "loader-utils": "^1.4.0", - "mkdirp": "^0.5.3", - "pify": "^4.0.1", - "schema-utils": "^2.6.5" - }, - "engines": { - "node": ">= 6.9" - }, - "peerDependencies": { - "@babel/core": "^7.0.0", - "webpack": ">=2" - } - }, - "node_modules/babel-plugin-dynamic-import-node": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.3.3.tgz", - "integrity": "sha512-jZVI+s9Zg3IqA/kdi0i6UDCybUI3aSBLnglhYbSSjKlV7yF1F/5LWv8MakQmvYpnbJDS6fcBL2KzHSxNCMtWSQ==", - "dev": true, - "dependencies": { - "object.assign": "^4.1.0" - } - }, - "node_modules/balanced-match": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", - "dev": true - }, - "node_modules/base": { - "version": "0.11.2", - "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", - "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", - "dev": true, - "dependencies": { - "cache-base": "^1.0.1", - "class-utils": "^0.3.5", - "component-emitter": "^1.2.1", - "define-property": "^1.0.0", - "isobject": "^3.0.1", - "mixin-deep": "^1.2.0", - "pascalcase": "^0.1.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/base/node_modules/define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "dependencies": { - "is-descriptor": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/base64-js": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.1.tgz", - "integrity": "sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g==", - "dev": true - }, - "node_modules/batch": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz", - "integrity": "sha1-3DQxT05nkxgJP8dgJyUl+UvyXBY=", - "dev": true - }, - "node_modules/bcrypt-pbkdf": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", - "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", - "dev": true, - "dependencies": { - "tweetnacl": "^0.14.3" - } - }, - "node_modules/big.js": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", - "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==", - "dev": true, - "engines": { - "node": "*" - } - }, - "node_modules/binary-extensions": { - "version": "1.13.1", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz", - "integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/bindings": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", - "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", - "dev": true, - "optional": true, - "dependencies": { - "file-uri-to-path": "1.0.0" - } - }, - "node_modules/bluebird": { - "version": "3.7.2", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", - "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", - "dev": true - }, - "node_modules/bn.js": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.1.2.tgz", - "integrity": "sha512-40rZaf3bUNKTVYu9sIeeEGOg7g14Yvnj9kH7b50EiwX0Q7A6umbvfI5tvHaOERH0XigqKkfLkFQxzb4e6CIXnA==", - "dev": true - }, - "node_modules/body-parser": { - "version": "1.19.0", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz", - "integrity": "sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==", - "dev": true, - "dependencies": { - "bytes": "3.1.0", - "content-type": "~1.0.4", - "debug": "2.6.9", - "depd": "~1.1.2", - "http-errors": "1.7.2", - "iconv-lite": "0.4.24", - "on-finished": "~2.3.0", - "qs": "6.7.0", - "raw-body": "2.4.0", - "type-is": "~1.6.17" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/body-parser/node_modules/bytes": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", - "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==", - "dev": true, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/body-parser/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/body-parser/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - }, - "node_modules/body-parser/node_modules/qs": { - "version": "6.7.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz", - "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==", - "dev": true, - "engines": { - "node": ">=0.6" - } - }, - "node_modules/bonjour": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/bonjour/-/bonjour-3.5.0.tgz", - "integrity": "sha1-jokKGD2O6aI5OzhExpGkK897yfU=", - "dev": true, - "dependencies": { - "array-flatten": "^2.1.0", - "deep-equal": "^1.0.1", - "dns-equal": "^1.0.0", - "dns-txt": "^2.0.2", - "multicast-dns": "^6.0.1", - "multicast-dns-service-types": "^1.1.0" - } - }, - "node_modules/boolbase": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", - "integrity": "sha1-aN/1++YMUes3cl6p4+0xDcwed24=", - "dev": true - }, - "node_modules/boxen": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/boxen/-/boxen-4.2.0.tgz", - "integrity": "sha512-eB4uT9RGzg2odpER62bBwSLvUeGC+WbRjjyyFhGsKnc8wp/m0+hQsMUvUe3H2V0D5vw0nBdO1hCJoZo5mKeuIQ==", - "dev": true, - "dependencies": { - "ansi-align": "^3.0.0", - "camelcase": "^5.3.1", - "chalk": "^3.0.0", - "cli-boxes": "^2.2.0", - "string-width": "^4.1.0", - "term-size": "^2.1.0", - "type-fest": "^0.8.1", - "widest-line": "^3.1.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/boxen/node_modules/ansi-styles": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", - "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", - "dev": true, - "dependencies": { - "@types/color-name": "^1.1.1", - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/boxen/node_modules/chalk": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", - "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/boxen/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/boxen/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "node_modules/boxen/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/boxen/node_modules/supports-color": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", - "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dev": true, - "dependencies": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/brorand": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", - "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=", - "dev": true - }, - "node_modules/browserify-aes": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", - "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", - "dev": true, - "dependencies": { - "buffer-xor": "^1.0.3", - "cipher-base": "^1.0.0", - "create-hash": "^1.1.0", - "evp_bytestokey": "^1.0.3", - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "node_modules/browserify-cipher": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz", - "integrity": "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==", - "dev": true, - "dependencies": { - "browserify-aes": "^1.0.4", - "browserify-des": "^1.0.0", - "evp_bytestokey": "^1.0.0" - } - }, - "node_modules/browserify-des": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.2.tgz", - "integrity": "sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==", - "dev": true, - "dependencies": { - "cipher-base": "^1.0.1", - "des.js": "^1.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "node_modules/browserify-rsa": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.0.1.tgz", - "integrity": "sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ=", - "dev": true, - "dependencies": { - "bn.js": "^4.1.0", - "randombytes": "^2.0.1" - } - }, - "node_modules/browserify-rsa/node_modules/bn.js": { - "version": "4.11.9", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz", - "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==", - "dev": true - }, - "node_modules/browserify-sign": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.2.0.tgz", - "integrity": "sha512-hEZC1KEeYuoHRqhGhTy6gWrpJA3ZDjFWv0DE61643ZnOXAKJb3u7yWcrU0mMc9SwAqK1n7myPGndkp0dFG7NFA==", - "dev": true, - "dependencies": { - "bn.js": "^5.1.1", - "browserify-rsa": "^4.0.1", - "create-hash": "^1.2.0", - "create-hmac": "^1.1.7", - "elliptic": "^6.5.2", - "inherits": "^2.0.4", - "parse-asn1": "^5.1.5", - "readable-stream": "^3.6.0", - "safe-buffer": "^5.2.0" - } - }, - "node_modules/browserify-sign/node_modules/readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "dev": true, - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/browserify-sign/node_modules/safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/browserify-zlib": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.2.0.tgz", - "integrity": "sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==", - "dev": true, - "dependencies": { - "pako": "~1.0.5" - } - }, - "node_modules/browserslist": { - "version": "4.16.6", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.16.6.tgz", - "integrity": "sha512-Wspk/PqO+4W9qp5iUTJsa1B/QrYn1keNCcEP5OvP7WBwT4KaDly0uONYmC6Xa3Z5IqnUgS0KcgLYu1l74x0ZXQ==", - "dev": true, - "dependencies": { - "caniuse-lite": "^1.0.30001219", - "colorette": "^1.2.2", - "electron-to-chromium": "^1.3.723", - "escalade": "^3.1.1", - "node-releases": "^1.1.71" - }, - "bin": { - "browserslist": "cli.js" - }, - "engines": { - "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - } - }, - "node_modules/buffer": { - "version": "4.9.2", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.2.tgz", - "integrity": "sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg==", - "dev": true, - "dependencies": { - "base64-js": "^1.0.2", - "ieee754": "^1.1.4", - "isarray": "^1.0.0" - } - }, - "node_modules/buffer-from": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", - "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", - "dev": true - }, - "node_modules/buffer-indexof": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/buffer-indexof/-/buffer-indexof-1.1.1.tgz", - "integrity": "sha512-4/rOEg86jivtPTeOUUT61jJO1Ya1TrR/OkqCSZDyq84WJh3LuuiphBYJN+fm5xufIk4XAFcEwte/8WzC8If/1g==", - "dev": true - }, - "node_modules/buffer-json": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/buffer-json/-/buffer-json-2.0.0.tgz", - "integrity": "sha512-+jjPFVqyfF1esi9fvfUs3NqM0pH1ziZ36VP4hmA/y/Ssfo/5w5xHKfTw9BwQjoJ1w/oVtpLomqwUHKdefGyuHw==", - "dev": true - }, - "node_modules/buffer-xor": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", - "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=", - "dev": true - }, - "node_modules/buffer/node_modules/isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "node_modules/builtin-status-codes": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz", - "integrity": "sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug=", - "dev": true - }, - "node_modules/bytes": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", - "integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg=", - "dev": true, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/cac": { - "version": "6.5.10", - "resolved": "https://registry.npmjs.org/cac/-/cac-6.5.10.tgz", - "integrity": "sha512-uxyxsID5p5kYlFFnhw86A4c8K5QTLRp6JM4AY2OtCq5lnnn4DGxV8YI1Z5rlt6KUjEKpA4qM+WZQshMoJY6dQQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/cacache": { - "version": "12.0.4", - "resolved": "https://registry.npmjs.org/cacache/-/cacache-12.0.4.tgz", - "integrity": "sha512-a0tMB40oefvuInr4Cwb3GerbL9xTj1D5yg0T5xrjGCGyfvbxseIXX7BAO/u/hIXdafzOI5JC3wDwHyf24buOAQ==", - "dev": true, - "dependencies": { - "bluebird": "^3.5.5", - "chownr": "^1.1.1", - "figgy-pudding": "^3.5.1", - "glob": "^7.1.4", - "graceful-fs": "^4.1.15", - "infer-owner": "^1.0.3", - "lru-cache": "^5.1.1", - "mississippi": "^3.0.0", - "mkdirp": "^0.5.1", - "move-concurrently": "^1.0.1", - "promise-inflight": "^1.0.1", - "rimraf": "^2.6.3", - "ssri": "^6.0.1", - "unique-filename": "^1.1.1", - "y18n": "^4.0.0" - } - }, - "node_modules/cache-base": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", - "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", - "dev": true, - "dependencies": { - "collection-visit": "^1.0.0", - "component-emitter": "^1.2.1", - "get-value": "^2.0.6", - "has-value": "^1.0.0", - "isobject": "^3.0.1", - "set-value": "^2.0.0", - "to-object-path": "^0.3.0", - "union-value": "^1.0.0", - "unset-value": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/cache-loader": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/cache-loader/-/cache-loader-3.0.1.tgz", - "integrity": "sha512-HzJIvGiGqYsFUrMjAJNDbVZoG7qQA+vy9AIoKs7s9DscNfki0I589mf2w6/tW+kkFH3zyiknoWV5Jdynu6b/zw==", - "dev": true, - "dependencies": { - "buffer-json": "^2.0.0", - "find-cache-dir": "^2.1.0", - "loader-utils": "^1.2.3", - "mkdirp": "^0.5.1", - "neo-async": "^2.6.1", - "schema-utils": "^1.0.0" - }, - "engines": { - "node": ">= 6.9.0" - }, - "peerDependencies": { - "webpack": "^4.0.0" - } - }, - "node_modules/cache-loader/node_modules/schema-utils": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", - "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", - "dev": true, - "dependencies": { - "ajv": "^6.1.0", - "ajv-errors": "^1.0.0", - "ajv-keywords": "^3.1.0" - }, - "engines": { - "node": ">= 4" - } - }, - "node_modules/cacheable-request": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-6.1.0.tgz", - "integrity": "sha512-Oj3cAGPCqOZX7Rz64Uny2GYAZNliQSqfbePrgAQ1wKAihYmCUnraBtJtKcGR4xz7wF+LoJC+ssFZvv5BgF9Igg==", - "dev": true, - "dependencies": { - "clone-response": "^1.0.2", - "get-stream": "^5.1.0", - "http-cache-semantics": "^4.0.0", - "keyv": "^3.0.0", - "lowercase-keys": "^2.0.0", - "normalize-url": "^4.1.0", - "responselike": "^1.0.2" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/cacheable-request/node_modules/get-stream": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.1.0.tgz", - "integrity": "sha512-EXr1FOzrzTfGeL0gQdeFEvOMm2mzMOglyiOXSTpPC+iAjAKftbr3jpCMWynogwYnM+eSj9sHGc6wjIcDvYiygw==", - "dev": true, - "dependencies": { - "pump": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/cacheable-request/node_modules/lowercase-keys": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", - "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/cacheable-request/node_modules/normalize-url": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-4.5.0.tgz", - "integrity": "sha512-2s47yzUxdexf1OhyRi4Em83iQk0aPvwTddtFz4hnSSw9dCEsLEGf6SwIO8ss/19S9iBb5sJaOuTvTGDeZI00BQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/call-me-maybe": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/call-me-maybe/-/call-me-maybe-1.0.1.tgz", - "integrity": "sha1-JtII6onje1y95gJQoV8DHBak1ms=", - "dev": true - }, - "node_modules/caller-callsite": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/caller-callsite/-/caller-callsite-2.0.0.tgz", - "integrity": "sha1-hH4PzgoiN1CpoCfFSzNzGtMVQTQ=", - "dev": true, - "dependencies": { - "callsites": "^2.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/caller-path": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-2.0.0.tgz", - "integrity": "sha1-Ro+DBE42mrIBD6xfBs7uFbsssfQ=", - "dev": true, - "dependencies": { - "caller-callsite": "^2.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/callsites": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-2.0.0.tgz", - "integrity": "sha1-BuuE8A7qQT2oav/vrL/7Ngk7PFA=", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/camel-case": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/camel-case/-/camel-case-3.0.0.tgz", - "integrity": "sha1-yjw2iKTpzzpM2nd9xNy8cTJJz3M=", - "dev": true, - "dependencies": { - "no-case": "^2.2.0", - "upper-case": "^1.1.1" - } - }, - "node_modules/camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/caniuse-api": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/caniuse-api/-/caniuse-api-3.0.0.tgz", - "integrity": "sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw==", - "dev": true, - "dependencies": { - "browserslist": "^4.0.0", - "caniuse-lite": "^1.0.0", - "lodash.memoize": "^4.1.2", - "lodash.uniq": "^4.5.0" - } - }, - "node_modules/caniuse-lite": { - "version": "1.0.30001230", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001230.tgz", - "integrity": "sha512-5yBd5nWCBS+jWKTcHOzXwo5xzcj4ePE/yjtkZyUV1BTUmrBaA9MRGC+e7mxnqXSA90CmCA8L3eKLaSUkt099IQ==", - "dev": true, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - } - }, - "node_modules/caseless": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", - "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=", - "dev": true - }, - "node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/chokidar": { - "version": "2.1.8", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.8.tgz", - "integrity": "sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg==", - "deprecated": "Chokidar 2 will break on node v14+. Upgrade to chokidar 3 with 15x less dependencies.", - "dev": true, - "dependencies": { - "anymatch": "^2.0.0", - "async-each": "^1.0.1", - "braces": "^2.3.2", - "glob-parent": "^3.1.0", - "inherits": "^2.0.3", - "is-binary-path": "^1.0.0", - "is-glob": "^4.0.0", - "normalize-path": "^3.0.0", - "path-is-absolute": "^1.0.0", - "readdirp": "^2.2.1", - "upath": "^1.1.1" - }, - "optionalDependencies": { - "fsevents": "^1.2.7" - } - }, - "node_modules/chownr": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", - "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", - "dev": true - }, - "node_modules/chrome-trace-event": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.2.tgz", - "integrity": "sha512-9e/zx1jw7B4CO+c/RXoCsfg/x1AfUBioy4owYH0bJprEYAx5hRFLRhWBqHAG57D0ZM4H7vxbP7bPe0VwhQRYDQ==", - "dev": true, - "dependencies": { - "tslib": "^1.9.0" - }, - "engines": { - "node": ">=6.0" - } - }, - "node_modules/ci-info": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", - "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==", - "dev": true - }, - "node_modules/cipher-base": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", - "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", - "dev": true, - "dependencies": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "node_modules/class-utils": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", - "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", - "dev": true, - "dependencies": { - "arr-union": "^3.1.0", - "define-property": "^0.2.5", - "isobject": "^3.0.0", - "static-extend": "^0.1.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/class-utils/node_modules/define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "dependencies": { - "is-descriptor": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/class-utils/node_modules/is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/class-utils/node_modules/is-accessor-descriptor/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/class-utils/node_modules/is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/class-utils/node_modules/is-data-descriptor/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/class-utils/node_modules/is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "dependencies": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/class-utils/node_modules/kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/clean-css": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-4.2.3.tgz", - "integrity": "sha512-VcMWDN54ZN/DS+g58HYL5/n4Zrqe8vHJpGA8KdgUXFU4fuP/aHNw8eld9SyEIyabIMJX/0RaY/fplOo5hYLSFA==", - "dev": true, - "dependencies": { - "source-map": "~0.6.0" - }, - "engines": { - "node": ">= 4.0" - } - }, - "node_modules/clean-css/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/cli-boxes": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-2.2.0.tgz", - "integrity": "sha512-gpaBrMAizVEANOpfZp/EEUixTXDyGt7DFzdK5hU+UbWt/J0lB0w20ncZj59Z9a93xHb9u12zF5BS6i9RKbtg4w==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/clipboard": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/clipboard/-/clipboard-2.0.6.tgz", - "integrity": "sha512-g5zbiixBRk/wyKakSwCKd7vQXDjFnAMGHoEyBogG/bw9kTD9GvdAvaoRR1ALcEzt3pVKxZR0pViekPMIS0QyGg==", - "dev": true, - "optional": true, - "dependencies": { - "good-listener": "^1.2.2", - "select": "^1.1.2", - "tiny-emitter": "^2.0.0" - } - }, - "node_modules/cliui": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", - "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", - "dev": true, - "dependencies": { - "string-width": "^3.1.0", - "strip-ansi": "^5.2.0", - "wrap-ansi": "^5.1.0" - } - }, - "node_modules/cliui/node_modules/ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/cliui/node_modules/emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", - "dev": true - }, - "node_modules/cliui/node_modules/is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/cliui/node_modules/string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, - "dependencies": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/cliui/node_modules/strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "dependencies": { - "ansi-regex": "^4.1.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/clone-response": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.2.tgz", - "integrity": "sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws=", - "dev": true, - "dependencies": { - "mimic-response": "^1.0.0" - } - }, - "node_modules/coa": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/coa/-/coa-2.0.2.tgz", - "integrity": "sha512-q5/jG+YQnSy4nRTV4F7lPepBJZ8qBNJJDBuJdoejDyLXgmL7IEo+Le2JDZudFTFt7mrCqIRaSjws4ygRCTCAXA==", - "dev": true, - "dependencies": { - "@types/q": "^1.5.1", - "chalk": "^2.4.1", - "q": "^1.1.2" - }, - "engines": { - "node": ">= 4.0" - } - }, - "node_modules/collection-visit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", - "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", - "dev": true, - "dependencies": { - "map-visit": "^1.0.0", - "object-visit": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/color": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/color/-/color-3.1.2.tgz", - "integrity": "sha512-vXTJhHebByxZn3lDvDJYw4lR5+uB3vuoHsuYA5AKuxRVn5wzzIfQKGLBmgdVRHKTJYeK5rvJcHnrd0Li49CFpg==", - "dev": true, - "dependencies": { - "color-convert": "^1.9.1", - "color-string": "^1.5.2" - } - }, - "node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "dependencies": { - "color-name": "1.1.3" - } - }, - "node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", - "dev": true - }, - "node_modules/color-string": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.5.3.tgz", - "integrity": "sha512-dC2C5qeWoYkxki5UAXapdjqO672AM4vZuPGRQfO8b5HKuKGBbKWpITyDYN7TOFKvRW7kOgAn3746clDBMDJyQw==", - "dev": true, - "dependencies": { - "color-name": "^1.0.0", - "simple-swizzle": "^0.2.2" - } - }, - "node_modules/colorette": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.2.2.tgz", - "integrity": "sha512-MKGMzyfeuutC/ZJ1cba9NqcNpfeqMUcYmyF1ZFY6/Cn7CNSAKx6a+s48sqLqyAiZuaP2TcqMhoo+dlwFnVxT9w==", - "dev": true - }, - "node_modules/combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "dev": true, - "dependencies": { - "delayed-stream": "~1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/commander": { - "version": "2.17.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.17.1.tgz", - "integrity": "sha512-wPMUt6FnH2yzG95SA6mzjQOEKUU3aLaDEmzs1ti+1E9h+CsrZghRlqEM/EJ4KscsQVG8uNN4uVreUeT8+drlgg==", - "dev": true - }, - "node_modules/commondir": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", - "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=", - "dev": true - }, - "node_modules/component-emitter": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", - "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==", - "dev": true - }, - "node_modules/compressible": { - "version": "2.0.18", - "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz", - "integrity": "sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==", - "dev": true, - "dependencies": { - "mime-db": ">= 1.43.0 < 2" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/compression": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/compression/-/compression-1.7.4.tgz", - "integrity": "sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ==", - "dev": true, - "dependencies": { - "accepts": "~1.3.5", - "bytes": "3.0.0", - "compressible": "~2.0.16", - "debug": "2.6.9", - "on-headers": "~1.0.2", - "safe-buffer": "5.1.2", - "vary": "~1.1.2" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/compression/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/compression/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - }, - "node_modules/concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", - "dev": true - }, - "node_modules/concat-stream": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", - "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", - "dev": true, - "engines": [ - "node >= 0.8" - ], - "dependencies": { - "buffer-from": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^2.2.2", - "typedarray": "^0.0.6" - } - }, - "node_modules/configstore": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/configstore/-/configstore-5.0.1.tgz", - "integrity": "sha512-aMKprgk5YhBNyH25hj8wGt2+D52Sw1DRRIzqBwLp2Ya9mFmY8KPvvtvmna8SxVR9JMZ4kzMD68N22vlaRpkeFA==", - "dev": true, - "dependencies": { - "dot-prop": "^5.2.0", - "graceful-fs": "^4.1.2", - "make-dir": "^3.0.0", - "unique-string": "^2.0.0", - "write-file-atomic": "^3.0.0", - "xdg-basedir": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/configstore/node_modules/make-dir": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", - "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", - "dev": true, - "dependencies": { - "semver": "^6.0.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/configstore/node_modules/semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true, - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/connect-history-api-fallback": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/connect-history-api-fallback/-/connect-history-api-fallback-1.6.0.tgz", - "integrity": "sha512-e54B99q/OUoH64zYYRf3HBP5z24G38h5D3qXu23JGRoigpX5Ss4r9ZnDk3g0Z8uQC2x2lPaJ+UlWBc1ZWBWdLg==", - "dev": true, - "engines": { - "node": ">=0.8" - } - }, - "node_modules/consola": { - "version": "2.12.2", - "resolved": "https://registry.npmjs.org/consola/-/consola-2.12.2.tgz", - "integrity": "sha512-c9mzemrAk57s3UIjepn8KKkuEH5fauMdot5kFSJUnqHcnApVS9Db8Rbv5AZ1Iz6lXzaGe9z1crQXhJtGX4h/Og==", - "dev": true - }, - "node_modules/console-browserify": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.2.0.tgz", - "integrity": "sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA==", - "dev": true - }, - "node_modules/consolidate": { - "version": "0.15.1", - "resolved": "https://registry.npmjs.org/consolidate/-/consolidate-0.15.1.tgz", - "integrity": "sha512-DW46nrsMJgy9kqAbPt5rKaCr7uFtpo4mSUvLHIUbJEjm0vo+aY5QLwBUq3FK4tRnJr/X0Psc0C4jf/h+HtXSMw==", - "dev": true, - "dependencies": { - "bluebird": "^3.1.1" - }, - "engines": { - "node": ">= 0.10.0" - } - }, - "node_modules/constants-browserify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz", - "integrity": "sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U=", - "dev": true - }, - "node_modules/content-disposition": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.3.tgz", - "integrity": "sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g==", - "dev": true, - "dependencies": { - "safe-buffer": "5.1.2" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/content-type": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", - "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==", - "dev": true, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/convert-source-map": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.7.0.tgz", - "integrity": "sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA==", - "dev": true, - "dependencies": { - "safe-buffer": "~5.1.1" - } - }, - "node_modules/cookie": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz", - "integrity": "sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg==", - "dev": true, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/cookie-signature": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", - "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=", - "dev": true - }, - "node_modules/copy-concurrently": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/copy-concurrently/-/copy-concurrently-1.0.5.tgz", - "integrity": "sha512-f2domd9fsVDFtaFcbaRZuYXwtdmnzqbADSwhSWYxYB/Q8zsdUUFMXVRwXGDMWmbEzAn1kdRrtI1T/KTFOL4X2A==", - "dev": true, - "dependencies": { - "aproba": "^1.1.1", - "fs-write-stream-atomic": "^1.0.8", - "iferr": "^0.1.5", - "mkdirp": "^0.5.1", - "rimraf": "^2.5.4", - "run-queue": "^1.0.0" - } - }, - "node_modules/copy-descriptor": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", - "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/copy-webpack-plugin": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/copy-webpack-plugin/-/copy-webpack-plugin-5.1.1.tgz", - "integrity": "sha512-P15M5ZC8dyCjQHWwd4Ia/dm0SgVvZJMYeykVIVYXbGyqO4dWB5oyPHp9i7wjwo5LhtlhKbiBCdS2NvM07Wlybg==", - "dev": true, - "dependencies": { - "cacache": "^12.0.3", - "find-cache-dir": "^2.1.0", - "glob-parent": "^3.1.0", - "globby": "^7.1.1", - "is-glob": "^4.0.1", - "loader-utils": "^1.2.3", - "minimatch": "^3.0.4", - "normalize-path": "^3.0.0", - "p-limit": "^2.2.1", - "schema-utils": "^1.0.0", - "serialize-javascript": "^2.1.2", - "webpack-log": "^2.0.0" - }, - "engines": { - "node": ">= 6.9.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "webpack": "^4.0.0 || ^5.0.0" - } - }, - "node_modules/copy-webpack-plugin/node_modules/globby": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/globby/-/globby-7.1.1.tgz", - "integrity": "sha1-+yzP+UAfhgCUXfral0QMypcrhoA=", - "dev": true, - "dependencies": { - "array-union": "^1.0.1", - "dir-glob": "^2.0.0", - "glob": "^7.1.2", - "ignore": "^3.3.5", - "pify": "^3.0.0", - "slash": "^1.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/copy-webpack-plugin/node_modules/ignore": { - "version": "3.3.10", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-3.3.10.tgz", - "integrity": "sha512-Pgs951kaMm5GXP7MOvxERINe3gsaVjUWFm+UZPSq9xYriQAksyhg0csnS0KXSNRD5NmNdapXEpjxG49+AKh/ug==", - "dev": true - }, - "node_modules/copy-webpack-plugin/node_modules/pify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/copy-webpack-plugin/node_modules/schema-utils": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", - "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", - "dev": true, - "dependencies": { - "ajv": "^6.1.0", - "ajv-errors": "^1.0.0", - "ajv-keywords": "^3.1.0" - }, - "engines": { - "node": ">= 4" - } - }, - "node_modules/copy-webpack-plugin/node_modules/slash": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-1.0.0.tgz", - "integrity": "sha1-xB8vbDn8FtHNF61LXYlhFK5HDVU=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/core-js": { - "version": "3.6.5", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.6.5.tgz", - "integrity": "sha512-vZVEEwZoIsI+vPEuoF9Iqf5H7/M3eeQqWlQnYa8FSKKePuYTf5MWnxb5SDAzCa60b3JBRS5g9b+Dq7b1y/RCrA==", - "dev": true, - "hasInstallScript": true, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/core-js" - } - }, - "node_modules/core-js-compat": { - "version": "3.6.5", - "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.6.5.tgz", - "integrity": "sha512-7ItTKOhOZbznhXAQ2g/slGg1PJV5zDO/WdkTwi7UEOJmkvsE32PWvx6mKtDjiMpjnR2CNf6BAD6sSxIlv7ptng==", - "dev": true, - "dependencies": { - "browserslist": "^4.8.5", - "semver": "7.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/core-js" - } - }, - "node_modules/core-js-compat/node_modules/semver": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.0.0.tgz", - "integrity": "sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A==", - "dev": true, - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", - "dev": true - }, - "node_modules/cosmiconfig": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-5.2.1.tgz", - "integrity": "sha512-H65gsXo1SKjf8zmrJ67eJk8aIRKV5ff2D4uKZIBZShbhGSpEmsQOPW/SKMKYhSTrqR7ufy6RP69rPogdaPh/kA==", - "dev": true, - "dependencies": { - "import-fresh": "^2.0.0", - "is-directory": "^0.3.1", - "js-yaml": "^3.13.1", - "parse-json": "^4.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/create-ecdh": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.3.tgz", - "integrity": "sha512-GbEHQPMOswGpKXM9kCWVrremUcBmjteUaQ01T9rkKCPDXfUHX0IoP9LpHYo2NPFampa4e+/pFDc3jQdxrxQLaw==", - "dev": true, - "dependencies": { - "bn.js": "^4.1.0", - "elliptic": "^6.0.0" - } - }, - "node_modules/create-ecdh/node_modules/bn.js": { - "version": "4.11.9", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz", - "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==", - "dev": true - }, - "node_modules/create-hash": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", - "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", - "dev": true, - "dependencies": { - "cipher-base": "^1.0.1", - "inherits": "^2.0.1", - "md5.js": "^1.3.4", - "ripemd160": "^2.0.1", - "sha.js": "^2.4.0" - } - }, - "node_modules/create-hmac": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", - "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", - "dev": true, - "dependencies": { - "cipher-base": "^1.0.3", - "create-hash": "^1.1.0", - "inherits": "^2.0.1", - "ripemd160": "^2.0.0", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - } - }, - "node_modules/cross-spawn": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", - "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", - "dev": true, - "dependencies": { - "nice-try": "^1.0.4", - "path-key": "^2.0.1", - "semver": "^5.5.0", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - }, - "engines": { - "node": ">=4.8" - } - }, - "node_modules/crypto-browserify": { - "version": "3.12.0", - "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz", - "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==", - "dev": true, - "dependencies": { - "browserify-cipher": "^1.0.0", - "browserify-sign": "^4.0.0", - "create-ecdh": "^4.0.0", - "create-hash": "^1.1.0", - "create-hmac": "^1.1.0", - "diffie-hellman": "^5.0.0", - "inherits": "^2.0.1", - "pbkdf2": "^3.0.3", - "public-encrypt": "^4.0.0", - "randombytes": "^2.0.0", - "randomfill": "^1.0.3" - }, - "engines": { - "node": "*" - } - }, - "node_modules/crypto-random-string": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-2.0.0.tgz", - "integrity": "sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/css": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/css/-/css-2.2.4.tgz", - "integrity": "sha512-oUnjmWpy0niI3x/mPL8dVEI1l7MnG3+HHyRPHf+YFSbK+svOhXpmSOcDURUh2aOCgl2grzrOPt1nHLuCVFULLw==", - "dev": true, - "dependencies": { - "inherits": "^2.0.3", - "source-map": "^0.6.1", - "source-map-resolve": "^0.5.2", - "urix": "^0.1.0" - } - }, - "node_modules/css-color-names": { - "version": "0.0.4", - "resolved": "https://registry.npmjs.org/css-color-names/-/css-color-names-0.0.4.tgz", - "integrity": "sha1-gIrcLnnPhHOAabZGyyDsJ762KeA=", - "dev": true, - "engines": { - "node": "*" - } - }, - "node_modules/css-declaration-sorter": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/css-declaration-sorter/-/css-declaration-sorter-4.0.1.tgz", - "integrity": "sha512-BcxQSKTSEEQUftYpBVnsH4SF05NTuBokb19/sBt6asXGKZ/6VP7PLG1CBCkFDYOnhXhPh0jMhO6xZ71oYHXHBA==", - "dev": true, - "dependencies": { - "postcss": "^7.0.1", - "timsort": "^0.3.0" - }, - "engines": { - "node": ">4" - } - }, - "node_modules/css-loader": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-2.1.1.tgz", - "integrity": "sha512-OcKJU/lt232vl1P9EEDamhoO9iKY3tIjY5GU+XDLblAykTdgs6Ux9P1hTHve8nFKy5KPpOXOsVI/hIwi3841+w==", - "dev": true, - "dependencies": { - "camelcase": "^5.2.0", - "icss-utils": "^4.1.0", - "loader-utils": "^1.2.3", - "normalize-path": "^3.0.0", - "postcss": "^7.0.14", - "postcss-modules-extract-imports": "^2.0.0", - "postcss-modules-local-by-default": "^2.0.6", - "postcss-modules-scope": "^2.1.0", - "postcss-modules-values": "^2.0.0", - "postcss-value-parser": "^3.3.0", - "schema-utils": "^1.0.0" - }, - "engines": { - "node": ">= 6.9.0" - }, - "peerDependencies": { - "webpack": "^4.0.0" - } - }, - "node_modules/css-loader/node_modules/postcss-value-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", - "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", - "dev": true - }, - "node_modules/css-loader/node_modules/schema-utils": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", - "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", - "dev": true, - "dependencies": { - "ajv": "^6.1.0", - "ajv-errors": "^1.0.0", - "ajv-keywords": "^3.1.0" - }, - "engines": { - "node": ">= 4" - } - }, - "node_modules/css-parse": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/css-parse/-/css-parse-2.0.0.tgz", - "integrity": "sha1-pGjuZnwW2BzPBcWMONKpfHgNv9Q=", - "dev": true, - "dependencies": { - "css": "^2.0.0" - } - }, - "node_modules/css-select": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/css-select/-/css-select-2.1.0.tgz", - "integrity": "sha512-Dqk7LQKpwLoH3VovzZnkzegqNSuAziQyNZUcrdDM401iY+R5NkGBXGmtO05/yaXQziALuPogeG0b7UAgjnTJTQ==", - "dev": true, - "dependencies": { - "boolbase": "^1.0.0", - "css-what": "^3.2.1", - "domutils": "^1.7.0", - "nth-check": "^1.0.2" - } - }, - "node_modules/css-select-base-adapter": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/css-select-base-adapter/-/css-select-base-adapter-0.1.1.tgz", - "integrity": "sha512-jQVeeRG70QI08vSTwf1jHxp74JoZsr2XSgETae8/xC8ovSnL2WF87GTLO86Sbwdt2lK4Umg4HnnwMO4YF3Ce7w==", - "dev": true - }, - "node_modules/css-tree": { - "version": "1.0.0-alpha.37", - "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.0.0-alpha.37.tgz", - "integrity": "sha512-DMxWJg0rnz7UgxKT0Q1HU/L9BeJI0M6ksor0OgqOnF+aRCDWg/N2641HmVyU9KVIu0OVVWOb2IpC9A+BJRnejg==", - "dev": true, - "dependencies": { - "mdn-data": "2.0.4", - "source-map": "^0.6.1" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/css-tree/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/css-what": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/css-what/-/css-what-3.3.0.tgz", - "integrity": "sha512-pv9JPyatiPaQ6pf4OvD/dbfm0o5LviWmwxNWzblYf/1u9QZd0ihV+PMwy5jdQWQ3349kZmKEx9WXuSka2dM4cg==", - "dev": true, - "engines": { - "node": ">= 6" - } - }, - "node_modules/css/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/cssesc": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", - "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", - "dev": true, - "bin": { - "cssesc": "bin/cssesc" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/cssnano": { - "version": "4.1.10", - "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-4.1.10.tgz", - "integrity": "sha512-5wny+F6H4/8RgNlaqab4ktc3e0/blKutmq8yNlBFXA//nSFFAqAngjNVRzUvCgYROULmZZUoosL/KSoZo5aUaQ==", - "dev": true, - "dependencies": { - "cosmiconfig": "^5.0.0", - "cssnano-preset-default": "^4.0.7", - "is-resolvable": "^1.0.0", - "postcss": "^7.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/cssnano-preset-default": { - "version": "4.0.7", - "resolved": "https://registry.npmjs.org/cssnano-preset-default/-/cssnano-preset-default-4.0.7.tgz", - "integrity": "sha512-x0YHHx2h6p0fCl1zY9L9roD7rnlltugGu7zXSKQx6k2rYw0Hi3IqxcoAGF7u9Q5w1nt7vK0ulxV8Lo+EvllGsA==", - "dev": true, - "dependencies": { - "css-declaration-sorter": "^4.0.1", - "cssnano-util-raw-cache": "^4.0.1", - "postcss": "^7.0.0", - "postcss-calc": "^7.0.1", - "postcss-colormin": "^4.0.3", - "postcss-convert-values": "^4.0.1", - "postcss-discard-comments": "^4.0.2", - "postcss-discard-duplicates": "^4.0.2", - "postcss-discard-empty": "^4.0.1", - "postcss-discard-overridden": "^4.0.1", - "postcss-merge-longhand": "^4.0.11", - "postcss-merge-rules": "^4.0.3", - "postcss-minify-font-values": "^4.0.2", - "postcss-minify-gradients": "^4.0.2", - "postcss-minify-params": "^4.0.2", - "postcss-minify-selectors": "^4.0.2", - "postcss-normalize-charset": "^4.0.1", - "postcss-normalize-display-values": "^4.0.2", - "postcss-normalize-positions": "^4.0.2", - "postcss-normalize-repeat-style": "^4.0.2", - "postcss-normalize-string": "^4.0.2", - "postcss-normalize-timing-functions": "^4.0.2", - "postcss-normalize-unicode": "^4.0.1", - "postcss-normalize-url": "^4.0.1", - "postcss-normalize-whitespace": "^4.0.2", - "postcss-ordered-values": "^4.1.2", - "postcss-reduce-initial": "^4.0.3", - "postcss-reduce-transforms": "^4.0.2", - "postcss-svgo": "^4.0.2", - "postcss-unique-selectors": "^4.0.1" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/cssnano-util-get-arguments": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/cssnano-util-get-arguments/-/cssnano-util-get-arguments-4.0.0.tgz", - "integrity": "sha1-7ToIKZ8h11dBsg87gfGU7UnMFQ8=", - "dev": true, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/cssnano-util-get-match": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/cssnano-util-get-match/-/cssnano-util-get-match-4.0.0.tgz", - "integrity": "sha1-wOTKB/U4a7F+xeUiULT1lhNlFW0=", - "dev": true, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/cssnano-util-raw-cache": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/cssnano-util-raw-cache/-/cssnano-util-raw-cache-4.0.1.tgz", - "integrity": "sha512-qLuYtWK2b2Dy55I8ZX3ky1Z16WYsx544Q0UWViebptpwn/xDBmog2TLg4f+DBMg1rJ6JDWtn96WHbOKDWt1WQA==", - "dev": true, - "dependencies": { - "postcss": "^7.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/cssnano-util-same-parent": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/cssnano-util-same-parent/-/cssnano-util-same-parent-4.0.1.tgz", - "integrity": "sha512-WcKx5OY+KoSIAxBW6UBBRay1U6vkYheCdjyVNDm85zt5K9mHoGOfsOsqIszfAqrQQFIIKgjh2+FDgIj/zsl21Q==", - "dev": true, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/csso": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/csso/-/csso-4.0.3.tgz", - "integrity": "sha512-NL3spysxUkcrOgnpsT4Xdl2aiEiBG6bXswAABQVHcMrfjjBisFOKwLDOmf4wf32aPdcJws1zds2B0Rg+jqMyHQ==", - "dev": true, - "dependencies": { - "css-tree": "1.0.0-alpha.39" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/csso/node_modules/css-tree": { - "version": "1.0.0-alpha.39", - "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.0.0-alpha.39.tgz", - "integrity": "sha512-7UvkEYgBAHRG9Nt980lYxjsTrCyHFN53ky3wVsDkiMdVqylqRt+Zc+jm5qw7/qyOvN2dHSYtX0e4MbCCExSvnA==", - "dev": true, - "dependencies": { - "mdn-data": "2.0.6", - "source-map": "^0.6.1" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/csso/node_modules/mdn-data": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.6.tgz", - "integrity": "sha512-rQvjv71olwNHgiTbfPZFkJtjNMciWgswYeciZhtvWLO8bmX3TnhyA62I6sTWOyZssWHJJjY6/KiWwqQsWWsqOA==", - "dev": true - }, - "node_modules/csso/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/cyclist": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/cyclist/-/cyclist-1.0.1.tgz", - "integrity": "sha1-WW6WmP0MgOEgOMK4LW6xs1tiJNk=", - "dev": true - }, - "node_modules/dashdash": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", - "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", - "dev": true, - "dependencies": { - "assert-plus": "^1.0.0" - }, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/de-indent": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/de-indent/-/de-indent-1.0.2.tgz", - "integrity": "sha1-sgOOhG3DO6pXlhKNCAS0VbjB4h0=", - "dev": true - }, - "node_modules/debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", - "deprecated": "Debug versions >=3.2.0 <3.2.7 || >=4 <4.3.1 have a low-severity ReDos regression when used in a Node.js environment. It is recommended you upgrade to 3.2.7 or 4.3.1. (https://github.com/visionmedia/debug/issues/797)", - "dev": true, - "dependencies": { - "ms": "^2.1.1" - } - }, - "node_modules/decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/decode-uri-component": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", - "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=", - "dev": true, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/decompress-response": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz", - "integrity": "sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M=", - "dev": true, - "dependencies": { - "mimic-response": "^1.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/deep-equal": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.1.1.tgz", - "integrity": "sha512-yd9c5AdiqVcR+JjcwUQb9DkhJc8ngNr0MahEBGvDiJw8puWab2yZlh+nkasOnZP+EGTAP6rRp2JzJhJZzvNF8g==", - "dev": true, - "dependencies": { - "is-arguments": "^1.0.4", - "is-date-object": "^1.0.1", - "is-regex": "^1.0.4", - "object-is": "^1.0.1", - "object-keys": "^1.1.1", - "regexp.prototype.flags": "^1.2.0" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/deep-extend": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", - "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", - "dev": true, - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/deepmerge": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-1.5.2.tgz", - "integrity": "sha512-95k0GDqvBjZavkuvzx/YqVLv/6YYa17fz6ILMSf7neqQITCPbnfEnQvEgMPNjH4kgobe7+WIL0yJEHku+H3qtQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/default-gateway": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/default-gateway/-/default-gateway-4.2.0.tgz", - "integrity": "sha512-h6sMrVB1VMWVrW13mSc6ia/DwYYw5MN6+exNu1OaJeFac5aSAvwM7lZ0NVfTABuSkQelr4h5oebg3KB1XPdjgA==", - "dev": true, - "dependencies": { - "execa": "^1.0.0", - "ip-regex": "^2.1.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/defer-to-connect": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-1.1.3.tgz", - "integrity": "sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ==", - "dev": true - }, - "node_modules/define-properties": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", - "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", - "dev": true, - "dependencies": { - "object-keys": "^1.0.12" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/define-property": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", - "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", - "dev": true, - "dependencies": { - "is-descriptor": "^1.0.2", - "isobject": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/del": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/del/-/del-4.1.1.tgz", - "integrity": "sha512-QwGuEUouP2kVwQenAsOof5Fv8K9t3D8Ca8NxcXKrIpEHjTXK5J2nXLdP+ALI1cgv8wj7KuwBhTwBkOZSJKM5XQ==", - "dev": true, - "dependencies": { - "@types/glob": "^7.1.1", - "globby": "^6.1.0", - "is-path-cwd": "^2.0.0", - "is-path-in-cwd": "^2.0.0", - "p-map": "^2.0.0", - "pify": "^4.0.1", - "rimraf": "^2.6.3" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/del/node_modules/globby": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-6.1.0.tgz", - "integrity": "sha1-9abXDoOV4hyFj7BInWTfAkJNUGw=", - "dev": true, - "dependencies": { - "array-union": "^1.0.1", - "glob": "^7.0.3", - "object-assign": "^4.0.1", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/del/node_modules/globby/node_modules/pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", - "dev": true, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/delegate": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/delegate/-/delegate-3.2.0.tgz", - "integrity": "sha512-IofjkYBZaZivn0V8nnsMJGBr4jVLxHDheKSW88PyxS5QC4Vo9ZbZVvhzlSxY87fVq3STR6r+4cGepyHkcWOQSw==", - "dev": true, - "optional": true - }, - "node_modules/depd": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", - "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=", - "dev": true, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/des.js": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.1.tgz", - "integrity": "sha512-Q0I4pfFrv2VPd34/vfLrFOoRmlYj3OV50i7fskps1jZWK1kApMWWT9G6RRUeYedLcBDIhnSDaUvJMb3AhUlaEA==", - "dev": true, - "dependencies": { - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0" - } - }, - "node_modules/destroy": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", - "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=", - "dev": true - }, - "node_modules/detect-node": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.0.4.tgz", - "integrity": "sha512-ZIzRpLJrOj7jjP2miAtgqIfmzbxa4ZOr5jJc601zklsfEx9oTzmmj2nVpIPRpNlRTIh8lc1kyViIY7BWSGNmKw==", - "dev": true - }, - "node_modules/diacritics": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/diacritics/-/diacritics-1.3.0.tgz", - "integrity": "sha1-PvqHMj67hj5mls67AILUj/PW96E=", - "dev": true - }, - "node_modules/diffie-hellman": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", - "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==", - "dev": true, - "dependencies": { - "bn.js": "^4.1.0", - "miller-rabin": "^4.0.0", - "randombytes": "^2.0.0" - } - }, - "node_modules/diffie-hellman/node_modules/bn.js": { - "version": "4.11.9", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz", - "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==", - "dev": true - }, - "node_modules/dir-glob": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-2.2.2.tgz", - "integrity": "sha512-f9LBi5QWzIW3I6e//uxZoLBlUt9kcp66qo0sSCxL6YZKc75R1c4MFCoe/LaZiBGmgujvQdxc5Bn3QhfyvK5Hsw==", - "dev": true, - "dependencies": { - "path-type": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/dns-equal": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/dns-equal/-/dns-equal-1.0.0.tgz", - "integrity": "sha1-s55/HabrCnW6nBcySzR1PEfgZU0=", - "dev": true - }, - "node_modules/dns-packet": { - "version": "1.3.4", - "resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-1.3.4.tgz", - "integrity": "sha512-BQ6F4vycLXBvdrJZ6S3gZewt6rcrks9KBgM9vrhW+knGRqc8uEdT7fuCwloc7nny5xNoMJ17HGH0R/6fpo8ECA==", - "dev": true, - "dependencies": { - "ip": "^1.1.0", - "safe-buffer": "^5.0.1" - } - }, - "node_modules/dns-txt": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/dns-txt/-/dns-txt-2.0.2.tgz", - "integrity": "sha1-uR2Ab10nGI5Ks+fRB9iBocxGQrY=", - "dev": true, - "dependencies": { - "buffer-indexof": "^1.0.0" - } - }, - "node_modules/docsearch.js": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/docsearch.js/-/docsearch.js-2.6.3.tgz", - "integrity": "sha512-GN+MBozuyz664ycpZY0ecdQE0ND/LSgJKhTLA0/v3arIS3S1Rpf2OJz6A35ReMsm91V5apcmzr5/kM84cvUg+A==", - "dev": true, - "dependencies": { - "algoliasearch": "^3.24.5", - "autocomplete.js": "0.36.0", - "hogan.js": "^3.0.2", - "request": "^2.87.0", - "stack-utils": "^1.0.1", - "to-factory": "^1.0.0", - "zepto": "^1.2.0" - } - }, - "node_modules/dom-converter": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/dom-converter/-/dom-converter-0.2.0.tgz", - "integrity": "sha512-gd3ypIPfOMr9h5jIKq8E3sHOTCjeirnl0WK5ZdS1AW0Odt0b1PaWaHdJ4Qk4klv+YB9aJBS7mESXjFoDQPu6DA==", - "dev": true, - "dependencies": { - "utila": "~0.4" - } - }, - "node_modules/dom-serializer": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.2.2.tgz", - "integrity": "sha512-2/xPb3ORsQ42nHYiSunXkDjPLBaEj/xTwUO4B7XCZQTRk7EBtTOPaygh10YAAh2OI1Qrp6NWfpAhzswj0ydt9g==", - "dev": true, - "dependencies": { - "domelementtype": "^2.0.1", - "entities": "^2.0.0" - } - }, - "node_modules/dom-serializer/node_modules/domelementtype": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.0.1.tgz", - "integrity": "sha512-5HOHUDsYZWV8FGWN0Njbr/Rn7f/eWSQi1v7+HsUVwXgn8nWWlL64zKDkS0n8ZmQ3mlWOMuXOnR+7Nx/5tMO5AQ==", - "dev": true - }, - "node_modules/dom-serializer/node_modules/entities": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/entities/-/entities-2.0.3.tgz", - "integrity": "sha512-MyoZ0jgnLvB2X3Lg5HqpFmn1kybDiIfEQmKzTb5apr51Rb+T3KdmMiqa70T+bhGnyv7bQ6WMj2QMHpGMmlrUYQ==", - "dev": true - }, - "node_modules/dom-walk": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/dom-walk/-/dom-walk-0.1.2.tgz", - "integrity": "sha512-6QvTW9mrGeIegrFXdtQi9pk7O/nSK6lSdXW2eqUspN5LWD7UTji2Fqw5V2YLjBpHEoU9Xl/eUWNpDeZvoyOv2w==", - "dev": true - }, - "node_modules/domain-browser": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-1.2.0.tgz", - "integrity": "sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA==", - "dev": true, - "engines": { - "node": ">=0.4", - "npm": ">=1.2" - } - }, - "node_modules/domelementtype": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.1.tgz", - "integrity": "sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==", - "dev": true - }, - "node_modules/domhandler": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.4.2.tgz", - "integrity": "sha512-JiK04h0Ht5u/80fdLMCEmV4zkNh2BcoMFBmZ/91WtYZ8qVXSKjiw7fXMgFPnHcSZgOo3XdinHvmnDUeMf5R4wA==", - "dev": true, - "dependencies": { - "domelementtype": "1" - } - }, - "node_modules/domutils": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.7.0.tgz", - "integrity": "sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg==", - "dev": true, - "dependencies": { - "dom-serializer": "0", - "domelementtype": "1" - } - }, - "node_modules/dot-prop": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.2.0.tgz", - "integrity": "sha512-uEUyaDKoSQ1M4Oq8l45hSE26SnTxL6snNnqvK/VWx5wJhmff5z0FUVJDKDanor/6w3kzE3i7XZOk+7wC0EXr1A==", - "dev": true, - "dependencies": { - "is-obj": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/duplexer3": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz", - "integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=", - "dev": true - }, - "node_modules/duplexify": { - "version": "3.7.1", - "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.7.1.tgz", - "integrity": "sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g==", - "dev": true, - "dependencies": { - "end-of-stream": "^1.0.0", - "inherits": "^2.0.1", - "readable-stream": "^2.0.0", - "stream-shift": "^1.0.0" - } - }, - "node_modules/ecc-jsbn": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", - "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", - "dev": true, - "dependencies": { - "jsbn": "~0.1.0", - "safer-buffer": "^2.1.0" - } - }, - "node_modules/ee-first": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", - "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=", - "dev": true - }, - "node_modules/electron-to-chromium": { - "version": "1.3.739", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.739.tgz", - "integrity": "sha512-+LPJVRsN7hGZ9EIUUiWCpO7l4E3qBYHNadazlucBfsXBbccDFNKUBAgzE68FnkWGJPwD/AfKhSzL+G+Iqb8A4A==", - "dev": true - }, - "node_modules/elliptic": { - "version": "6.5.3", - "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.3.tgz", - "integrity": "sha512-IMqzv5wNQf+E6aHeIqATs0tOLeOTwj1QKbRcS3jBbYkl5oLAserA8yJTT7/VyHUYG91PRmPyeQDObKLPpeS4dw==", - "dev": true, - "dependencies": { - "bn.js": "^4.4.0", - "brorand": "^1.0.1", - "hash.js": "^1.0.0", - "hmac-drbg": "^1.0.0", - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0", - "minimalistic-crypto-utils": "^1.0.0" - } - }, - "node_modules/elliptic/node_modules/bn.js": { - "version": "4.11.9", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz", - "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==", - "dev": true - }, - "node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true - }, - "node_modules/emojis-list": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", - "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==", - "dev": true, - "engines": { - "node": ">= 4" - } - }, - "node_modules/encodeurl": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", - "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=", - "dev": true, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/end-of-stream": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", - "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", - "dev": true, - "dependencies": { - "once": "^1.4.0" - } - }, - "node_modules/enhanced-resolve": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-4.1.1.tgz", - "integrity": "sha512-98p2zE+rL7/g/DzMHMTF4zZlCgeVdJ7yr6xzEpJRYwFYrGi9ANdn5DnJURg6RpBkyk60XYDnWIv51VfIhfNGuA==", - "dev": true, - "dependencies": { - "graceful-fs": "^4.1.2", - "memory-fs": "^0.5.0", - "tapable": "^1.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/enhanced-resolve/node_modules/memory-fs": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.5.0.tgz", - "integrity": "sha512-jA0rdU5KoQMC0e6ppoNRtpp6vjFq6+NY7r8hywnC7V+1Xj/MtHwGIbB1QaK/dunyjWteJzmkpd7ooeWg10T7GA==", - "dev": true, - "dependencies": { - "errno": "^0.1.3", - "readable-stream": "^2.0.1" - }, - "engines": { - "node": ">=4.3.0 <5.0.0 || >=5.10" - } - }, - "node_modules/entities": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz", - "integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==", - "dev": true - }, - "node_modules/envify": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/envify/-/envify-4.1.0.tgz", - "integrity": "sha512-IKRVVoAYr4pIx4yIWNsz9mOsboxlNXiu7TNBnem/K/uTHdkyzXWDzHCK7UTolqBbgaBz0tQHsD3YNls0uIIjiw==", - "dev": true, - "dependencies": { - "esprima": "^4.0.0", - "through": "~2.3.4" - }, - "bin": { - "envify": "bin/envify" - } - }, - "node_modules/envinfo": { - "version": "7.5.1", - "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.5.1.tgz", - "integrity": "sha512-hQBkDf2iO4Nv0CNHpCuSBeaSrveU6nThVxFGTrq/eDlV716UQk09zChaJae4mZRsos1x4YLY2TaH3LHUae3ZmQ==", - "dev": true, - "bin": { - "envinfo": "dist/cli.js" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/errno": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.7.tgz", - "integrity": "sha512-MfrRBDWzIWifgq6tJj60gkAwtLNb6sQPlcFrSOflcP1aFmmruKQ2wRnze/8V6kgyz7H3FF8Npzv78mZ7XLLflg==", - "dev": true, - "dependencies": { - "prr": "~1.0.1" - }, - "bin": { - "errno": "cli.js" - } - }, - "node_modules/error-ex": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", - "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", - "dev": true, - "dependencies": { - "is-arrayish": "^0.2.1" - } - }, - "node_modules/es-abstract": { - "version": "1.17.5", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.5.tgz", - "integrity": "sha512-BR9auzDbySxOcfog0tLECW8l28eRGpDpU3Dm3Hp4q/N+VtLTmyj4EUN088XZWQDW/hzj6sYRDXeOFsaAODKvpg==", - "dev": true, - "dependencies": { - "es-to-primitive": "^1.2.1", - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1", - "is-callable": "^1.1.5", - "is-regex": "^1.0.5", - "object-inspect": "^1.7.0", - "object-keys": "^1.1.1", - "object.assign": "^4.1.0", - "string.prototype.trimleft": "^2.1.1", - "string.prototype.trimright": "^2.1.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/es-to-primitive": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", - "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", - "dev": true, - "dependencies": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/es6-promise": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", - "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==", - "dev": true - }, - "node_modules/escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/escape-goat": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/escape-goat/-/escape-goat-2.1.1.tgz", - "integrity": "sha512-8/uIhbG12Csjy2JEW7D9pHbreaVaS/OpN3ycnyvElTdwM5n6GY6W6e2IPemfvGZeUMqZ9A/3GqIZMgKnBhAw/Q==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/escape-html": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", - "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=", - "dev": true - }, - "node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", - "dev": true, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/eslint-scope": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.3.tgz", - "integrity": "sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg==", - "dev": true, - "dependencies": { - "esrecurse": "^4.1.0", - "estraverse": "^4.1.1" - }, - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", - "dev": true, - "bin": { - "esparse": "bin/esparse.js", - "esvalidate": "bin/esvalidate.js" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/esrecurse": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz", - "integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==", - "dev": true, - "dependencies": { - "estraverse": "^4.1.0" - }, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", - "dev": true, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/etag": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", - "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=", - "dev": true, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/eventemitter3": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.4.tgz", - "integrity": "sha512-rlaVLnVxtxvoyLsQQFBx53YmXHDxRIzzTLbdfxqi4yocpSjAxXwkU0cScM5JgSKMqEhrZpnvQ2D9gjylR0AimQ==", - "dev": true - }, - "node_modules/events": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/events/-/events-1.1.1.tgz", - "integrity": "sha1-nr23Y1rQmccNzEwqH1AEKI6L2SQ=", - "dev": true, - "engines": { - "node": ">=0.4.x" - } - }, - "node_modules/eventsource": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/eventsource/-/eventsource-1.0.7.tgz", - "integrity": "sha512-4Ln17+vVT0k8aWq+t/bF5arcS3EpT9gYtW66EPacdj/mAFevznsnyoHLPy2BA8gbIQeIHoPsvwmfBftfcG//BQ==", - "dev": true, - "dependencies": { - "original": "^1.0.0" - }, - "engines": { - "node": ">=0.12.0" - } - }, - "node_modules/evp_bytestokey": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", - "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", - "dev": true, - "dependencies": { - "md5.js": "^1.3.4", - "safe-buffer": "^5.1.1" - } - }, - "node_modules/execa": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", - "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", - "dev": true, - "dependencies": { - "cross-spawn": "^6.0.0", - "get-stream": "^4.0.0", - "is-stream": "^1.1.0", - "npm-run-path": "^2.0.0", - "p-finally": "^1.0.0", - "signal-exit": "^3.0.0", - "strip-eof": "^1.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/expand-brackets": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", - "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", - "dev": true, - "dependencies": { - "debug": "^2.3.3", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "posix-character-classes": "^0.1.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/expand-brackets/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/expand-brackets/node_modules/define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "dependencies": { - "is-descriptor": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/expand-brackets/node_modules/is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/expand-brackets/node_modules/is-accessor-descriptor/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/expand-brackets/node_modules/is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/expand-brackets/node_modules/is-data-descriptor/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/expand-brackets/node_modules/is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "dependencies": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/expand-brackets/node_modules/kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/expand-brackets/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - }, - "node_modules/express": { - "version": "4.17.1", - "resolved": "https://registry.npmjs.org/express/-/express-4.17.1.tgz", - "integrity": "sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g==", - "dev": true, - "dependencies": { - "accepts": "~1.3.7", - "array-flatten": "1.1.1", - "body-parser": "1.19.0", - "content-disposition": "0.5.3", - "content-type": "~1.0.4", - "cookie": "0.4.0", - "cookie-signature": "1.0.6", - "debug": "2.6.9", - "depd": "~1.1.2", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "finalhandler": "~1.1.2", - "fresh": "0.5.2", - "merge-descriptors": "1.0.1", - "methods": "~1.1.2", - "on-finished": "~2.3.0", - "parseurl": "~1.3.3", - "path-to-regexp": "0.1.7", - "proxy-addr": "~2.0.5", - "qs": "6.7.0", - "range-parser": "~1.2.1", - "safe-buffer": "5.1.2", - "send": "0.17.1", - "serve-static": "1.14.1", - "setprototypeof": "1.1.1", - "statuses": "~1.5.0", - "type-is": "~1.6.18", - "utils-merge": "1.0.1", - "vary": "~1.1.2" - }, - "engines": { - "node": ">= 0.10.0" - } - }, - "node_modules/express/node_modules/array-flatten": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", - "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=", - "dev": true - }, - "node_modules/express/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/express/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - }, - "node_modules/express/node_modules/qs": { - "version": "6.7.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz", - "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==", - "dev": true, - "engines": { - "node": ">=0.6" - } - }, - "node_modules/extend": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", - "dev": true - }, - "node_modules/extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "dependencies": { - "is-extendable": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/extglob": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", - "dev": true, - "dependencies": { - "array-unique": "^0.3.2", - "define-property": "^1.0.0", - "expand-brackets": "^2.1.4", - "extend-shallow": "^2.0.1", - "fragment-cache": "^0.2.1", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/extglob/node_modules/define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "dependencies": { - "is-descriptor": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/extsprintf": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", - "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=", - "dev": true, - "engines": [ - "node >=0.6.0" - ] - }, - "node_modules/fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true - }, - "node_modules/fast-glob": { - "version": "2.2.7", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-2.2.7.tgz", - "integrity": "sha512-g1KuQwHOZAmOZMuBtHdxDtju+T2RT8jgCC9aANsbpdiDDTSnjgfuVsIBNKbUeJI3oKMRExcfNDtJl4OhbffMsw==", - "dev": true, - "dependencies": { - "@mrmlnc/readdir-enhanced": "^2.2.1", - "@nodelib/fs.stat": "^1.1.2", - "glob-parent": "^3.1.0", - "is-glob": "^4.0.0", - "merge2": "^1.2.3", - "micromatch": "^3.1.10" - }, - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/fast-json-stable-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", - "dev": true - }, - "node_modules/faye-websocket": { - "version": "0.10.0", - "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.10.0.tgz", - "integrity": "sha1-TkkvjQTftviQA1B/btvy1QHnxvQ=", - "dev": true, - "dependencies": { - "websocket-driver": ">=0.5.1" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/figgy-pudding": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/figgy-pudding/-/figgy-pudding-3.5.2.tgz", - "integrity": "sha512-0btnI/H8f2pavGMN8w40mlSKOfTK2SVJmBfBeVIj3kNw0swwgzyRq0d5TJVOwodFmtvpPeWPN/MCcfuWF0Ezbw==", - "dev": true - }, - "node_modules/figures": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", - "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", - "dev": true, - "dependencies": { - "escape-string-regexp": "^1.0.5" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/file-loader": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/file-loader/-/file-loader-3.0.1.tgz", - "integrity": "sha512-4sNIOXgtH/9WZq4NvlfU3Opn5ynUsqBwSLyM+I7UOwdGigTBYfVVQEwe/msZNX/j4pCJTIM14Fsw66Svo1oVrw==", - "dev": true, - "dependencies": { - "loader-utils": "^1.0.2", - "schema-utils": "^1.0.0" - }, - "engines": { - "node": ">= 6.9.0" - }, - "peerDependencies": { - "webpack": "^4.0.0" - } - }, - "node_modules/file-loader/node_modules/schema-utils": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", - "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", - "dev": true, - "dependencies": { - "ajv": "^6.1.0", - "ajv-errors": "^1.0.0", - "ajv-keywords": "^3.1.0" - }, - "engines": { - "node": ">= 4" - } - }, - "node_modules/file-uri-to-path": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", - "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", - "dev": true, - "optional": true - }, - "node_modules/fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "dev": true, - "dependencies": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/finalhandler": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", - "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", - "dev": true, - "dependencies": { - "debug": "2.6.9", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "on-finished": "~2.3.0", - "parseurl": "~1.3.3", - "statuses": "~1.5.0", - "unpipe": "~1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/finalhandler/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/finalhandler/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - }, - "node_modules/find-cache-dir": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-2.1.0.tgz", - "integrity": "sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ==", - "dev": true, - "dependencies": { - "commondir": "^1.0.1", - "make-dir": "^2.0.0", - "pkg-dir": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "dev": true, - "dependencies": { - "locate-path": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/flush-write-stream": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/flush-write-stream/-/flush-write-stream-1.1.1.tgz", - "integrity": "sha512-3Z4XhFZ3992uIq0XOqb9AreonueSYphE6oYbpt5+3u06JWklbsPkNv3ZKkP9Bz/r+1MWCaMoSQ28P85+1Yc77w==", - "dev": true, - "dependencies": { - "inherits": "^2.0.3", - "readable-stream": "^2.3.6" - } - }, - "node_modules/follow-redirects": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.11.0.tgz", - "integrity": "sha512-KZm0V+ll8PfBrKwMzdo5D13b1bur9Iq9Zd/RMmAoQQcl2PxxFml8cxXPaaPYVbV0RjNjq1CU7zIzAOqtUPudmA==", - "dev": true, - "dependencies": { - "debug": "^3.0.0" - }, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/follow-redirects/node_modules/debug": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", - "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", - "deprecated": "Debug versions >=3.2.0 <3.2.7 || >=4 <4.3.1 have a low-severity ReDos regression when used in a Node.js environment. It is recommended you upgrade to 3.2.7 or 4.3.1. (https://github.com/visionmedia/debug/issues/797)", - "dev": true, - "dependencies": { - "ms": "^2.1.1" - } - }, - "node_modules/for-in": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", - "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/foreach": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/foreach/-/foreach-2.0.5.tgz", - "integrity": "sha1-C+4AUBiusmDQo6865ljdATbsG5k=", - "dev": true - }, - "node_modules/forever-agent": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", - "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=", - "dev": true, - "engines": { - "node": "*" - } - }, - "node_modules/form-data": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", - "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", - "dev": true, - "dependencies": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.6", - "mime-types": "^2.1.12" - }, - "engines": { - "node": ">= 0.12" - } - }, - "node_modules/forwarded": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz", - "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=", - "dev": true, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/fragment-cache": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", - "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", - "dev": true, - "dependencies": { - "map-cache": "^0.2.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/fresh": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", - "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=", - "dev": true, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/from2": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/from2/-/from2-2.3.0.tgz", - "integrity": "sha1-i/tVAr3kpNNs/e6gB/zKIdfjgq8=", - "dev": true, - "dependencies": { - "inherits": "^2.0.1", - "readable-stream": "^2.0.0" - } - }, - "node_modules/fs-extra": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", - "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", - "dev": true, - "dependencies": { - "graceful-fs": "^4.1.2", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - }, - "engines": { - "node": ">=6 <7 || >=8" - } - }, - "node_modules/fs-write-stream-atomic": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz", - "integrity": "sha1-tH31NJPvkR33VzHnCp3tAYnbQMk=", - "dev": true, - "dependencies": { - "graceful-fs": "^4.1.2", - "iferr": "^0.1.5", - "imurmurhash": "^0.1.4", - "readable-stream": "1 || 2" - } - }, - "node_modules/fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", - "dev": true - }, - "node_modules/fsevents": { - "version": "1.2.13", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz", - "integrity": "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==", - "deprecated": "fsevents 1 will break on node v14+ and could be using insecure binaries. Upgrade to fsevents 2.", - "dev": true, - "hasInstallScript": true, - "optional": true, - "os": [ - "darwin" - ], - "dependencies": { - "bindings": "^1.5.0", - "nan": "^2.12.1" - }, - "engines": { - "node": ">= 4.0" - } - }, - "node_modules/function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", - "dev": true - }, - "node_modules/gensync": { - "version": "1.0.0-beta.1", - "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.1.tgz", - "integrity": "sha512-r8EC6NO1sngH/zdD9fiRDLdcgnbayXah+mLgManTaIZJqEC1MZstmnox8KpnI2/fxQwrp5OpCOYWLp4rBl4Jcg==", - "dev": true, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "dev": true, - "engines": { - "node": "6.* || 8.* || >= 10.*" - } - }, - "node_modules/get-stream": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", - "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", - "dev": true, - "dependencies": { - "pump": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/get-value": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", - "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/getpass": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", - "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", - "dev": true, - "dependencies": { - "assert-plus": "^1.0.0" - } - }, - "node_modules/glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "dev": true, - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/glob-parent": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", - "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", - "dev": true, - "dependencies": { - "is-glob": "^3.1.0", - "path-dirname": "^1.0.0" - } - }, - "node_modules/glob-parent/node_modules/is-glob": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", - "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", - "dev": true, - "dependencies": { - "is-extglob": "^2.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/glob-to-regexp": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.3.0.tgz", - "integrity": "sha1-jFoUlNIGbFcMw7/kSWF1rMTVAqs=", - "dev": true - }, - "node_modules/global": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/global/-/global-4.4.0.tgz", - "integrity": "sha512-wv/LAoHdRE3BeTGz53FAamhGlPLhlssK45usmGFThIi4XqnBmjKQ16u+RNbP7WvigRZDxUsM0J3gcQ5yicaL0w==", - "dev": true, - "dependencies": { - "min-document": "^2.19.0", - "process": "^0.11.10" - } - }, - "node_modules/global-dirs": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-2.0.1.tgz", - "integrity": "sha512-5HqUqdhkEovj2Of/ms3IeS/EekcO54ytHRLV4PEY2rhRwrHXLQjeVEES0Lhka0xwNDtGYn58wyC4s5+MHsOO6A==", - "dev": true, - "dependencies": { - "ini": "^1.3.5" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/globals": { - "version": "11.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/globby": { - "version": "9.2.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-9.2.0.tgz", - "integrity": "sha512-ollPHROa5mcxDEkwg6bPt3QbEf4pDQSNtd6JPL1YvOvAo/7/0VAm9TccUeoTmarjPw4pfUthSCqcyfNB1I3ZSg==", - "dev": true, - "dependencies": { - "@types/glob": "^7.1.1", - "array-union": "^1.0.2", - "dir-glob": "^2.2.2", - "fast-glob": "^2.2.6", - "glob": "^7.1.3", - "ignore": "^4.0.3", - "pify": "^4.0.1", - "slash": "^2.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/good-listener": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/good-listener/-/good-listener-1.2.2.tgz", - "integrity": "sha1-1TswzfkxPf+33JoNR3CWqm0UXFA=", - "dev": true, - "optional": true, - "dependencies": { - "delegate": "^3.1.2" - } - }, - "node_modules/got": { - "version": "9.6.0", - "resolved": "https://registry.npmjs.org/got/-/got-9.6.0.tgz", - "integrity": "sha512-R7eWptXuGYxwijs0eV+v3o6+XH1IqVK8dJOEecQfTmkncw9AV4dcw/Dhxi8MdlqPthxxpZyizMzyg8RTmEsG+Q==", - "dev": true, - "dependencies": { - "@sindresorhus/is": "^0.14.0", - "@szmarczak/http-timer": "^1.1.2", - "cacheable-request": "^6.0.0", - "decompress-response": "^3.3.0", - "duplexer3": "^0.1.4", - "get-stream": "^4.1.0", - "lowercase-keys": "^1.0.1", - "mimic-response": "^1.0.1", - "p-cancelable": "^1.0.0", - "to-readable-stream": "^1.0.0", - "url-parse-lax": "^3.0.0" - }, - "engines": { - "node": ">=8.6" - } - }, - "node_modules/graceful-fs": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", - "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", - "dev": true - }, - "node_modules/gray-matter": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/gray-matter/-/gray-matter-4.0.2.tgz", - "integrity": "sha512-7hB/+LxrOjq/dd8APlK0r24uL/67w7SkYnfwhNFwg/VDIGWGmduTDYf3WNstLW2fbbmRwrDGCVSJ2isuf2+4Hw==", - "dev": true, - "dependencies": { - "js-yaml": "^3.11.0", - "kind-of": "^6.0.2", - "section-matter": "^1.0.0", - "strip-bom-string": "^1.0.0" - }, - "engines": { - "node": ">=6.0" - } - }, - "node_modules/handle-thing": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/handle-thing/-/handle-thing-2.0.1.tgz", - "integrity": "sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg==", - "dev": true - }, - "node_modules/har-schema": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", - "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/har-validator": { - "version": "5.1.3", - "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.3.tgz", - "integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==", - "deprecated": "this library is no longer supported", - "dev": true, - "dependencies": { - "ajv": "^6.5.5", - "har-schema": "^2.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "dev": true, - "dependencies": { - "function-bind": "^1.1.1" - }, - "engines": { - "node": ">= 0.4.0" - } - }, - "node_modules/has-ansi": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", - "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", - "dev": true, - "dependencies": { - "ansi-regex": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/has-ansi/node_modules/ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/has-symbols": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz", - "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==", - "dev": true, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", - "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", - "dev": true, - "dependencies": { - "get-value": "^2.0.6", - "has-values": "^1.0.0", - "isobject": "^3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/has-values": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", - "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=", - "dev": true, - "dependencies": { - "is-number": "^3.0.0", - "kind-of": "^4.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/has-values/node_modules/kind-of": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", - "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", - "dev": true, - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/has-yarn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/has-yarn/-/has-yarn-2.1.0.tgz", - "integrity": "sha512-UqBRqi4ju7T+TqGNdqAO0PaSVGsDGJUBQvk9eUWNGRY1CFGDzYhLWoM7JQEemnlvVcv/YEmc2wNW8BC24EnUsw==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/hash-base": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz", - "integrity": "sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==", - "dev": true, - "dependencies": { - "inherits": "^2.0.4", - "readable-stream": "^3.6.0", - "safe-buffer": "^5.2.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/hash-base/node_modules/readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "dev": true, - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/hash-base/node_modules/safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/hash-sum": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/hash-sum/-/hash-sum-1.0.2.tgz", - "integrity": "sha1-M7QHd3VMZDJXPBIMw4CLvRDUfwQ=", - "dev": true - }, - "node_modules/hash.js": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", - "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", - "dev": true, - "dependencies": { - "inherits": "^2.0.3", - "minimalistic-assert": "^1.0.1" - } - }, - "node_modules/he": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", - "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", - "dev": true, - "bin": { - "he": "bin/he" - } - }, - "node_modules/hex-color-regex": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/hex-color-regex/-/hex-color-regex-1.1.0.tgz", - "integrity": "sha512-l9sfDFsuqtOqKDsQdqrMRk0U85RZc0RtOR9yPI7mRVOa4FsR/BVnZ0shmQRM96Ji99kYZP/7hn1cedc1+ApsTQ==", - "dev": true - }, - "node_modules/hmac-drbg": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", - "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", - "dev": true, - "dependencies": { - "hash.js": "^1.0.3", - "minimalistic-assert": "^1.0.0", - "minimalistic-crypto-utils": "^1.0.1" - } - }, - "node_modules/hogan.js": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/hogan.js/-/hogan.js-3.0.2.tgz", - "integrity": "sha1-TNnhq9QpQUbnZ55B14mHMrAse/0=", - "dev": true, - "dependencies": { - "mkdirp": "0.3.0", - "nopt": "1.0.10" - }, - "bin": { - "hulk": "bin/hulk" - } - }, - "node_modules/hogan.js/node_modules/mkdirp": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.3.0.tgz", - "integrity": "sha1-G79asbqCevI1dRQ0kEJkVfSB/h4=", - "deprecated": "Legacy versions of mkdirp are no longer supported. Please update to mkdirp 1.x. (Note that the API surface has changed to use Promises in 1.x.)", - "dev": true, - "engines": { - "node": "*" - } - }, - "node_modules/hpack.js": { - "version": "2.1.6", - "resolved": "https://registry.npmjs.org/hpack.js/-/hpack.js-2.1.6.tgz", - "integrity": "sha1-h3dMCUnlE/QuhFdbPEVoH63ioLI=", - "dev": true, - "dependencies": { - "inherits": "^2.0.1", - "obuf": "^1.0.0", - "readable-stream": "^2.0.1", - "wbuf": "^1.1.0" - } - }, - "node_modules/hsl-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/hsl-regex/-/hsl-regex-1.0.0.tgz", - "integrity": "sha1-1JMwx4ntgZ4nakwNJy3/owsY/m4=", - "dev": true - }, - "node_modules/hsla-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/hsla-regex/-/hsla-regex-1.0.0.tgz", - "integrity": "sha1-wc56MWjIxmFAM6S194d/OyJfnDg=", - "dev": true - }, - "node_modules/html-comment-regex": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/html-comment-regex/-/html-comment-regex-1.1.2.tgz", - "integrity": "sha512-P+M65QY2JQ5Y0G9KKdlDpo0zK+/OHptU5AaBwUfAIDJZk1MYf32Frm84EcOytfJE0t5JvkAnKlmjsXDnWzCJmQ==", - "dev": true - }, - "node_modules/html-entities": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-1.3.1.tgz", - "integrity": "sha512-rhE/4Z3hIhzHAUKbW8jVcCyuT5oJCXXqhN/6mXXVCpzTmvJnoH2HL/bt3EZ6p55jbFJBeAe1ZNpL5BugLujxNA==", - "dev": true - }, - "node_modules/html-minifier": { - "version": "3.5.21", - "resolved": "https://registry.npmjs.org/html-minifier/-/html-minifier-3.5.21.tgz", - "integrity": "sha512-LKUKwuJDhxNa3uf/LPR/KVjm/l3rBqtYeCOAekvG8F1vItxMUpueGd94i/asDDr8/1u7InxzFA5EeGjhhG5mMA==", - "dev": true, - "dependencies": { - "camel-case": "3.0.x", - "clean-css": "4.2.x", - "commander": "2.17.x", - "he": "1.2.x", - "param-case": "2.1.x", - "relateurl": "0.2.x", - "uglify-js": "3.4.x" - }, - "bin": { - "html-minifier": "cli.js" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/html-tags": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/html-tags/-/html-tags-2.0.0.tgz", - "integrity": "sha1-ELMKOGCF9Dzt41PMj6fLDe7qZos=", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/htmlparser2": { - "version": "3.10.1", - "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.10.1.tgz", - "integrity": "sha512-IgieNijUMbkDovyoKObU1DUhm1iwNYE/fuifEoEHfd1oZKZDaONBSkal7Y01shxsM49R4XaMdGez3WnF9UfiCQ==", - "dev": true, - "dependencies": { - "domelementtype": "^1.3.1", - "domhandler": "^2.3.0", - "domutils": "^1.5.1", - "entities": "^1.1.1", - "inherits": "^2.0.1", - "readable-stream": "^3.1.1" - } - }, - "node_modules/htmlparser2/node_modules/readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "dev": true, - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/http-cache-semantics": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz", - "integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==", - "dev": true - }, - "node_modules/http-deceiver": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/http-deceiver/-/http-deceiver-1.2.7.tgz", - "integrity": "sha1-+nFolEq5pRnTN8sL7HKE3D5yPYc=", - "dev": true - }, - "node_modules/http-errors": { - "version": "1.7.2", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz", - "integrity": "sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==", - "dev": true, - "dependencies": { - "depd": "~1.1.2", - "inherits": "2.0.3", - "setprototypeof": "1.1.1", - "statuses": ">= 1.5.0 < 2", - "toidentifier": "1.0.0" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/http-errors/node_modules/inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", - "dev": true - }, - "node_modules/http-proxy": { - "version": "1.18.1", - "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.1.tgz", - "integrity": "sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==", - "dev": true, - "dependencies": { - "eventemitter3": "^4.0.0", - "follow-redirects": "^1.0.0", - "requires-port": "^1.0.0" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/http-proxy-middleware": { - "version": "0.19.1", - "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-0.19.1.tgz", - "integrity": "sha512-yHYTgWMQO8VvwNS22eLLloAkvungsKdKTLO8AJlftYIKNfJr3GK3zK0ZCfzDDGUBttdGc8xFy1mCitvNKQtC3Q==", - "dev": true, - "dependencies": { - "http-proxy": "^1.17.0", - "is-glob": "^4.0.0", - "lodash": "^4.17.11", - "micromatch": "^3.1.10" - }, - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/http-signature": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", - "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", - "dev": true, - "dependencies": { - "assert-plus": "^1.0.0", - "jsprim": "^1.2.2", - "sshpk": "^1.7.0" - }, - "engines": { - "node": ">=0.8", - "npm": ">=1.3.7" - } - }, - "node_modules/https-browserify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz", - "integrity": "sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM=", - "dev": true - }, - "node_modules/iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "dev": true, - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/icss-replace-symbols": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/icss-replace-symbols/-/icss-replace-symbols-1.1.0.tgz", - "integrity": "sha1-Bupvg2ead0njhs/h/oEq5dsiPe0=", - "dev": true - }, - "node_modules/icss-utils": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-4.1.1.tgz", - "integrity": "sha512-4aFq7wvWyMHKgxsH8QQtGpvbASCf+eM3wPRLI6R+MgAnTCZ6STYsRvttLvRWK0Nfif5piF394St3HeJDaljGPA==", - "dev": true, - "dependencies": { - "postcss": "^7.0.14" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/ieee754": { - "version": "1.1.13", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.13.tgz", - "integrity": "sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg==", - "dev": true - }, - "node_modules/iferr": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/iferr/-/iferr-0.1.5.tgz", - "integrity": "sha1-xg7taebY/bazEEofy8ocGS3FtQE=", - "dev": true - }, - "node_modules/ignore": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", - "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", - "dev": true, - "engines": { - "node": ">= 4" - } - }, - "node_modules/immediate": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.3.0.tgz", - "integrity": "sha512-HR7EVodfFUdQCTIeySw+WDRFJlPcLOJbXfwwZ7Oom6tjsvZ3bOkCDJHehQC3nxJrv7+f9XecwazynjU8e4Vw3Q==", - "dev": true - }, - "node_modules/import-cwd": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/import-cwd/-/import-cwd-2.1.0.tgz", - "integrity": "sha1-qmzzbnInYShcs3HsZRn1PiQ1sKk=", - "dev": true, - "dependencies": { - "import-from": "^2.1.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/import-fresh": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-2.0.0.tgz", - "integrity": "sha1-2BNVwVYS04bGH53dOSLUMEgipUY=", - "dev": true, - "dependencies": { - "caller-path": "^2.0.0", - "resolve-from": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/import-from": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/import-from/-/import-from-2.1.0.tgz", - "integrity": "sha1-M1238qev/VOqpHHUuAId7ja387E=", - "dev": true, - "dependencies": { - "resolve-from": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/import-lazy": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-2.1.0.tgz", - "integrity": "sha1-BWmOPUXIjo1+nZLLBYTnfwlvPkM=", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/import-local": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/import-local/-/import-local-2.0.0.tgz", - "integrity": "sha512-b6s04m3O+s3CGSbqDIyP4R6aAwAeYlVq9+WUWep6iHa8ETRf9yei1U48C5MmfJmV9AiLYYBKPMq/W+/WRpQmCQ==", - "dev": true, - "dependencies": { - "pkg-dir": "^3.0.0", - "resolve-cwd": "^2.0.0" - }, - "bin": { - "import-local-fixture": "fixtures/cli.js" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", - "dev": true, - "engines": { - "node": ">=0.8.19" - } - }, - "node_modules/indexes-of": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/indexes-of/-/indexes-of-1.0.1.tgz", - "integrity": "sha1-8w9xbI4r00bHtn0985FVZqfAVgc=", - "dev": true - }, - "node_modules/infer-owner": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/infer-owner/-/infer-owner-1.0.4.tgz", - "integrity": "sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A==", - "dev": true - }, - "node_modules/inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "dev": true, - "dependencies": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "node_modules/inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true - }, - "node_modules/ini": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", - "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", - "dev": true - }, - "node_modules/internal-ip": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/internal-ip/-/internal-ip-4.3.0.tgz", - "integrity": "sha512-S1zBo1D6zcsyuC6PMmY5+55YMILQ9av8lotMx447Bq6SAgo/sDK6y6uUKmuYhW7eacnIhFfsPmCNYdDzsnnDCg==", - "dev": true, - "dependencies": { - "default-gateway": "^4.2.0", - "ipaddr.js": "^1.9.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/invariant": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", - "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", - "dev": true, - "dependencies": { - "loose-envify": "^1.0.0" - } - }, - "node_modules/ip": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.5.tgz", - "integrity": "sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo=", - "dev": true - }, - "node_modules/ip-regex": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/ip-regex/-/ip-regex-2.1.0.tgz", - "integrity": "sha1-+ni/XS5pE8kRzp+BnuUUa7bYROk=", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/ipaddr.js": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", - "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", - "dev": true, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/is-absolute-url": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-absolute-url/-/is-absolute-url-2.1.0.tgz", - "integrity": "sha1-UFMN+4T8yap9vnhS6Do3uTufKqY=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "dependencies": { - "kind-of": "^6.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-arguments": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.0.4.tgz", - "integrity": "sha512-xPh0Rmt8NE65sNzvyUmWgI1tz3mKq74lGA0mL8LYZcoIzKOzDh6HmrYm3d18k60nHerC8A9Km8kYu87zfSFnLA==", - "dev": true, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/is-arrayish": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", - "dev": true - }, - "node_modules/is-binary-path": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", - "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=", - "dev": true, - "dependencies": { - "binary-extensions": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-buffer": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", - "dev": true - }, - "node_modules/is-callable": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.0.tgz", - "integrity": "sha512-pyVD9AaGLxtg6srb2Ng6ynWJqkHU9bEM087AKck0w8QwDarTfNcpIYoU8x8Hv2Icm8u6kFJM18Dag8lyqGkviw==", - "dev": true, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-ci": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-2.0.0.tgz", - "integrity": "sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==", - "dev": true, - "dependencies": { - "ci-info": "^2.0.0" - }, - "bin": { - "is-ci": "bin.js" - } - }, - "node_modules/is-color-stop": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-color-stop/-/is-color-stop-1.1.0.tgz", - "integrity": "sha1-z/9HGu5N1cnhWFmPvhKWe1za00U=", - "dev": true, - "dependencies": { - "css-color-names": "^0.0.4", - "hex-color-regex": "^1.1.0", - "hsl-regex": "^1.0.0", - "hsla-regex": "^1.0.0", - "rgb-regex": "^1.0.1", - "rgba-regex": "^1.0.0" - } - }, - "node_modules/is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "dependencies": { - "kind-of": "^6.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-date-object": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.2.tgz", - "integrity": "sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g==", - "dev": true, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "dependencies": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-directory": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/is-directory/-/is-directory-0.3.1.tgz", - "integrity": "sha1-YTObbyR1/Hcv2cnYP1yFddwVSuE=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/is-glob": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", - "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", - "dev": true, - "dependencies": { - "is-extglob": "^2.1.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-installed-globally": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.3.2.tgz", - "integrity": "sha512-wZ8x1js7Ia0kecP/CHM/3ABkAmujX7WPvQk6uu3Fly/Mk44pySulQpnHG46OMjHGXApINnV4QhY3SWnECO2z5g==", - "dev": true, - "dependencies": { - "global-dirs": "^2.0.1", - "is-path-inside": "^3.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/is-npm": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/is-npm/-/is-npm-4.0.0.tgz", - "integrity": "sha512-96ECIfh9xtDDlPylNPXhzjsykHsMJZ18ASpaWzQyBr4YRTcVjUvzaHayDAES2oU/3KpljhHUjtSRNiDwi0F0ig==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-number/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-obj": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz", - "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/is-path-cwd": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-2.2.0.tgz", - "integrity": "sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/is-path-in-cwd": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-2.1.0.tgz", - "integrity": "sha512-rNocXHgipO+rvnP6dk3zI20RpOtrAM/kzbB258Uw5BWr3TpXi861yzjo16Dn4hUox07iw5AyeMLHWsujkjzvRQ==", - "dev": true, - "dependencies": { - "is-path-inside": "^2.1.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/is-path-in-cwd/node_modules/is-path-inside": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-2.1.0.tgz", - "integrity": "sha512-wiyhTzfDWsvwAW53OBWF5zuvaOGlZ6PwYxAbPVDhpm+gM09xKQGjBq/8uYN12aDvMxnAnq3dxTyoSoRNmg5YFg==", - "dev": true, - "dependencies": { - "path-is-inside": "^1.0.2" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/is-path-inside": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.2.tgz", - "integrity": "sha512-/2UGPSgmtqwo1ktx8NDHjuPwZWmHhO+gj0f93EkhLB5RgW9RZevWYYlIkS6zePc6U2WpOdQYIwHe9YC4DWEBVg==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/is-plain-obj": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", - "integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "dev": true, - "dependencies": { - "isobject": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-regex": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.0.tgz", - "integrity": "sha512-iI97M8KTWID2la5uYXlkbSDQIg4F6o1sYboZKKTDpnDQMLtUL86zxhgDet3Q2SriaYsyGqZ6Mn2SjbRKeLHdqw==", - "dev": true, - "dependencies": { - "has-symbols": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-resolvable": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.1.0.tgz", - "integrity": "sha512-qgDYXFSR5WvEfuS5dMj6oTMEbrrSaM0CrFk2Yiq/gXnBvD9pMa2jGXxyhGLfvhZpuMZe18CJpFxAt3CRs42NMg==", - "dev": true - }, - "node_modules/is-stream": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-svg": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-svg/-/is-svg-3.0.0.tgz", - "integrity": "sha512-gi4iHK53LR2ujhLVVj+37Ykh9GLqYHX6JOVXbLAucaG/Cqw9xwdFOjDM2qeifLs1sF1npXXFvDu0r5HNgCMrzQ==", - "dev": true, - "dependencies": { - "html-comment-regex": "^1.1.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/is-symbol": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.3.tgz", - "integrity": "sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ==", - "dev": true, - "dependencies": { - "has-symbols": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-typedarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", - "dev": true - }, - "node_modules/is-windows": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", - "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-wsl": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz", - "integrity": "sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0=", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/is-yarn-global": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/is-yarn-global/-/is-yarn-global-0.3.0.tgz", - "integrity": "sha512-VjSeb/lHmkoyd8ryPVIKvOCn4D1koMqY+vqyjjUfc3xyKtP4dYOxM44sZrnqQSzSds3xyOrUTLTC9LVCVgLngw==", - "dev": true - }, - "node_modules/isarray": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", - "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", - "dev": true - }, - "node_modules/isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", - "dev": true - }, - "node_modules/isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/isstream": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", - "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=", - "dev": true - }, - "node_modules/javascript-stringify": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/javascript-stringify/-/javascript-stringify-2.0.1.tgz", - "integrity": "sha512-yV+gqbd5vaOYjqlbk16EG89xB5udgjqQF3C5FAORDg4f/IS1Yc5ERCv5e/57yBcfJYw05V5JyIXabhwb75Xxow==", - "dev": true - }, - "node_modules/js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "dev": true - }, - "node_modules/js-yaml": { - "version": "3.14.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.0.tgz", - "integrity": "sha512-/4IbIeHcD9VMHFqDR/gQ7EdZdLimOvW2DdcxFjdyyZ9NsbS+ccrXqVWDtab/lRl5AlUqmpBx8EhPaWR+OtY17A==", - "dev": true, - "dependencies": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/jsbn": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", - "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", - "dev": true - }, - "node_modules/jsesc": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", - "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", - "dev": true, - "bin": { - "jsesc": "bin/jsesc" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/json-buffer": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.0.tgz", - "integrity": "sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg=", - "dev": true - }, - "node_modules/json-parse-better-errors": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", - "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", - "dev": true - }, - "node_modules/json-schema": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", - "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=", - "dev": true - }, - "node_modules/json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true - }, - "node_modules/json-stringify-safe": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=", - "dev": true - }, - "node_modules/json3": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/json3/-/json3-3.3.3.tgz", - "integrity": "sha512-c7/8mbUsKigAbLkD5B010BK4D9LZm7A1pNItkEwiUZRpIN66exu/e7YQWysGun+TRKaJp8MhemM+VkfWv42aCA==", - "dev": true - }, - "node_modules/json5": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.1.3.tgz", - "integrity": "sha512-KXPvOm8K9IJKFM0bmdn8QXh7udDh1g/giieX0NLCaMnb4hEiVFqnop2ImTXCc5e0/oHz3LTqmHGtExn5hfMkOA==", - "dev": true, - "dependencies": { - "minimist": "^1.2.5" - }, - "bin": { - "json5": "lib/cli.js" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/jsonfile": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", - "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", - "dev": true, - "optionalDependencies": { - "graceful-fs": "^4.1.6" - } - }, - "node_modules/jsprim": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", - "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", - "dev": true, - "engines": [ - "node >=0.6.0" - ], - "dependencies": { - "assert-plus": "1.0.0", - "extsprintf": "1.3.0", - "json-schema": "0.2.3", - "verror": "1.10.0" - } - }, - "node_modules/keyv": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/keyv/-/keyv-3.1.0.tgz", - "integrity": "sha512-9ykJ/46SN/9KPM/sichzQ7OvXyGDYKGTaDlKMGCAlg2UK8KRy4jb0d8sFc+0Tt0YYnThq8X2RZgCg74RPxgcVA==", - "dev": true, - "dependencies": { - "json-buffer": "3.0.0" - } - }, - "node_modules/killable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/killable/-/killable-1.0.1.tgz", - "integrity": "sha512-LzqtLKlUwirEUyl/nicirVmNiPvYs7l5n8wOPP7fyJVpUPkvCnW/vuiXGpylGUlnPDnB7311rARzAt3Mhswpjg==", - "dev": true - }, - "node_modules/kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/last-call-webpack-plugin": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/last-call-webpack-plugin/-/last-call-webpack-plugin-3.0.0.tgz", - "integrity": "sha512-7KI2l2GIZa9p2spzPIVZBYyNKkN+e/SQPpnjlTiPhdbDW3F86tdKKELxKpzJ5sgU19wQWsACULZmpTPYHeWO5w==", - "dev": true, - "dependencies": { - "lodash": "^4.17.5", - "webpack-sources": "^1.1.0" - } - }, - "node_modules/latest-version": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/latest-version/-/latest-version-5.1.0.tgz", - "integrity": "sha512-weT+r0kTkRQdCdYCNtkMwWXQTMEswKrFBkm4ckQOMVhhqhIMI1UT2hMj+1iigIhgSZm5gTmrRXBNoGUgaTY1xA==", - "dev": true, - "dependencies": { - "package-json": "^6.3.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/leven": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", - "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/levenary": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/levenary/-/levenary-1.1.1.tgz", - "integrity": "sha512-mkAdOIt79FD6irqjYSs4rdbnlT5vRonMEvBVPVb3XmevfS8kgRXwfes0dhPdEtzTWD/1eNE/Bm/G1iRt6DcnQQ==", - "dev": true, - "dependencies": { - "leven": "^3.1.0" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/linkify-it": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-2.2.0.tgz", - "integrity": "sha512-GnAl/knGn+i1U/wjBz3akz2stz+HrHLsxMwHQGofCDfPvlf+gDKN58UtfmUquTY4/MXeE2x7k19KQmeoZi94Iw==", - "dev": true, - "dependencies": { - "uc.micro": "^1.0.1" - } - }, - "node_modules/load-script": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/load-script/-/load-script-1.0.0.tgz", - "integrity": "sha1-BJGTngvuVkPuSUp+PaPSuscMbKQ=", - "dev": true - }, - "node_modules/loader-runner": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-2.4.0.tgz", - "integrity": "sha512-Jsmr89RcXGIwivFY21FcRrisYZfvLMTWx5kOLc+JTxtpBOG6xML0vzbc6SEQG2FO9/4Fc3wW4LVcB5DmGflaRw==", - "dev": true, - "engines": { - "node": ">=4.3.0 <5.0.0 || >=5.10" - } - }, - "node_modules/loader-utils": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.0.tgz", - "integrity": "sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA==", - "dev": true, - "dependencies": { - "big.js": "^5.2.2", - "emojis-list": "^3.0.0", - "json5": "^1.0.1" - }, - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/loader-utils/node_modules/json5": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", - "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", - "dev": true, - "dependencies": { - "minimist": "^1.2.0" - }, - "bin": { - "json5": "lib/cli.js" - } - }, - "node_modules/locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", - "dev": true, - "dependencies": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", - "dev": true - }, - "node_modules/lodash._reinterpolate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz", - "integrity": "sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0=", - "dev": true - }, - "node_modules/lodash.clonedeep": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", - "integrity": "sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=", - "dev": true - }, - "node_modules/lodash.debounce": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", - "integrity": "sha1-gteb/zCmfEAF/9XiUVMArZyk168=", - "dev": true - }, - "node_modules/lodash.kebabcase": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/lodash.kebabcase/-/lodash.kebabcase-4.1.1.tgz", - "integrity": "sha1-hImxyw0p/4gZXM7KRI/21swpXDY=", - "dev": true - }, - "node_modules/lodash.memoize": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", - "integrity": "sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4=", - "dev": true - }, - "node_modules/lodash.template": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.template/-/lodash.template-4.5.0.tgz", - "integrity": "sha512-84vYFxIkmidUiFxidA/KjjH9pAycqW+h980j7Fuz5qxRtO9pgB7MDFTdys1N7A5mcucRiDyEq4fusljItR1T/A==", - "dev": true, - "dependencies": { - "lodash._reinterpolate": "^3.0.0", - "lodash.templatesettings": "^4.0.0" - } - }, - "node_modules/lodash.templatesettings": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/lodash.templatesettings/-/lodash.templatesettings-4.2.0.tgz", - "integrity": "sha512-stgLz+i3Aa9mZgnjr/O+v9ruKZsPsndy7qPZOchbqk2cnTU1ZaldKK+v7m54WoKIyxiuMZTKT2H81F8BeAc3ZQ==", - "dev": true, - "dependencies": { - "lodash._reinterpolate": "^3.0.0" - } - }, - "node_modules/lodash.uniq": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz", - "integrity": "sha1-0CJTc662Uq3BvILklFM5qEJ1R3M=", - "dev": true - }, - "node_modules/loglevel": { - "version": "1.6.8", - "resolved": "https://registry.npmjs.org/loglevel/-/loglevel-1.6.8.tgz", - "integrity": "sha512-bsU7+gc9AJ2SqpzxwU3+1fedl8zAntbtC5XYlt3s2j1hJcn2PsXSmgN8TaLG/J1/2mod4+cE/3vNL70/c1RNCA==", - "dev": true, - "engines": { - "node": ">= 0.6.0" - }, - "funding": { - "type": "tidelift", - "url": "https://tidelift.com/subscription/pkg/npm-loglevel?utm_medium=referral&utm_source=npm_fund" - } - }, - "node_modules/loose-envify": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", - "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", - "dev": true, - "dependencies": { - "js-tokens": "^3.0.0 || ^4.0.0" - }, - "bin": { - "loose-envify": "cli.js" - } - }, - "node_modules/lower-case": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-1.1.4.tgz", - "integrity": "sha1-miyr0bno4K6ZOkv31YdcOcQujqw=", - "dev": true - }, - "node_modules/lowercase-keys": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz", - "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/lru-cache": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", - "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", - "dev": true, - "dependencies": { - "yallist": "^3.0.2" - } - }, - "node_modules/make-dir": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", - "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", - "dev": true, - "dependencies": { - "pify": "^4.0.1", - "semver": "^5.6.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/map-cache": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", - "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/map-visit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", - "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=", - "dev": true, - "dependencies": { - "object-visit": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/markdown-it": { - "version": "8.4.2", - "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-8.4.2.tgz", - "integrity": "sha512-GcRz3AWTqSUphY3vsUqQSFMbgR38a4Lh3GWlHRh/7MRwz8mcu9n2IO7HOh+bXHrR9kOPDl5RNCaEsrneb+xhHQ==", - "dev": true, - "dependencies": { - "argparse": "^1.0.7", - "entities": "~1.1.1", - "linkify-it": "^2.0.0", - "mdurl": "^1.0.1", - "uc.micro": "^1.0.5" - }, - "bin": { - "markdown-it": "bin/markdown-it.js" - } - }, - "node_modules/markdown-it-anchor": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/markdown-it-anchor/-/markdown-it-anchor-5.3.0.tgz", - "integrity": "sha512-/V1MnLL/rgJ3jkMWo84UR+K+jF1cxNG1a+KwqeXqTIJ+jtA8aWSHuigx8lTzauiIjBDbwF3NcWQMotd0Dm39jA==", - "dev": true, - "peerDependencies": { - "markdown-it": "*" - } - }, - "node_modules/markdown-it-chain": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/markdown-it-chain/-/markdown-it-chain-1.3.0.tgz", - "integrity": "sha512-XClV8I1TKy8L2qsT9iX3qiV+50ZtcInGXI80CA+DP62sMs7hXlyV/RM3hfwy5O3Ad0sJm9xIwQELgANfESo8mQ==", - "dev": true, - "dependencies": { - "webpack-chain": "^4.9.0" - }, - "engines": { - "node": ">=6.9" - }, - "peerDependencies": { - "markdown-it": ">=5.0.0" - } - }, - "node_modules/markdown-it-chain/node_modules/javascript-stringify": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/javascript-stringify/-/javascript-stringify-1.6.0.tgz", - "integrity": "sha1-FC0RHzpuPa6PSpr9d9RYVbWpzOM=", - "dev": true - }, - "node_modules/markdown-it-chain/node_modules/webpack-chain": { - "version": "4.12.1", - "resolved": "https://registry.npmjs.org/webpack-chain/-/webpack-chain-4.12.1.tgz", - "integrity": "sha512-BCfKo2YkDe2ByqkEWe1Rw+zko4LsyS75LVr29C6xIrxAg9JHJ4pl8kaIZ396SUSNp6b4815dRZPSTAS8LlURRQ==", - "dev": true, - "dependencies": { - "deepmerge": "^1.5.2", - "javascript-stringify": "^1.6.0" - } - }, - "node_modules/markdown-it-container": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/markdown-it-container/-/markdown-it-container-2.0.0.tgz", - "integrity": "sha1-ABm0P9Au7+zi8ZYKKJX7qBpARpU=", - "dev": true - }, - "node_modules/markdown-it-emoji": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/markdown-it-emoji/-/markdown-it-emoji-1.4.0.tgz", - "integrity": "sha1-m+4OmpkKljupbfaYDE/dsF37Tcw=", - "dev": true - }, - "node_modules/markdown-it-table-of-contents": { - "version": "0.4.4", - "resolved": "https://registry.npmjs.org/markdown-it-table-of-contents/-/markdown-it-table-of-contents-0.4.4.tgz", - "integrity": "sha512-TAIHTHPwa9+ltKvKPWulm/beozQU41Ab+FIefRaQV1NRnpzwcV9QOe6wXQS5WLivm5Q/nlo0rl6laGkMDZE7Gw==", - "dev": true, - "engines": { - "node": ">6.4.0" - } - }, - "node_modules/md5.js": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", - "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", - "dev": true, - "dependencies": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "node_modules/mdn-data": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.4.tgz", - "integrity": "sha512-iV3XNKw06j5Q7mi6h+9vbx23Tv7JkjEVgKHW4pimwyDGWm0OIQntJJ+u1C6mg6mK1EaTv42XQ7w76yuzH7M2cA==", - "dev": true - }, - "node_modules/mdurl": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz", - "integrity": "sha1-/oWy7HWlkDfyrf7BAP1sYBdhFS4=", - "dev": true - }, - "node_modules/media-typer": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", - "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=", - "dev": true, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/memory-fs": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.4.1.tgz", - "integrity": "sha1-OpoguEYlI+RHz7x+i7gO1me/xVI=", - "dev": true, - "dependencies": { - "errno": "^0.1.3", - "readable-stream": "^2.0.1" - } - }, - "node_modules/merge-descriptors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", - "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=", - "dev": true - }, - "node_modules/merge-source-map": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/merge-source-map/-/merge-source-map-1.1.0.tgz", - "integrity": "sha512-Qkcp7P2ygktpMPh2mCQZaf3jhN6D3Z/qVZHSdWvQ+2Ef5HgRAPBO57A77+ENm0CPx2+1Ce/MYKi3ymqdfuqibw==", - "dev": true, - "dependencies": { - "source-map": "^0.6.1" - } - }, - "node_modules/merge-source-map/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/merge2": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", - "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", - "dev": true, - "engines": { - "node": ">= 8" - } - }, - "node_modules/methods": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", - "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=", - "dev": true, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": true, - "dependencies": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/micromatch/node_modules/extend-shallow": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", - "dev": true, - "dependencies": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/micromatch/node_modules/is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, - "dependencies": { - "is-plain-object": "^2.0.4" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/miller-rabin": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz", - "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==", - "dev": true, - "dependencies": { - "bn.js": "^4.0.0", - "brorand": "^1.0.1" - }, - "bin": { - "miller-rabin": "bin/miller-rabin" - } - }, - "node_modules/miller-rabin/node_modules/bn.js": { - "version": "4.11.9", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz", - "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==", - "dev": true - }, - "node_modules/mime": { - "version": "2.4.6", - "resolved": "https://registry.npmjs.org/mime/-/mime-2.4.6.tgz", - "integrity": "sha512-RZKhC3EmpBchfTGBVb8fb+RL2cWyw/32lshnsETttkBAyAUXSGHxbEJWWRXc751DrIxG1q04b8QwMbAwkRPpUA==", - "dev": true, - "bin": { - "mime": "cli.js" - }, - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/mime-db": { - "version": "1.44.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.44.0.tgz", - "integrity": "sha512-/NOTfLrsPBVeH7YtFPgsVWveuL+4SjjYxaQ1xtM1KMFj7HdxlBlxeyNLzhyJVx7r4rZGJAZ/6lkKCitSc/Nmpg==", - "dev": true, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mime-types": { - "version": "2.1.27", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.27.tgz", - "integrity": "sha512-JIhqnCasI9yD+SsmkquHBxTSEuZdQX5BuQnS2Vc7puQQQ+8yiP5AY5uWhpdv4YL4VM5c6iliiYWPgJ/nJQLp7w==", - "dev": true, - "dependencies": { - "mime-db": "1.44.0" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mimic-response": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", - "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/min-document": { - "version": "2.19.0", - "resolved": "https://registry.npmjs.org/min-document/-/min-document-2.19.0.tgz", - "integrity": "sha1-e9KC4/WELtKVu3SM3Z8f+iyCRoU=", - "dev": true, - "dependencies": { - "dom-walk": "^0.1.0" - } - }, - "node_modules/mini-css-extract-plugin": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-0.6.0.tgz", - "integrity": "sha512-79q5P7YGI6rdnVyIAV4NXpBQJFWdkzJxCim3Kog4078fM0piAaFlwocqbejdWtLW1cEzCexPrh6EdyFsPgVdAw==", - "dev": true, - "dependencies": { - "loader-utils": "^1.1.0", - "normalize-url": "^2.0.1", - "schema-utils": "^1.0.0", - "webpack-sources": "^1.1.0" - }, - "engines": { - "node": ">= 6.9.0" - }, - "peerDependencies": { - "webpack": "^4.4.0" - } - }, - "node_modules/mini-css-extract-plugin/node_modules/schema-utils": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", - "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", - "dev": true, - "dependencies": { - "ajv": "^6.1.0", - "ajv-errors": "^1.0.0", - "ajv-keywords": "^3.1.0" - }, - "engines": { - "node": ">= 4" - } - }, - "node_modules/minimalistic-assert": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", - "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", - "dev": true - }, - "node_modules/minimalistic-crypto-utils": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", - "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=", - "dev": true - }, - "node_modules/minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "dev": true, - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", - "dev": true - }, - "node_modules/mississippi": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/mississippi/-/mississippi-3.0.0.tgz", - "integrity": "sha512-x471SsVjUtBRtcvd4BzKE9kFC+/2TeWgKCgw0bZcw1b9l2X3QX5vCWgF+KaZaYm87Ss//rHnWryupDrgLvmSkA==", - "dev": true, - "dependencies": { - "concat-stream": "^1.5.0", - "duplexify": "^3.4.2", - "end-of-stream": "^1.1.0", - "flush-write-stream": "^1.0.0", - "from2": "^2.1.0", - "parallel-transform": "^1.1.0", - "pump": "^3.0.0", - "pumpify": "^1.3.3", - "stream-each": "^1.1.0", - "through2": "^2.0.0" - }, - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/mixin-deep": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz", - "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==", - "dev": true, - "dependencies": { - "for-in": "^1.0.2", - "is-extendable": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/mixin-deep/node_modules/is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, - "dependencies": { - "is-plain-object": "^2.0.4" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/mkdirp": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", - "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", - "dev": true, - "dependencies": { - "minimist": "^1.2.5" - }, - "bin": { - "mkdirp": "bin/cmd.js" - } - }, - "node_modules/move-concurrently": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/move-concurrently/-/move-concurrently-1.0.1.tgz", - "integrity": "sha1-viwAX9oy4LKa8fBdfEszIUxwH5I=", - "dev": true, - "dependencies": { - "aproba": "^1.1.1", - "copy-concurrently": "^1.0.0", - "fs-write-stream-atomic": "^1.0.8", - "mkdirp": "^0.5.1", - "rimraf": "^2.5.4", - "run-queue": "^1.0.3" - } - }, - "node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, - "node_modules/multicast-dns": { - "version": "6.2.3", - "resolved": "https://registry.npmjs.org/multicast-dns/-/multicast-dns-6.2.3.tgz", - "integrity": "sha512-ji6J5enbMyGRHIAkAOu3WdV8nggqviKCEKtXcOqfphZZtQrmHKycfynJ2V7eVPUA4NhJ6V7Wf4TmGbTwKE9B6g==", - "dev": true, - "dependencies": { - "dns-packet": "^1.3.1", - "thunky": "^1.0.2" - }, - "bin": { - "multicast-dns": "cli.js" - } - }, - "node_modules/multicast-dns-service-types": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/multicast-dns-service-types/-/multicast-dns-service-types-1.1.0.tgz", - "integrity": "sha1-iZ8R2WhuXgXLkbNdXw5jt3PPyQE=", - "dev": true - }, - "node_modules/nan": { - "version": "2.14.1", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.1.tgz", - "integrity": "sha512-isWHgVjnFjh2x2yuJ/tj3JbwoHu3UC2dX5G/88Cm24yB6YopVgxvBObDY7n5xW6ExmFhJpSEQqFPvq9zaXc8Jw==", - "dev": true, - "optional": true - }, - "node_modules/nanomatch": { - "version": "1.2.13", - "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", - "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", - "dev": true, - "dependencies": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "fragment-cache": "^0.2.1", - "is-windows": "^1.0.2", - "kind-of": "^6.0.2", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/nanomatch/node_modules/extend-shallow": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", - "dev": true, - "dependencies": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/nanomatch/node_modules/is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, - "dependencies": { - "is-plain-object": "^2.0.4" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/negotiator": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz", - "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==", - "dev": true, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/neo-async": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.1.tgz", - "integrity": "sha512-iyam8fBuCUpWeKPGpaNMetEocMt364qkCsfL9JuhjXX6dRnguRVOfk2GZaDpPjcOKiiXCPINZC1GczQ7iTq3Zw==", - "dev": true - }, - "node_modules/nice-try": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", - "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", - "dev": true - }, - "node_modules/no-case": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/no-case/-/no-case-2.3.2.tgz", - "integrity": "sha512-rmTZ9kz+f3rCvK2TD1Ue/oZlns7OGoIWP4fc3llxxRXlOkHKoWPPWJOfFYpITabSow43QJbRIoHQXtt10VldyQ==", - "dev": true, - "dependencies": { - "lower-case": "^1.1.1" - } - }, - "node_modules/node-forge": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.9.0.tgz", - "integrity": "sha512-7ASaDa3pD+lJ3WvXFsxekJQelBKRpne+GOVbLbtHYdd7pFspyeuJHnWfLplGf3SwKGbfs/aYl5V/JCIaHVUKKQ==", - "dev": true, - "engines": { - "node": ">= 4.5.0" - } - }, - "node_modules/node-libs-browser": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/node-libs-browser/-/node-libs-browser-2.2.1.tgz", - "integrity": "sha512-h/zcD8H9kaDZ9ALUWwlBUDo6TKF8a7qBSCSEGfjTVIYeqsioSKaAX+BN7NgiMGp6iSIXZ3PxgCu8KS3b71YK5Q==", - "dev": true, - "dependencies": { - "assert": "^1.1.1", - "browserify-zlib": "^0.2.0", - "buffer": "^4.3.0", - "console-browserify": "^1.1.0", - "constants-browserify": "^1.0.0", - "crypto-browserify": "^3.11.0", - "domain-browser": "^1.1.1", - "events": "^3.0.0", - "https-browserify": "^1.0.0", - "os-browserify": "^0.3.0", - "path-browserify": "0.0.1", - "process": "^0.11.10", - "punycode": "^1.2.4", - "querystring-es3": "^0.2.0", - "readable-stream": "^2.3.3", - "stream-browserify": "^2.0.1", - "stream-http": "^2.7.2", - "string_decoder": "^1.0.0", - "timers-browserify": "^2.0.4", - "tty-browserify": "0.0.0", - "url": "^0.11.0", - "util": "^0.11.0", - "vm-browserify": "^1.0.1" - } - }, - "node_modules/node-libs-browser/node_modules/events": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/events/-/events-3.1.0.tgz", - "integrity": "sha512-Rv+u8MLHNOdMjTAFeT3nCjHn2aGlx435FP/sDHNaRhDEMwyI/aB22Kj2qIN8R0cw3z28psEQLYwxVKLsKrMgWg==", - "dev": true, - "engines": { - "node": ">=0.8.x" - } - }, - "node_modules/node-libs-browser/node_modules/punycode": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", - "dev": true - }, - "node_modules/node-releases": { - "version": "1.1.72", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.72.tgz", - "integrity": "sha512-LLUo+PpH3dU6XizX3iVoubUNheF/owjXCZZ5yACDxNnPtgFuludV1ZL3ayK1kVep42Rmm0+R9/Y60NQbZ2bifw==", - "dev": true - }, - "node_modules/nopt": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/nopt/-/nopt-1.0.10.tgz", - "integrity": "sha1-bd0hvSoxQXuScn3Vhfim83YI6+4=", - "dev": true, - "dependencies": { - "abbrev": "1" - }, - "bin": { - "nopt": "bin/nopt.js" - }, - "engines": { - "node": "*" - } - }, - "node_modules/normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/normalize-range": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz", - "integrity": "sha1-LRDAa9/TEuqXd2laTShDlFa3WUI=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/normalize-url": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-2.0.1.tgz", - "integrity": "sha512-D6MUW4K/VzoJ4rJ01JFKxDrtY1v9wrgzCX5f2qj/lzH1m/lW6MhUZFKerVsnyjOhOsYzI9Kqqak+10l4LvLpMw==", - "dev": true, - "dependencies": { - "prepend-http": "^2.0.0", - "query-string": "^5.0.1", - "sort-keys": "^2.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/npm-run-path": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", - "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", - "dev": true, - "dependencies": { - "path-key": "^2.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/nprogress": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/nprogress/-/nprogress-0.2.0.tgz", - "integrity": "sha1-y480xTIT2JVyP8urkH6UIq28r7E=", - "dev": true - }, - "node_modules/nth-check": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-1.0.2.tgz", - "integrity": "sha512-WeBOdju8SnzPN5vTUJYxYUxLeXpCaVP5i5e0LF8fg7WORF2Wd7wFX/pk0tYZk7s8T+J7VLy0Da6J1+wCT0AtHg==", - "dev": true, - "dependencies": { - "boolbase": "~1.0.0" - } - }, - "node_modules/num2fraction": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/num2fraction/-/num2fraction-1.2.2.tgz", - "integrity": "sha1-b2gragJ6Tp3fpFZM0lidHU5mnt4=", - "dev": true - }, - "node_modules/oauth-sign": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", - "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", - "dev": true, - "engines": { - "node": "*" - } - }, - "node_modules/object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object-copy": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", - "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=", - "dev": true, - "dependencies": { - "copy-descriptor": "^0.1.0", - "define-property": "^0.2.5", - "kind-of": "^3.0.3" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object-copy/node_modules/define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "dependencies": { - "is-descriptor": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object-copy/node_modules/is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object-copy/node_modules/is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object-copy/node_modules/is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "dependencies": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object-copy/node_modules/is-descriptor/node_modules/kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object-copy/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object-inspect": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.7.0.tgz", - "integrity": "sha512-a7pEHdh1xKIAgTySUGgLMx/xwDZskN1Ud6egYYN3EdRW4ZMPNEDUTF+hwy2LUC+Bl+SyLXANnwz/jyh/qutKUw==", - "dev": true, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/object-is": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/object-is/-/object-is-1.1.2.tgz", - "integrity": "sha512-5lHCz+0uufF6wZ7CRFWJN3hp8Jqblpgve06U5CMQ3f//6iDjPr2PEo9MWCjEssDsa+UZEL4PkFpr+BMop6aKzQ==", - "dev": true, - "dependencies": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.5" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/object-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", - "dev": true, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/object-visit": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", - "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=", - "dev": true, - "dependencies": { - "isobject": "^3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object.assign": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz", - "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==", - "dev": true, - "dependencies": { - "define-properties": "^1.1.2", - "function-bind": "^1.1.1", - "has-symbols": "^1.0.0", - "object-keys": "^1.0.11" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/object.getownpropertydescriptors": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.0.tgz", - "integrity": "sha512-Z53Oah9A3TdLoblT7VKJaTDdXdT+lQO+cNpKVnya5JDe9uLvzu1YyY1yFDFrcxrlRgWrEFH0jJtD/IbuwjcEVg==", - "dev": true, - "dependencies": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.0-next.1" - }, - "engines": { - "node": ">= 0.8" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/object.pick": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", - "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", - "dev": true, - "dependencies": { - "isobject": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object.values": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.1.tgz", - "integrity": "sha512-WTa54g2K8iu0kmS/us18jEmdv1a4Wi//BZ/DTVYEcH0XhLM5NYdpDHja3gt57VrZLcNAO2WGA+KpWsDBaHt6eA==", - "dev": true, - "dependencies": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.0-next.1", - "function-bind": "^1.1.1", - "has": "^1.0.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/obuf": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/obuf/-/obuf-1.1.2.tgz", - "integrity": "sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==", - "dev": true - }, - "node_modules/on-finished": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", - "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", - "dev": true, - "dependencies": { - "ee-first": "1.1.1" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/on-headers": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz", - "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==", - "dev": true, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "dev": true, - "dependencies": { - "wrappy": "1" - } - }, - "node_modules/opencollective-postinstall": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/opencollective-postinstall/-/opencollective-postinstall-2.0.3.tgz", - "integrity": "sha512-8AV/sCtuzUeTo8gQK5qDZzARrulB3egtLzFgteqB2tcT4Mw7B8Kt7JcDHmltjz6FOAHsvTevk70gZEbhM4ZS9Q==", - "dev": true, - "bin": { - "opencollective-postinstall": "index.js" - } - }, - "node_modules/opn": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/opn/-/opn-5.5.0.tgz", - "integrity": "sha512-PqHpggC9bLV0VeWcdKhkpxY+3JTzetLSqTCWL/z/tFIbI6G8JCjondXklT1JinczLz2Xib62sSp0T/gKT4KksA==", - "dev": true, - "dependencies": { - "is-wsl": "^1.1.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/optimize-css-assets-webpack-plugin": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/optimize-css-assets-webpack-plugin/-/optimize-css-assets-webpack-plugin-5.0.3.tgz", - "integrity": "sha512-q9fbvCRS6EYtUKKSwI87qm2IxlyJK5b4dygW1rKUBT6mMDhdG5e5bZT63v6tnJR9F9FB/H5a0HTmtw+laUBxKA==", - "dev": true, - "dependencies": { - "cssnano": "^4.1.10", - "last-call-webpack-plugin": "^3.0.0" - }, - "peerDependencies": { - "webpack": "^4.0.0" - } - }, - "node_modules/original": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/original/-/original-1.0.2.tgz", - "integrity": "sha512-hyBVl6iqqUOJ8FqRe+l/gS8H+kKYjrEndd5Pm1MfBtsEKA038HkkdbAl/72EAXGyonD/PFsvmVG+EvcIpliMBg==", - "dev": true, - "dependencies": { - "url-parse": "^1.4.3" - } - }, - "node_modules/os-browserify": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz", - "integrity": "sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc=", - "dev": true - }, - "node_modules/p-cancelable": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-1.1.0.tgz", - "integrity": "sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/p-finally": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", - "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "dependencies": { - "p-try": "^2.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", - "dev": true, - "dependencies": { - "p-limit": "^2.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/p-map": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-2.1.0.tgz", - "integrity": "sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/p-retry": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/p-retry/-/p-retry-3.0.1.tgz", - "integrity": "sha512-XE6G4+YTTkT2a0UWb2kjZe8xNwf8bIbnqpc/IS/idOBVhyves0mK5OJgeocjx7q5pvX/6m23xuzVPYT1uGM73w==", - "dev": true, - "dependencies": { - "retry": "^0.12.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/package-json": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/package-json/-/package-json-6.5.0.tgz", - "integrity": "sha512-k3bdm2n25tkyxcjSKzB5x8kfVxlMdgsbPr0GkZcwHsLpba6cBjqCt1KlcChKEvxHIcTB1FVMuwoijZ26xex5MQ==", - "dev": true, - "dependencies": { - "got": "^9.6.0", - "registry-auth-token": "^4.0.0", - "registry-url": "^5.0.0", - "semver": "^6.2.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/package-json/node_modules/semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true, - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/pako": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", - "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==", - "dev": true - }, - "node_modules/parallel-transform": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/parallel-transform/-/parallel-transform-1.2.0.tgz", - "integrity": "sha512-P2vSmIu38uIlvdcU7fDkyrxj33gTUy/ABO5ZUbGowxNCopBq/OoD42bP4UmMrJoPyk4Uqf0mu3mtWBhHCZD8yg==", - "dev": true, - "dependencies": { - "cyclist": "^1.0.1", - "inherits": "^2.0.3", - "readable-stream": "^2.1.5" - } - }, - "node_modules/param-case": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/param-case/-/param-case-2.1.1.tgz", - "integrity": "sha1-35T9jPZTHs915r75oIWPvHK+Ikc=", - "dev": true, - "dependencies": { - "no-case": "^2.2.0" - } - }, - "node_modules/parse-asn1": { - "version": "5.1.5", - "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.5.tgz", - "integrity": "sha512-jkMYn1dcJqF6d5CpU689bq7w/b5ALS9ROVSpQDPrZsqqesUJii9qutvoT5ltGedNXMO2e16YUWIghG9KxaViTQ==", - "dev": true, - "dependencies": { - "asn1.js": "^4.0.0", - "browserify-aes": "^1.0.0", - "create-hash": "^1.1.0", - "evp_bytestokey": "^1.0.0", - "pbkdf2": "^3.0.3", - "safe-buffer": "^5.1.1" - } - }, - "node_modules/parse-json": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", - "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", - "dev": true, - "dependencies": { - "error-ex": "^1.3.1", - "json-parse-better-errors": "^1.0.1" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/parseurl": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", - "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", - "dev": true, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/pascalcase": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", - "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/path-browserify": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.1.tgz", - "integrity": "sha512-BapA40NHICOS+USX9SN4tyhq+A2RrN/Ws5F0Z5aMHDp98Fl86lX8Oti8B7uN93L4Ifv4fHOEA+pQw87gmMO/lQ==", - "dev": true - }, - "node_modules/path-dirname": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz", - "integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=", - "dev": true - }, - "node_modules/path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/path-is-inside": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", - "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=", - "dev": true - }, - "node_modules/path-key": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", - "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/path-parse": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", - "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", - "dev": true - }, - "node_modules/path-to-regexp": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", - "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=", - "dev": true - }, - "node_modules/path-type": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", - "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", - "dev": true, - "dependencies": { - "pify": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/path-type/node_modules/pify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/pbkdf2": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.1.tgz", - "integrity": "sha512-4Ejy1OPxi9f2tt1rRV7Go7zmfDQ+ZectEQz3VGUQhgq62HtIRPDyG/JtnwIxs6x3uNMwo2V7q1fMvKjb+Tnpqg==", - "dev": true, - "dependencies": { - "create-hash": "^1.1.2", - "create-hmac": "^1.1.4", - "ripemd160": "^2.0.1", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - }, - "engines": { - "node": ">=0.12" - } - }, - "node_modules/performance-now": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", - "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=", - "dev": true - }, - "node_modules/picomatch": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz", - "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==", - "dev": true, - "optional": true, - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/pify": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", - "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/pinkie": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", - "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/pinkie-promise": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", - "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", - "dev": true, - "dependencies": { - "pinkie": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/pkg-dir": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz", - "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==", - "dev": true, - "dependencies": { - "find-up": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/portfinder": { - "version": "1.0.26", - "resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.26.tgz", - "integrity": "sha512-Xi7mKxJHHMI3rIUrnm/jjUgwhbYMkp/XKEcZX3aG4BrumLpq3nmoQMX+ClYnDZnZ/New7IatC1no5RX0zo1vXQ==", - "dev": true, - "dependencies": { - "async": "^2.6.2", - "debug": "^3.1.1", - "mkdirp": "^0.5.1" - }, - "engines": { - "node": ">= 0.12.0" - } - }, - "node_modules/portfinder/node_modules/debug": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", - "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", - "deprecated": "Debug versions >=3.2.0 <3.2.7 || >=4 <4.3.1 have a low-severity ReDos regression when used in a Node.js environment. It is recommended you upgrade to 3.2.7 or 4.3.1. (https://github.com/visionmedia/debug/issues/797)", - "dev": true, - "dependencies": { - "ms": "^2.1.1" - } - }, - "node_modules/posix-character-classes": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", - "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/postcss": { - "version": "7.0.32", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.32.tgz", - "integrity": "sha512-03eXong5NLnNCD05xscnGKGDZ98CyzoqPSMjOe6SuoQY7Z2hIj0Ld1g/O/UQRuOle2aRtiIRDg9tDcTGAkLfKw==", - "dev": true, - "dependencies": { - "chalk": "^2.4.2", - "source-map": "^0.6.1", - "supports-color": "^6.1.0" - }, - "engines": { - "node": ">=6.0.0" - }, - "funding": { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/postcss" - } - }, - "node_modules/postcss-calc": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/postcss-calc/-/postcss-calc-7.0.2.tgz", - "integrity": "sha512-rofZFHUg6ZIrvRwPeFktv06GdbDYLcGqh9EwiMutZg+a0oePCCw1zHOEiji6LCpyRcjTREtPASuUqeAvYlEVvQ==", - "dev": true, - "dependencies": { - "postcss": "^7.0.27", - "postcss-selector-parser": "^6.0.2", - "postcss-value-parser": "^4.0.2" - } - }, - "node_modules/postcss-colormin": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/postcss-colormin/-/postcss-colormin-4.0.3.tgz", - "integrity": "sha512-WyQFAdDZpExQh32j0U0feWisZ0dmOtPl44qYmJKkq9xFWY3p+4qnRzCHeNrkeRhwPHz9bQ3mo0/yVkaply0MNw==", - "dev": true, - "dependencies": { - "browserslist": "^4.0.0", - "color": "^3.0.0", - "has": "^1.0.0", - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/postcss-colormin/node_modules/postcss-value-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", - "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", - "dev": true - }, - "node_modules/postcss-convert-values": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/postcss-convert-values/-/postcss-convert-values-4.0.1.tgz", - "integrity": "sha512-Kisdo1y77KUC0Jmn0OXU/COOJbzM8cImvw1ZFsBgBgMgb1iL23Zs/LXRe3r+EZqM3vGYKdQ2YJVQ5VkJI+zEJQ==", - "dev": true, - "dependencies": { - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/postcss-convert-values/node_modules/postcss-value-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", - "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", - "dev": true - }, - "node_modules/postcss-discard-comments": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/postcss-discard-comments/-/postcss-discard-comments-4.0.2.tgz", - "integrity": "sha512-RJutN259iuRf3IW7GZyLM5Sw4GLTOH8FmsXBnv8Ab/Tc2k4SR4qbV4DNbyyY4+Sjo362SyDmW2DQ7lBSChrpkg==", - "dev": true, - "dependencies": { - "postcss": "^7.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/postcss-discard-duplicates": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/postcss-discard-duplicates/-/postcss-discard-duplicates-4.0.2.tgz", - "integrity": "sha512-ZNQfR1gPNAiXZhgENFfEglF93pciw0WxMkJeVmw8eF+JZBbMD7jp6C67GqJAXVZP2BWbOztKfbsdmMp/k8c6oQ==", - "dev": true, - "dependencies": { - "postcss": "^7.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/postcss-discard-empty": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/postcss-discard-empty/-/postcss-discard-empty-4.0.1.tgz", - "integrity": "sha512-B9miTzbznhDjTfjvipfHoqbWKwd0Mj+/fL5s1QOz06wufguil+Xheo4XpOnc4NqKYBCNqqEzgPv2aPBIJLox0w==", - "dev": true, - "dependencies": { - "postcss": "^7.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/postcss-discard-overridden": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/postcss-discard-overridden/-/postcss-discard-overridden-4.0.1.tgz", - "integrity": "sha512-IYY2bEDD7g1XM1IDEsUT4//iEYCxAmP5oDSFMVU/JVvT7gh+l4fmjciLqGgwjdWpQIdb0Che2VX00QObS5+cTg==", - "dev": true, - "dependencies": { - "postcss": "^7.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/postcss-load-config": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-2.1.0.tgz", - "integrity": "sha512-4pV3JJVPLd5+RueiVVB+gFOAa7GWc25XQcMp86Zexzke69mKf6Nx9LRcQywdz7yZI9n1udOxmLuAwTBypypF8Q==", - "dev": true, - "dependencies": { - "cosmiconfig": "^5.0.0", - "import-cwd": "^2.0.0" - }, - "engines": { - "node": ">= 4" - } - }, - "node_modules/postcss-loader": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/postcss-loader/-/postcss-loader-3.0.0.tgz", - "integrity": "sha512-cLWoDEY5OwHcAjDnkyRQzAXfs2jrKjXpO/HQFcc5b5u/r7aa471wdmChmwfnv7x2u840iat/wi0lQ5nbRgSkUA==", - "dev": true, - "dependencies": { - "loader-utils": "^1.1.0", - "postcss": "^7.0.0", - "postcss-load-config": "^2.0.0", - "schema-utils": "^1.0.0" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/postcss-loader/node_modules/schema-utils": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", - "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", - "dev": true, - "dependencies": { - "ajv": "^6.1.0", - "ajv-errors": "^1.0.0", - "ajv-keywords": "^3.1.0" - }, - "engines": { - "node": ">= 4" - } - }, - "node_modules/postcss-merge-longhand": { - "version": "4.0.11", - "resolved": "https://registry.npmjs.org/postcss-merge-longhand/-/postcss-merge-longhand-4.0.11.tgz", - "integrity": "sha512-alx/zmoeXvJjp7L4mxEMjh8lxVlDFX1gqWHzaaQewwMZiVhLo42TEClKaeHbRf6J7j82ZOdTJ808RtN0ZOZwvw==", - "dev": true, - "dependencies": { - "css-color-names": "0.0.4", - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0", - "stylehacks": "^4.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/postcss-merge-longhand/node_modules/postcss-value-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", - "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", - "dev": true - }, - "node_modules/postcss-merge-rules": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/postcss-merge-rules/-/postcss-merge-rules-4.0.3.tgz", - "integrity": "sha512-U7e3r1SbvYzO0Jr3UT/zKBVgYYyhAz0aitvGIYOYK5CPmkNih+WDSsS5tvPrJ8YMQYlEMvsZIiqmn7HdFUaeEQ==", - "dev": true, - "dependencies": { - "browserslist": "^4.0.0", - "caniuse-api": "^3.0.0", - "cssnano-util-same-parent": "^4.0.0", - "postcss": "^7.0.0", - "postcss-selector-parser": "^3.0.0", - "vendors": "^1.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/postcss-merge-rules/node_modules/postcss-selector-parser": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-3.1.2.tgz", - "integrity": "sha512-h7fJ/5uWuRVyOtkO45pnt1Ih40CEleeyCHzipqAZO2e5H20g25Y48uYnFUiShvY4rZWNJ/Bib/KVPmanaCtOhA==", - "dev": true, - "dependencies": { - "dot-prop": "^5.2.0", - "indexes-of": "^1.0.1", - "uniq": "^1.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/postcss-minify-font-values": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/postcss-minify-font-values/-/postcss-minify-font-values-4.0.2.tgz", - "integrity": "sha512-j85oO6OnRU9zPf04+PZv1LYIYOprWm6IA6zkXkrJXyRveDEuQggG6tvoy8ir8ZwjLxLuGfNkCZEQG7zan+Hbtg==", - "dev": true, - "dependencies": { - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/postcss-minify-font-values/node_modules/postcss-value-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", - "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", - "dev": true - }, - "node_modules/postcss-minify-gradients": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/postcss-minify-gradients/-/postcss-minify-gradients-4.0.2.tgz", - "integrity": "sha512-qKPfwlONdcf/AndP1U8SJ/uzIJtowHlMaSioKzebAXSG4iJthlWC9iSWznQcX4f66gIWX44RSA841HTHj3wK+Q==", - "dev": true, - "dependencies": { - "cssnano-util-get-arguments": "^4.0.0", - "is-color-stop": "^1.0.0", - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/postcss-minify-gradients/node_modules/postcss-value-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", - "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", - "dev": true - }, - "node_modules/postcss-minify-params": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/postcss-minify-params/-/postcss-minify-params-4.0.2.tgz", - "integrity": "sha512-G7eWyzEx0xL4/wiBBJxJOz48zAKV2WG3iZOqVhPet/9geefm/Px5uo1fzlHu+DOjT+m0Mmiz3jkQzVHe6wxAWg==", - "dev": true, - "dependencies": { - "alphanum-sort": "^1.0.0", - "browserslist": "^4.0.0", - "cssnano-util-get-arguments": "^4.0.0", - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0", - "uniqs": "^2.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/postcss-minify-params/node_modules/postcss-value-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", - "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", - "dev": true - }, - "node_modules/postcss-minify-selectors": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/postcss-minify-selectors/-/postcss-minify-selectors-4.0.2.tgz", - "integrity": "sha512-D5S1iViljXBj9kflQo4YutWnJmwm8VvIsU1GeXJGiG9j8CIg9zs4voPMdQDUmIxetUOh60VilsNzCiAFTOqu3g==", - "dev": true, - "dependencies": { - "alphanum-sort": "^1.0.0", - "has": "^1.0.0", - "postcss": "^7.0.0", - "postcss-selector-parser": "^3.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/postcss-minify-selectors/node_modules/postcss-selector-parser": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-3.1.2.tgz", - "integrity": "sha512-h7fJ/5uWuRVyOtkO45pnt1Ih40CEleeyCHzipqAZO2e5H20g25Y48uYnFUiShvY4rZWNJ/Bib/KVPmanaCtOhA==", - "dev": true, - "dependencies": { - "dot-prop": "^5.2.0", - "indexes-of": "^1.0.1", - "uniq": "^1.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/postcss-modules-extract-imports": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-2.0.0.tgz", - "integrity": "sha512-LaYLDNS4SG8Q5WAWqIJgdHPJrDDr/Lv775rMBFUbgjTz6j34lUznACHcdRWroPvXANP2Vj7yNK57vp9eFqzLWQ==", - "dev": true, - "dependencies": { - "postcss": "^7.0.5" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/postcss-modules-local-by-default": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-2.0.6.tgz", - "integrity": "sha512-oLUV5YNkeIBa0yQl7EYnxMgy4N6noxmiwZStaEJUSe2xPMcdNc8WmBQuQCx18H5psYbVxz8zoHk0RAAYZXP9gA==", - "dev": true, - "dependencies": { - "postcss": "^7.0.6", - "postcss-selector-parser": "^6.0.0", - "postcss-value-parser": "^3.3.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/postcss-modules-local-by-default/node_modules/postcss-value-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", - "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", - "dev": true - }, - "node_modules/postcss-modules-scope": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-2.2.0.tgz", - "integrity": "sha512-YyEgsTMRpNd+HmyC7H/mh3y+MeFWevy7V1evVhJWewmMbjDHIbZbOXICC2y+m1xI1UVfIT1HMW/O04Hxyu9oXQ==", - "dev": true, - "dependencies": { - "postcss": "^7.0.6", - "postcss-selector-parser": "^6.0.0" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/postcss-modules-values": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/postcss-modules-values/-/postcss-modules-values-2.0.0.tgz", - "integrity": "sha512-Ki7JZa7ff1N3EIMlPnGTZfUMe69FFwiQPnVSXC9mnn3jozCRBYIxiZd44yJOV2AmabOo4qFf8s0dC/+lweG7+w==", - "dev": true, - "dependencies": { - "icss-replace-symbols": "^1.1.0", - "postcss": "^7.0.6" - } - }, - "node_modules/postcss-normalize-charset": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/postcss-normalize-charset/-/postcss-normalize-charset-4.0.1.tgz", - "integrity": "sha512-gMXCrrlWh6G27U0hF3vNvR3w8I1s2wOBILvA87iNXaPvSNo5uZAMYsZG7XjCUf1eVxuPfyL4TJ7++SGZLc9A3g==", - "dev": true, - "dependencies": { - "postcss": "^7.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/postcss-normalize-display-values": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/postcss-normalize-display-values/-/postcss-normalize-display-values-4.0.2.tgz", - "integrity": "sha512-3F2jcsaMW7+VtRMAqf/3m4cPFhPD3EFRgNs18u+k3lTJJlVe7d0YPO+bnwqo2xg8YiRpDXJI2u8A0wqJxMsQuQ==", - "dev": true, - "dependencies": { - "cssnano-util-get-match": "^4.0.0", - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/postcss-normalize-display-values/node_modules/postcss-value-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", - "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", - "dev": true - }, - "node_modules/postcss-normalize-positions": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/postcss-normalize-positions/-/postcss-normalize-positions-4.0.2.tgz", - "integrity": "sha512-Dlf3/9AxpxE+NF1fJxYDeggi5WwV35MXGFnnoccP/9qDtFrTArZ0D0R+iKcg5WsUd8nUYMIl8yXDCtcrT8JrdA==", - "dev": true, - "dependencies": { - "cssnano-util-get-arguments": "^4.0.0", - "has": "^1.0.0", - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/postcss-normalize-positions/node_modules/postcss-value-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", - "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", - "dev": true - }, - "node_modules/postcss-normalize-repeat-style": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/postcss-normalize-repeat-style/-/postcss-normalize-repeat-style-4.0.2.tgz", - "integrity": "sha512-qvigdYYMpSuoFs3Is/f5nHdRLJN/ITA7huIoCyqqENJe9PvPmLhNLMu7QTjPdtnVf6OcYYO5SHonx4+fbJE1+Q==", - "dev": true, - "dependencies": { - "cssnano-util-get-arguments": "^4.0.0", - "cssnano-util-get-match": "^4.0.0", - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/postcss-normalize-repeat-style/node_modules/postcss-value-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", - "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", - "dev": true - }, - "node_modules/postcss-normalize-string": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/postcss-normalize-string/-/postcss-normalize-string-4.0.2.tgz", - "integrity": "sha512-RrERod97Dnwqq49WNz8qo66ps0swYZDSb6rM57kN2J+aoyEAJfZ6bMx0sx/F9TIEX0xthPGCmeyiam/jXif0eA==", - "dev": true, - "dependencies": { - "has": "^1.0.0", - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/postcss-normalize-string/node_modules/postcss-value-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", - "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", - "dev": true - }, - "node_modules/postcss-normalize-timing-functions": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/postcss-normalize-timing-functions/-/postcss-normalize-timing-functions-4.0.2.tgz", - "integrity": "sha512-acwJY95edP762e++00Ehq9L4sZCEcOPyaHwoaFOhIwWCDfik6YvqsYNxckee65JHLKzuNSSmAdxwD2Cud1Z54A==", - "dev": true, - "dependencies": { - "cssnano-util-get-match": "^4.0.0", - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/postcss-normalize-timing-functions/node_modules/postcss-value-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", - "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", - "dev": true - }, - "node_modules/postcss-normalize-unicode": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/postcss-normalize-unicode/-/postcss-normalize-unicode-4.0.1.tgz", - "integrity": "sha512-od18Uq2wCYn+vZ/qCOeutvHjB5jm57ToxRaMeNuf0nWVHaP9Hua56QyMF6fs/4FSUnVIw0CBPsU0K4LnBPwYwg==", - "dev": true, - "dependencies": { - "browserslist": "^4.0.0", - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/postcss-normalize-unicode/node_modules/postcss-value-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", - "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", - "dev": true - }, - "node_modules/postcss-normalize-url": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/postcss-normalize-url/-/postcss-normalize-url-4.0.1.tgz", - "integrity": "sha512-p5oVaF4+IHwu7VpMan/SSpmpYxcJMtkGppYf0VbdH5B6hN8YNmVyJLuY9FmLQTzY3fag5ESUUHDqM+heid0UVA==", - "dev": true, - "dependencies": { - "is-absolute-url": "^2.0.0", - "normalize-url": "^3.0.0", - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/postcss-normalize-url/node_modules/normalize-url": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-3.3.0.tgz", - "integrity": "sha512-U+JJi7duF1o+u2pynbp2zXDW2/PADgC30f0GsHZtRh+HOcXHnw137TrNlyxxRvWW5fjKd3bcLHPxofWuCjaeZg==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/postcss-normalize-url/node_modules/postcss-value-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", - "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", - "dev": true - }, - "node_modules/postcss-normalize-whitespace": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/postcss-normalize-whitespace/-/postcss-normalize-whitespace-4.0.2.tgz", - "integrity": "sha512-tO8QIgrsI3p95r8fyqKV+ufKlSHh9hMJqACqbv2XknufqEDhDvbguXGBBqxw9nsQoXWf0qOqppziKJKHMD4GtA==", - "dev": true, - "dependencies": { - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/postcss-normalize-whitespace/node_modules/postcss-value-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", - "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", - "dev": true - }, - "node_modules/postcss-ordered-values": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/postcss-ordered-values/-/postcss-ordered-values-4.1.2.tgz", - "integrity": "sha512-2fCObh5UanxvSxeXrtLtlwVThBvHn6MQcu4ksNT2tsaV2Fg76R2CV98W7wNSlX+5/pFwEyaDwKLLoEV7uRybAw==", - "dev": true, - "dependencies": { - "cssnano-util-get-arguments": "^4.0.0", - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/postcss-ordered-values/node_modules/postcss-value-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", - "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", - "dev": true - }, - "node_modules/postcss-reduce-initial": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/postcss-reduce-initial/-/postcss-reduce-initial-4.0.3.tgz", - "integrity": "sha512-gKWmR5aUulSjbzOfD9AlJiHCGH6AEVLaM0AV+aSioxUDd16qXP1PCh8d1/BGVvpdWn8k/HiK7n6TjeoXN1F7DA==", - "dev": true, - "dependencies": { - "browserslist": "^4.0.0", - "caniuse-api": "^3.0.0", - "has": "^1.0.0", - "postcss": "^7.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/postcss-reduce-transforms": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/postcss-reduce-transforms/-/postcss-reduce-transforms-4.0.2.tgz", - "integrity": "sha512-EEVig1Q2QJ4ELpJXMZR8Vt5DQx8/mo+dGWSR7vWXqcob2gQLyQGsionYcGKATXvQzMPn6DSN1vTN7yFximdIAg==", - "dev": true, - "dependencies": { - "cssnano-util-get-match": "^4.0.0", - "has": "^1.0.0", - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/postcss-reduce-transforms/node_modules/postcss-value-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", - "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", - "dev": true - }, - "node_modules/postcss-safe-parser": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/postcss-safe-parser/-/postcss-safe-parser-4.0.2.tgz", - "integrity": "sha512-Uw6ekxSWNLCPesSv/cmqf2bY/77z11O7jZGPax3ycZMFU/oi2DMH9i89AdHc1tRwFg/arFoEwX0IS3LCUxJh1g==", - "dev": true, - "dependencies": { - "postcss": "^7.0.26" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/postcss-selector-parser": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.2.tgz", - "integrity": "sha512-36P2QR59jDTOAiIkqEprfJDsoNrvwFei3eCqKd1Y0tUsBimsq39BLp7RD+JWny3WgB1zGhJX8XVePwm9k4wdBg==", - "dev": true, - "dependencies": { - "cssesc": "^3.0.0", - "indexes-of": "^1.0.1", - "uniq": "^1.0.1" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/postcss-svgo": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/postcss-svgo/-/postcss-svgo-4.0.2.tgz", - "integrity": "sha512-C6wyjo3VwFm0QgBy+Fu7gCYOkCmgmClghO+pjcxvrcBKtiKt0uCF+hvbMO1fyv5BMImRK90SMb+dwUnfbGd+jw==", - "dev": true, - "dependencies": { - "is-svg": "^3.0.0", - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0", - "svgo": "^1.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/postcss-svgo/node_modules/postcss-value-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", - "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", - "dev": true - }, - "node_modules/postcss-unique-selectors": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/postcss-unique-selectors/-/postcss-unique-selectors-4.0.1.tgz", - "integrity": "sha512-+JanVaryLo9QwZjKrmJgkI4Fn8SBgRO6WXQBJi7KiAVPlmxikB5Jzc4EvXMT2H0/m0RjrVVm9rGNhZddm/8Spg==", - "dev": true, - "dependencies": { - "alphanum-sort": "^1.0.0", - "postcss": "^7.0.0", - "uniqs": "^2.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/postcss-value-parser": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.1.0.tgz", - "integrity": "sha512-97DXOFbQJhk71ne5/Mt6cOu6yxsSfM0QGQyl0L25Gca4yGWEGJaig7l7gbCX623VqTBNGLRLaVUCnNkcedlRSQ==", - "dev": true - }, - "node_modules/postcss/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/postcss/node_modules/supports-color": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", - "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", - "dev": true, - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/prepend-http": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-2.0.0.tgz", - "integrity": "sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc=", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/prettier": { - "version": "1.19.1", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-1.19.1.tgz", - "integrity": "sha512-s7PoyDv/II1ObgQunCbB9PdLmUcBZcnWOcxDh7O0N/UwDEsHyqkW+Qh28jW+mVuCdx7gLB0BotYI1Y6uI9iyew==", - "dev": true, - "optional": true, - "bin": { - "prettier": "bin-prettier.js" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/pretty-error": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/pretty-error/-/pretty-error-2.1.1.tgz", - "integrity": "sha1-X0+HyPkeWuPzuoerTPXgOxoX8aM=", - "dev": true, - "dependencies": { - "renderkid": "^2.0.1", - "utila": "~0.4" - } - }, - "node_modules/pretty-time": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/pretty-time/-/pretty-time-1.1.0.tgz", - "integrity": "sha512-28iF6xPQrP8Oa6uxE6a1biz+lWeTOAPKggvjB8HAs6nVMKZwf5bG++632Dx614hIWgUPkgivRfG+a8uAXGTIbA==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/prismjs": { - "version": "1.23.0", - "resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.23.0.tgz", - "integrity": "sha512-c29LVsqOaLbBHuIbsTxaKENh1N2EQBOHaWv7gkHN4dgRbxSREqDnDbtFJYdpPauS4YCplMSNCABQ6Eeor69bAA==", - "dev": true, - "optionalDependencies": { - "clipboard": "^2.0.0" - } - }, - "node_modules/private": { - "version": "0.1.8", - "resolved": "https://registry.npmjs.org/private/-/private-0.1.8.tgz", - "integrity": "sha512-VvivMrbvd2nKkiG38qjULzlc+4Vx4wm/whI9pQD35YrARNnhxeiRktSOhSukRLFNlzg6Br/cJPet5J/u19r/mg==", - "dev": true, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/process": { - "version": "0.11.10", - "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", - "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=", - "dev": true, - "engines": { - "node": ">= 0.6.0" - } - }, - "node_modules/process-nextick-args": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", - "dev": true - }, - "node_modules/promise-inflight": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz", - "integrity": "sha1-mEcocL8igTL8vdhoEputEsPAKeM=", - "dev": true - }, - "node_modules/proxy-addr": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.6.tgz", - "integrity": "sha512-dh/frvCBVmSsDYzw6n926jv974gddhkFPfiN8hPOi30Wax25QZyZEGveluCgliBnqmuM+UJmBErbAUFIoDbjOw==", - "dev": true, - "dependencies": { - "forwarded": "~0.1.2", - "ipaddr.js": "1.9.1" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/prr": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", - "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=", - "dev": true - }, - "node_modules/pseudomap": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", - "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=", - "dev": true - }, - "node_modules/psl": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", - "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==", - "dev": true - }, - "node_modules/public-encrypt": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz", - "integrity": "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==", - "dev": true, - "dependencies": { - "bn.js": "^4.1.0", - "browserify-rsa": "^4.0.0", - "create-hash": "^1.1.0", - "parse-asn1": "^5.0.0", - "randombytes": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "node_modules/public-encrypt/node_modules/bn.js": { - "version": "4.11.9", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz", - "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==", - "dev": true - }, - "node_modules/pump": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", - "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", - "dev": true, - "dependencies": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, - "node_modules/pumpify": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/pumpify/-/pumpify-1.5.1.tgz", - "integrity": "sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ==", - "dev": true, - "dependencies": { - "duplexify": "^3.6.0", - "inherits": "^2.0.3", - "pump": "^2.0.0" - } - }, - "node_modules/pumpify/node_modules/pump": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pump/-/pump-2.0.1.tgz", - "integrity": "sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==", - "dev": true, - "dependencies": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, - "node_modules/punycode": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/pupa": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pupa/-/pupa-2.0.1.tgz", - "integrity": "sha512-hEJH0s8PXLY/cdXh66tNEQGndDrIKNqNC5xmrysZy3i5C3oEoLna7YAOad+7u125+zH1HNXUmGEkrhb3c2VriA==", - "dev": true, - "dependencies": { - "escape-goat": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/q": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", - "integrity": "sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc=", - "dev": true, - "engines": { - "node": ">=0.6.0", - "teleport": ">=0.2.0" - } - }, - "node_modules/qs": { - "version": "6.5.2", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", - "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==", - "dev": true, - "engines": { - "node": ">=0.6" - } - }, - "node_modules/query-string": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/query-string/-/query-string-5.1.1.tgz", - "integrity": "sha512-gjWOsm2SoGlgLEdAGt7a6slVOk9mGiXmPFMqrEhLQ68rhQuBnpfs3+EmlvqKyxnCo9/PPlF+9MtY02S1aFg+Jw==", - "dev": true, - "dependencies": { - "decode-uri-component": "^0.2.0", - "object-assign": "^4.1.0", - "strict-uri-encode": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/querystring": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", - "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=", - "deprecated": "The", - "dev": true, - "engines": { - "node": ">=0.4.x" - } - }, - "node_modules/querystring-es3": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz", - "integrity": "sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM=", - "dev": true, - "engines": { - "node": ">=0.4.x" - } - }, - "node_modules/querystringify": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", - "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==", - "dev": true - }, - "node_modules/randombytes": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", - "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", - "dev": true, - "dependencies": { - "safe-buffer": "^5.1.0" - } - }, - "node_modules/randomfill": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz", - "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==", - "dev": true, - "dependencies": { - "randombytes": "^2.0.5", - "safe-buffer": "^5.1.0" - } - }, - "node_modules/range-parser": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", - "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", - "dev": true, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/raw-body": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.0.tgz", - "integrity": "sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q==", - "dev": true, - "dependencies": { - "bytes": "3.1.0", - "http-errors": "1.7.2", - "iconv-lite": "0.4.24", - "unpipe": "1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/raw-body/node_modules/bytes": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", - "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==", - "dev": true, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/rc": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", - "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", - "dev": true, - "dependencies": { - "deep-extend": "^0.6.0", - "ini": "~1.3.0", - "minimist": "^1.2.0", - "strip-json-comments": "~2.0.1" - }, - "bin": { - "rc": "cli.js" - } - }, - "node_modules/readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "node_modules/readable-stream/node_modules/isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "node_modules/readdirp": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz", - "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==", - "dev": true, - "dependencies": { - "graceful-fs": "^4.1.11", - "micromatch": "^3.1.10", - "readable-stream": "^2.0.2" - }, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/reduce": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/reduce/-/reduce-1.0.2.tgz", - "integrity": "sha512-xX7Fxke/oHO5IfZSk77lvPa/7bjMh9BuCk4OOoX5XTXrM7s0Z+MkPfSDfz0q7r91BhhGSs8gii/VEN/7zhCPpQ==", - "dev": true, - "dependencies": { - "object-keys": "^1.1.0" - } - }, - "node_modules/regenerate": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.1.tgz", - "integrity": "sha512-j2+C8+NtXQgEKWk49MMP5P/u2GhnahTtVkRIHr5R5lVRlbKvmQ+oS+A5aLKWp2ma5VkT8sh6v+v4hbH0YHR66A==", - "dev": true - }, - "node_modules/regenerate-unicode-properties": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-8.2.0.tgz", - "integrity": "sha512-F9DjY1vKLo/tPePDycuH3dn9H1OTPIkVD9Kz4LODu+F2C75mgjAJ7x/gwy6ZcSNRAAkhNlJSOHRe8k3p+K9WhA==", - "dev": true, - "dependencies": { - "regenerate": "^1.4.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/regenerator-runtime": { - "version": "0.13.5", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.5.tgz", - "integrity": "sha512-ZS5w8CpKFinUzOwW3c83oPeVXoNsrLsaCoLtJvAClH135j/R77RuymhiSErhm2lKcwSCIpmvIWSbDkIfAqKQlA==", - "dev": true - }, - "node_modules/regenerator-transform": { - "version": "0.14.4", - "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.14.4.tgz", - "integrity": "sha512-EaJaKPBI9GvKpvUz2mz4fhx7WPgvwRLY9v3hlNHWmAuJHI13T4nwKnNvm5RWJzEdnI5g5UwtOww+S8IdoUC2bw==", - "dev": true, - "dependencies": { - "@babel/runtime": "^7.8.4", - "private": "^0.1.8" - } - }, - "node_modules/regex-not": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", - "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", - "dev": true, - "dependencies": { - "extend-shallow": "^3.0.2", - "safe-regex": "^1.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/regex-not/node_modules/extend-shallow": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", - "dev": true, - "dependencies": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/regex-not/node_modules/is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, - "dependencies": { - "is-plain-object": "^2.0.4" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/regexp.prototype.flags": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.3.0.tgz", - "integrity": "sha512-2+Q0C5g951OlYlJz6yu5/M33IcsESLlLfsyIaLJaG4FA2r4yP8MvVMJUUP/fVBkSpbbbZlS5gynbEWLipiiXiQ==", - "dev": true, - "dependencies": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.0-next.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/regexpu-core": { - "version": "4.7.0", - "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-4.7.0.tgz", - "integrity": "sha512-TQ4KXRnIn6tz6tjnrXEkD/sshygKH/j5KzK86X8MkeHyZ8qst/LZ89j3X4/8HEIfHANTFIP/AbXakeRhWIl5YQ==", - "dev": true, - "dependencies": { - "regenerate": "^1.4.0", - "regenerate-unicode-properties": "^8.2.0", - "regjsgen": "^0.5.1", - "regjsparser": "^0.6.4", - "unicode-match-property-ecmascript": "^1.0.4", - "unicode-match-property-value-ecmascript": "^1.2.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/registry-auth-token": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-4.1.1.tgz", - "integrity": "sha512-9bKS7nTl9+/A1s7tnPeGrUpRcVY+LUh7bfFgzpndALdPfXQBfQV77rQVtqgUV3ti4vc/Ik81Ex8UJDWDQ12zQA==", - "dev": true, - "dependencies": { - "rc": "^1.2.8" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/registry-url": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/registry-url/-/registry-url-5.1.0.tgz", - "integrity": "sha512-8acYXXTI0AkQv6RAOjE3vOaIXZkT9wo4LOFbBKYQEEnnMNBpKqdUrI6S4NT0KPIo/WVvJ5tE/X5LF/TQUf0ekw==", - "dev": true, - "dependencies": { - "rc": "^1.2.8" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/regjsgen": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.5.2.tgz", - "integrity": "sha512-OFFT3MfrH90xIW8OOSyUrk6QHD5E9JOTeGodiJeBS3J6IwlgzJMNE/1bZklWz5oTg+9dCMyEetclvCVXOPoN3A==", - "dev": true - }, - "node_modules/regjsparser": { - "version": "0.6.4", - "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.6.4.tgz", - "integrity": "sha512-64O87/dPDgfk8/RQqC4gkZoGyyWFIEUTTh80CU6CWuK5vkCGyekIx+oKcEIYtP/RAxSQltCZHCNu/mdd7fqlJw==", - "dev": true, - "dependencies": { - "jsesc": "~0.5.0" - }, - "bin": { - "regjsparser": "bin/parser" - } - }, - "node_modules/regjsparser/node_modules/jsesc": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", - "integrity": "sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=", - "dev": true, - "bin": { - "jsesc": "bin/jsesc" - } - }, - "node_modules/relateurl": { - "version": "0.2.7", - "resolved": "https://registry.npmjs.org/relateurl/-/relateurl-0.2.7.tgz", - "integrity": "sha1-VNvzd+UUQKypCkzSdGANP/LYiKk=", - "dev": true, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/remove-trailing-separator": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", - "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=", - "dev": true - }, - "node_modules/renderkid": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/renderkid/-/renderkid-2.0.3.tgz", - "integrity": "sha512-z8CLQp7EZBPCwCnncgf9C4XAi3WR0dv+uWu/PjIyhhAb5d6IJ/QZqlHFprHeKT+59//V6BNUsLbvN8+2LarxGA==", - "dev": true, - "dependencies": { - "css-select": "^1.1.0", - "dom-converter": "^0.2", - "htmlparser2": "^3.3.0", - "strip-ansi": "^3.0.0", - "utila": "^0.4.0" - } - }, - "node_modules/renderkid/node_modules/ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/renderkid/node_modules/css-select": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/css-select/-/css-select-1.2.0.tgz", - "integrity": "sha1-KzoRBTnFNV8c2NMUYj6HCxIeyFg=", - "dev": true, - "dependencies": { - "boolbase": "~1.0.0", - "css-what": "2.1", - "domutils": "1.5.1", - "nth-check": "~1.0.1" - } - }, - "node_modules/renderkid/node_modules/css-what": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/css-what/-/css-what-2.1.3.tgz", - "integrity": "sha512-a+EPoD+uZiNfh+5fxw2nO9QwFa6nJe2Or35fGY6Ipw1R3R4AGz1d1TEZrCegvw2YTmZ0jXirGYlzxxpYSHwpEg==", - "dev": true, - "engines": { - "node": "*" - } - }, - "node_modules/renderkid/node_modules/domutils": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.5.1.tgz", - "integrity": "sha1-3NhIiib1Y9YQeeSMn3t+Mjc2gs8=", - "dev": true, - "dependencies": { - "dom-serializer": "0", - "domelementtype": "1" - } - }, - "node_modules/renderkid/node_modules/strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dev": true, - "dependencies": { - "ansi-regex": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/repeat-element": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.3.tgz", - "integrity": "sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/repeat-string": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", - "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", - "dev": true, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/request": { - "version": "2.88.2", - "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", - "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", - "deprecated": "request has been deprecated, see https://github.com/request/request/issues/3142", - "dev": true, - "dependencies": { - "aws-sign2": "~0.7.0", - "aws4": "^1.8.0", - "caseless": "~0.12.0", - "combined-stream": "~1.0.6", - "extend": "~3.0.2", - "forever-agent": "~0.6.1", - "form-data": "~2.3.2", - "har-validator": "~5.1.3", - "http-signature": "~1.2.0", - "is-typedarray": "~1.0.0", - "isstream": "~0.1.2", - "json-stringify-safe": "~5.0.1", - "mime-types": "~2.1.19", - "oauth-sign": "~0.9.0", - "performance-now": "^2.1.0", - "qs": "~6.5.2", - "safe-buffer": "^5.1.2", - "tough-cookie": "~2.5.0", - "tunnel-agent": "^0.6.0", - "uuid": "^3.3.2" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/require-main-filename": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", - "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", - "dev": true - }, - "node_modules/requires-port": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", - "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=", - "dev": true - }, - "node_modules/resolve": { - "version": "1.17.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", - "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", - "dev": true, - "dependencies": { - "path-parse": "^1.0.6" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/resolve-cwd": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-2.0.0.tgz", - "integrity": "sha1-AKn3OHVW4nA46uIyyqNypqWbZlo=", - "dev": true, - "dependencies": { - "resolve-from": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/resolve-from": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", - "integrity": "sha1-six699nWiBvItuZTM17rywoYh0g=", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/resolve-url": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", - "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=", - "deprecated": "https://github.com/lydell/resolve-url#deprecated", - "dev": true - }, - "node_modules/responselike": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/responselike/-/responselike-1.0.2.tgz", - "integrity": "sha1-kYcg7ztjHFZCvgaPFa3lpG9Loec=", - "dev": true, - "dependencies": { - "lowercase-keys": "^1.0.0" - } - }, - "node_modules/ret": { - "version": "0.1.15", - "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", - "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", - "dev": true, - "engines": { - "node": ">=0.12" - } - }, - "node_modules/retry": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz", - "integrity": "sha1-G0KmJmoh8HQh0bC1S33BZ7AcATs=", - "dev": true, - "engines": { - "node": ">= 4" - } - }, - "node_modules/rgb-regex": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/rgb-regex/-/rgb-regex-1.0.1.tgz", - "integrity": "sha1-wODWiC3w4jviVKR16O3UGRX+rrE=", - "dev": true - }, - "node_modules/rgba-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/rgba-regex/-/rgba-regex-1.0.0.tgz", - "integrity": "sha1-QzdOLiyglosO8VI0YLfXMP8i7rM=", - "dev": true - }, - "node_modules/rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", - "dev": true, - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - } - }, - "node_modules/ripemd160": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", - "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", - "dev": true, - "dependencies": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1" - } - }, - "node_modules/run-queue": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/run-queue/-/run-queue-1.0.3.tgz", - "integrity": "sha1-6Eg5bwV9Ij8kOGkkYY4laUFh7Ec=", - "dev": true, - "dependencies": { - "aproba": "^1.1.1" - } - }, - "node_modules/safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "node_modules/safe-regex": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", - "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", - "dev": true, - "dependencies": { - "ret": "~0.1.10" - } - }, - "node_modules/safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "dev": true - }, - "node_modules/sax": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", - "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==", - "dev": true - }, - "node_modules/schema-utils": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.0.tgz", - "integrity": "sha512-0ilKFI6QQF5nxDZLFn2dMjvc4hjg/Wkg7rHd3jK6/A4a1Hl9VFdQWvgB1UMGoU94pad1P/8N7fMcEnLnSiju8A==", - "dev": true, - "dependencies": { - "@types/json-schema": "^7.0.4", - "ajv": "^6.12.2", - "ajv-keywords": "^3.4.1" - }, - "engines": { - "node": ">= 8.9.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - } - }, - "node_modules/section-matter": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/section-matter/-/section-matter-1.0.0.tgz", - "integrity": "sha512-vfD3pmTzGpufjScBh50YHKzEu2lxBWhVEHsNGoEXmCmn2hKGfeNLYMzCJpe8cD7gqX7TJluOVpBkAequ6dgMmA==", - "dev": true, - "dependencies": { - "extend-shallow": "^2.0.1", - "kind-of": "^6.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/select": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/select/-/select-1.1.2.tgz", - "integrity": "sha1-DnNQrN7ICxEIUoeG7B1EGNEbOW0=", - "dev": true, - "optional": true - }, - "node_modules/select-hose": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz", - "integrity": "sha1-Yl2GWPhlr0Psliv8N2o3NZpJlMo=", - "dev": true - }, - "node_modules/selfsigned": { - "version": "1.10.7", - "resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-1.10.7.tgz", - "integrity": "sha512-8M3wBCzeWIJnQfl43IKwOmC4H/RAp50S8DF60znzjW5GVqTcSe2vWclt7hmYVPkKPlHWOu5EaWOMZ2Y6W8ZXTA==", - "dev": true, - "dependencies": { - "node-forge": "0.9.0" - } - }, - "node_modules/semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true, - "bin": { - "semver": "bin/semver" - } - }, - "node_modules/semver-diff": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/semver-diff/-/semver-diff-3.1.1.tgz", - "integrity": "sha512-GX0Ix/CJcHyB8c4ykpHGIAvLyOwOobtM/8d+TQkAd81/bEjgPHrfba41Vpesr7jX/t8Uh+R3EX9eAS5be+jQYg==", - "dev": true, - "dependencies": { - "semver": "^6.3.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/semver-diff/node_modules/semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true, - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/send": { - "version": "0.17.1", - "resolved": "https://registry.npmjs.org/send/-/send-0.17.1.tgz", - "integrity": "sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg==", - "dev": true, - "dependencies": { - "debug": "2.6.9", - "depd": "~1.1.2", - "destroy": "~1.0.4", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "fresh": "0.5.2", - "http-errors": "~1.7.2", - "mime": "1.6.0", - "ms": "2.1.1", - "on-finished": "~2.3.0", - "range-parser": "~1.2.1", - "statuses": "~1.5.0" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/send/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/send/node_modules/debug/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - }, - "node_modules/send/node_modules/mime": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", - "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", - "dev": true, - "bin": { - "mime": "cli.js" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/send/node_modules/ms": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", - "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", - "dev": true - }, - "node_modules/serialize-javascript": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-2.1.2.tgz", - "integrity": "sha512-rs9OggEUF0V4jUSecXazOYsLfu7OGK2qIn3c7IPBiffz32XniEp/TX9Xmc9LQfK2nQ2QKHvZ2oygKUGU0lG4jQ==", - "dev": true - }, - "node_modules/serve-index": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/serve-index/-/serve-index-1.9.1.tgz", - "integrity": "sha1-03aNabHn2C5c4FD/9bRTvqEqkjk=", - "dev": true, - "dependencies": { - "accepts": "~1.3.4", - "batch": "0.6.1", - "debug": "2.6.9", - "escape-html": "~1.0.3", - "http-errors": "~1.6.2", - "mime-types": "~2.1.17", - "parseurl": "~1.3.2" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/serve-index/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/serve-index/node_modules/http-errors": { - "version": "1.6.3", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", - "integrity": "sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0=", - "dev": true, - "dependencies": { - "depd": "~1.1.2", - "inherits": "2.0.3", - "setprototypeof": "1.1.0", - "statuses": ">= 1.4.0 < 2" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/serve-index/node_modules/inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", - "dev": true - }, - "node_modules/serve-index/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - }, - "node_modules/serve-index/node_modules/setprototypeof": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", - "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==", - "dev": true - }, - "node_modules/serve-static": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.1.tgz", - "integrity": "sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg==", - "dev": true, - "dependencies": { - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "parseurl": "~1.3.3", - "send": "0.17.1" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/set-blocking": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", - "dev": true - }, - "node_modules/set-value": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz", - "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==", - "dev": true, - "dependencies": { - "extend-shallow": "^2.0.1", - "is-extendable": "^0.1.1", - "is-plain-object": "^2.0.3", - "split-string": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/setimmediate": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", - "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=", - "dev": true - }, - "node_modules/setprototypeof": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz", - "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==", - "dev": true - }, - "node_modules/sha.js": { - "version": "2.4.11", - "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", - "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", - "dev": true, - "dependencies": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - }, - "bin": { - "sha.js": "bin.js" - } - }, - "node_modules/shebang-command": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", - "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", - "dev": true, - "dependencies": { - "shebang-regex": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/shebang-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", - "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/signal-exit": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz", - "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==", - "dev": true - }, - "node_modules/simple-swizzle": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz", - "integrity": "sha1-pNprY1/8zMoz9w0Xy5JZLeleVXo=", - "dev": true, - "dependencies": { - "is-arrayish": "^0.3.1" - } - }, - "node_modules/simple-swizzle/node_modules/is-arrayish": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz", - "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==", - "dev": true - }, - "node_modules/slash": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz", - "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/smoothscroll-polyfill": { - "version": "0.4.4", - "resolved": "https://registry.npmjs.org/smoothscroll-polyfill/-/smoothscroll-polyfill-0.4.4.tgz", - "integrity": "sha512-TK5ZA9U5RqCwMpfoMq/l1mrH0JAR7y7KRvOBx0n2869aLxch+gT9GhN3yUfjiw+d/DiF1mKo14+hd62JyMmoBg==", - "dev": true - }, - "node_modules/snapdragon": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", - "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", - "dev": true, - "dependencies": { - "base": "^0.11.1", - "debug": "^2.2.0", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "map-cache": "^0.2.2", - "source-map": "^0.5.6", - "source-map-resolve": "^0.5.0", - "use": "^3.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon-node": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", - "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", - "dev": true, - "dependencies": { - "define-property": "^1.0.0", - "isobject": "^3.0.0", - "snapdragon-util": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon-node/node_modules/define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "dependencies": { - "is-descriptor": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon-util": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", - "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", - "dev": true, - "dependencies": { - "kind-of": "^3.2.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon-util/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/snapdragon/node_modules/define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "dependencies": { - "is-descriptor": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon/node_modules/is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon/node_modules/is-accessor-descriptor/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon/node_modules/is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon/node_modules/is-data-descriptor/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon/node_modules/is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "dependencies": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon/node_modules/kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - }, - "node_modules/sockjs": { - "version": "0.3.20", - "resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.20.tgz", - "integrity": "sha512-SpmVOVpdq0DJc0qArhF3E5xsxvaiqGNb73XfgBpK1y3UD5gs8DSo8aCTsuT5pX8rssdc2NDIzANwP9eCAiSdTA==", - "dev": true, - "dependencies": { - "faye-websocket": "^0.10.0", - "uuid": "^3.4.0", - "websocket-driver": "0.6.5" - } - }, - "node_modules/sockjs-client": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/sockjs-client/-/sockjs-client-1.4.0.tgz", - "integrity": "sha512-5zaLyO8/nri5cua0VtOrFXBPK1jbL4+1cebT/mmKA1E1ZXOvJrII75bPu0l0k843G/+iAbhEqzyKr0w/eCCj7g==", - "dev": true, - "dependencies": { - "debug": "^3.2.5", - "eventsource": "^1.0.7", - "faye-websocket": "~0.11.1", - "inherits": "^2.0.3", - "json3": "^3.3.2", - "url-parse": "^1.4.3" - } - }, - "node_modules/sockjs-client/node_modules/debug": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", - "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", - "deprecated": "Debug versions >=3.2.0 <3.2.7 || >=4 <4.3.1 have a low-severity ReDos regression when used in a Node.js environment. It is recommended you upgrade to 3.2.7 or 4.3.1. (https://github.com/visionmedia/debug/issues/797)", - "dev": true, - "dependencies": { - "ms": "^2.1.1" - } - }, - "node_modules/sockjs-client/node_modules/faye-websocket": { - "version": "0.11.3", - "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.3.tgz", - "integrity": "sha512-D2y4bovYpzziGgbHYtGCMjlJM36vAl/y+xUyn1C+FVx8szd1E+86KwVw6XvYSzOP8iMpm1X0I4xJD+QtUb36OA==", - "dev": true, - "dependencies": { - "websocket-driver": ">=0.5.1" - }, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/sort-keys": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/sort-keys/-/sort-keys-2.0.0.tgz", - "integrity": "sha1-ZYU1WEhh7JfXMNbPQYIuH1ZoQSg=", - "dev": true, - "dependencies": { - "is-plain-obj": "^1.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/source-list-map": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.1.tgz", - "integrity": "sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw==", - "dev": true - }, - "node_modules/source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/source-map-resolve": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz", - "integrity": "sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==", - "dev": true, - "dependencies": { - "atob": "^2.1.2", - "decode-uri-component": "^0.2.0", - "resolve-url": "^0.2.1", - "source-map-url": "^0.4.0", - "urix": "^0.1.0" - } - }, - "node_modules/source-map-support": { - "version": "0.5.19", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz", - "integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==", - "dev": true, - "dependencies": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - }, - "node_modules/source-map-support/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/source-map-url": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz", - "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=", - "dev": true - }, - "node_modules/spdy": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/spdy/-/spdy-4.0.2.tgz", - "integrity": "sha512-r46gZQZQV+Kl9oItvl1JZZqJKGr+oEkB08A6BzkiR7593/7IbtuncXHd2YoYeTsG4157ZssMu9KYvUHLcjcDoA==", - "dev": true, - "dependencies": { - "debug": "^4.1.0", - "handle-thing": "^2.0.0", - "http-deceiver": "^1.2.7", - "select-hose": "^2.0.0", - "spdy-transport": "^3.0.0" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/spdy-transport": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/spdy-transport/-/spdy-transport-3.0.0.tgz", - "integrity": "sha512-hsLVFE5SjA6TCisWeJXFKniGGOpBgMLmerfO2aCyCU5s7nJ/rpAepqmFifv/GCbSbueEeAJJnmSQ2rKC/g8Fcw==", - "dev": true, - "dependencies": { - "debug": "^4.1.0", - "detect-node": "^2.0.4", - "hpack.js": "^2.1.6", - "obuf": "^1.1.2", - "readable-stream": "^3.0.6", - "wbuf": "^1.7.3" - } - }, - "node_modules/spdy-transport/node_modules/readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "dev": true, - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/split-string": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", - "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", - "dev": true, - "dependencies": { - "extend-shallow": "^3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/split-string/node_modules/extend-shallow": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", - "dev": true, - "dependencies": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/split-string/node_modules/is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, - "dependencies": { - "is-plain-object": "^2.0.4" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", - "dev": true - }, - "node_modules/sshpk": { - "version": "1.16.1", - "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", - "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", - "dev": true, - "dependencies": { - "asn1": "~0.2.3", - "assert-plus": "^1.0.0", - "bcrypt-pbkdf": "^1.0.0", - "dashdash": "^1.12.0", - "ecc-jsbn": "~0.1.1", - "getpass": "^0.1.1", - "jsbn": "~0.1.0", - "safer-buffer": "^2.0.2", - "tweetnacl": "~0.14.0" - }, - "bin": { - "sshpk-conv": "bin/sshpk-conv", - "sshpk-sign": "bin/sshpk-sign", - "sshpk-verify": "bin/sshpk-verify" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ssri": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/ssri/-/ssri-6.0.2.tgz", - "integrity": "sha512-cepbSq/neFK7xB6A50KHN0xHDotYzq58wWCa5LeWqnPrHG8GzfEjO/4O8kpmcGW+oaxkvhEJCWgbgNk4/ZV93Q==", - "dev": true, - "dependencies": { - "figgy-pudding": "^3.5.1" - } - }, - "node_modules/stable": { - "version": "0.1.8", - "resolved": "https://registry.npmjs.org/stable/-/stable-0.1.8.tgz", - "integrity": "sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w==", - "dev": true - }, - "node_modules/stack-utils": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-1.0.2.tgz", - "integrity": "sha512-MTX+MeG5U994cazkjd/9KNAapsHnibjMLnfXodlkXw76JEea0UiNzrqidzo1emMwk7w5Qhc9jd4Bn9TBb1MFwA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/static-extend": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", - "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=", - "dev": true, - "dependencies": { - "define-property": "^0.2.5", - "object-copy": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/static-extend/node_modules/define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "dependencies": { - "is-descriptor": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/static-extend/node_modules/is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/static-extend/node_modules/is-accessor-descriptor/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/static-extend/node_modules/is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/static-extend/node_modules/is-data-descriptor/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/static-extend/node_modules/is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "dependencies": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/static-extend/node_modules/kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/statuses": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", - "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=", - "dev": true, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/std-env": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/std-env/-/std-env-2.2.1.tgz", - "integrity": "sha512-IjYQUinA3lg5re/YMlwlfhqNRTzMZMqE+pezevdcTaHceqx8ngEi1alX9nNCk9Sc81fy1fLDeQoaCzeiW1yBOQ==", - "dev": true, - "dependencies": { - "ci-info": "^1.6.0" - } - }, - "node_modules/std-env/node_modules/ci-info": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-1.6.0.tgz", - "integrity": "sha512-vsGdkwSCDpWmP80ncATX7iea5DWQemg1UgCW5J8tqjU3lYw4FBYuj89J0CTVomA7BEfvSZd84GmHko+MxFQU2A==", - "dev": true - }, - "node_modules/stream-browserify": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.2.tgz", - "integrity": "sha512-nX6hmklHs/gr2FuxYDltq8fJA1GDlxKQCz8O/IM4atRqBH8OORmBNgfvW5gG10GT/qQ9u0CzIvr2X5Pkt6ntqg==", - "dev": true, - "dependencies": { - "inherits": "~2.0.1", - "readable-stream": "^2.0.2" - } - }, - "node_modules/stream-each": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/stream-each/-/stream-each-1.2.3.tgz", - "integrity": "sha512-vlMC2f8I2u/bZGqkdfLQW/13Zihpej/7PmSiMQsbYddxuTsJp8vRe2x2FvVExZg7FaOds43ROAuFJwPR4MTZLw==", - "dev": true, - "dependencies": { - "end-of-stream": "^1.1.0", - "stream-shift": "^1.0.0" - } - }, - "node_modules/stream-http": { - "version": "2.8.3", - "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-2.8.3.tgz", - "integrity": "sha512-+TSkfINHDo4J+ZobQLWiMouQYB+UVYFttRA94FpEzzJ7ZdqcL4uUUQ7WkdkI4DSozGmgBUE/a47L+38PenXhUw==", - "dev": true, - "dependencies": { - "builtin-status-codes": "^3.0.0", - "inherits": "^2.0.1", - "readable-stream": "^2.3.6", - "to-arraybuffer": "^1.0.0", - "xtend": "^4.0.0" - } - }, - "node_modules/stream-shift": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.1.tgz", - "integrity": "sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ==", - "dev": true - }, - "node_modules/strict-uri-encode": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz", - "integrity": "sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "dependencies": { - "safe-buffer": "~5.1.0" - } - }, - "node_modules/string-width": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", - "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", - "dev": true, - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/string.prototype.trimend": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.1.tgz", - "integrity": "sha512-LRPxFUaTtpqYsTeNKaFOw3R4bxIzWOnbQ837QfBylo8jIxtcbK/A/sMV7Q+OAV/vWo+7s25pOE10KYSjaSO06g==", - "dev": true, - "dependencies": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.5" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/string.prototype.trimleft": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/string.prototype.trimleft/-/string.prototype.trimleft-2.1.2.tgz", - "integrity": "sha512-gCA0tza1JBvqr3bfAIFJGqfdRTyPae82+KTnm3coDXkZN9wnuW3HjGgN386D7hfv5CHQYCI022/rJPVlqXyHSw==", - "dev": true, - "dependencies": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.5", - "string.prototype.trimstart": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/string.prototype.trimright": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/string.prototype.trimright/-/string.prototype.trimright-2.1.2.tgz", - "integrity": "sha512-ZNRQ7sY3KroTaYjRS6EbNiiHrOkjihL9aQE/8gfQ4DtAC/aEBRHFJa44OmoWxGGqXuJlfKkZW4WcXErGr+9ZFg==", - "dev": true, - "dependencies": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.5", - "string.prototype.trimend": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/string.prototype.trimstart": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.1.tgz", - "integrity": "sha512-XxZn+QpvrBI1FOcg6dIpxUPgWCPuNXvMD72aaRaUQv1eD4e/Qy8i/hFTe0BUmD60p/QA6bh1avmuPTfNjqVWRw==", - "dev": true, - "dependencies": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.5" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/strip-ansi": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", - "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", - "dev": true, - "dependencies": { - "ansi-regex": "^5.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-bom-string": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/strip-bom-string/-/strip-bom-string-1.0.0.tgz", - "integrity": "sha1-5SEekiQ2n7uB1jOi8ABE3IztrZI=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/strip-eof": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", - "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/strip-json-comments": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/stylehacks": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/stylehacks/-/stylehacks-4.0.3.tgz", - "integrity": "sha512-7GlLk9JwlElY4Y6a/rmbH2MhVlTyVmiJd1PfTCqFaIBEGMYNsrO/v3SeGTdhBThLg4Z+NbOk/qFMwCa+J+3p/g==", - "dev": true, - "dependencies": { - "browserslist": "^4.0.0", - "postcss": "^7.0.0", - "postcss-selector-parser": "^3.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/stylehacks/node_modules/postcss-selector-parser": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-3.1.2.tgz", - "integrity": "sha512-h7fJ/5uWuRVyOtkO45pnt1Ih40CEleeyCHzipqAZO2e5H20g25Y48uYnFUiShvY4rZWNJ/Bib/KVPmanaCtOhA==", - "dev": true, - "dependencies": { - "dot-prop": "^5.2.0", - "indexes-of": "^1.0.1", - "uniq": "^1.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/stylus": { - "version": "0.54.7", - "resolved": "https://registry.npmjs.org/stylus/-/stylus-0.54.7.tgz", - "integrity": "sha512-Yw3WMTzVwevT6ZTrLCYNHAFmanMxdylelL3hkWNgPMeTCpMwpV3nXjpOHuBXtFv7aiO2xRuQS6OoAdgkNcSNug==", - "dev": true, - "dependencies": { - "css-parse": "~2.0.0", - "debug": "~3.1.0", - "glob": "^7.1.3", - "mkdirp": "~0.5.x", - "safer-buffer": "^2.1.2", - "sax": "~1.2.4", - "semver": "^6.0.0", - "source-map": "^0.7.3" - }, - "bin": { - "stylus": "bin/stylus" - }, - "engines": { - "node": "*" - } - }, - "node_modules/stylus-loader": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/stylus-loader/-/stylus-loader-3.0.2.tgz", - "integrity": "sha512-+VomPdZ6a0razP+zinir61yZgpw2NfljeSsdUF5kJuEzlo3khXhY19Fn6l8QQz1GRJGtMCo8nG5C04ePyV7SUA==", - "dev": true, - "dependencies": { - "loader-utils": "^1.0.2", - "lodash.clonedeep": "^4.5.0", - "when": "~3.6.x" - }, - "peerDependencies": { - "stylus": ">=0.52.4" - } - }, - "node_modules/stylus/node_modules/debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", - "dev": true, - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/stylus/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - }, - "node_modules/stylus/node_modules/semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true, - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/stylus/node_modules/source-map": { - "version": "0.7.3", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", - "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==", - "dev": true, - "engines": { - "node": ">= 8" - } - }, - "node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/svg-tags": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/svg-tags/-/svg-tags-1.0.0.tgz", - "integrity": "sha1-WPcc7jvVGbWdSyqEO2x95krAR2Q=", - "dev": true - }, - "node_modules/svgo": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/svgo/-/svgo-1.3.2.tgz", - "integrity": "sha512-yhy/sQYxR5BkC98CY7o31VGsg014AKLEPxdfhora76l36hD9Rdy5NZA/Ocn6yayNPgSamYdtX2rFJdcv07AYVw==", - "dev": true, - "dependencies": { - "chalk": "^2.4.1", - "coa": "^2.0.2", - "css-select": "^2.0.0", - "css-select-base-adapter": "^0.1.1", - "css-tree": "1.0.0-alpha.37", - "csso": "^4.0.2", - "js-yaml": "^3.13.1", - "mkdirp": "~0.5.1", - "object.values": "^1.1.0", - "sax": "~1.2.4", - "stable": "^0.1.8", - "unquote": "~1.1.1", - "util.promisify": "~1.0.0" - }, - "bin": { - "svgo": "bin/svgo" - }, - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/tapable": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-1.1.3.tgz", - "integrity": "sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/term-size": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/term-size/-/term-size-2.2.0.tgz", - "integrity": "sha512-a6sumDlzyHVJWb8+YofY4TW112G6p2FCPEAFk+59gIYHv3XHRhm9ltVQ9kli4hNWeQBwSpe8cRN25x0ROunMOw==", - "dev": true, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/terser": { - "version": "4.7.0", - "resolved": "https://registry.npmjs.org/terser/-/terser-4.7.0.tgz", - "integrity": "sha512-Lfb0RiZcjRDXCC3OSHJpEkxJ9Qeqs6mp2v4jf2MHfy8vGERmVDuvjXdd/EnP5Deme5F2yBRBymKmKHCBg2echw==", - "dev": true, - "dependencies": { - "commander": "^2.20.0", - "source-map": "~0.6.1", - "source-map-support": "~0.5.12" - }, - "bin": { - "terser": "bin/terser" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/terser-webpack-plugin": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-1.4.4.tgz", - "integrity": "sha512-U4mACBHIegmfoEe5fdongHESNJWqsGU+W0S/9+BmYGVQDw1+c2Ow05TpMhxjPK1sRb7cuYq1BPl1e5YHJMTCqA==", - "dev": true, - "dependencies": { - "cacache": "^12.0.2", - "find-cache-dir": "^2.1.0", - "is-wsl": "^1.1.0", - "schema-utils": "^1.0.0", - "serialize-javascript": "^3.1.0", - "source-map": "^0.6.1", - "terser": "^4.1.2", - "webpack-sources": "^1.4.0", - "worker-farm": "^1.7.0" - }, - "engines": { - "node": ">= 6.9.0" - }, - "peerDependencies": { - "webpack": "^4.0.0" - } - }, - "node_modules/terser-webpack-plugin/node_modules/schema-utils": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", - "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", - "dev": true, - "dependencies": { - "ajv": "^6.1.0", - "ajv-errors": "^1.0.0", - "ajv-keywords": "^3.1.0" - }, - "engines": { - "node": ">= 4" - } - }, - "node_modules/terser-webpack-plugin/node_modules/serialize-javascript": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-3.1.0.tgz", - "integrity": "sha512-JIJT1DGiWmIKhzRsG91aS6Ze4sFUrYbltlkg2onR5OrnNM02Kl/hnY/T4FN2omvyeBbQmMJv+K4cPOpGzOTFBg==", - "dev": true, - "dependencies": { - "randombytes": "^2.1.0" - } - }, - "node_modules/terser-webpack-plugin/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/terser/node_modules/commander": { - "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", - "dev": true - }, - "node_modules/terser/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/text-table": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", - "dev": true - }, - "node_modules/through": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", - "dev": true - }, - "node_modules/through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "dev": true, - "dependencies": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - } - }, - "node_modules/thunky": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/thunky/-/thunky-1.1.0.tgz", - "integrity": "sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==", - "dev": true - }, - "node_modules/timers-browserify": { - "version": "2.0.11", - "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.11.tgz", - "integrity": "sha512-60aV6sgJ5YEbzUdn9c8kYGIqOubPoUdqQCul3SBAsRCZ40s6Y5cMcrW4dt3/k/EsbLVJNl9n6Vz3fTc+k2GeKQ==", - "dev": true, - "dependencies": { - "setimmediate": "^1.0.4" - }, - "engines": { - "node": ">=0.6.0" - } - }, - "node_modules/timsort": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/timsort/-/timsort-0.3.0.tgz", - "integrity": "sha1-QFQRqOfmM5/mTbmiNN4R3DHgK9Q=", - "dev": true - }, - "node_modules/tiny-emitter": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/tiny-emitter/-/tiny-emitter-2.1.0.tgz", - "integrity": "sha512-NB6Dk1A9xgQPMoGqC5CVXn123gWyte215ONT5Pp5a0yt4nlEoO1ZWeCwpncaekPHXO60i47ihFnZPiRPjRMq4Q==", - "dev": true, - "optional": true - }, - "node_modules/to-arraybuffer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz", - "integrity": "sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M=", - "dev": true - }, - "node_modules/to-factory": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/to-factory/-/to-factory-1.0.0.tgz", - "integrity": "sha1-hzivi9lxIK0dQEeXKtpVY7+UebE=", - "dev": true - }, - "node_modules/to-fast-properties": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", - "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/to-object-path": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", - "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=", - "dev": true, - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/to-object-path/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/to-readable-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/to-readable-stream/-/to-readable-stream-1.0.0.tgz", - "integrity": "sha512-Iq25XBt6zD5npPhlLVXGFN3/gyR2/qODcKNNyTMd4vbm39HUaOiAM4PMq0eMVC/Tkxz+Zjdsc55g9yyz+Yq00Q==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/to-regex": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", - "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", - "dev": true, - "dependencies": { - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "regex-not": "^1.0.2", - "safe-regex": "^1.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/to-regex-range": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", - "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", - "dev": true, - "dependencies": { - "is-number": "^3.0.0", - "repeat-string": "^1.6.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/to-regex/node_modules/extend-shallow": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", - "dev": true, - "dependencies": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/to-regex/node_modules/is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, - "dependencies": { - "is-plain-object": "^2.0.4" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/toidentifier": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz", - "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==", - "dev": true, - "engines": { - "node": ">=0.6" - } - }, - "node_modules/toml": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/toml/-/toml-3.0.0.tgz", - "integrity": "sha512-y/mWCZinnvxjTKYhJ+pYxwD0mRLVvOtdS2Awbgxln6iEnt4rk0yBxeSBHkGJcPucRiG0e55mwWp+g/05rsrd6w==", - "dev": true - }, - "node_modules/toposort": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/toposort/-/toposort-1.0.7.tgz", - "integrity": "sha1-LmhELZ9k7HILjMieZEOsbKqVACk=", - "dev": true - }, - "node_modules/tough-cookie": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", - "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", - "dev": true, - "dependencies": { - "psl": "^1.1.28", - "punycode": "^2.1.1" - }, - "engines": { - "node": ">=0.8" - } - }, - "node_modules/tslib": { - "version": "1.13.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.13.0.tgz", - "integrity": "sha512-i/6DQjL8Xf3be4K/E6Wgpekn5Qasl1usyw++dAA35Ue5orEn65VIxOA+YvNNl9HV3qv70T7CNwjODHZrLwvd1Q==", - "dev": true - }, - "node_modules/tty-browserify": { - "version": "0.0.0", - "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz", - "integrity": "sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY=", - "dev": true - }, - "node_modules/tunnel-agent": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", - "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", - "dev": true, - "dependencies": { - "safe-buffer": "^5.0.1" - }, - "engines": { - "node": "*" - } - }, - "node_modules/tweetnacl": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", - "dev": true - }, - "node_modules/type-fest": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", - "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/type-is": { - "version": "1.6.18", - "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", - "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", - "dev": true, - "dependencies": { - "media-typer": "0.3.0", - "mime-types": "~2.1.24" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/typedarray": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", - "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", - "dev": true - }, - "node_modules/typedarray-to-buffer": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", - "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", - "dev": true, - "dependencies": { - "is-typedarray": "^1.0.0" - } - }, - "node_modules/uc.micro": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.6.tgz", - "integrity": "sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==", - "dev": true - }, - "node_modules/uglify-js": { - "version": "3.4.10", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.4.10.tgz", - "integrity": "sha512-Y2VsbPVs0FIshJztycsO2SfPk7/KAF/T72qzv9u5EpQ4kB2hQoHlhNQTsNyy6ul7lQtqJN/AoWeS23OzEiEFxw==", - "dev": true, - "dependencies": { - "commander": "~2.19.0", - "source-map": "~0.6.1" - }, - "bin": { - "uglifyjs": "bin/uglifyjs" - }, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/uglify-js/node_modules/commander": { - "version": "2.19.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.19.0.tgz", - "integrity": "sha512-6tvAOO+D6OENvRAh524Dh9jcfKTYDQAqvqezbCW82xj5X0pSrcpxtvRKHLG0yBY6SD7PSDrJaj+0AiOcKVd1Xg==", - "dev": true - }, - "node_modules/uglify-js/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/unicode-canonical-property-names-ecmascript": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-1.0.4.tgz", - "integrity": "sha512-jDrNnXWHd4oHiTZnx/ZG7gtUTVp+gCcTTKr8L0HjlwphROEW3+Him+IpvC+xcJEFegapiMZyZe02CyuOnRmbnQ==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/unicode-match-property-ecmascript": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-1.0.4.tgz", - "integrity": "sha512-L4Qoh15vTfntsn4P1zqnHulG0LdXgjSO035fEpdtp6YxXhMT51Q6vgM5lYdG/5X3MjS+k/Y9Xw4SFCY9IkR0rg==", - "dev": true, - "dependencies": { - "unicode-canonical-property-names-ecmascript": "^1.0.4", - "unicode-property-aliases-ecmascript": "^1.0.4" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/unicode-match-property-value-ecmascript": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-1.2.0.tgz", - "integrity": "sha512-wjuQHGQVofmSJv1uVISKLE5zO2rNGzM/KCYZch/QQvez7C1hUhBIuZ701fYXExuufJFMPhv2SyL8CyoIfMLbIQ==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/unicode-property-aliases-ecmascript": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-1.1.0.tgz", - "integrity": "sha512-PqSoPh/pWetQ2phoj5RLiaqIk4kCNwoV3CI+LfGmWLKI3rE3kl1h59XpX2BjgDrmbxD9ARtQobPGU1SguCYuQg==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/union-value": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", - "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==", - "dev": true, - "dependencies": { - "arr-union": "^3.1.0", - "get-value": "^2.0.6", - "is-extendable": "^0.1.1", - "set-value": "^2.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/uniq": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/uniq/-/uniq-1.0.1.tgz", - "integrity": "sha1-sxxa6CVIRKOoKBVBzisEuGWnNP8=", - "dev": true - }, - "node_modules/uniqs": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/uniqs/-/uniqs-2.0.0.tgz", - "integrity": "sha1-/+3ks2slKQaW5uFl1KWe25mOawI=", - "dev": true - }, - "node_modules/unique-filename": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-1.1.1.tgz", - "integrity": "sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ==", - "dev": true, - "dependencies": { - "unique-slug": "^2.0.0" - } - }, - "node_modules/unique-slug": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-2.0.2.tgz", - "integrity": "sha512-zoWr9ObaxALD3DOPfjPSqxt4fnZiWblxHIgeWqW8x7UqDzEtHEQLzji2cuJYQFCU6KmoJikOYAZlrTHHebjx2w==", - "dev": true, - "dependencies": { - "imurmurhash": "^0.1.4" - } - }, - "node_modules/unique-string": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-2.0.0.tgz", - "integrity": "sha512-uNaeirEPvpZWSgzwsPGtU2zVSTrn/8L5q/IexZmH0eH6SA73CmAA5U4GwORTxQAZs95TAXLNqeLoPPNO5gZfWg==", - "dev": true, - "dependencies": { - "crypto-random-string": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/universalify": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", - "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", - "dev": true, - "engines": { - "node": ">= 4.0.0" - } - }, - "node_modules/unpipe": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", - "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=", - "dev": true, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/unquote": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/unquote/-/unquote-1.1.1.tgz", - "integrity": "sha1-j97XMk7G6IoP+LkF58CYzcCG1UQ=", - "dev": true - }, - "node_modules/unset-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", - "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=", - "dev": true, - "dependencies": { - "has-value": "^0.3.1", - "isobject": "^3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/unset-value/node_modules/has-value": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", - "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=", - "dev": true, - "dependencies": { - "get-value": "^2.0.3", - "has-values": "^0.1.4", - "isobject": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/unset-value/node_modules/has-value/node_modules/isobject": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", - "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", - "dev": true, - "dependencies": { - "isarray": "1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/unset-value/node_modules/has-values": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", - "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/unset-value/node_modules/isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "node_modules/upath": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz", - "integrity": "sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==", - "dev": true, - "engines": { - "node": ">=4", - "yarn": "*" - } - }, - "node_modules/update-notifier": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-4.1.0.tgz", - "integrity": "sha512-w3doE1qtI0/ZmgeoDoARmI5fjDoT93IfKgEGqm26dGUOh8oNpaSTsGNdYRN/SjOuo10jcJGwkEL3mroKzktkew==", - "dev": true, - "dependencies": { - "boxen": "^4.2.0", - "chalk": "^3.0.0", - "configstore": "^5.0.1", - "has-yarn": "^2.1.0", - "import-lazy": "^2.1.0", - "is-ci": "^2.0.0", - "is-installed-globally": "^0.3.1", - "is-npm": "^4.0.0", - "is-yarn-global": "^0.3.0", - "latest-version": "^5.0.0", - "pupa": "^2.0.1", - "semver-diff": "^3.1.1", - "xdg-basedir": "^4.0.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/yeoman/update-notifier?sponsor=1" - } - }, - "node_modules/update-notifier/node_modules/ansi-styles": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", - "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", - "dev": true, - "dependencies": { - "@types/color-name": "^1.1.1", - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/update-notifier/node_modules/chalk": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", - "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/update-notifier/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/update-notifier/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "node_modules/update-notifier/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/update-notifier/node_modules/supports-color": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", - "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/upper-case": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/upper-case/-/upper-case-1.1.3.tgz", - "integrity": "sha1-9rRQHC7EzdJrp4vnIilh3ndiFZg=", - "dev": true - }, - "node_modules/uri-js": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", - "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", - "dev": true, - "dependencies": { - "punycode": "^2.1.0" - } - }, - "node_modules/urix": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", - "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=", - "deprecated": "Please see https://github.com/lydell/urix#deprecated", - "dev": true - }, - "node_modules/url": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz", - "integrity": "sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE=", - "dev": true, - "dependencies": { - "punycode": "1.3.2", - "querystring": "0.2.0" - } - }, - "node_modules/url-loader": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/url-loader/-/url-loader-1.1.2.tgz", - "integrity": "sha512-dXHkKmw8FhPqu8asTc1puBfe3TehOCo2+RmOOev5suNCIYBcT626kxiWg1NBVkwc4rO8BGa7gP70W7VXuqHrjg==", - "dev": true, - "dependencies": { - "loader-utils": "^1.1.0", - "mime": "^2.0.3", - "schema-utils": "^1.0.0" - }, - "engines": { - "node": ">= 6.9.0" - }, - "peerDependencies": { - "webpack": "^3.0.0 || ^4.0.0" - } - }, - "node_modules/url-loader/node_modules/schema-utils": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", - "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", - "dev": true, - "dependencies": { - "ajv": "^6.1.0", - "ajv-errors": "^1.0.0", - "ajv-keywords": "^3.1.0" - }, - "engines": { - "node": ">= 4" - } - }, - "node_modules/url-parse": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.1.tgz", - "integrity": "sha512-HOfCOUJt7iSYzEx/UqgtwKRMC6EU91NFhsCHMv9oM03VJcVo2Qrp8T8kI9D7amFf1cu+/3CEhgb3rF9zL7k85Q==", - "dev": true, - "dependencies": { - "querystringify": "^2.1.1", - "requires-port": "^1.0.0" - } - }, - "node_modules/url-parse-lax": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-3.0.0.tgz", - "integrity": "sha1-FrXK/Afb42dsGxmZF3gj1lA6yww=", - "dev": true, - "dependencies": { - "prepend-http": "^2.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/url/node_modules/punycode": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", - "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=", - "dev": true - }, - "node_modules/use": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", - "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/util": { - "version": "0.11.1", - "resolved": "https://registry.npmjs.org/util/-/util-0.11.1.tgz", - "integrity": "sha512-HShAsny+zS2TZfaXxD9tYj4HQGlBezXZMZuM/S5PKLLoZkShZiGk9o5CzukI1LVHZvjdvZ2Sj1aW/Ndn2NB/HQ==", - "dev": true, - "dependencies": { - "inherits": "2.0.3" - } - }, - "node_modules/util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", - "dev": true - }, - "node_modules/util.promisify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/util.promisify/-/util.promisify-1.0.1.tgz", - "integrity": "sha512-g9JpC/3He3bm38zsLupWryXHoEcS22YHthuPQSJdMy6KNrzIRzWqcsHzD/WUnqe45whVou4VIsPew37DoXWNrA==", - "dev": true, - "dependencies": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.2", - "has-symbols": "^1.0.1", - "object.getownpropertydescriptors": "^2.1.0" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/util/node_modules/inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", - "dev": true - }, - "node_modules/utila": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/utila/-/utila-0.4.0.tgz", - "integrity": "sha1-ihagXURWV6Oupe7MWxKk+lN5dyw=", - "dev": true - }, - "node_modules/utils-merge": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", - "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=", - "dev": true, - "engines": { - "node": ">= 0.4.0" - } - }, - "node_modules/uuid": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", - "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", - "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.", - "dev": true, - "bin": { - "uuid": "bin/uuid" - } - }, - "node_modules/vary": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", - "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=", - "dev": true, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/vendors": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/vendors/-/vendors-1.0.4.tgz", - "integrity": "sha512-/juG65kTL4Cy2su4P8HjtkTxk6VmJDiOPBufWniqQ6wknac6jNiXS9vU+hO3wgusiyqWlzTbVHi0dyJqRONg3w==", - "dev": true, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/verror": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", - "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", - "dev": true, - "engines": [ - "node >=0.6.0" - ], - "dependencies": { - "assert-plus": "^1.0.0", - "core-util-is": "1.0.2", - "extsprintf": "^1.2.0" - } - }, - "node_modules/vm-browserify": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-1.1.2.tgz", - "integrity": "sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==", - "dev": true - }, - "node_modules/vue": { - "version": "2.6.11", - "resolved": "https://registry.npmjs.org/vue/-/vue-2.6.11.tgz", - "integrity": "sha512-VfPwgcGABbGAue9+sfrD4PuwFar7gPb1yl1UK1MwXoQPAw0BKSqWfoYCT/ThFrdEVWoI51dBuyCoiNU9bZDZxQ==", - "dev": true - }, - "node_modules/vue-hot-reload-api": { - "version": "2.3.4", - "resolved": "https://registry.npmjs.org/vue-hot-reload-api/-/vue-hot-reload-api-2.3.4.tgz", - "integrity": "sha512-BXq3jwIagosjgNVae6tkHzzIk6a8MHFtzAdwhnV5VlvPTFxDCvIttgSiHWjdGoTJvXtmRu5HacExfdarRcFhog==", - "dev": true - }, - "node_modules/vue-loader": { - "version": "15.9.2", - "resolved": "https://registry.npmjs.org/vue-loader/-/vue-loader-15.9.2.tgz", - "integrity": "sha512-oXBubaY//CYEISBlHX+c2YPJbmOH68xXPXjFv4MAgPqQvUsnjrBAjCJi8HXZ/r/yfn0tPL5VZj1Zcp8mJPI8VA==", - "dev": true, - "dependencies": { - "@vue/component-compiler-utils": "^3.1.0", - "hash-sum": "^1.0.2", - "loader-utils": "^1.1.0", - "vue-hot-reload-api": "^2.3.0", - "vue-style-loader": "^4.1.0" - }, - "peerDependencies": { - "css-loader": "*", - "webpack": "^3.0.0 || ^4.1.0 || ^5.0.0-0" - }, - "peerDependenciesMeta": { - "cache-loader": { - "optional": true - }, - "vue-template-compiler": { - "optional": true - } - } - }, - "node_modules/vue-router": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/vue-router/-/vue-router-3.3.2.tgz", - "integrity": "sha512-5sEbcfb7MW8mY8lbUVbF4kgcipGXsagkM/X+pb6n0MhjP+RorWIUTPAPSqgPaiPOxVCXgAItBl8Vwz8vq78faA==", - "dev": true - }, - "node_modules/vue-server-renderer": { - "version": "2.6.11", - "resolved": "https://registry.npmjs.org/vue-server-renderer/-/vue-server-renderer-2.6.11.tgz", - "integrity": "sha512-V3faFJHr2KYfdSIalL+JjinZSHYUhlrvJ9pzCIjjwSh77+pkrsXpK4PucdPcng57+N77pd1LrKqwbqjQdktU1A==", - "dev": true, - "dependencies": { - "chalk": "^1.1.3", - "hash-sum": "^1.0.2", - "he": "^1.1.0", - "lodash.template": "^4.5.0", - "lodash.uniq": "^4.5.0", - "resolve": "^1.2.0", - "serialize-javascript": "^2.1.2", - "source-map": "0.5.6" - } - }, - "node_modules/vue-server-renderer/node_modules/ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/vue-server-renderer/node_modules/ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/vue-server-renderer/node_modules/chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "dev": true, - "dependencies": { - "ansi-styles": "^2.2.1", - "escape-string-regexp": "^1.0.2", - "has-ansi": "^2.0.0", - "strip-ansi": "^3.0.0", - "supports-color": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/vue-server-renderer/node_modules/source-map": { - "version": "0.5.6", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.6.tgz", - "integrity": "sha1-dc449SvwczxafwwRjYEzSiu19BI=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/vue-server-renderer/node_modules/strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dev": true, - "dependencies": { - "ansi-regex": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/vue-server-renderer/node_modules/supports-color": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", - "dev": true, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/vue-style-loader": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/vue-style-loader/-/vue-style-loader-4.1.2.tgz", - "integrity": "sha512-0ip8ge6Gzz/Bk0iHovU9XAUQaFt/G2B61bnWa2tCcqqdgfHs1lF9xXorFbE55Gmy92okFT+8bfmySuUOu13vxQ==", - "dev": true, - "dependencies": { - "hash-sum": "^1.0.2", - "loader-utils": "^1.0.2" - } - }, - "node_modules/vue-template-compiler": { - "version": "2.6.11", - "resolved": "https://registry.npmjs.org/vue-template-compiler/-/vue-template-compiler-2.6.11.tgz", - "integrity": "sha512-KIq15bvQDrcCjpGjrAhx4mUlyyHfdmTaoNfeoATHLAiWB+MU3cx4lOzMwrnUh9cCxy0Lt1T11hAFY6TQgroUAA==", - "dev": true, - "dependencies": { - "de-indent": "^1.0.2", - "he": "^1.1.0" - } - }, - "node_modules/vue-template-es2015-compiler": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/vue-template-es2015-compiler/-/vue-template-es2015-compiler-1.9.1.tgz", - "integrity": "sha512-4gDntzrifFnCEvyoO8PqyJDmguXgVPxKiIxrBKjIowvL9l+N66196+72XVYR8BBf1Uv1Fgt3bGevJ+sEmxfZzw==", - "dev": true - }, - "node_modules/vuepress": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/vuepress/-/vuepress-1.5.1.tgz", - "integrity": "sha512-UB5YHwcS1t0XVPfMN4pcKanH2Wb9XvhRNJMGt4O9wiUauwlgC6cwnwhatR3AmsbiwybQYgiOSj+CJKuhjYgAeQ==", - "dev": true, - "hasInstallScript": true, - "dependencies": { - "@vuepress/core": "1.5.1", - "@vuepress/theme-default": "1.5.1", - "cac": "^6.5.6", - "envinfo": "^7.2.0", - "opencollective-postinstall": "^2.0.2", - "update-notifier": "^4.0.0" - }, - "bin": { - "vuepress": "cli.js" - }, - "engines": { - "node": ">=8.6" - } - }, - "node_modules/vuepress-html-webpack-plugin": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/vuepress-html-webpack-plugin/-/vuepress-html-webpack-plugin-3.2.0.tgz", - "integrity": "sha512-BebAEl1BmWlro3+VyDhIOCY6Gef2MCBllEVAP3NUAtMguiyOwo/dClbwJ167WYmcxHJKLl7b0Chr9H7fpn1d0A==", - "dev": true, - "dependencies": { - "html-minifier": "^3.2.3", - "loader-utils": "^0.2.16", - "lodash": "^4.17.3", - "pretty-error": "^2.0.2", - "tapable": "^1.0.0", - "toposort": "^1.0.0", - "util.promisify": "1.0.0" - }, - "engines": { - "node": ">=6.9" - }, - "peerDependencies": { - "webpack": "^1.0.0 || ^2.0.0 || ^3.0.0 || ^4.0.0" - } - }, - "node_modules/vuepress-html-webpack-plugin/node_modules/big.js": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/big.js/-/big.js-3.2.0.tgz", - "integrity": "sha512-+hN/Zh2D08Mx65pZ/4g5bsmNiZUuChDiQfTUQ7qJr4/kuopCr88xZsAXv6mBoZEsUI4OuGHlX59qE94K2mMW8Q==", - "dev": true, - "engines": { - "node": "*" - } - }, - "node_modules/vuepress-html-webpack-plugin/node_modules/emojis-list": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-2.1.0.tgz", - "integrity": "sha1-TapNnbAPmBmIDHn6RXrlsJof04k=", - "dev": true, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/vuepress-html-webpack-plugin/node_modules/json5": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-0.5.1.tgz", - "integrity": "sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE=", - "dev": true, - "bin": { - "json5": "lib/cli.js" - } - }, - "node_modules/vuepress-html-webpack-plugin/node_modules/loader-utils": { - "version": "0.2.17", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-0.2.17.tgz", - "integrity": "sha1-+G5jdNQyBabmxg6RlvF8Apm/s0g=", - "dev": true, - "dependencies": { - "big.js": "^3.1.3", - "emojis-list": "^2.0.0", - "json5": "^0.5.0", - "object-assign": "^4.0.1" - } - }, - "node_modules/vuepress-html-webpack-plugin/node_modules/util.promisify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/util.promisify/-/util.promisify-1.0.0.tgz", - "integrity": "sha512-i+6qA2MPhvoKLuxnJNpXAGhg7HphQOSUq2LKMZD0m15EiskXUkMvKdF4Uui0WYeCUGea+o2cw/ZuwehtfsrNkA==", - "dev": true, - "dependencies": { - "define-properties": "^1.1.2", - "object.getownpropertydescriptors": "^2.0.3" - } - }, - "node_modules/vuepress-plugin-container": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/vuepress-plugin-container/-/vuepress-plugin-container-2.1.4.tgz", - "integrity": "sha512-l+EkeL+rC6DJch1wAZUFIkNDaz2TNOg4NQTHa3yMAsYkC+QaSRubGdN6YwOSmfjxVmM9s9D3gwBWw0O7OBhqRg==", - "dev": true, - "dependencies": { - "markdown-it-container": "^2.0.0" - } - }, - "node_modules/vuepress-plugin-smooth-scroll": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/vuepress-plugin-smooth-scroll/-/vuepress-plugin-smooth-scroll-0.0.3.tgz", - "integrity": "sha512-qsQkDftLVFLe8BiviIHaLV0Ea38YLZKKonDGsNQy1IE0wllFpFIEldWD8frWZtDFdx6b/O3KDMgVQ0qp5NjJCg==", - "dev": true, - "dependencies": { - "smoothscroll-polyfill": "^0.4.3" - } - }, - "node_modules/watchpack": { - "version": "1.7.2", - "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.7.2.tgz", - "integrity": "sha512-ymVbbQP40MFTp+cNMvpyBpBtygHnPzPkHqoIwRRj/0B8KhqQwV8LaKjtbaxF2lK4vl8zN9wCxS46IFCU5K4W0g==", - "dev": true, - "dependencies": { - "graceful-fs": "^4.1.2", - "neo-async": "^2.5.0" - }, - "optionalDependencies": { - "chokidar": "^3.4.0", - "watchpack-chokidar2": "^2.0.0" - } - }, - "node_modules/watchpack-chokidar2": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/watchpack-chokidar2/-/watchpack-chokidar2-2.0.0.tgz", - "integrity": "sha512-9TyfOyN/zLUbA288wZ8IsMZ+6cbzvsNyEzSBp6e/zkifi6xxbl8SmQ/CxQq32k8NNqrdVEVUVSEf56L4rQ/ZxA==", - "dev": true, - "optional": true, - "dependencies": { - "chokidar": "^2.1.8" - }, - "engines": { - "node": "<8.10.0" - } - }, - "node_modules/watchpack/node_modules/anymatch": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz", - "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==", - "dev": true, - "optional": true, - "dependencies": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/watchpack/node_modules/binary-extensions": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.0.0.tgz", - "integrity": "sha512-Phlt0plgpIIBOGTT/ehfFnbNlfsDEiqmzE2KRXoX1bLIlir4X/MR+zSyBEkL05ffWgnRSf/DXv+WrUAVr93/ow==", - "dev": true, - "optional": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/watchpack/node_modules/braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "dev": true, - "optional": true, - "dependencies": { - "fill-range": "^7.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/watchpack/node_modules/chokidar": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.4.0.tgz", - "integrity": "sha512-aXAaho2VJtisB/1fg1+3nlLJqGOuewTzQpd/Tz0yTg2R0e4IGtshYvtjowyEumcBv2z+y4+kc75Mz7j5xJskcQ==", - "dev": true, - "optional": true, - "dependencies": { - "anymatch": "~3.1.1", - "braces": "~3.0.2", - "glob-parent": "~5.1.0", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.4.0" - }, - "engines": { - "node": ">= 8.10.0" - }, - "optionalDependencies": { - "fsevents": "~2.1.2" - } - }, - "node_modules/watchpack/node_modules/fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "dev": true, - "optional": true, - "dependencies": { - "to-regex-range": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/watchpack/node_modules/fsevents": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz", - "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==", - "deprecated": "\"Please update to latest v2.3 or v2.2\"", - "dev": true, - "hasInstallScript": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" - } - }, - "node_modules/watchpack/node_modules/glob-parent": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz", - "integrity": "sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==", - "dev": true, - "optional": true, - "dependencies": { - "is-glob": "^4.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/watchpack/node_modules/is-binary-path": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", - "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "dev": true, - "optional": true, - "dependencies": { - "binary-extensions": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/watchpack/node_modules/is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true, - "optional": true, - "engines": { - "node": ">=0.12.0" - } - }, - "node_modules/watchpack/node_modules/readdirp": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.4.0.tgz", - "integrity": "sha512-0xe001vZBnJEK+uKcj8qOhyAKPzIT+gStxWr3LCB0DwcXR5NZJ3IaC+yGnHCYzB/S7ov3m3EEbZI2zeNvX+hGQ==", - "dev": true, - "optional": true, - "dependencies": { - "picomatch": "^2.2.1" - }, - "engines": { - "node": ">=8.10.0" - } - }, - "node_modules/watchpack/node_modules/to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, - "optional": true, - "dependencies": { - "is-number": "^7.0.0" - }, - "engines": { - "node": ">=8.0" - } - }, - "node_modules/wbuf": { - "version": "1.7.3", - "resolved": "https://registry.npmjs.org/wbuf/-/wbuf-1.7.3.tgz", - "integrity": "sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA==", - "dev": true, - "dependencies": { - "minimalistic-assert": "^1.0.0" - } - }, - "node_modules/webpack": { - "version": "4.43.0", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-4.43.0.tgz", - "integrity": "sha512-GW1LjnPipFW2Y78OOab8NJlCflB7EFskMih2AHdvjbpKMeDJqEgSx24cXXXiPS65+WSwVyxtDsJH6jGX2czy+g==", - "dev": true, - "dependencies": { - "@webassemblyjs/ast": "1.9.0", - "@webassemblyjs/helper-module-context": "1.9.0", - "@webassemblyjs/wasm-edit": "1.9.0", - "@webassemblyjs/wasm-parser": "1.9.0", - "acorn": "^6.4.1", - "ajv": "^6.10.2", - "ajv-keywords": "^3.4.1", - "chrome-trace-event": "^1.0.2", - "enhanced-resolve": "^4.1.0", - "eslint-scope": "^4.0.3", - "json-parse-better-errors": "^1.0.2", - "loader-runner": "^2.4.0", - "loader-utils": "^1.2.3", - "memory-fs": "^0.4.1", - "micromatch": "^3.1.10", - "mkdirp": "^0.5.3", - "neo-async": "^2.6.1", - "node-libs-browser": "^2.2.1", - "schema-utils": "^1.0.0", - "tapable": "^1.1.3", - "terser-webpack-plugin": "^1.4.3", - "watchpack": "^1.6.1", - "webpack-sources": "^1.4.1" - }, - "bin": { - "webpack": "bin/webpack.js" - }, - "engines": { - "node": ">=6.11.5" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - } - }, - "node_modules/webpack-chain": { - "version": "6.4.0", - "resolved": "https://registry.npmjs.org/webpack-chain/-/webpack-chain-6.4.0.tgz", - "integrity": "sha512-f97PYqxU+9/u0IUqp/ekAHRhBD1IQwhBv3wlJo2nvyELpr2vNnUqO3XQEk+qneg0uWGP54iciotszpjfnEExFA==", - "dev": true, - "dependencies": { - "deepmerge": "^1.5.2", - "javascript-stringify": "^2.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/webpack-dev-middleware": { - "version": "3.7.2", - "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-3.7.2.tgz", - "integrity": "sha512-1xC42LxbYoqLNAhV6YzTYacicgMZQTqRd27Sim9wn5hJrX3I5nxYy1SxSd4+gjUFsz1dQFj+yEe6zEVmSkeJjw==", - "dev": true, - "dependencies": { - "memory-fs": "^0.4.1", - "mime": "^2.4.4", - "mkdirp": "^0.5.1", - "range-parser": "^1.2.1", - "webpack-log": "^2.0.0" - }, - "engines": { - "node": ">= 6" - }, - "peerDependencies": { - "webpack": "^4.0.0" - } - }, - "node_modules/webpack-dev-server": { - "version": "3.11.0", - "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-3.11.0.tgz", - "integrity": "sha512-PUxZ+oSTxogFQgkTtFndEtJIPNmml7ExwufBZ9L2/Xyyd5PnOL5UreWe5ZT7IU25DSdykL9p1MLQzmLh2ljSeg==", - "dev": true, - "dependencies": { - "ansi-html": "0.0.7", - "bonjour": "^3.5.0", - "chokidar": "^2.1.8", - "compression": "^1.7.4", - "connect-history-api-fallback": "^1.6.0", - "debug": "^4.1.1", - "del": "^4.1.1", - "express": "^4.17.1", - "html-entities": "^1.3.1", - "http-proxy-middleware": "0.19.1", - "import-local": "^2.0.0", - "internal-ip": "^4.3.0", - "ip": "^1.1.5", - "is-absolute-url": "^3.0.3", - "killable": "^1.0.1", - "loglevel": "^1.6.8", - "opn": "^5.5.0", - "p-retry": "^3.0.1", - "portfinder": "^1.0.26", - "schema-utils": "^1.0.0", - "selfsigned": "^1.10.7", - "semver": "^6.3.0", - "serve-index": "^1.9.1", - "sockjs": "0.3.20", - "sockjs-client": "1.4.0", - "spdy": "^4.0.2", - "strip-ansi": "^3.0.1", - "supports-color": "^6.1.0", - "url": "^0.11.0", - "webpack-dev-middleware": "^3.7.2", - "webpack-log": "^2.0.0", - "ws": "^6.2.1", - "yargs": "^13.3.2" - }, - "bin": { - "webpack-dev-server": "bin/webpack-dev-server.js" - }, - "engines": { - "node": ">= 6.11.5" - }, - "peerDependencies": { - "webpack": "^4.0.0 || ^5.0.0" - }, - "peerDependenciesMeta": { - "webpack-cli": { - "optional": true - } - } - }, - "node_modules/webpack-dev-server/node_modules/ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/webpack-dev-server/node_modules/is-absolute-url": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/is-absolute-url/-/is-absolute-url-3.0.3.tgz", - "integrity": "sha512-opmNIX7uFnS96NtPmhWQgQx6/NYFgsUXYMllcfzwWKUMwfo8kku1TvE6hkNcH+Q1ts5cMVrsY7j0bxXQDciu9Q==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/webpack-dev-server/node_modules/schema-utils": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", - "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", - "dev": true, - "dependencies": { - "ajv": "^6.1.0", - "ajv-errors": "^1.0.0", - "ajv-keywords": "^3.1.0" - }, - "engines": { - "node": ">= 4" - } - }, - "node_modules/webpack-dev-server/node_modules/semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true, - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/webpack-dev-server/node_modules/strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dev": true, - "dependencies": { - "ansi-regex": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/webpack-dev-server/node_modules/supports-color": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", - "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", - "dev": true, - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/webpack-log": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/webpack-log/-/webpack-log-2.0.0.tgz", - "integrity": "sha512-cX8G2vR/85UYG59FgkoMamwHUIkSSlV3bBMRsbxVXVUk2j6NleCKjQ/WE9eYg9WY4w25O9w8wKP4rzNZFmUcUg==", - "dev": true, - "dependencies": { - "ansi-colors": "^3.0.0", - "uuid": "^3.3.2" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/webpack-merge": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-4.2.2.tgz", - "integrity": "sha512-TUE1UGoTX2Cd42j3krGYqObZbOD+xF7u28WB7tfUordytSjbWTIjK/8V0amkBfTYN4/pB/GIDlJZZ657BGG19g==", - "dev": true, - "dependencies": { - "lodash": "^4.17.15" - } - }, - "node_modules/webpack-sources": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.4.3.tgz", - "integrity": "sha512-lgTS3Xhv1lCOKo7SA5TjKXMjpSM4sBjNV5+q2bqesbSPs5FjGmU6jjtBSkX9b4qW87vDIsCIlUPOEhbZrMdjeQ==", - "dev": true, - "dependencies": { - "source-list-map": "^2.0.0", - "source-map": "~0.6.1" - } - }, - "node_modules/webpack-sources/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/webpack/node_modules/schema-utils": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", - "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", - "dev": true, - "dependencies": { - "ajv": "^6.1.0", - "ajv-errors": "^1.0.0", - "ajv-keywords": "^3.1.0" - }, - "engines": { - "node": ">= 4" - } - }, - "node_modules/webpackbar": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/webpackbar/-/webpackbar-3.2.0.tgz", - "integrity": "sha512-PC4o+1c8gWWileUfwabe0gqptlXUDJd5E0zbpr2xHP1VSOVlZVPBZ8j6NCR8zM5zbKdxPhctHXahgpNK1qFDPw==", - "dev": true, - "dependencies": { - "ansi-escapes": "^4.1.0", - "chalk": "^2.4.1", - "consola": "^2.6.0", - "figures": "^3.0.0", - "pretty-time": "^1.1.0", - "std-env": "^2.2.1", - "text-table": "^0.2.0", - "wrap-ansi": "^5.1.0" - }, - "engines": { - "node": ">= 6.9.0" - }, - "peerDependencies": { - "webpack": "^3.0.0 || ^4.0.0" - } - }, - "node_modules/websocket-driver": { - "version": "0.6.5", - "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.6.5.tgz", - "integrity": "sha1-XLJVbOuF9Dc8bYI4qmkchFThOjY=", - "dev": true, - "dependencies": { - "websocket-extensions": ">=0.1.1" - }, - "engines": { - "node": ">=0.6.0" - } - }, - "node_modules/websocket-extensions": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.4.tgz", - "integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==", - "dev": true, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/when": { - "version": "3.6.4", - "resolved": "https://registry.npmjs.org/when/-/when-3.6.4.tgz", - "integrity": "sha1-RztRfsFZ4rhQBUl6E5g/CVQS404=", - "dev": true - }, - "node_modules/which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dev": true, - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "which": "bin/which" - } - }, - "node_modules/which-module": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", - "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", - "dev": true - }, - "node_modules/widest-line": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-3.1.0.tgz", - "integrity": "sha512-NsmoXalsWVDMGupxZ5R08ka9flZjjiLvHVAWYOKtiKM8ujtZWr9cRffak+uSE48+Ob8ObalXpwyeUiyDD6QFgg==", - "dev": true, - "dependencies": { - "string-width": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/worker-farm": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/worker-farm/-/worker-farm-1.7.0.tgz", - "integrity": "sha512-rvw3QTZc8lAxyVrqcSGVm5yP/IJ2UcB3U0graE3LCFoZ0Yn2x4EoVSqJKdB/T5M+FLcRPjz4TDacRf3OCfNUzw==", - "dev": true, - "dependencies": { - "errno": "~0.1.7" - } - }, - "node_modules/wrap-ansi": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", - "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", - "dev": true, - "dependencies": { - "ansi-styles": "^3.2.0", - "string-width": "^3.0.0", - "strip-ansi": "^5.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/wrap-ansi/node_modules/ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/wrap-ansi/node_modules/emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", - "dev": true - }, - "node_modules/wrap-ansi/node_modules/is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/wrap-ansi/node_modules/string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, - "dependencies": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/wrap-ansi/node_modules/strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "dependencies": { - "ansi-regex": "^4.1.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", - "dev": true - }, - "node_modules/write-file-atomic": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", - "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", - "dev": true, - "dependencies": { - "imurmurhash": "^0.1.4", - "is-typedarray": "^1.0.0", - "signal-exit": "^3.0.2", - "typedarray-to-buffer": "^3.1.5" - } - }, - "node_modules/ws": { - "version": "6.2.2", - "resolved": "https://registry.npmjs.org/ws/-/ws-6.2.2.tgz", - "integrity": "sha512-zmhltoSR8u1cnDsD43TX59mzoMZsLKqUweyYBAIvTngR3shc0W6aOZylZmq/7hqyVxPdi+5Ud2QInblgyE72fw==", - "dev": true, - "dependencies": { - "async-limiter": "~1.0.0" - } - }, - "node_modules/xdg-basedir": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-4.0.0.tgz", - "integrity": "sha512-PSNhEJDejZYV7h50BohL09Er9VaIefr2LMAf3OEmpCkjOi34eYyQYAXUTjEQtZJTKcF0E2UKTh+osDLsgNim9Q==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/xtend": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", - "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", - "dev": true, - "engines": { - "node": ">=0.4" - } - }, - "node_modules/y18n": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.1.tgz", - "integrity": "sha512-wNcy4NvjMYL8gogWWYAO7ZFWFfHcbdbE57tZO8e4cbpj8tfUcwrwqSl3ad8HxpYWCdXcJUCeKKZS62Av1affwQ==", - "dev": true - }, - "node_modules/yallist": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", - "dev": true - }, - "node_modules/yargs": { - "version": "13.3.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", - "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", - "dev": true, - "dependencies": { - "cliui": "^5.0.0", - "find-up": "^3.0.0", - "get-caller-file": "^2.0.1", - "require-directory": "^2.1.1", - "require-main-filename": "^2.0.0", - "set-blocking": "^2.0.0", - "string-width": "^3.0.0", - "which-module": "^2.0.0", - "y18n": "^4.0.0", - "yargs-parser": "^13.1.2" - } - }, - "node_modules/yargs-parser": { - "version": "13.1.2", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", - "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", - "dev": true, - "dependencies": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - } - }, - "node_modules/yargs/node_modules/ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/yargs/node_modules/emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", - "dev": true - }, - "node_modules/yargs/node_modules/is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/yargs/node_modules/string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, - "dependencies": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/yargs/node_modules/strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "dependencies": { - "ansi-regex": "^4.1.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/zepto": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/zepto/-/zepto-1.2.0.tgz", - "integrity": "sha1-4Se9nmb9hGvl6rSME5SIL3wOT5g=", - "dev": true - } - }, - "dependencies": { - "@babel/code-frame": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.1.tgz", - "integrity": "sha512-IGhtTmpjGbYzcEDOw7DcQtbQSXcG9ftmAXtWTu9V936vDye4xjjekktFAtgZsWpzTj/X01jocB46mTywm/4SZw==", - "dev": true, - "requires": { - "@babel/highlight": "^7.10.1" - } - }, - "@babel/compat-data": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.10.1.tgz", - "integrity": "sha512-CHvCj7So7iCkGKPRFUfryXIkU2gSBw7VSZFYLsqVhrS47269VK2Hfi9S/YcublPMW8k1u2bQBlbDruoQEm4fgw==", - "dev": true, - "requires": { - "browserslist": "^4.12.0", - "invariant": "^2.2.4", - "semver": "^5.5.0" - } - }, - "@babel/core": { - "version": "7.10.2", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.10.2.tgz", - "integrity": "sha512-KQmV9yguEjQsXqyOUGKjS4+3K8/DlOCE2pZcq4augdQmtTy5iv5EHtmMSJ7V4c1BIPjuwtZYqYLCq9Ga+hGBRQ==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.10.1", - "@babel/generator": "^7.10.2", - "@babel/helper-module-transforms": "^7.10.1", - "@babel/helpers": "^7.10.1", - "@babel/parser": "^7.10.2", - "@babel/template": "^7.10.1", - "@babel/traverse": "^7.10.1", - "@babel/types": "^7.10.2", - "convert-source-map": "^1.7.0", - "debug": "^4.1.0", - "gensync": "^1.0.0-beta.1", - "json5": "^2.1.2", - "lodash": "^4.17.13", - "resolve": "^1.3.2", - "semver": "^5.4.1", - "source-map": "^0.5.0" - } - }, - "@babel/generator": { - "version": "7.10.2", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.10.2.tgz", - "integrity": "sha512-AxfBNHNu99DTMvlUPlt1h2+Hn7knPpH5ayJ8OqDWSeLld+Fi2AYBTC/IejWDM9Edcii4UzZRCsbUt0WlSDsDsA==", - "dev": true, - "requires": { - "@babel/types": "^7.10.2", - "jsesc": "^2.5.1", - "lodash": "^4.17.13", - "source-map": "^0.5.0" - } - }, - "@babel/helper-annotate-as-pure": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.10.1.tgz", - "integrity": "sha512-ewp3rvJEwLaHgyWGe4wQssC2vjks3E80WiUe2BpMb0KhreTjMROCbxXcEovTrbeGVdQct5VjQfrv9EgC+xMzCw==", - "dev": true, - "requires": { - "@babel/types": "^7.10.1" - } - }, - "@babel/helper-builder-binary-assignment-operator-visitor": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.10.1.tgz", - "integrity": "sha512-cQpVq48EkYxUU0xozpGCLla3wlkdRRqLWu1ksFMXA9CM5KQmyyRpSEsYXbao7JUkOw/tAaYKCaYyZq6HOFYtyw==", - "dev": true, - "requires": { - "@babel/helper-explode-assignable-expression": "^7.10.1", - "@babel/types": "^7.10.1" - } - }, - "@babel/helper-compilation-targets": { - "version": "7.10.2", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.10.2.tgz", - "integrity": "sha512-hYgOhF4To2UTB4LTaZepN/4Pl9LD4gfbJx8A34mqoluT8TLbof1mhUlYuNWTEebONa8+UlCC4X0TEXu7AOUyGA==", - "dev": true, - "requires": { - "@babel/compat-data": "^7.10.1", - "browserslist": "^4.12.0", - "invariant": "^2.2.4", - "levenary": "^1.1.1", - "semver": "^5.5.0" - } - }, - "@babel/helper-create-class-features-plugin": { - "version": "7.10.2", - "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.10.2.tgz", - "integrity": "sha512-5C/QhkGFh1vqcziq1vAL6SI9ymzUp8BCYjFpvYVhWP4DlATIb3u5q3iUd35mvlyGs8fO7hckkW7i0tmH+5+bvQ==", - "dev": true, - "requires": { - "@babel/helper-function-name": "^7.10.1", - "@babel/helper-member-expression-to-functions": "^7.10.1", - "@babel/helper-optimise-call-expression": "^7.10.1", - "@babel/helper-plugin-utils": "^7.10.1", - "@babel/helper-replace-supers": "^7.10.1", - "@babel/helper-split-export-declaration": "^7.10.1" - } - }, - "@babel/helper-create-regexp-features-plugin": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.10.1.tgz", - "integrity": "sha512-Rx4rHS0pVuJn5pJOqaqcZR4XSgeF9G/pO/79t+4r7380tXFJdzImFnxMU19f83wjSrmKHq6myrM10pFHTGzkUA==", - "dev": true, - "requires": { - "@babel/helper-annotate-as-pure": "^7.10.1", - "@babel/helper-regex": "^7.10.1", - "regexpu-core": "^4.7.0" - } - }, - "@babel/helper-define-map": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/helper-define-map/-/helper-define-map-7.10.1.tgz", - "integrity": "sha512-+5odWpX+OnvkD0Zmq7panrMuAGQBu6aPUgvMzuMGo4R+jUOvealEj2hiqI6WhxgKrTpFoFj0+VdsuA8KDxHBDg==", - "dev": true, - "requires": { - "@babel/helper-function-name": "^7.10.1", - "@babel/types": "^7.10.1", - "lodash": "^4.17.13" - } - }, - "@babel/helper-explode-assignable-expression": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.10.1.tgz", - "integrity": "sha512-vcUJ3cDjLjvkKzt6rHrl767FeE7pMEYfPanq5L16GRtrXIoznc0HykNW2aEYkcnP76P0isoqJ34dDMFZwzEpJg==", - "dev": true, - "requires": { - "@babel/traverse": "^7.10.1", - "@babel/types": "^7.10.1" - } - }, - "@babel/helper-function-name": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.10.1.tgz", - "integrity": "sha512-fcpumwhs3YyZ/ttd5Rz0xn0TpIwVkN7X0V38B9TWNfVF42KEkhkAAuPCQ3oXmtTRtiPJrmZ0TrfS0GKF0eMaRQ==", - "dev": true, - "requires": { - "@babel/helper-get-function-arity": "^7.10.1", - "@babel/template": "^7.10.1", - "@babel/types": "^7.10.1" - } - }, - "@babel/helper-get-function-arity": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.10.1.tgz", - "integrity": "sha512-F5qdXkYGOQUb0hpRaPoetF9AnsXknKjWMZ+wmsIRsp5ge5sFh4c3h1eH2pRTTuy9KKAA2+TTYomGXAtEL2fQEw==", - "dev": true, - "requires": { - "@babel/types": "^7.10.1" - } - }, - "@babel/helper-hoist-variables": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.10.1.tgz", - "integrity": "sha512-vLm5srkU8rI6X3+aQ1rQJyfjvCBLXP8cAGeuw04zeAM2ItKb1e7pmVmLyHb4sDaAYnLL13RHOZPLEtcGZ5xvjg==", - "dev": true, - "requires": { - "@babel/types": "^7.10.1" - } - }, - "@babel/helper-member-expression-to-functions": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.10.1.tgz", - "integrity": "sha512-u7XLXeM2n50gb6PWJ9hoO5oO7JFPaZtrh35t8RqKLT1jFKj9IWeD1zrcrYp1q1qiZTdEarfDWfTIP8nGsu0h5g==", - "dev": true, - "requires": { - "@babel/types": "^7.10.1" - } - }, - "@babel/helper-module-imports": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.10.1.tgz", - "integrity": "sha512-SFxgwYmZ3HZPyZwJRiVNLRHWuW2OgE5k2nrVs6D9Iv4PPnXVffuEHy83Sfx/l4SqF+5kyJXjAyUmrG7tNm+qVg==", - "dev": true, - "requires": { - "@babel/types": "^7.10.1" - } - }, - "@babel/helper-module-transforms": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.10.1.tgz", - "integrity": "sha512-RLHRCAzyJe7Q7sF4oy2cB+kRnU4wDZY/H2xJFGof+M+SJEGhZsb+GFj5j1AD8NiSaVBJ+Pf0/WObiXu/zxWpFg==", - "dev": true, - "requires": { - "@babel/helper-module-imports": "^7.10.1", - "@babel/helper-replace-supers": "^7.10.1", - "@babel/helper-simple-access": "^7.10.1", - "@babel/helper-split-export-declaration": "^7.10.1", - "@babel/template": "^7.10.1", - "@babel/types": "^7.10.1", - "lodash": "^4.17.13" - } - }, - "@babel/helper-optimise-call-expression": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.10.1.tgz", - "integrity": "sha512-a0DjNS1prnBsoKx83dP2falChcs7p3i8VMzdrSbfLhuQra/2ENC4sbri34dz/rWmDADsmF1q5GbfaXydh0Jbjg==", - "dev": true, - "requires": { - "@babel/types": "^7.10.1" - } - }, - "@babel/helper-plugin-utils": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.1.tgz", - "integrity": "sha512-fvoGeXt0bJc7VMWZGCAEBEMo/HAjW2mP8apF5eXK0wSqwLAVHAISCWRoLMBMUs2kqeaG77jltVqu4Hn8Egl3nA==", - "dev": true - }, - "@babel/helper-regex": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/helper-regex/-/helper-regex-7.10.1.tgz", - "integrity": "sha512-7isHr19RsIJWWLLFn21ubFt223PjQyg1HY7CZEMRr820HttHPpVvrsIN3bUOo44DEfFV4kBXO7Abbn9KTUZV7g==", - "dev": true, - "requires": { - "lodash": "^4.17.13" - } - }, - "@babel/helper-remap-async-to-generator": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.10.1.tgz", - "integrity": "sha512-RfX1P8HqsfgmJ6CwaXGKMAqbYdlleqglvVtht0HGPMSsy2V6MqLlOJVF/0Qyb/m2ZCi2z3q3+s6Pv7R/dQuZ6A==", - "dev": true, - "requires": { - "@babel/helper-annotate-as-pure": "^7.10.1", - "@babel/helper-wrap-function": "^7.10.1", - "@babel/template": "^7.10.1", - "@babel/traverse": "^7.10.1", - "@babel/types": "^7.10.1" - } - }, - "@babel/helper-replace-supers": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.10.1.tgz", - "integrity": "sha512-SOwJzEfpuQwInzzQJGjGaiG578UYmyi2Xw668klPWV5n07B73S0a9btjLk/52Mlcxa+5AdIYqws1KyXRfMoB7A==", - "dev": true, - "requires": { - "@babel/helper-member-expression-to-functions": "^7.10.1", - "@babel/helper-optimise-call-expression": "^7.10.1", - "@babel/traverse": "^7.10.1", - "@babel/types": "^7.10.1" - } - }, - "@babel/helper-simple-access": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.10.1.tgz", - "integrity": "sha512-VSWpWzRzn9VtgMJBIWTZ+GP107kZdQ4YplJlCmIrjoLVSi/0upixezHCDG8kpPVTBJpKfxTH01wDhh+jS2zKbw==", - "dev": true, - "requires": { - "@babel/template": "^7.10.1", - "@babel/types": "^7.10.1" - } - }, - "@babel/helper-split-export-declaration": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.10.1.tgz", - "integrity": "sha512-UQ1LVBPrYdbchNhLwj6fetj46BcFwfS4NllJo/1aJsT+1dLTEnXJL0qHqtY7gPzF8S2fXBJamf1biAXV3X077g==", - "dev": true, - "requires": { - "@babel/types": "^7.10.1" - } - }, - "@babel/helper-validator-identifier": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.1.tgz", - "integrity": "sha512-5vW/JXLALhczRCWP0PnFDMCJAchlBvM7f4uk/jXritBnIa6E1KmqmtrS3yn1LAnxFBypQ3eneLuXjsnfQsgILw==", - "dev": true - }, - "@babel/helper-wrap-function": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.10.1.tgz", - "integrity": "sha512-C0MzRGteVDn+H32/ZgbAv5r56f2o1fZSA/rj/TYo8JEJNHg+9BdSmKBUND0shxWRztWhjlT2cvHYuynpPsVJwQ==", - "dev": true, - "requires": { - "@babel/helper-function-name": "^7.10.1", - "@babel/template": "^7.10.1", - "@babel/traverse": "^7.10.1", - "@babel/types": "^7.10.1" - } - }, - "@babel/helpers": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.10.1.tgz", - "integrity": "sha512-muQNHF+IdU6wGgkaJyhhEmI54MOZBKsFfsXFhboz1ybwJ1Kl7IHlbm2a++4jwrmY5UYsgitt5lfqo1wMFcHmyw==", - "dev": true, - "requires": { - "@babel/template": "^7.10.1", - "@babel/traverse": "^7.10.1", - "@babel/types": "^7.10.1" - } - }, - "@babel/highlight": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.1.tgz", - "integrity": "sha512-8rMof+gVP8mxYZApLF/JgNDAkdKa+aJt3ZYxF8z6+j/hpeXL7iMsKCPHa2jNMHu/qqBwzQF4OHNoYi8dMA/rYg==", - "dev": true, - "requires": { - "@babel/helper-validator-identifier": "^7.10.1", - "chalk": "^2.0.0", - "js-tokens": "^4.0.0" - } - }, - "@babel/parser": { - "version": "7.10.2", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.10.2.tgz", - "integrity": "sha512-PApSXlNMJyB4JiGVhCOlzKIif+TKFTvu0aQAhnTvfP/z3vVSN6ZypH5bfUNwFXXjRQtUEBNFd2PtmCmG2Py3qQ==", - "dev": true - }, - "@babel/plugin-proposal-async-generator-functions": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.10.1.tgz", - "integrity": "sha512-vzZE12ZTdB336POZjmpblWfNNRpMSua45EYnRigE2XsZxcXcIyly2ixnTJasJE4Zq3U7t2d8rRF7XRUuzHxbOw==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.10.1", - "@babel/helper-remap-async-to-generator": "^7.10.1", - "@babel/plugin-syntax-async-generators": "^7.8.0" - } - }, - "@babel/plugin-proposal-class-properties": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.10.1.tgz", - "integrity": "sha512-sqdGWgoXlnOdgMXU+9MbhzwFRgxVLeiGBqTrnuS7LC2IBU31wSsESbTUreT2O418obpfPdGUR2GbEufZF1bpqw==", - "dev": true, - "requires": { - "@babel/helper-create-class-features-plugin": "^7.10.1", - "@babel/helper-plugin-utils": "^7.10.1" - } - }, - "@babel/plugin-proposal-decorators": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.10.1.tgz", - "integrity": "sha512-xBfteh352MTke2U1NpclzMDmAmCdQ2fBZjhZQQfGTjXw6qcRYMkt528sA1U8o0ThDCSeuETXIj5bOGdxN+5gkw==", - "dev": true, - "requires": { - "@babel/helper-create-class-features-plugin": "^7.10.1", - "@babel/helper-plugin-utils": "^7.10.1", - "@babel/plugin-syntax-decorators": "^7.10.1" - } - }, - "@babel/plugin-proposal-dynamic-import": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.10.1.tgz", - "integrity": "sha512-Cpc2yUVHTEGPlmiQzXj026kqwjEQAD9I4ZC16uzdbgWgitg/UHKHLffKNCQZ5+y8jpIZPJcKcwsr2HwPh+w3XA==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.10.1", - "@babel/plugin-syntax-dynamic-import": "^7.8.0" - } - }, - "@babel/plugin-proposal-json-strings": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.10.1.tgz", - "integrity": "sha512-m8r5BmV+ZLpWPtMY2mOKN7wre6HIO4gfIiV+eOmsnZABNenrt/kzYBwrh+KOfgumSWpnlGs5F70J8afYMSJMBg==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.10.1", - "@babel/plugin-syntax-json-strings": "^7.8.0" - } - }, - "@babel/plugin-proposal-nullish-coalescing-operator": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.10.1.tgz", - "integrity": "sha512-56cI/uHYgL2C8HVuHOuvVowihhX0sxb3nnfVRzUeVHTWmRHTZrKuAh/OBIMggGU/S1g/1D2CRCXqP+3u7vX7iA==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.10.1", - "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.0" - } - }, - "@babel/plugin-proposal-numeric-separator": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.10.1.tgz", - "integrity": "sha512-jjfym4N9HtCiNfyyLAVD8WqPYeHUrw4ihxuAynWj6zzp2gf9Ey2f7ImhFm6ikB3CLf5Z/zmcJDri6B4+9j9RsA==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.10.1", - "@babel/plugin-syntax-numeric-separator": "^7.10.1" - } - }, - "@babel/plugin-proposal-object-rest-spread": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.10.1.tgz", - "integrity": "sha512-Z+Qri55KiQkHh7Fc4BW6o+QBuTagbOp9txE+4U1i79u9oWlf2npkiDx+Rf3iK3lbcHBuNy9UOkwuR5wOMH3LIQ==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.10.1", - "@babel/plugin-syntax-object-rest-spread": "^7.8.0", - "@babel/plugin-transform-parameters": "^7.10.1" - } - }, - "@babel/plugin-proposal-optional-catch-binding": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.10.1.tgz", - "integrity": "sha512-VqExgeE62YBqI3ogkGoOJp1R6u12DFZjqwJhqtKc2o5m1YTUuUWnos7bZQFBhwkxIFpWYJ7uB75U7VAPPiKETA==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.10.1", - "@babel/plugin-syntax-optional-catch-binding": "^7.8.0" - } - }, - "@babel/plugin-proposal-optional-chaining": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.10.1.tgz", - "integrity": "sha512-dqQj475q8+/avvok72CF3AOSV/SGEcH29zT5hhohqqvvZ2+boQoOr7iGldBG5YXTO2qgCgc2B3WvVLUdbeMlGA==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.10.1", - "@babel/plugin-syntax-optional-chaining": "^7.8.0" - } - }, - "@babel/plugin-proposal-private-methods": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.10.1.tgz", - "integrity": "sha512-RZecFFJjDiQ2z6maFprLgrdnm0OzoC23Mx89xf1CcEsxmHuzuXOdniEuI+S3v7vjQG4F5sa6YtUp+19sZuSxHg==", - "dev": true, - "requires": { - "@babel/helper-create-class-features-plugin": "^7.10.1", - "@babel/helper-plugin-utils": "^7.10.1" - } - }, - "@babel/plugin-proposal-unicode-property-regex": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.10.1.tgz", - "integrity": "sha512-JjfngYRvwmPwmnbRZyNiPFI8zxCZb8euzbCG/LxyKdeTb59tVciKo9GK9bi6JYKInk1H11Dq9j/zRqIH4KigfQ==", - "dev": true, - "requires": { - "@babel/helper-create-regexp-features-plugin": "^7.10.1", - "@babel/helper-plugin-utils": "^7.10.1" - } - }, - "@babel/plugin-syntax-async-generators": { - "version": "7.8.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", - "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-class-properties": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.10.1.tgz", - "integrity": "sha512-Gf2Yx/iRs1JREDtVZ56OrjjgFHCaldpTnuy9BHla10qyVT3YkIIGEtoDWhyop0ksu1GvNjHIoYRBqm3zoR1jyQ==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.10.1" - } - }, - "@babel/plugin-syntax-decorators": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-decorators/-/plugin-syntax-decorators-7.10.1.tgz", - "integrity": "sha512-a9OAbQhKOwSle1Vr0NJu/ISg1sPfdEkfRKWpgPuzhnWWzForou2gIeUIIwjAMHRekhhpJ7eulZlYs0H14Cbi+g==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.10.1" - } - }, - "@babel/plugin-syntax-dynamic-import": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz", - "integrity": "sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-json-strings": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", - "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-jsx": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.10.1.tgz", - "integrity": "sha512-+OxyOArpVFXQeXKLO9o+r2I4dIoVoy6+Uu0vKELrlweDM3QJADZj+Z+5ERansZqIZBcLj42vHnDI8Rz9BnRIuQ==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.10.1" - } - }, - "@babel/plugin-syntax-nullish-coalescing-operator": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", - "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-numeric-separator": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.1.tgz", - "integrity": "sha512-uTd0OsHrpe3tH5gRPTxG8Voh99/WCU78vIm5NMRYPAqC8lR4vajt6KkCAknCHrx24vkPdd/05yfdGSB4EIY2mg==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.10.1" - } - }, - "@babel/plugin-syntax-object-rest-spread": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", - "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-optional-catch-binding": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", - "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-optional-chaining": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", - "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-top-level-await": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.10.1.tgz", - "integrity": "sha512-hgA5RYkmZm8FTFT3yu2N9Bx7yVVOKYT6yEdXXo6j2JTm0wNxgqaGeQVaSHRjhfnQbX91DtjFB6McRFSlcJH3xQ==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.10.1" - } - }, - "@babel/plugin-transform-arrow-functions": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.10.1.tgz", - "integrity": "sha512-6AZHgFJKP3DJX0eCNJj01RpytUa3SOGawIxweHkNX2L6PYikOZmoh5B0d7hIHaIgveMjX990IAa/xK7jRTN8OA==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.10.1" - } - }, - "@babel/plugin-transform-async-to-generator": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.10.1.tgz", - "integrity": "sha512-XCgYjJ8TY2slj6SReBUyamJn3k2JLUIiiR5b6t1mNCMSvv7yx+jJpaewakikp0uWFQSF7ChPPoe3dHmXLpISkg==", - "dev": true, - "requires": { - "@babel/helper-module-imports": "^7.10.1", - "@babel/helper-plugin-utils": "^7.10.1", - "@babel/helper-remap-async-to-generator": "^7.10.1" - } - }, - "@babel/plugin-transform-block-scoped-functions": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.10.1.tgz", - "integrity": "sha512-B7K15Xp8lv0sOJrdVAoukKlxP9N59HS48V1J3U/JGj+Ad+MHq+am6xJVs85AgXrQn4LV8vaYFOB+pr/yIuzW8Q==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.10.1" - } - }, - "@babel/plugin-transform-block-scoping": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.10.1.tgz", - "integrity": "sha512-8bpWG6TtF5akdhIm/uWTyjHqENpy13Fx8chg7pFH875aNLwX8JxIxqm08gmAT+Whe6AOmaTeLPe7dpLbXt+xUw==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.10.1", - "lodash": "^4.17.13" - } - }, - "@babel/plugin-transform-classes": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.10.1.tgz", - "integrity": "sha512-P9V0YIh+ln/B3RStPoXpEQ/CoAxQIhRSUn7aXqQ+FZJ2u8+oCtjIXR3+X0vsSD8zv+mb56K7wZW1XiDTDGiDRQ==", - "dev": true, - "requires": { - "@babel/helper-annotate-as-pure": "^7.10.1", - "@babel/helper-define-map": "^7.10.1", - "@babel/helper-function-name": "^7.10.1", - "@babel/helper-optimise-call-expression": "^7.10.1", - "@babel/helper-plugin-utils": "^7.10.1", - "@babel/helper-replace-supers": "^7.10.1", - "@babel/helper-split-export-declaration": "^7.10.1", - "globals": "^11.1.0" - } - }, - "@babel/plugin-transform-computed-properties": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.10.1.tgz", - "integrity": "sha512-mqSrGjp3IefMsXIenBfGcPXxJxweQe2hEIwMQvjtiDQ9b1IBvDUjkAtV/HMXX47/vXf14qDNedXsIiNd1FmkaQ==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.10.1" - } - }, - "@babel/plugin-transform-destructuring": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.10.1.tgz", - "integrity": "sha512-V/nUc4yGWG71OhaTH705pU8ZSdM6c1KmmLP8ys59oOYbT7RpMYAR3MsVOt6OHL0WzG7BlTU076va9fjJyYzJMA==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.10.1" - } - }, - "@babel/plugin-transform-dotall-regex": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.10.1.tgz", - "integrity": "sha512-19VIMsD1dp02RvduFUmfzj8uknaO3uiHHF0s3E1OHnVsNj8oge8EQ5RzHRbJjGSetRnkEuBYO7TG1M5kKjGLOA==", - "dev": true, - "requires": { - "@babel/helper-create-regexp-features-plugin": "^7.10.1", - "@babel/helper-plugin-utils": "^7.10.1" - } - }, - "@babel/plugin-transform-duplicate-keys": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.10.1.tgz", - "integrity": "sha512-wIEpkX4QvX8Mo9W6XF3EdGttrIPZWozHfEaDTU0WJD/TDnXMvdDh30mzUl/9qWhnf7naicYartcEfUghTCSNpA==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.10.1" - } - }, - "@babel/plugin-transform-exponentiation-operator": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.10.1.tgz", - "integrity": "sha512-lr/przdAbpEA2BUzRvjXdEDLrArGRRPwbaF9rvayuHRvdQ7lUTTkZnhZrJ4LE2jvgMRFF4f0YuPQ20vhiPYxtA==", - "dev": true, - "requires": { - "@babel/helper-builder-binary-assignment-operator-visitor": "^7.10.1", - "@babel/helper-plugin-utils": "^7.10.1" - } - }, - "@babel/plugin-transform-for-of": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.10.1.tgz", - "integrity": "sha512-US8KCuxfQcn0LwSCMWMma8M2R5mAjJGsmoCBVwlMygvmDUMkTCykc84IqN1M7t+agSfOmLYTInLCHJM+RUoz+w==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.10.1" - } - }, - "@babel/plugin-transform-function-name": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.10.1.tgz", - "integrity": "sha512-//bsKsKFBJfGd65qSNNh1exBy5Y9gD9ZN+DvrJ8f7HXr4avE5POW6zB7Rj6VnqHV33+0vXWUwJT0wSHubiAQkw==", - "dev": true, - "requires": { - "@babel/helper-function-name": "^7.10.1", - "@babel/helper-plugin-utils": "^7.10.1" - } - }, - "@babel/plugin-transform-literals": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.10.1.tgz", - "integrity": "sha512-qi0+5qgevz1NHLZroObRm5A+8JJtibb7vdcPQF1KQE12+Y/xxl8coJ+TpPW9iRq+Mhw/NKLjm+5SHtAHCC7lAw==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.10.1" - } - }, - "@babel/plugin-transform-member-expression-literals": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.10.1.tgz", - "integrity": "sha512-UmaWhDokOFT2GcgU6MkHC11i0NQcL63iqeufXWfRy6pUOGYeCGEKhvfFO6Vz70UfYJYHwveg62GS83Rvpxn+NA==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.10.1" - } - }, - "@babel/plugin-transform-modules-amd": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.10.1.tgz", - "integrity": "sha512-31+hnWSFRI4/ACFr1qkboBbrTxoBIzj7qA69qlq8HY8p7+YCzkCT6/TvQ1a4B0z27VeWtAeJd6pr5G04dc1iHw==", - "dev": true, - "requires": { - "@babel/helper-module-transforms": "^7.10.1", - "@babel/helper-plugin-utils": "^7.10.1", - "babel-plugin-dynamic-import-node": "^2.3.3" - } - }, - "@babel/plugin-transform-modules-commonjs": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.10.1.tgz", - "integrity": "sha512-AQG4fc3KOah0vdITwt7Gi6hD9BtQP/8bhem7OjbaMoRNCH5Djx42O2vYMfau7QnAzQCa+RJnhJBmFFMGpQEzrg==", - "dev": true, - "requires": { - "@babel/helper-module-transforms": "^7.10.1", - "@babel/helper-plugin-utils": "^7.10.1", - "@babel/helper-simple-access": "^7.10.1", - "babel-plugin-dynamic-import-node": "^2.3.3" - } - }, - "@babel/plugin-transform-modules-systemjs": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.10.1.tgz", - "integrity": "sha512-ewNKcj1TQZDL3YnO85qh9zo1YF1CHgmSTlRQgHqe63oTrMI85cthKtZjAiZSsSNjPQ5NCaYo5QkbYqEw1ZBgZA==", - "dev": true, - "requires": { - "@babel/helper-hoist-variables": "^7.10.1", - "@babel/helper-module-transforms": "^7.10.1", - "@babel/helper-plugin-utils": "^7.10.1", - "babel-plugin-dynamic-import-node": "^2.3.3" - } - }, - "@babel/plugin-transform-modules-umd": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.10.1.tgz", - "integrity": "sha512-EIuiRNMd6GB6ulcYlETnYYfgv4AxqrswghmBRQbWLHZxN4s7mupxzglnHqk9ZiUpDI4eRWewedJJNj67PWOXKA==", - "dev": true, - "requires": { - "@babel/helper-module-transforms": "^7.10.1", - "@babel/helper-plugin-utils": "^7.10.1" - } - }, - "@babel/plugin-transform-named-capturing-groups-regex": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.8.3.tgz", - "integrity": "sha512-f+tF/8UVPU86TrCb06JoPWIdDpTNSGGcAtaD9mLP0aYGA0OS0j7j7DHJR0GTFrUZPUU6loZhbsVZgTh0N+Qdnw==", - "dev": true, - "requires": { - "@babel/helper-create-regexp-features-plugin": "^7.8.3" - } - }, - "@babel/plugin-transform-new-target": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.10.1.tgz", - "integrity": "sha512-MBlzPc1nJvbmO9rPr1fQwXOM2iGut+JC92ku6PbiJMMK7SnQc1rytgpopveE3Evn47gzvGYeCdgfCDbZo0ecUw==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.10.1" - } - }, - "@babel/plugin-transform-object-super": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.10.1.tgz", - "integrity": "sha512-WnnStUDN5GL+wGQrJylrnnVlFhFmeArINIR9gjhSeYyvroGhBrSAXYg/RHsnfzmsa+onJrTJrEClPzgNmmQ4Gw==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.10.1", - "@babel/helper-replace-supers": "^7.10.1" - } - }, - "@babel/plugin-transform-parameters": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.10.1.tgz", - "integrity": "sha512-tJ1T0n6g4dXMsL45YsSzzSDZCxiHXAQp/qHrucOq5gEHncTA3xDxnd5+sZcoQp+N1ZbieAaB8r/VUCG0gqseOg==", - "dev": true, - "requires": { - "@babel/helper-get-function-arity": "^7.10.1", - "@babel/helper-plugin-utils": "^7.10.1" - } - }, - "@babel/plugin-transform-property-literals": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.10.1.tgz", - "integrity": "sha512-Kr6+mgag8auNrgEpbfIWzdXYOvqDHZOF0+Bx2xh4H2EDNwcbRb9lY6nkZg8oSjsX+DH9Ebxm9hOqtKW+gRDeNA==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.10.1" - } - }, - "@babel/plugin-transform-regenerator": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.10.1.tgz", - "integrity": "sha512-B3+Y2prScgJ2Bh/2l9LJxKbb8C8kRfsG4AdPT+n7ixBHIxJaIG8bi8tgjxUMege1+WqSJ+7gu1YeoMVO3gPWzw==", - "dev": true, - "requires": { - "regenerator-transform": "^0.14.2" - } - }, - "@babel/plugin-transform-reserved-words": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.10.1.tgz", - "integrity": "sha512-qN1OMoE2nuqSPmpTqEM7OvJ1FkMEV+BjVeZZm9V9mq/x1JLKQ4pcv8riZJMNN3u2AUGl0ouOMjRr2siecvHqUQ==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.10.1" - } - }, - "@babel/plugin-transform-runtime": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.10.1.tgz", - "integrity": "sha512-4w2tcglDVEwXJ5qxsY++DgWQdNJcCCsPxfT34wCUwIf2E7dI7pMpH8JczkMBbgBTNzBX62SZlNJ9H+De6Zebaw==", - "dev": true, - "requires": { - "@babel/helper-module-imports": "^7.10.1", - "@babel/helper-plugin-utils": "^7.10.1", - "resolve": "^1.8.1", - "semver": "^5.5.1" - } - }, - "@babel/plugin-transform-shorthand-properties": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.10.1.tgz", - "integrity": "sha512-AR0E/lZMfLstScFwztApGeyTHJ5u3JUKMjneqRItWeEqDdHWZwAOKycvQNCasCK/3r5YXsuNG25funcJDu7Y2g==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.10.1" - } - }, - "@babel/plugin-transform-spread": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.10.1.tgz", - "integrity": "sha512-8wTPym6edIrClW8FI2IoaePB91ETOtg36dOkj3bYcNe7aDMN2FXEoUa+WrmPc4xa1u2PQK46fUX2aCb+zo9rfw==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.10.1" - } - }, - "@babel/plugin-transform-sticky-regex": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.10.1.tgz", - "integrity": "sha512-j17ojftKjrL7ufX8ajKvwRilwqTok4q+BjkknmQw9VNHnItTyMP5anPFzxFJdCQs7clLcWpCV3ma+6qZWLnGMA==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.10.1", - "@babel/helper-regex": "^7.10.1" - } - }, - "@babel/plugin-transform-template-literals": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.10.1.tgz", - "integrity": "sha512-t7B/3MQf5M1T9hPCRG28DNGZUuxAuDqLYS03rJrIk2prj/UV7Z6FOneijhQhnv/Xa039vidXeVbvjK2SK5f7Gg==", - "dev": true, - "requires": { - "@babel/helper-annotate-as-pure": "^7.10.1", - "@babel/helper-plugin-utils": "^7.10.1" - } - }, - "@babel/plugin-transform-typeof-symbol": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.10.1.tgz", - "integrity": "sha512-qX8KZcmbvA23zDi+lk9s6hC1FM7jgLHYIjuLgULgc8QtYnmB3tAVIYkNoKRQ75qWBeyzcoMoK8ZQmogGtC/w0g==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.10.1" - } - }, - "@babel/plugin-transform-unicode-escapes": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.10.1.tgz", - "integrity": "sha512-zZ0Poh/yy1d4jeDWpx/mNwbKJVwUYJX73q+gyh4bwtG0/iUlzdEu0sLMda8yuDFS6LBQlT/ST1SJAR6zYwXWgw==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.10.1" - } - }, - "@babel/plugin-transform-unicode-regex": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.10.1.tgz", - "integrity": "sha512-Y/2a2W299k0VIUdbqYm9X2qS6fE0CUBhhiPpimK6byy7OJ/kORLlIX+J6UrjgNu5awvs62k+6RSslxhcvVw2Tw==", - "dev": true, - "requires": { - "@babel/helper-create-regexp-features-plugin": "^7.10.1", - "@babel/helper-plugin-utils": "^7.10.1" - } - }, - "@babel/preset-env": { - "version": "7.10.2", - "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.10.2.tgz", - "integrity": "sha512-MjqhX0RZaEgK/KueRzh+3yPSk30oqDKJ5HP5tqTSB1e2gzGS3PLy7K0BIpnp78+0anFuSwOeuCf1zZO7RzRvEA==", - "dev": true, - "requires": { - "@babel/compat-data": "^7.10.1", - "@babel/helper-compilation-targets": "^7.10.2", - "@babel/helper-module-imports": "^7.10.1", - "@babel/helper-plugin-utils": "^7.10.1", - "@babel/plugin-proposal-async-generator-functions": "^7.10.1", - "@babel/plugin-proposal-class-properties": "^7.10.1", - "@babel/plugin-proposal-dynamic-import": "^7.10.1", - "@babel/plugin-proposal-json-strings": "^7.10.1", - "@babel/plugin-proposal-nullish-coalescing-operator": "^7.10.1", - "@babel/plugin-proposal-numeric-separator": "^7.10.1", - "@babel/plugin-proposal-object-rest-spread": "^7.10.1", - "@babel/plugin-proposal-optional-catch-binding": "^7.10.1", - "@babel/plugin-proposal-optional-chaining": "^7.10.1", - "@babel/plugin-proposal-private-methods": "^7.10.1", - "@babel/plugin-proposal-unicode-property-regex": "^7.10.1", - "@babel/plugin-syntax-async-generators": "^7.8.0", - "@babel/plugin-syntax-class-properties": "^7.10.1", - "@babel/plugin-syntax-dynamic-import": "^7.8.0", - "@babel/plugin-syntax-json-strings": "^7.8.0", - "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.0", - "@babel/plugin-syntax-numeric-separator": "^7.10.1", - "@babel/plugin-syntax-object-rest-spread": "^7.8.0", - "@babel/plugin-syntax-optional-catch-binding": "^7.8.0", - "@babel/plugin-syntax-optional-chaining": "^7.8.0", - "@babel/plugin-syntax-top-level-await": "^7.10.1", - "@babel/plugin-transform-arrow-functions": "^7.10.1", - "@babel/plugin-transform-async-to-generator": "^7.10.1", - "@babel/plugin-transform-block-scoped-functions": "^7.10.1", - "@babel/plugin-transform-block-scoping": "^7.10.1", - "@babel/plugin-transform-classes": "^7.10.1", - "@babel/plugin-transform-computed-properties": "^7.10.1", - "@babel/plugin-transform-destructuring": "^7.10.1", - "@babel/plugin-transform-dotall-regex": "^7.10.1", - "@babel/plugin-transform-duplicate-keys": "^7.10.1", - "@babel/plugin-transform-exponentiation-operator": "^7.10.1", - "@babel/plugin-transform-for-of": "^7.10.1", - "@babel/plugin-transform-function-name": "^7.10.1", - "@babel/plugin-transform-literals": "^7.10.1", - "@babel/plugin-transform-member-expression-literals": "^7.10.1", - "@babel/plugin-transform-modules-amd": "^7.10.1", - "@babel/plugin-transform-modules-commonjs": "^7.10.1", - "@babel/plugin-transform-modules-systemjs": "^7.10.1", - "@babel/plugin-transform-modules-umd": "^7.10.1", - "@babel/plugin-transform-named-capturing-groups-regex": "^7.8.3", - "@babel/plugin-transform-new-target": "^7.10.1", - "@babel/plugin-transform-object-super": "^7.10.1", - "@babel/plugin-transform-parameters": "^7.10.1", - "@babel/plugin-transform-property-literals": "^7.10.1", - "@babel/plugin-transform-regenerator": "^7.10.1", - "@babel/plugin-transform-reserved-words": "^7.10.1", - "@babel/plugin-transform-shorthand-properties": "^7.10.1", - "@babel/plugin-transform-spread": "^7.10.1", - "@babel/plugin-transform-sticky-regex": "^7.10.1", - "@babel/plugin-transform-template-literals": "^7.10.1", - "@babel/plugin-transform-typeof-symbol": "^7.10.1", - "@babel/plugin-transform-unicode-escapes": "^7.10.1", - "@babel/plugin-transform-unicode-regex": "^7.10.1", - "@babel/preset-modules": "^0.1.3", - "@babel/types": "^7.10.2", - "browserslist": "^4.12.0", - "core-js-compat": "^3.6.2", - "invariant": "^2.2.2", - "levenary": "^1.1.1", - "semver": "^5.5.0" - } - }, - "@babel/preset-modules": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.3.tgz", - "integrity": "sha512-Ra3JXOHBq2xd56xSF7lMKXdjBn3T772Y1Wet3yWnkDly9zHvJki029tAFzvAAK5cf4YV3yoxuP61crYRol6SVg==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0", - "@babel/plugin-proposal-unicode-property-regex": "^7.4.4", - "@babel/plugin-transform-dotall-regex": "^7.4.4", - "@babel/types": "^7.4.4", - "esutils": "^2.0.2" - } - }, - "@babel/runtime": { - "version": "7.10.2", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.10.2.tgz", - "integrity": "sha512-6sF3uQw2ivImfVIl62RZ7MXhO2tap69WeWK57vAaimT6AZbE4FbqjdEJIN1UqoD6wI6B+1n9UiagafH1sxjOtg==", - "dev": true, - "requires": { - "regenerator-runtime": "^0.13.4" - } - }, - "@babel/template": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.10.1.tgz", - "integrity": "sha512-OQDg6SqvFSsc9A0ej6SKINWrpJiNonRIniYondK2ViKhB06i3c0s+76XUft71iqBEe9S1OKsHwPAjfHnuvnCig==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.10.1", - "@babel/parser": "^7.10.1", - "@babel/types": "^7.10.1" - } - }, - "@babel/traverse": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.10.1.tgz", - "integrity": "sha512-C/cTuXeKt85K+p08jN6vMDz8vSV0vZcI0wmQ36o6mjbuo++kPMdpOYw23W2XH04dbRt9/nMEfA4W3eR21CD+TQ==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.10.1", - "@babel/generator": "^7.10.1", - "@babel/helper-function-name": "^7.10.1", - "@babel/helper-split-export-declaration": "^7.10.1", - "@babel/parser": "^7.10.1", - "@babel/types": "^7.10.1", - "debug": "^4.1.0", - "globals": "^11.1.0", - "lodash": "^4.17.13" - } - }, - "@babel/types": { - "version": "7.10.2", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.10.2.tgz", - "integrity": "sha512-AD3AwWBSz0AWF0AkCN9VPiWrvldXq+/e3cHa4J89vo4ymjz1XwrBFFVZmkJTsQIPNk+ZVomPSXUJqq8yyjZsng==", - "dev": true, - "requires": { - "@babel/helper-validator-identifier": "^7.10.1", - "lodash": "^4.17.13", - "to-fast-properties": "^2.0.0" - } - }, - "@mrmlnc/readdir-enhanced": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/@mrmlnc/readdir-enhanced/-/readdir-enhanced-2.2.1.tgz", - "integrity": "sha512-bPHp6Ji8b41szTOcaP63VlnbbO5Ny6dwAATtY6JTjh5N2OLrb5Qk/Th5cRkRQhkWCt+EJsYrNB0MiL+Gpn6e3g==", - "dev": true, - "requires": { - "call-me-maybe": "^1.0.1", - "glob-to-regexp": "^0.3.0" - } - }, - "@nodelib/fs.stat": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-1.1.3.tgz", - "integrity": "sha512-shAmDyaQC4H92APFoIaVDHCx5bStIocgvbwQyxPRrbUY20V1EYTbSDchWbuwlMG3V17cprZhA6+78JfB+3DTPw==", - "dev": true - }, - "@sindresorhus/is": { - "version": "0.14.0", - "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.14.0.tgz", - "integrity": "sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ==", - "dev": true - }, - "@szmarczak/http-timer": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-1.1.2.tgz", - "integrity": "sha512-XIB2XbzHTN6ieIjfIMV9hlVcfPU26s2vafYWQcZHWXHOxiaRZYEDKEwdl129Zyg50+foYV2jCgtrqSA6qNuNSA==", - "dev": true, - "requires": { - "defer-to-connect": "^1.0.1" - } - }, - "@types/color-name": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@types/color-name/-/color-name-1.1.1.tgz", - "integrity": "sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==", - "dev": true - }, - "@types/glob": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.2.tgz", - "integrity": "sha512-VgNIkxK+j7Nz5P7jvUZlRvhuPSmsEfS03b0alKcq5V/STUKAa3Plemsn5mrQUO7am6OErJ4rhGEGJbACclrtRA==", - "dev": true, - "requires": { - "@types/minimatch": "*", - "@types/node": "*" - } - }, - "@types/json-schema": { - "version": "7.0.5", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.5.tgz", - "integrity": "sha512-7+2BITlgjgDhH0vvwZU/HZJVyk+2XUlvxXe8dFMedNX/aMkaOq++rMAFXc0tM7ij15QaWlbdQASBR9dihi+bDQ==", - "dev": true - }, - "@types/minimatch": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz", - "integrity": "sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==", - "dev": true - }, - "@types/node": { - "version": "14.0.13", - "resolved": "https://registry.npmjs.org/@types/node/-/node-14.0.13.tgz", - "integrity": "sha512-rouEWBImiRaSJsVA+ITTFM6ZxibuAlTuNOCyxVbwreu6k6+ujs7DfnU9o+PShFhET78pMBl3eH+AGSI5eOTkPA==", - "dev": true - }, - "@types/q": { - "version": "1.5.4", - "resolved": "https://registry.npmjs.org/@types/q/-/q-1.5.4.tgz", - "integrity": "sha512-1HcDas8SEj4z1Wc696tH56G8OlRaH/sqZOynNNB+HF0WOeXPaxTtbYzJY2oEfiUxjSKjhCKr+MvR7dCHcEelug==", - "dev": true - }, - "@vue/babel-helper-vue-jsx-merge-props": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@vue/babel-helper-vue-jsx-merge-props/-/babel-helper-vue-jsx-merge-props-1.0.0.tgz", - "integrity": "sha512-6tyf5Cqm4m6v7buITuwS+jHzPlIPxbFzEhXR5JGZpbrvOcp1hiQKckd305/3C7C36wFekNTQSxAtgeM0j0yoUw==", - "dev": true - }, - "@vue/babel-plugin-transform-vue-jsx": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@vue/babel-plugin-transform-vue-jsx/-/babel-plugin-transform-vue-jsx-1.1.2.tgz", - "integrity": "sha512-YfdaoSMvD1nj7+DsrwfTvTnhDXI7bsuh+Y5qWwvQXlD24uLgnsoww3qbiZvWf/EoviZMrvqkqN4CBw0W3BWUTQ==", - "dev": true, - "requires": { - "@babel/helper-module-imports": "^7.0.0", - "@babel/plugin-syntax-jsx": "^7.2.0", - "@vue/babel-helper-vue-jsx-merge-props": "^1.0.0", - "html-tags": "^2.0.0", - "lodash.kebabcase": "^4.1.1", - "svg-tags": "^1.0.0" - } - }, - "@vue/babel-preset-app": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/@vue/babel-preset-app/-/babel-preset-app-4.4.1.tgz", - "integrity": "sha512-VHVROEBBiW0dnuNuzlFElkncXo+zxh5Px0MZ51Th5da8UPbQodf43mnpotMnFtmCPTXAFL58tzDttu1FgrgfpQ==", - "dev": true, - "requires": { - "@babel/core": "^7.9.6", - "@babel/helper-compilation-targets": "^7.9.6", - "@babel/helper-module-imports": "^7.8.3", - "@babel/plugin-proposal-class-properties": "^7.8.3", - "@babel/plugin-proposal-decorators": "^7.8.3", - "@babel/plugin-syntax-dynamic-import": "^7.8.3", - "@babel/plugin-syntax-jsx": "^7.8.3", - "@babel/plugin-transform-runtime": "^7.9.6", - "@babel/preset-env": "^7.9.6", - "@babel/runtime": "^7.9.6", - "@vue/babel-preset-jsx": "^1.1.2", - "babel-plugin-dynamic-import-node": "^2.3.3", - "core-js": "^3.6.5", - "core-js-compat": "^3.6.5", - "semver": "^6.1.0" - }, - "dependencies": { - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true - } - } - }, - "@vue/babel-preset-jsx": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@vue/babel-preset-jsx/-/babel-preset-jsx-1.1.2.tgz", - "integrity": "sha512-zDpVnFpeC9YXmvGIDSsKNdL7qCG2rA3gjywLYHPCKDT10erjxF4U+6ay9X6TW5fl4GsDlJp9bVfAVQAAVzxxvQ==", - "dev": true, - "requires": { - "@vue/babel-helper-vue-jsx-merge-props": "^1.0.0", - "@vue/babel-plugin-transform-vue-jsx": "^1.1.2", - "@vue/babel-sugar-functional-vue": "^1.1.2", - "@vue/babel-sugar-inject-h": "^1.1.2", - "@vue/babel-sugar-v-model": "^1.1.2", - "@vue/babel-sugar-v-on": "^1.1.2" - } - }, - "@vue/babel-sugar-functional-vue": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@vue/babel-sugar-functional-vue/-/babel-sugar-functional-vue-1.1.2.tgz", - "integrity": "sha512-YhmdJQSVEFF5ETJXzrMpj0nkCXEa39TvVxJTuVjzvP2rgKhdMmQzlJuMv/HpadhZaRVMCCF3AEjjJcK5q/cYzQ==", - "dev": true, - "requires": { - "@babel/plugin-syntax-jsx": "^7.2.0" - } - }, - "@vue/babel-sugar-inject-h": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@vue/babel-sugar-inject-h/-/babel-sugar-inject-h-1.1.2.tgz", - "integrity": "sha512-VRSENdTvD5htpnVp7i7DNuChR5rVMcORdXjvv5HVvpdKHzDZAYiLSD+GhnhxLm3/dMuk8pSzV+k28ECkiN5m8w==", - "dev": true, - "requires": { - "@babel/plugin-syntax-jsx": "^7.2.0" - } - }, - "@vue/babel-sugar-v-model": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@vue/babel-sugar-v-model/-/babel-sugar-v-model-1.1.2.tgz", - "integrity": "sha512-vLXPvNq8vDtt0u9LqFdpGM9W9IWDmCmCyJXuozlq4F4UYVleXJ2Fa+3JsnTZNJcG+pLjjfnEGHci2339Kj5sGg==", - "dev": true, - "requires": { - "@babel/plugin-syntax-jsx": "^7.2.0", - "@vue/babel-helper-vue-jsx-merge-props": "^1.0.0", - "@vue/babel-plugin-transform-vue-jsx": "^1.1.2", - "camelcase": "^5.0.0", - "html-tags": "^2.0.0", - "svg-tags": "^1.0.0" - } - }, - "@vue/babel-sugar-v-on": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@vue/babel-sugar-v-on/-/babel-sugar-v-on-1.1.2.tgz", - "integrity": "sha512-T8ZCwC8Jp2uRtcZ88YwZtZXe7eQrJcfRq0uTFy6ShbwYJyz5qWskRFoVsdTi9o0WEhmQXxhQUewodOSCUPVmsQ==", - "dev": true, - "requires": { - "@babel/plugin-syntax-jsx": "^7.2.0", - "@vue/babel-plugin-transform-vue-jsx": "^1.1.2", - "camelcase": "^5.0.0" - } - }, - "@vue/component-compiler-utils": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/@vue/component-compiler-utils/-/component-compiler-utils-3.1.2.tgz", - "integrity": "sha512-QLq9z8m79mCinpaEeSURhnNCN6djxpHw0lpP/bodMlt5kALfONpryMthvnrQOlTcIKoF+VoPi+lPHUYeDFPXug==", - "dev": true, - "requires": { - "consolidate": "^0.15.1", - "hash-sum": "^1.0.2", - "lru-cache": "^4.1.2", - "merge-source-map": "^1.1.0", - "postcss": "^7.0.14", - "postcss-selector-parser": "^6.0.2", - "prettier": "^1.18.2", - "source-map": "~0.6.1", - "vue-template-es2015-compiler": "^1.9.0" - }, - "dependencies": { - "lru-cache": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", - "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", - "dev": true, - "requires": { - "pseudomap": "^1.0.2", - "yallist": "^2.1.2" - } - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - }, - "yallist": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", - "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=", - "dev": true - } - } - }, - "@vuepress/core": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/@vuepress/core/-/core-1.5.1.tgz", - "integrity": "sha512-gLogkq6Mm8/y7SuywNNE2ny2idMAoBUnRV40TpYK1pOAjQKRlbh3C1fDck+N/nUubB7zKkZUt7uBVqzSRGk9/g==", - "dev": true, - "requires": { - "@babel/core": "^7.8.4", - "@vue/babel-preset-app": "^4.1.2", - "@vuepress/markdown": "1.5.1", - "@vuepress/markdown-loader": "1.5.1", - "@vuepress/plugin-last-updated": "1.5.1", - "@vuepress/plugin-register-components": "1.5.1", - "@vuepress/shared-utils": "1.5.1", - "autoprefixer": "^9.5.1", - "babel-loader": "^8.0.4", - "cache-loader": "^3.0.0", - "chokidar": "^2.0.3", - "connect-history-api-fallback": "^1.5.0", - "copy-webpack-plugin": "^5.0.2", - "core-js": "^3.6.4", - "cross-spawn": "^6.0.5", - "css-loader": "^2.1.1", - "file-loader": "^3.0.1", - "js-yaml": "^3.13.1", - "lru-cache": "^5.1.1", - "mini-css-extract-plugin": "0.6.0", - "optimize-css-assets-webpack-plugin": "^5.0.1", - "portfinder": "^1.0.13", - "postcss-loader": "^3.0.0", - "postcss-safe-parser": "^4.0.1", - "toml": "^3.0.0", - "url-loader": "^1.0.1", - "vue": "^2.6.10", - "vue-loader": "^15.7.1", - "vue-router": "^3.1.3", - "vue-server-renderer": "^2.6.10", - "vue-template-compiler": "^2.6.10", - "vuepress-html-webpack-plugin": "^3.2.0", - "vuepress-plugin-container": "^2.0.2", - "webpack": "^4.8.1", - "webpack-chain": "^6.0.0", - "webpack-dev-server": "^3.5.1", - "webpack-merge": "^4.1.2", - "webpackbar": "3.2.0" - } - }, - "@vuepress/markdown": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/@vuepress/markdown/-/markdown-1.5.1.tgz", - "integrity": "sha512-GzlSa2stbmcnAIgdQISXzDW6qlXONp0wxdB5OFOJe6tBHW1JcSiXFk6A9bcQuYKoF+wyAZyrLExpM8FVp0qpug==", - "dev": true, - "requires": { - "@vuepress/shared-utils": "1.5.1", - "markdown-it": "^8.4.1", - "markdown-it-anchor": "^5.0.2", - "markdown-it-chain": "^1.3.0", - "markdown-it-emoji": "^1.4.0", - "markdown-it-table-of-contents": "^0.4.0", - "prismjs": "^1.13.0" - } - }, - "@vuepress/markdown-loader": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/@vuepress/markdown-loader/-/markdown-loader-1.5.1.tgz", - "integrity": "sha512-yITErIhfzjNBV4KC4dALGDoe9nIF29YQcIC0UbtNtV2zlkUERkRkP+AowT3G1WMBYzY3XhtoCZqXtxxuSCDILQ==", - "dev": true, - "requires": { - "@vuepress/markdown": "1.5.1", - "loader-utils": "^1.1.0", - "lru-cache": "^5.1.1" - } - }, - "@vuepress/plugin-active-header-links": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/@vuepress/plugin-active-header-links/-/plugin-active-header-links-1.5.1.tgz", - "integrity": "sha512-GGqmlJlIJ3NEkAi2Gzob6CemDL5o0cv4TRLvWzjW43H0Pj1idoOi0mbKXtWAIZ6QicrZupeJUMhy49qyipvSWQ==", - "dev": true, - "requires": { - "lodash.debounce": "^4.0.8" - } - }, - "@vuepress/plugin-last-updated": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/@vuepress/plugin-last-updated/-/plugin-last-updated-1.5.1.tgz", - "integrity": "sha512-uG9P88gJ7KxmMDcTCEHbT248rJ0fZABeHxvyXodUAzSG0bDdqXjw4p34PdkzlWnHHLDiYKBIHIcEYSvKmOiRPQ==", - "dev": true, - "requires": { - "cross-spawn": "^6.0.5" - } - }, - "@vuepress/plugin-nprogress": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/@vuepress/plugin-nprogress/-/plugin-nprogress-1.5.1.tgz", - "integrity": "sha512-BMoJL9Xc+XKoiVe7pSZntuVkt06u8i594J3Q4eEFkmrSRj8D+n9YFFjdRWTfae2haPMtMAvwpVeohAQ6ii61LA==", - "dev": true, - "requires": { - "nprogress": "^0.2.0" - } - }, - "@vuepress/plugin-register-components": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/@vuepress/plugin-register-components/-/plugin-register-components-1.5.1.tgz", - "integrity": "sha512-pnovxJepFIQ8mx+uXg62OZ9KoFE1aOIBKxOmmtI5g9Qurx2NTVv5AWUtoi76xYbCxBpl313ffcCyvxMUfXPsrQ==", - "dev": true, - "requires": { - "@vuepress/shared-utils": "1.5.1" - } - }, - "@vuepress/plugin-search": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/@vuepress/plugin-search/-/plugin-search-1.5.1.tgz", - "integrity": "sha512-JyYrTzDDZs6ANZgp7+DnuRTm3OB1LgrxUJriD5qLb7NXEDwWvJnf7noFxnp7j+yaMogCZN1IloTU0PLSLqub9A==", - "dev": true - }, - "@vuepress/shared-utils": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/@vuepress/shared-utils/-/shared-utils-1.5.1.tgz", - "integrity": "sha512-rktTYlKa4vla6GlUZZmIiIW6Dfl+YbfcgGvkWE5A7MiIqEmJKnoqKOxJOHLPbnD+T5Ssfu71bj4FVXCG89DUmA==", - "dev": true, - "requires": { - "chalk": "^2.3.2", - "diacritics": "^1.3.0", - "escape-html": "^1.0.3", - "fs-extra": "^7.0.1", - "globby": "^9.2.0", - "gray-matter": "^4.0.1", - "hash-sum": "^1.0.2", - "semver": "^6.0.0", - "upath": "^1.1.0" - }, - "dependencies": { - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true - } - } - }, - "@vuepress/theme-default": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/@vuepress/theme-default/-/theme-default-1.5.1.tgz", - "integrity": "sha512-CojJNniskrFWE/LQg7WE+4SYg7Q8xMChqXj74C4/475kCOd9dPHVeCkuvmjIpZ7NJ2m96aNlG1TvDnOTuhLCCQ==", - "dev": true, - "requires": { - "@vuepress/plugin-active-header-links": "1.5.1", - "@vuepress/plugin-nprogress": "1.5.1", - "@vuepress/plugin-search": "1.5.1", - "docsearch.js": "^2.5.2", - "lodash": "^4.17.15", - "stylus": "^0.54.5", - "stylus-loader": "^3.0.2", - "vuepress-plugin-container": "^2.0.2", - "vuepress-plugin-smooth-scroll": "^0.0.3" - } - }, - "@webassemblyjs/ast": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.9.0.tgz", - "integrity": "sha512-C6wW5L+b7ogSDVqymbkkvuW9kruN//YisMED04xzeBBqjHa2FYnmvOlS6Xj68xWQRgWvI9cIglsjFowH/RJyEA==", - "dev": true, - "requires": { - "@webassemblyjs/helper-module-context": "1.9.0", - "@webassemblyjs/helper-wasm-bytecode": "1.9.0", - "@webassemblyjs/wast-parser": "1.9.0" - } - }, - "@webassemblyjs/floating-point-hex-parser": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.9.0.tgz", - "integrity": "sha512-TG5qcFsS8QB4g4MhrxK5TqfdNe7Ey/7YL/xN+36rRjl/BlGE/NcBvJcqsRgCP6Z92mRE+7N50pRIi8SmKUbcQA==", - "dev": true - }, - "@webassemblyjs/helper-api-error": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.9.0.tgz", - "integrity": "sha512-NcMLjoFMXpsASZFxJ5h2HZRcEhDkvnNFOAKneP5RbKRzaWJN36NC4jqQHKwStIhGXu5mUWlUUk7ygdtrO8lbmw==", - "dev": true - }, - "@webassemblyjs/helper-buffer": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.9.0.tgz", - "integrity": "sha512-qZol43oqhq6yBPx7YM3m9Bv7WMV9Eevj6kMi6InKOuZxhw+q9hOkvq5e/PpKSiLfyetpaBnogSbNCfBwyB00CA==", - "dev": true - }, - "@webassemblyjs/helper-code-frame": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-code-frame/-/helper-code-frame-1.9.0.tgz", - "integrity": "sha512-ERCYdJBkD9Vu4vtjUYe8LZruWuNIToYq/ME22igL+2vj2dQ2OOujIZr3MEFvfEaqKoVqpsFKAGsRdBSBjrIvZA==", - "dev": true, - "requires": { - "@webassemblyjs/wast-printer": "1.9.0" - } - }, - "@webassemblyjs/helper-fsm": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-fsm/-/helper-fsm-1.9.0.tgz", - "integrity": "sha512-OPRowhGbshCb5PxJ8LocpdX9Kl0uB4XsAjl6jH/dWKlk/mzsANvhwbiULsaiqT5GZGT9qinTICdj6PLuM5gslw==", - "dev": true - }, - "@webassemblyjs/helper-module-context": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-module-context/-/helper-module-context-1.9.0.tgz", - "integrity": "sha512-MJCW8iGC08tMk2enck1aPW+BE5Cw8/7ph/VGZxwyvGbJwjktKkDK7vy7gAmMDx88D7mhDTCNKAW5tED+gZ0W8g==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.9.0" - } - }, - "@webassemblyjs/helper-wasm-bytecode": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.9.0.tgz", - "integrity": "sha512-R7FStIzyNcd7xKxCZH5lE0Bqy+hGTwS3LJjuv1ZVxd9O7eHCedSdrId/hMOd20I+v8wDXEn+bjfKDLzTepoaUw==", - "dev": true - }, - "@webassemblyjs/helper-wasm-section": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.9.0.tgz", - "integrity": "sha512-XnMB8l3ek4tvrKUUku+IVaXNHz2YsJyOOmz+MMkZvh8h1uSJpSen6vYnw3IoQ7WwEuAhL8Efjms1ZWjqh2agvw==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.9.0", - "@webassemblyjs/helper-buffer": "1.9.0", - "@webassemblyjs/helper-wasm-bytecode": "1.9.0", - "@webassemblyjs/wasm-gen": "1.9.0" - } - }, - "@webassemblyjs/ieee754": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.9.0.tgz", - "integrity": "sha512-dcX8JuYU/gvymzIHc9DgxTzUUTLexWwt8uCTWP3otys596io0L5aW02Gb1RjYpx2+0Jus1h4ZFqjla7umFniTg==", - "dev": true, - "requires": { - "@xtuc/ieee754": "^1.2.0" - } - }, - "@webassemblyjs/leb128": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.9.0.tgz", - "integrity": "sha512-ENVzM5VwV1ojs9jam6vPys97B/S65YQtv/aanqnU7D8aSoHFX8GyhGg0CMfyKNIHBuAVjy3tlzd5QMMINa7wpw==", - "dev": true, - "requires": { - "@xtuc/long": "4.2.2" - } - }, - "@webassemblyjs/utf8": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.9.0.tgz", - "integrity": "sha512-GZbQlWtopBTP0u7cHrEx+73yZKrQoBMpwkGEIqlacljhXCkVM1kMQge/Mf+csMJAjEdSwhOyLAS0AoR3AG5P8w==", - "dev": true - }, - "@webassemblyjs/wasm-edit": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.9.0.tgz", - "integrity": "sha512-FgHzBm80uwz5M8WKnMTn6j/sVbqilPdQXTWraSjBwFXSYGirpkSWE2R9Qvz9tNiTKQvoKILpCuTjBKzOIm0nxw==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.9.0", - "@webassemblyjs/helper-buffer": "1.9.0", - "@webassemblyjs/helper-wasm-bytecode": "1.9.0", - "@webassemblyjs/helper-wasm-section": "1.9.0", - "@webassemblyjs/wasm-gen": "1.9.0", - "@webassemblyjs/wasm-opt": "1.9.0", - "@webassemblyjs/wasm-parser": "1.9.0", - "@webassemblyjs/wast-printer": "1.9.0" - } - }, - "@webassemblyjs/wasm-gen": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.9.0.tgz", - "integrity": "sha512-cPE3o44YzOOHvlsb4+E9qSqjc9Qf9Na1OO/BHFy4OI91XDE14MjFN4lTMezzaIWdPqHnsTodGGNP+iRSYfGkjA==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.9.0", - "@webassemblyjs/helper-wasm-bytecode": "1.9.0", - "@webassemblyjs/ieee754": "1.9.0", - "@webassemblyjs/leb128": "1.9.0", - "@webassemblyjs/utf8": "1.9.0" - } - }, - "@webassemblyjs/wasm-opt": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.9.0.tgz", - "integrity": "sha512-Qkjgm6Anhm+OMbIL0iokO7meajkzQD71ioelnfPEj6r4eOFuqm4YC3VBPqXjFyyNwowzbMD+hizmprP/Fwkl2A==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.9.0", - "@webassemblyjs/helper-buffer": "1.9.0", - "@webassemblyjs/wasm-gen": "1.9.0", - "@webassemblyjs/wasm-parser": "1.9.0" - } - }, - "@webassemblyjs/wasm-parser": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.9.0.tgz", - "integrity": "sha512-9+wkMowR2AmdSWQzsPEjFU7njh8HTO5MqO8vjwEHuM+AMHioNqSBONRdr0NQQ3dVQrzp0s8lTcYqzUdb7YgELA==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.9.0", - "@webassemblyjs/helper-api-error": "1.9.0", - "@webassemblyjs/helper-wasm-bytecode": "1.9.0", - "@webassemblyjs/ieee754": "1.9.0", - "@webassemblyjs/leb128": "1.9.0", - "@webassemblyjs/utf8": "1.9.0" - } - }, - "@webassemblyjs/wast-parser": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-parser/-/wast-parser-1.9.0.tgz", - "integrity": "sha512-qsqSAP3QQ3LyZjNC/0jBJ/ToSxfYJ8kYyuiGvtn/8MK89VrNEfwj7BPQzJVHi0jGTRK2dGdJ5PRqhtjzoww+bw==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.9.0", - "@webassemblyjs/floating-point-hex-parser": "1.9.0", - "@webassemblyjs/helper-api-error": "1.9.0", - "@webassemblyjs/helper-code-frame": "1.9.0", - "@webassemblyjs/helper-fsm": "1.9.0", - "@xtuc/long": "4.2.2" - } - }, - "@webassemblyjs/wast-printer": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.9.0.tgz", - "integrity": "sha512-2J0nE95rHXHyQ24cWjMKJ1tqB/ds8z/cyeOZxJhcb+rW+SQASVjuznUSmdz5GpVJTzU8JkhYut0D3siFDD6wsA==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.9.0", - "@webassemblyjs/wast-parser": "1.9.0", - "@xtuc/long": "4.2.2" - } - }, - "@xtuc/ieee754": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", - "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", - "dev": true - }, - "@xtuc/long": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", - "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", - "dev": true - }, - "abbrev": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", - "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", - "dev": true - }, - "accepts": { - "version": "1.3.7", - "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz", - "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==", - "dev": true, - "requires": { - "mime-types": "~2.1.24", - "negotiator": "0.6.2" - } - }, - "acorn": { - "version": "6.4.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.1.tgz", - "integrity": "sha512-ZVA9k326Nwrj3Cj9jlh3wGFutC2ZornPNARZwsNYqQYgN0EsV2d53w5RN/co65Ohn4sUAUtb1rSUAOD6XN9idA==", - "dev": true - }, - "agentkeepalive": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-2.2.0.tgz", - "integrity": "sha1-xdG9SxKQCPEWPyNvhuX66iAm4u8=", - "dev": true - }, - "ajv": { - "version": "6.12.2", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.2.tgz", - "integrity": "sha512-k+V+hzjm5q/Mr8ef/1Y9goCmlsK4I6Sm74teeyGvFk1XrOsbsKLjEdrvny42CZ+a8sXbk8KWpY/bDwS+FLL2UQ==", - "dev": true, - "requires": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - } - }, - "ajv-errors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/ajv-errors/-/ajv-errors-1.0.1.tgz", - "integrity": "sha512-DCRfO/4nQ+89p/RK43i8Ezd41EqdGIU4ld7nGF8OQ14oc/we5rEntLCUa7+jrn3nn83BosfwZA0wb4pon2o8iQ==", - "dev": true, - "requires": {} - }, - "ajv-keywords": { - "version": "3.4.1", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.4.1.tgz", - "integrity": "sha512-RO1ibKvd27e6FEShVFfPALuHI3WjSVNeK5FIsmme/LYRNxjKuNj+Dt7bucLa6NdSv3JcVTyMlm9kGR84z1XpaQ==", - "dev": true, - "requires": {} - }, - "algoliasearch": { - "version": "3.35.1", - "resolved": "https://registry.npmjs.org/algoliasearch/-/algoliasearch-3.35.1.tgz", - "integrity": "sha512-K4yKVhaHkXfJ/xcUnil04xiSrB8B8yHZoFEhWNpXg23eiCnqvTZw1tn/SqvdsANlYHLJlKl0qi3I/Q2Sqo7LwQ==", - "dev": true, - "requires": { - "agentkeepalive": "^2.2.0", - "debug": "^2.6.9", - "envify": "^4.0.0", - "es6-promise": "^4.1.0", - "events": "^1.1.0", - "foreach": "^2.0.5", - "global": "^4.3.2", - "inherits": "^2.0.1", - "isarray": "^2.0.1", - "load-script": "^1.0.0", - "object-keys": "^1.0.11", - "querystring-es3": "^0.2.1", - "reduce": "^1.0.1", - "semver": "^5.1.0", - "tunnel-agent": "^0.6.0" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - } - } - }, - "alphanum-sort": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/alphanum-sort/-/alphanum-sort-1.0.2.tgz", - "integrity": "sha1-l6ERlkmyEa0zaR2fn0hqjsn74KM=", - "dev": true - }, - "ansi-align": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-3.0.0.tgz", - "integrity": "sha512-ZpClVKqXN3RGBmKibdfWzqCY4lnjEuoNzU5T0oEFpfd/z5qJHVarukridD4juLO2FXMiwUQxr9WqQtaYa8XRYw==", - "dev": true, - "requires": { - "string-width": "^3.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true - }, - "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - } - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "requires": { - "ansi-regex": "^4.1.0" - } - } - } - }, - "ansi-colors": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.4.tgz", - "integrity": "sha512-hHUXGagefjN2iRrID63xckIvotOXOojhQKWIPUZ4mNUZ9nLZW+7FMNoE1lOkEhNWYsx/7ysGIuJYCiMAA9FnrA==", - "dev": true - }, - "ansi-escapes": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.1.tgz", - "integrity": "sha512-JWF7ocqNrp8u9oqpgV+wH5ftbt+cfvv+PTjOvKLT3AdYly/LmORARfEVT1iyjwN+4MqE5UmVKoAdIBqeoCHgLA==", - "dev": true, - "requires": { - "type-fest": "^0.11.0" - }, - "dependencies": { - "type-fest": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.11.0.tgz", - "integrity": "sha512-OdjXJxnCN1AvyLSzeKIgXTXxV+99ZuXl3Hpo9XpJAv9MBcHrrJOQ5kV7ypXOuQie+AmWG25hLbiKdwYTifzcfQ==", - "dev": true - } - } - }, - "ansi-html": { - "version": "0.0.7", - "resolved": "https://registry.npmjs.org/ansi-html/-/ansi-html-0.0.7.tgz", - "integrity": "sha1-gTWEAhliqenm/QOflA0S9WynhZ4=", - "dev": true - }, - "ansi-regex": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", - "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", - "dev": true - }, - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "anymatch": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", - "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", - "dev": true, - "requires": { - "micromatch": "^3.1.4", - "normalize-path": "^2.1.1" - }, - "dependencies": { - "normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", - "dev": true, - "requires": { - "remove-trailing-separator": "^1.0.1" - } - } - } - }, - "aproba": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", - "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==", - "dev": true - }, - "argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "dev": true, - "requires": { - "sprintf-js": "~1.0.2" - } - }, - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", - "dev": true - }, - "arr-flatten": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", - "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", - "dev": true - }, - "arr-union": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", - "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=", - "dev": true - }, - "array-flatten": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-2.1.2.tgz", - "integrity": "sha512-hNfzcOV8W4NdualtqBFPyVO+54DSJuZGY9qT4pRroB6S9e3iiido2ISIC5h9R2sPJ8H3FHCIiEnsv1lPXO3KtQ==", - "dev": true - }, - "array-union": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", - "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=", - "dev": true, - "requires": { - "array-uniq": "^1.0.1" - } - }, - "array-uniq": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", - "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=", - "dev": true - }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "dev": true - }, - "asn1": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", - "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", - "dev": true, - "requires": { - "safer-buffer": "~2.1.0" - } - }, - "asn1.js": { - "version": "4.10.1", - "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-4.10.1.tgz", - "integrity": "sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw==", - "dev": true, - "requires": { - "bn.js": "^4.0.0", - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0" - }, - "dependencies": { - "bn.js": { - "version": "4.11.9", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz", - "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==", - "dev": true - } - } - }, - "assert": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/assert/-/assert-1.5.0.tgz", - "integrity": "sha512-EDsgawzwoun2CZkCgtxJbv392v4nbk9XDD06zI+kQYoBM/3RBWLlEyJARDOmhAAosBjWACEkKL6S+lIZtcAubA==", - "dev": true, - "requires": { - "object-assign": "^4.1.1", - "util": "0.10.3" - }, - "dependencies": { - "inherits": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", - "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=", - "dev": true - }, - "util": { - "version": "0.10.3", - "resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz", - "integrity": "sha1-evsa/lCAUkZInj23/g7TeTNqwPk=", - "dev": true, - "requires": { - "inherits": "2.0.1" - } - } - } - }, - "assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", - "dev": true - }, - "assign-symbols": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", - "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=", - "dev": true - }, - "async": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/async/-/async-2.6.3.tgz", - "integrity": "sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==", - "dev": true, - "requires": { - "lodash": "^4.17.14" - } - }, - "async-each": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.3.tgz", - "integrity": "sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ==", - "dev": true - }, - "async-limiter": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz", - "integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==", - "dev": true - }, - "asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", - "dev": true - }, - "atob": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", - "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==", - "dev": true - }, - "autocomplete.js": { - "version": "0.36.0", - "resolved": "https://registry.npmjs.org/autocomplete.js/-/autocomplete.js-0.36.0.tgz", - "integrity": "sha512-jEwUXnVMeCHHutUt10i/8ZiRaCb0Wo+ZyKxeGsYwBDtw6EJHqEeDrq4UwZRD8YBSvp3g6klP678il2eeiVXN2Q==", - "dev": true, - "requires": { - "immediate": "^3.2.3" - } - }, - "autoprefixer": { - "version": "9.8.0", - "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-9.8.0.tgz", - "integrity": "sha512-D96ZiIHXbDmU02dBaemyAg53ez+6F5yZmapmgKcjm35yEe1uVDYI8hGW3VYoGRaG290ZFf91YxHrR518vC0u/A==", - "dev": true, - "requires": { - "browserslist": "^4.12.0", - "caniuse-lite": "^1.0.30001061", - "chalk": "^2.4.2", - "normalize-range": "^0.1.2", - "num2fraction": "^1.2.2", - "postcss": "^7.0.30", - "postcss-value-parser": "^4.1.0" - } - }, - "aws-sign2": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", - "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=", - "dev": true - }, - "aws4": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.10.0.tgz", - "integrity": "sha512-3YDiu347mtVtjpyV3u5kVqQLP242c06zwDOgpeRnybmXlYYsLbtTrUBUm8i8srONt+FWobl5aibnU1030PeeuA==", - "dev": true - }, - "babel-loader": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-8.1.0.tgz", - "integrity": "sha512-7q7nC1tYOrqvUrN3LQK4GwSk/TQorZSOlO9C+RZDZpODgyN4ZlCqE5q9cDsyWOliN+aU9B4JX01xK9eJXowJLw==", - "dev": true, - "requires": { - "find-cache-dir": "^2.1.0", - "loader-utils": "^1.4.0", - "mkdirp": "^0.5.3", - "pify": "^4.0.1", - "schema-utils": "^2.6.5" - } - }, - "babel-plugin-dynamic-import-node": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.3.3.tgz", - "integrity": "sha512-jZVI+s9Zg3IqA/kdi0i6UDCybUI3aSBLnglhYbSSjKlV7yF1F/5LWv8MakQmvYpnbJDS6fcBL2KzHSxNCMtWSQ==", - "dev": true, - "requires": { - "object.assign": "^4.1.0" - } - }, - "balanced-match": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", - "dev": true - }, - "base": { - "version": "0.11.2", - "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", - "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", - "dev": true, - "requires": { - "cache-base": "^1.0.1", - "class-utils": "^0.3.5", - "component-emitter": "^1.2.1", - "define-property": "^1.0.0", - "isobject": "^3.0.1", - "mixin-deep": "^1.2.0", - "pascalcase": "^0.1.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - } - } - }, - "base64-js": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.1.tgz", - "integrity": "sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g==", - "dev": true - }, - "batch": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz", - "integrity": "sha1-3DQxT05nkxgJP8dgJyUl+UvyXBY=", - "dev": true - }, - "bcrypt-pbkdf": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", - "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", - "dev": true, - "requires": { - "tweetnacl": "^0.14.3" - } - }, - "big.js": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", - "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==", - "dev": true - }, - "binary-extensions": { - "version": "1.13.1", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz", - "integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==", - "dev": true - }, - "bindings": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", - "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", - "dev": true, - "optional": true, - "requires": { - "file-uri-to-path": "1.0.0" - } - }, - "bluebird": { - "version": "3.7.2", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", - "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", - "dev": true - }, - "bn.js": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.1.2.tgz", - "integrity": "sha512-40rZaf3bUNKTVYu9sIeeEGOg7g14Yvnj9kH7b50EiwX0Q7A6umbvfI5tvHaOERH0XigqKkfLkFQxzb4e6CIXnA==", - "dev": true - }, - "body-parser": { - "version": "1.19.0", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz", - "integrity": "sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==", - "dev": true, - "requires": { - "bytes": "3.1.0", - "content-type": "~1.0.4", - "debug": "2.6.9", - "depd": "~1.1.2", - "http-errors": "1.7.2", - "iconv-lite": "0.4.24", - "on-finished": "~2.3.0", - "qs": "6.7.0", - "raw-body": "2.4.0", - "type-is": "~1.6.17" - }, - "dependencies": { - "bytes": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", - "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==", - "dev": true - }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - }, - "qs": { - "version": "6.7.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz", - "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==", - "dev": true - } - } - }, - "bonjour": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/bonjour/-/bonjour-3.5.0.tgz", - "integrity": "sha1-jokKGD2O6aI5OzhExpGkK897yfU=", - "dev": true, - "requires": { - "array-flatten": "^2.1.0", - "deep-equal": "^1.0.1", - "dns-equal": "^1.0.0", - "dns-txt": "^2.0.2", - "multicast-dns": "^6.0.1", - "multicast-dns-service-types": "^1.1.0" - } - }, - "boolbase": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", - "integrity": "sha1-aN/1++YMUes3cl6p4+0xDcwed24=", - "dev": true - }, - "boxen": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/boxen/-/boxen-4.2.0.tgz", - "integrity": "sha512-eB4uT9RGzg2odpER62bBwSLvUeGC+WbRjjyyFhGsKnc8wp/m0+hQsMUvUe3H2V0D5vw0nBdO1hCJoZo5mKeuIQ==", - "dev": true, - "requires": { - "ansi-align": "^3.0.0", - "camelcase": "^5.3.1", - "chalk": "^3.0.0", - "cli-boxes": "^2.2.0", - "string-width": "^4.1.0", - "term-size": "^2.1.0", - "type-fest": "^0.8.1", - "widest-line": "^3.1.0" - }, - "dependencies": { - "ansi-styles": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", - "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", - "dev": true, - "requires": { - "@types/color-name": "^1.1.1", - "color-convert": "^2.0.1" - } - }, - "chalk": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", - "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, - "supports-color": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", - "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - } - } - }, - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dev": true, - "requires": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - } - }, - "brorand": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", - "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=", - "dev": true - }, - "browserify-aes": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", - "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", - "dev": true, - "requires": { - "buffer-xor": "^1.0.3", - "cipher-base": "^1.0.0", - "create-hash": "^1.1.0", - "evp_bytestokey": "^1.0.3", - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "browserify-cipher": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz", - "integrity": "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==", - "dev": true, - "requires": { - "browserify-aes": "^1.0.4", - "browserify-des": "^1.0.0", - "evp_bytestokey": "^1.0.0" - } - }, - "browserify-des": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.2.tgz", - "integrity": "sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==", - "dev": true, - "requires": { - "cipher-base": "^1.0.1", - "des.js": "^1.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "browserify-rsa": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.0.1.tgz", - "integrity": "sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ=", - "dev": true, - "requires": { - "bn.js": "^4.1.0", - "randombytes": "^2.0.1" - }, - "dependencies": { - "bn.js": { - "version": "4.11.9", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz", - "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==", - "dev": true - } - } - }, - "browserify-sign": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.2.0.tgz", - "integrity": "sha512-hEZC1KEeYuoHRqhGhTy6gWrpJA3ZDjFWv0DE61643ZnOXAKJb3u7yWcrU0mMc9SwAqK1n7myPGndkp0dFG7NFA==", - "dev": true, - "requires": { - "bn.js": "^5.1.1", - "browserify-rsa": "^4.0.1", - "create-hash": "^1.2.0", - "create-hmac": "^1.1.7", - "elliptic": "^6.5.2", - "inherits": "^2.0.4", - "parse-asn1": "^5.1.5", - "readable-stream": "^3.6.0", - "safe-buffer": "^5.2.0" - }, - "dependencies": { - "readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - }, - "safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "dev": true - } - } - }, - "browserify-zlib": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.2.0.tgz", - "integrity": "sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==", - "dev": true, - "requires": { - "pako": "~1.0.5" - } - }, - "browserslist": { - "version": "4.16.6", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.16.6.tgz", - "integrity": "sha512-Wspk/PqO+4W9qp5iUTJsa1B/QrYn1keNCcEP5OvP7WBwT4KaDly0uONYmC6Xa3Z5IqnUgS0KcgLYu1l74x0ZXQ==", - "dev": true, - "requires": { - "caniuse-lite": "^1.0.30001219", - "colorette": "^1.2.2", - "electron-to-chromium": "^1.3.723", - "escalade": "^3.1.1", - "node-releases": "^1.1.71" - } - }, - "buffer": { - "version": "4.9.2", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.2.tgz", - "integrity": "sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg==", - "dev": true, - "requires": { - "base64-js": "^1.0.2", - "ieee754": "^1.1.4", - "isarray": "^1.0.0" - }, - "dependencies": { - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - } - } - }, - "buffer-from": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", - "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", - "dev": true - }, - "buffer-indexof": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/buffer-indexof/-/buffer-indexof-1.1.1.tgz", - "integrity": "sha512-4/rOEg86jivtPTeOUUT61jJO1Ya1TrR/OkqCSZDyq84WJh3LuuiphBYJN+fm5xufIk4XAFcEwte/8WzC8If/1g==", - "dev": true - }, - "buffer-json": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/buffer-json/-/buffer-json-2.0.0.tgz", - "integrity": "sha512-+jjPFVqyfF1esi9fvfUs3NqM0pH1ziZ36VP4hmA/y/Ssfo/5w5xHKfTw9BwQjoJ1w/oVtpLomqwUHKdefGyuHw==", - "dev": true - }, - "buffer-xor": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", - "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=", - "dev": true - }, - "builtin-status-codes": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz", - "integrity": "sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug=", - "dev": true - }, - "bytes": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", - "integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg=", - "dev": true - }, - "cac": { - "version": "6.5.10", - "resolved": "https://registry.npmjs.org/cac/-/cac-6.5.10.tgz", - "integrity": "sha512-uxyxsID5p5kYlFFnhw86A4c8K5QTLRp6JM4AY2OtCq5lnnn4DGxV8YI1Z5rlt6KUjEKpA4qM+WZQshMoJY6dQQ==", - "dev": true - }, - "cacache": { - "version": "12.0.4", - "resolved": "https://registry.npmjs.org/cacache/-/cacache-12.0.4.tgz", - "integrity": "sha512-a0tMB40oefvuInr4Cwb3GerbL9xTj1D5yg0T5xrjGCGyfvbxseIXX7BAO/u/hIXdafzOI5JC3wDwHyf24buOAQ==", - "dev": true, - "requires": { - "bluebird": "^3.5.5", - "chownr": "^1.1.1", - "figgy-pudding": "^3.5.1", - "glob": "^7.1.4", - "graceful-fs": "^4.1.15", - "infer-owner": "^1.0.3", - "lru-cache": "^5.1.1", - "mississippi": "^3.0.0", - "mkdirp": "^0.5.1", - "move-concurrently": "^1.0.1", - "promise-inflight": "^1.0.1", - "rimraf": "^2.6.3", - "ssri": "^6.0.1", - "unique-filename": "^1.1.1", - "y18n": "^4.0.0" - } - }, - "cache-base": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", - "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", - "dev": true, - "requires": { - "collection-visit": "^1.0.0", - "component-emitter": "^1.2.1", - "get-value": "^2.0.6", - "has-value": "^1.0.0", - "isobject": "^3.0.1", - "set-value": "^2.0.0", - "to-object-path": "^0.3.0", - "union-value": "^1.0.0", - "unset-value": "^1.0.0" - } - }, - "cache-loader": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/cache-loader/-/cache-loader-3.0.1.tgz", - "integrity": "sha512-HzJIvGiGqYsFUrMjAJNDbVZoG7qQA+vy9AIoKs7s9DscNfki0I589mf2w6/tW+kkFH3zyiknoWV5Jdynu6b/zw==", - "dev": true, - "requires": { - "buffer-json": "^2.0.0", - "find-cache-dir": "^2.1.0", - "loader-utils": "^1.2.3", - "mkdirp": "^0.5.1", - "neo-async": "^2.6.1", - "schema-utils": "^1.0.0" - }, - "dependencies": { - "schema-utils": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", - "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", - "dev": true, - "requires": { - "ajv": "^6.1.0", - "ajv-errors": "^1.0.0", - "ajv-keywords": "^3.1.0" - } - } - } - }, - "cacheable-request": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-6.1.0.tgz", - "integrity": "sha512-Oj3cAGPCqOZX7Rz64Uny2GYAZNliQSqfbePrgAQ1wKAihYmCUnraBtJtKcGR4xz7wF+LoJC+ssFZvv5BgF9Igg==", - "dev": true, - "requires": { - "clone-response": "^1.0.2", - "get-stream": "^5.1.0", - "http-cache-semantics": "^4.0.0", - "keyv": "^3.0.0", - "lowercase-keys": "^2.0.0", - "normalize-url": "^4.1.0", - "responselike": "^1.0.2" - }, - "dependencies": { - "get-stream": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.1.0.tgz", - "integrity": "sha512-EXr1FOzrzTfGeL0gQdeFEvOMm2mzMOglyiOXSTpPC+iAjAKftbr3jpCMWynogwYnM+eSj9sHGc6wjIcDvYiygw==", - "dev": true, - "requires": { - "pump": "^3.0.0" - } - }, - "lowercase-keys": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", - "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==", - "dev": true - }, - "normalize-url": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-4.5.0.tgz", - "integrity": "sha512-2s47yzUxdexf1OhyRi4Em83iQk0aPvwTddtFz4hnSSw9dCEsLEGf6SwIO8ss/19S9iBb5sJaOuTvTGDeZI00BQ==", - "dev": true - } - } - }, - "call-me-maybe": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/call-me-maybe/-/call-me-maybe-1.0.1.tgz", - "integrity": "sha1-JtII6onje1y95gJQoV8DHBak1ms=", - "dev": true - }, - "caller-callsite": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/caller-callsite/-/caller-callsite-2.0.0.tgz", - "integrity": "sha1-hH4PzgoiN1CpoCfFSzNzGtMVQTQ=", - "dev": true, - "requires": { - "callsites": "^2.0.0" - } - }, - "caller-path": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-2.0.0.tgz", - "integrity": "sha1-Ro+DBE42mrIBD6xfBs7uFbsssfQ=", - "dev": true, - "requires": { - "caller-callsite": "^2.0.0" - } - }, - "callsites": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-2.0.0.tgz", - "integrity": "sha1-BuuE8A7qQT2oav/vrL/7Ngk7PFA=", - "dev": true - }, - "camel-case": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/camel-case/-/camel-case-3.0.0.tgz", - "integrity": "sha1-yjw2iKTpzzpM2nd9xNy8cTJJz3M=", - "dev": true, - "requires": { - "no-case": "^2.2.0", - "upper-case": "^1.1.1" - } - }, - "camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "dev": true - }, - "caniuse-api": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/caniuse-api/-/caniuse-api-3.0.0.tgz", - "integrity": "sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw==", - "dev": true, - "requires": { - "browserslist": "^4.0.0", - "caniuse-lite": "^1.0.0", - "lodash.memoize": "^4.1.2", - "lodash.uniq": "^4.5.0" - } - }, - "caniuse-lite": { - "version": "1.0.30001230", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001230.tgz", - "integrity": "sha512-5yBd5nWCBS+jWKTcHOzXwo5xzcj4ePE/yjtkZyUV1BTUmrBaA9MRGC+e7mxnqXSA90CmCA8L3eKLaSUkt099IQ==", - "dev": true - }, - "caseless": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", - "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=", - "dev": true - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "chokidar": { - "version": "2.1.8", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.8.tgz", - "integrity": "sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg==", - "dev": true, - "requires": { - "anymatch": "^2.0.0", - "async-each": "^1.0.1", - "braces": "^2.3.2", - "fsevents": "^1.2.7", - "glob-parent": "^3.1.0", - "inherits": "^2.0.3", - "is-binary-path": "^1.0.0", - "is-glob": "^4.0.0", - "normalize-path": "^3.0.0", - "path-is-absolute": "^1.0.0", - "readdirp": "^2.2.1", - "upath": "^1.1.1" - } - }, - "chownr": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", - "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", - "dev": true - }, - "chrome-trace-event": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.2.tgz", - "integrity": "sha512-9e/zx1jw7B4CO+c/RXoCsfg/x1AfUBioy4owYH0bJprEYAx5hRFLRhWBqHAG57D0ZM4H7vxbP7bPe0VwhQRYDQ==", - "dev": true, - "requires": { - "tslib": "^1.9.0" - } - }, - "ci-info": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", - "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==", - "dev": true - }, - "cipher-base": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", - "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "class-utils": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", - "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", - "dev": true, - "requires": { - "arr-union": "^3.1.0", - "define-property": "^0.2.5", - "isobject": "^3.0.0", - "static-extend": "^0.1.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - } - }, - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } - } - }, - "clean-css": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-4.2.3.tgz", - "integrity": "sha512-VcMWDN54ZN/DS+g58HYL5/n4Zrqe8vHJpGA8KdgUXFU4fuP/aHNw8eld9SyEIyabIMJX/0RaY/fplOo5hYLSFA==", - "dev": true, - "requires": { - "source-map": "~0.6.0" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - } - } - }, - "cli-boxes": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-2.2.0.tgz", - "integrity": "sha512-gpaBrMAizVEANOpfZp/EEUixTXDyGt7DFzdK5hU+UbWt/J0lB0w20ncZj59Z9a93xHb9u12zF5BS6i9RKbtg4w==", - "dev": true - }, - "clipboard": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/clipboard/-/clipboard-2.0.6.tgz", - "integrity": "sha512-g5zbiixBRk/wyKakSwCKd7vQXDjFnAMGHoEyBogG/bw9kTD9GvdAvaoRR1ALcEzt3pVKxZR0pViekPMIS0QyGg==", - "dev": true, - "optional": true, - "requires": { - "good-listener": "^1.2.2", - "select": "^1.1.2", - "tiny-emitter": "^2.0.0" - } - }, - "cliui": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", - "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", - "dev": true, - "requires": { - "string-width": "^3.1.0", - "strip-ansi": "^5.2.0", - "wrap-ansi": "^5.1.0" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true - }, - "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - } - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "requires": { - "ansi-regex": "^4.1.0" - } - } - } - }, - "clone-response": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.2.tgz", - "integrity": "sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws=", - "dev": true, - "requires": { - "mimic-response": "^1.0.0" - } - }, - "coa": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/coa/-/coa-2.0.2.tgz", - "integrity": "sha512-q5/jG+YQnSy4nRTV4F7lPepBJZ8qBNJJDBuJdoejDyLXgmL7IEo+Le2JDZudFTFt7mrCqIRaSjws4ygRCTCAXA==", - "dev": true, - "requires": { - "@types/q": "^1.5.1", - "chalk": "^2.4.1", - "q": "^1.1.2" - } - }, - "collection-visit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", - "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", - "dev": true, - "requires": { - "map-visit": "^1.0.0", - "object-visit": "^1.0.0" - } - }, - "color": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/color/-/color-3.1.2.tgz", - "integrity": "sha512-vXTJhHebByxZn3lDvDJYw4lR5+uB3vuoHsuYA5AKuxRVn5wzzIfQKGLBmgdVRHKTJYeK5rvJcHnrd0Li49CFpg==", - "dev": true, - "requires": { - "color-convert": "^1.9.1", - "color-string": "^1.5.2" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", - "dev": true - }, - "color-string": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.5.3.tgz", - "integrity": "sha512-dC2C5qeWoYkxki5UAXapdjqO672AM4vZuPGRQfO8b5HKuKGBbKWpITyDYN7TOFKvRW7kOgAn3746clDBMDJyQw==", - "dev": true, - "requires": { - "color-name": "^1.0.0", - "simple-swizzle": "^0.2.2" - } - }, - "colorette": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.2.2.tgz", - "integrity": "sha512-MKGMzyfeuutC/ZJ1cba9NqcNpfeqMUcYmyF1ZFY6/Cn7CNSAKx6a+s48sqLqyAiZuaP2TcqMhoo+dlwFnVxT9w==", - "dev": true - }, - "combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "dev": true, - "requires": { - "delayed-stream": "~1.0.0" - } - }, - "commander": { - "version": "2.17.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.17.1.tgz", - "integrity": "sha512-wPMUt6FnH2yzG95SA6mzjQOEKUU3aLaDEmzs1ti+1E9h+CsrZghRlqEM/EJ4KscsQVG8uNN4uVreUeT8+drlgg==", - "dev": true - }, - "commondir": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", - "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=", - "dev": true - }, - "component-emitter": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", - "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==", - "dev": true - }, - "compressible": { - "version": "2.0.18", - "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz", - "integrity": "sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==", - "dev": true, - "requires": { - "mime-db": ">= 1.43.0 < 2" - } - }, - "compression": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/compression/-/compression-1.7.4.tgz", - "integrity": "sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ==", - "dev": true, - "requires": { - "accepts": "~1.3.5", - "bytes": "3.0.0", - "compressible": "~2.0.16", - "debug": "2.6.9", - "on-headers": "~1.0.2", - "safe-buffer": "5.1.2", - "vary": "~1.1.2" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - } - } - }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", - "dev": true - }, - "concat-stream": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", - "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", - "dev": true, - "requires": { - "buffer-from": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^2.2.2", - "typedarray": "^0.0.6" - } - }, - "configstore": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/configstore/-/configstore-5.0.1.tgz", - "integrity": "sha512-aMKprgk5YhBNyH25hj8wGt2+D52Sw1DRRIzqBwLp2Ya9mFmY8KPvvtvmna8SxVR9JMZ4kzMD68N22vlaRpkeFA==", - "dev": true, - "requires": { - "dot-prop": "^5.2.0", - "graceful-fs": "^4.1.2", - "make-dir": "^3.0.0", - "unique-string": "^2.0.0", - "write-file-atomic": "^3.0.0", - "xdg-basedir": "^4.0.0" - }, - "dependencies": { - "make-dir": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", - "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", - "dev": true, - "requires": { - "semver": "^6.0.0" - } - }, - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true - } - } - }, - "connect-history-api-fallback": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/connect-history-api-fallback/-/connect-history-api-fallback-1.6.0.tgz", - "integrity": "sha512-e54B99q/OUoH64zYYRf3HBP5z24G38h5D3qXu23JGRoigpX5Ss4r9ZnDk3g0Z8uQC2x2lPaJ+UlWBc1ZWBWdLg==", - "dev": true - }, - "consola": { - "version": "2.12.2", - "resolved": "https://registry.npmjs.org/consola/-/consola-2.12.2.tgz", - "integrity": "sha512-c9mzemrAk57s3UIjepn8KKkuEH5fauMdot5kFSJUnqHcnApVS9Db8Rbv5AZ1Iz6lXzaGe9z1crQXhJtGX4h/Og==", - "dev": true - }, - "console-browserify": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.2.0.tgz", - "integrity": "sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA==", - "dev": true - }, - "consolidate": { - "version": "0.15.1", - "resolved": "https://registry.npmjs.org/consolidate/-/consolidate-0.15.1.tgz", - "integrity": "sha512-DW46nrsMJgy9kqAbPt5rKaCr7uFtpo4mSUvLHIUbJEjm0vo+aY5QLwBUq3FK4tRnJr/X0Psc0C4jf/h+HtXSMw==", - "dev": true, - "requires": { - "bluebird": "^3.1.1" - } - }, - "constants-browserify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz", - "integrity": "sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U=", - "dev": true - }, - "content-disposition": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.3.tgz", - "integrity": "sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g==", - "dev": true, - "requires": { - "safe-buffer": "5.1.2" - } - }, - "content-type": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", - "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==", - "dev": true - }, - "convert-source-map": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.7.0.tgz", - "integrity": "sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.1" - } - }, - "cookie": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz", - "integrity": "sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg==", - "dev": true - }, - "cookie-signature": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", - "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=", - "dev": true - }, - "copy-concurrently": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/copy-concurrently/-/copy-concurrently-1.0.5.tgz", - "integrity": "sha512-f2domd9fsVDFtaFcbaRZuYXwtdmnzqbADSwhSWYxYB/Q8zsdUUFMXVRwXGDMWmbEzAn1kdRrtI1T/KTFOL4X2A==", - "dev": true, - "requires": { - "aproba": "^1.1.1", - "fs-write-stream-atomic": "^1.0.8", - "iferr": "^0.1.5", - "mkdirp": "^0.5.1", - "rimraf": "^2.5.4", - "run-queue": "^1.0.0" - } - }, - "copy-descriptor": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", - "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=", - "dev": true - }, - "copy-webpack-plugin": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/copy-webpack-plugin/-/copy-webpack-plugin-5.1.1.tgz", - "integrity": "sha512-P15M5ZC8dyCjQHWwd4Ia/dm0SgVvZJMYeykVIVYXbGyqO4dWB5oyPHp9i7wjwo5LhtlhKbiBCdS2NvM07Wlybg==", - "dev": true, - "requires": { - "cacache": "^12.0.3", - "find-cache-dir": "^2.1.0", - "glob-parent": "^3.1.0", - "globby": "^7.1.1", - "is-glob": "^4.0.1", - "loader-utils": "^1.2.3", - "minimatch": "^3.0.4", - "normalize-path": "^3.0.0", - "p-limit": "^2.2.1", - "schema-utils": "^1.0.0", - "serialize-javascript": "^2.1.2", - "webpack-log": "^2.0.0" - }, - "dependencies": { - "globby": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/globby/-/globby-7.1.1.tgz", - "integrity": "sha1-+yzP+UAfhgCUXfral0QMypcrhoA=", - "dev": true, - "requires": { - "array-union": "^1.0.1", - "dir-glob": "^2.0.0", - "glob": "^7.1.2", - "ignore": "^3.3.5", - "pify": "^3.0.0", - "slash": "^1.0.0" - } - }, - "ignore": { - "version": "3.3.10", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-3.3.10.tgz", - "integrity": "sha512-Pgs951kaMm5GXP7MOvxERINe3gsaVjUWFm+UZPSq9xYriQAksyhg0csnS0KXSNRD5NmNdapXEpjxG49+AKh/ug==", - "dev": true - }, - "pify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", - "dev": true - }, - "schema-utils": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", - "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", - "dev": true, - "requires": { - "ajv": "^6.1.0", - "ajv-errors": "^1.0.0", - "ajv-keywords": "^3.1.0" - } - }, - "slash": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-1.0.0.tgz", - "integrity": "sha1-xB8vbDn8FtHNF61LXYlhFK5HDVU=", - "dev": true - } - } - }, - "core-js": { - "version": "3.6.5", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.6.5.tgz", - "integrity": "sha512-vZVEEwZoIsI+vPEuoF9Iqf5H7/M3eeQqWlQnYa8FSKKePuYTf5MWnxb5SDAzCa60b3JBRS5g9b+Dq7b1y/RCrA==", - "dev": true - }, - "core-js-compat": { - "version": "3.6.5", - "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.6.5.tgz", - "integrity": "sha512-7ItTKOhOZbznhXAQ2g/slGg1PJV5zDO/WdkTwi7UEOJmkvsE32PWvx6mKtDjiMpjnR2CNf6BAD6sSxIlv7ptng==", - "dev": true, - "requires": { - "browserslist": "^4.8.5", - "semver": "7.0.0" - }, - "dependencies": { - "semver": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.0.0.tgz", - "integrity": "sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A==", - "dev": true - } - } - }, - "core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", - "dev": true - }, - "cosmiconfig": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-5.2.1.tgz", - "integrity": "sha512-H65gsXo1SKjf8zmrJ67eJk8aIRKV5ff2D4uKZIBZShbhGSpEmsQOPW/SKMKYhSTrqR7ufy6RP69rPogdaPh/kA==", - "dev": true, - "requires": { - "import-fresh": "^2.0.0", - "is-directory": "^0.3.1", - "js-yaml": "^3.13.1", - "parse-json": "^4.0.0" - } - }, - "create-ecdh": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.3.tgz", - "integrity": "sha512-GbEHQPMOswGpKXM9kCWVrremUcBmjteUaQ01T9rkKCPDXfUHX0IoP9LpHYo2NPFampa4e+/pFDc3jQdxrxQLaw==", - "dev": true, - "requires": { - "bn.js": "^4.1.0", - "elliptic": "^6.0.0" - }, - "dependencies": { - "bn.js": { - "version": "4.11.9", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz", - "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==", - "dev": true - } - } - }, - "create-hash": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", - "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", - "dev": true, - "requires": { - "cipher-base": "^1.0.1", - "inherits": "^2.0.1", - "md5.js": "^1.3.4", - "ripemd160": "^2.0.1", - "sha.js": "^2.4.0" - } - }, - "create-hmac": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", - "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", - "dev": true, - "requires": { - "cipher-base": "^1.0.3", - "create-hash": "^1.1.0", - "inherits": "^2.0.1", - "ripemd160": "^2.0.0", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - } - }, - "cross-spawn": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", - "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", - "dev": true, - "requires": { - "nice-try": "^1.0.4", - "path-key": "^2.0.1", - "semver": "^5.5.0", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - } - }, - "crypto-browserify": { - "version": "3.12.0", - "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz", - "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==", - "dev": true, - "requires": { - "browserify-cipher": "^1.0.0", - "browserify-sign": "^4.0.0", - "create-ecdh": "^4.0.0", - "create-hash": "^1.1.0", - "create-hmac": "^1.1.0", - "diffie-hellman": "^5.0.0", - "inherits": "^2.0.1", - "pbkdf2": "^3.0.3", - "public-encrypt": "^4.0.0", - "randombytes": "^2.0.0", - "randomfill": "^1.0.3" - } - }, - "crypto-random-string": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-2.0.0.tgz", - "integrity": "sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==", - "dev": true - }, - "css": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/css/-/css-2.2.4.tgz", - "integrity": "sha512-oUnjmWpy0niI3x/mPL8dVEI1l7MnG3+HHyRPHf+YFSbK+svOhXpmSOcDURUh2aOCgl2grzrOPt1nHLuCVFULLw==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "source-map": "^0.6.1", - "source-map-resolve": "^0.5.2", - "urix": "^0.1.0" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - } - } - }, - "css-color-names": { - "version": "0.0.4", - "resolved": "https://registry.npmjs.org/css-color-names/-/css-color-names-0.0.4.tgz", - "integrity": "sha1-gIrcLnnPhHOAabZGyyDsJ762KeA=", - "dev": true - }, - "css-declaration-sorter": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/css-declaration-sorter/-/css-declaration-sorter-4.0.1.tgz", - "integrity": "sha512-BcxQSKTSEEQUftYpBVnsH4SF05NTuBokb19/sBt6asXGKZ/6VP7PLG1CBCkFDYOnhXhPh0jMhO6xZ71oYHXHBA==", - "dev": true, - "requires": { - "postcss": "^7.0.1", - "timsort": "^0.3.0" - } - }, - "css-loader": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-2.1.1.tgz", - "integrity": "sha512-OcKJU/lt232vl1P9EEDamhoO9iKY3tIjY5GU+XDLblAykTdgs6Ux9P1hTHve8nFKy5KPpOXOsVI/hIwi3841+w==", - "dev": true, - "requires": { - "camelcase": "^5.2.0", - "icss-utils": "^4.1.0", - "loader-utils": "^1.2.3", - "normalize-path": "^3.0.0", - "postcss": "^7.0.14", - "postcss-modules-extract-imports": "^2.0.0", - "postcss-modules-local-by-default": "^2.0.6", - "postcss-modules-scope": "^2.1.0", - "postcss-modules-values": "^2.0.0", - "postcss-value-parser": "^3.3.0", - "schema-utils": "^1.0.0" - }, - "dependencies": { - "postcss-value-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", - "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", - "dev": true - }, - "schema-utils": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", - "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", - "dev": true, - "requires": { - "ajv": "^6.1.0", - "ajv-errors": "^1.0.0", - "ajv-keywords": "^3.1.0" - } - } - } - }, - "css-parse": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/css-parse/-/css-parse-2.0.0.tgz", - "integrity": "sha1-pGjuZnwW2BzPBcWMONKpfHgNv9Q=", - "dev": true, - "requires": { - "css": "^2.0.0" - } - }, - "css-select": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/css-select/-/css-select-2.1.0.tgz", - "integrity": "sha512-Dqk7LQKpwLoH3VovzZnkzegqNSuAziQyNZUcrdDM401iY+R5NkGBXGmtO05/yaXQziALuPogeG0b7UAgjnTJTQ==", - "dev": true, - "requires": { - "boolbase": "^1.0.0", - "css-what": "^3.2.1", - "domutils": "^1.7.0", - "nth-check": "^1.0.2" - } - }, - "css-select-base-adapter": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/css-select-base-adapter/-/css-select-base-adapter-0.1.1.tgz", - "integrity": "sha512-jQVeeRG70QI08vSTwf1jHxp74JoZsr2XSgETae8/xC8ovSnL2WF87GTLO86Sbwdt2lK4Umg4HnnwMO4YF3Ce7w==", - "dev": true - }, - "css-tree": { - "version": "1.0.0-alpha.37", - "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.0.0-alpha.37.tgz", - "integrity": "sha512-DMxWJg0rnz7UgxKT0Q1HU/L9BeJI0M6ksor0OgqOnF+aRCDWg/N2641HmVyU9KVIu0OVVWOb2IpC9A+BJRnejg==", - "dev": true, - "requires": { - "mdn-data": "2.0.4", - "source-map": "^0.6.1" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - } - } - }, - "css-what": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/css-what/-/css-what-3.3.0.tgz", - "integrity": "sha512-pv9JPyatiPaQ6pf4OvD/dbfm0o5LviWmwxNWzblYf/1u9QZd0ihV+PMwy5jdQWQ3349kZmKEx9WXuSka2dM4cg==", - "dev": true - }, - "cssesc": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", - "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", - "dev": true - }, - "cssnano": { - "version": "4.1.10", - "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-4.1.10.tgz", - "integrity": "sha512-5wny+F6H4/8RgNlaqab4ktc3e0/blKutmq8yNlBFXA//nSFFAqAngjNVRzUvCgYROULmZZUoosL/KSoZo5aUaQ==", - "dev": true, - "requires": { - "cosmiconfig": "^5.0.0", - "cssnano-preset-default": "^4.0.7", - "is-resolvable": "^1.0.0", - "postcss": "^7.0.0" - } - }, - "cssnano-preset-default": { - "version": "4.0.7", - "resolved": "https://registry.npmjs.org/cssnano-preset-default/-/cssnano-preset-default-4.0.7.tgz", - "integrity": "sha512-x0YHHx2h6p0fCl1zY9L9roD7rnlltugGu7zXSKQx6k2rYw0Hi3IqxcoAGF7u9Q5w1nt7vK0ulxV8Lo+EvllGsA==", - "dev": true, - "requires": { - "css-declaration-sorter": "^4.0.1", - "cssnano-util-raw-cache": "^4.0.1", - "postcss": "^7.0.0", - "postcss-calc": "^7.0.1", - "postcss-colormin": "^4.0.3", - "postcss-convert-values": "^4.0.1", - "postcss-discard-comments": "^4.0.2", - "postcss-discard-duplicates": "^4.0.2", - "postcss-discard-empty": "^4.0.1", - "postcss-discard-overridden": "^4.0.1", - "postcss-merge-longhand": "^4.0.11", - "postcss-merge-rules": "^4.0.3", - "postcss-minify-font-values": "^4.0.2", - "postcss-minify-gradients": "^4.0.2", - "postcss-minify-params": "^4.0.2", - "postcss-minify-selectors": "^4.0.2", - "postcss-normalize-charset": "^4.0.1", - "postcss-normalize-display-values": "^4.0.2", - "postcss-normalize-positions": "^4.0.2", - "postcss-normalize-repeat-style": "^4.0.2", - "postcss-normalize-string": "^4.0.2", - "postcss-normalize-timing-functions": "^4.0.2", - "postcss-normalize-unicode": "^4.0.1", - "postcss-normalize-url": "^4.0.1", - "postcss-normalize-whitespace": "^4.0.2", - "postcss-ordered-values": "^4.1.2", - "postcss-reduce-initial": "^4.0.3", - "postcss-reduce-transforms": "^4.0.2", - "postcss-svgo": "^4.0.2", - "postcss-unique-selectors": "^4.0.1" - } - }, - "cssnano-util-get-arguments": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/cssnano-util-get-arguments/-/cssnano-util-get-arguments-4.0.0.tgz", - "integrity": "sha1-7ToIKZ8h11dBsg87gfGU7UnMFQ8=", - "dev": true - }, - "cssnano-util-get-match": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/cssnano-util-get-match/-/cssnano-util-get-match-4.0.0.tgz", - "integrity": "sha1-wOTKB/U4a7F+xeUiULT1lhNlFW0=", - "dev": true - }, - "cssnano-util-raw-cache": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/cssnano-util-raw-cache/-/cssnano-util-raw-cache-4.0.1.tgz", - "integrity": "sha512-qLuYtWK2b2Dy55I8ZX3ky1Z16WYsx544Q0UWViebptpwn/xDBmog2TLg4f+DBMg1rJ6JDWtn96WHbOKDWt1WQA==", - "dev": true, - "requires": { - "postcss": "^7.0.0" - } - }, - "cssnano-util-same-parent": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/cssnano-util-same-parent/-/cssnano-util-same-parent-4.0.1.tgz", - "integrity": "sha512-WcKx5OY+KoSIAxBW6UBBRay1U6vkYheCdjyVNDm85zt5K9mHoGOfsOsqIszfAqrQQFIIKgjh2+FDgIj/zsl21Q==", - "dev": true - }, - "csso": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/csso/-/csso-4.0.3.tgz", - "integrity": "sha512-NL3spysxUkcrOgnpsT4Xdl2aiEiBG6bXswAABQVHcMrfjjBisFOKwLDOmf4wf32aPdcJws1zds2B0Rg+jqMyHQ==", - "dev": true, - "requires": { - "css-tree": "1.0.0-alpha.39" - }, - "dependencies": { - "css-tree": { - "version": "1.0.0-alpha.39", - "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.0.0-alpha.39.tgz", - "integrity": "sha512-7UvkEYgBAHRG9Nt980lYxjsTrCyHFN53ky3wVsDkiMdVqylqRt+Zc+jm5qw7/qyOvN2dHSYtX0e4MbCCExSvnA==", - "dev": true, - "requires": { - "mdn-data": "2.0.6", - "source-map": "^0.6.1" - } - }, - "mdn-data": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.6.tgz", - "integrity": "sha512-rQvjv71olwNHgiTbfPZFkJtjNMciWgswYeciZhtvWLO8bmX3TnhyA62I6sTWOyZssWHJJjY6/KiWwqQsWWsqOA==", - "dev": true - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - } - } - }, - "cyclist": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/cyclist/-/cyclist-1.0.1.tgz", - "integrity": "sha1-WW6WmP0MgOEgOMK4LW6xs1tiJNk=", - "dev": true - }, - "dashdash": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", - "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", - "dev": true, - "requires": { - "assert-plus": "^1.0.0" - } - }, - "de-indent": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/de-indent/-/de-indent-1.0.2.tgz", - "integrity": "sha1-sgOOhG3DO6pXlhKNCAS0VbjB4h0=", - "dev": true - }, - "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - }, - "decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", - "dev": true - }, - "decode-uri-component": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", - "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=", - "dev": true - }, - "decompress-response": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz", - "integrity": "sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M=", - "dev": true, - "requires": { - "mimic-response": "^1.0.0" - } - }, - "deep-equal": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.1.1.tgz", - "integrity": "sha512-yd9c5AdiqVcR+JjcwUQb9DkhJc8ngNr0MahEBGvDiJw8puWab2yZlh+nkasOnZP+EGTAP6rRp2JzJhJZzvNF8g==", - "dev": true, - "requires": { - "is-arguments": "^1.0.4", - "is-date-object": "^1.0.1", - "is-regex": "^1.0.4", - "object-is": "^1.0.1", - "object-keys": "^1.1.1", - "regexp.prototype.flags": "^1.2.0" - } - }, - "deep-extend": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", - "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", - "dev": true - }, - "deepmerge": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-1.5.2.tgz", - "integrity": "sha512-95k0GDqvBjZavkuvzx/YqVLv/6YYa17fz6ILMSf7neqQITCPbnfEnQvEgMPNjH4kgobe7+WIL0yJEHku+H3qtQ==", - "dev": true - }, - "default-gateway": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/default-gateway/-/default-gateway-4.2.0.tgz", - "integrity": "sha512-h6sMrVB1VMWVrW13mSc6ia/DwYYw5MN6+exNu1OaJeFac5aSAvwM7lZ0NVfTABuSkQelr4h5oebg3KB1XPdjgA==", - "dev": true, - "requires": { - "execa": "^1.0.0", - "ip-regex": "^2.1.0" - } - }, - "defer-to-connect": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-1.1.3.tgz", - "integrity": "sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ==", - "dev": true - }, - "define-properties": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", - "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", - "dev": true, - "requires": { - "object-keys": "^1.0.12" - } - }, - "define-property": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", - "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", - "dev": true, - "requires": { - "is-descriptor": "^1.0.2", - "isobject": "^3.0.1" - } - }, - "del": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/del/-/del-4.1.1.tgz", - "integrity": "sha512-QwGuEUouP2kVwQenAsOof5Fv8K9t3D8Ca8NxcXKrIpEHjTXK5J2nXLdP+ALI1cgv8wj7KuwBhTwBkOZSJKM5XQ==", - "dev": true, - "requires": { - "@types/glob": "^7.1.1", - "globby": "^6.1.0", - "is-path-cwd": "^2.0.0", - "is-path-in-cwd": "^2.0.0", - "p-map": "^2.0.0", - "pify": "^4.0.1", - "rimraf": "^2.6.3" - }, - "dependencies": { - "globby": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-6.1.0.tgz", - "integrity": "sha1-9abXDoOV4hyFj7BInWTfAkJNUGw=", - "dev": true, - "requires": { - "array-union": "^1.0.1", - "glob": "^7.0.3", - "object-assign": "^4.0.1", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0" - }, - "dependencies": { - "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", - "dev": true - } - } - } - } - }, - "delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", - "dev": true - }, - "delegate": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/delegate/-/delegate-3.2.0.tgz", - "integrity": "sha512-IofjkYBZaZivn0V8nnsMJGBr4jVLxHDheKSW88PyxS5QC4Vo9ZbZVvhzlSxY87fVq3STR6r+4cGepyHkcWOQSw==", - "dev": true, - "optional": true - }, - "depd": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", - "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=", - "dev": true - }, - "des.js": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.1.tgz", - "integrity": "sha512-Q0I4pfFrv2VPd34/vfLrFOoRmlYj3OV50i7fskps1jZWK1kApMWWT9G6RRUeYedLcBDIhnSDaUvJMb3AhUlaEA==", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0" - } - }, - "destroy": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", - "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=", - "dev": true - }, - "detect-node": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.0.4.tgz", - "integrity": "sha512-ZIzRpLJrOj7jjP2miAtgqIfmzbxa4ZOr5jJc601zklsfEx9oTzmmj2nVpIPRpNlRTIh8lc1kyViIY7BWSGNmKw==", - "dev": true - }, - "diacritics": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/diacritics/-/diacritics-1.3.0.tgz", - "integrity": "sha1-PvqHMj67hj5mls67AILUj/PW96E=", - "dev": true - }, - "diffie-hellman": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", - "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==", - "dev": true, - "requires": { - "bn.js": "^4.1.0", - "miller-rabin": "^4.0.0", - "randombytes": "^2.0.0" - }, - "dependencies": { - "bn.js": { - "version": "4.11.9", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz", - "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==", - "dev": true - } - } - }, - "dir-glob": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-2.2.2.tgz", - "integrity": "sha512-f9LBi5QWzIW3I6e//uxZoLBlUt9kcp66qo0sSCxL6YZKc75R1c4MFCoe/LaZiBGmgujvQdxc5Bn3QhfyvK5Hsw==", - "dev": true, - "requires": { - "path-type": "^3.0.0" - } - }, - "dns-equal": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/dns-equal/-/dns-equal-1.0.0.tgz", - "integrity": "sha1-s55/HabrCnW6nBcySzR1PEfgZU0=", - "dev": true - }, - "dns-packet": { - "version": "1.3.4", - "resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-1.3.4.tgz", - "integrity": "sha512-BQ6F4vycLXBvdrJZ6S3gZewt6rcrks9KBgM9vrhW+knGRqc8uEdT7fuCwloc7nny5xNoMJ17HGH0R/6fpo8ECA==", - "dev": true, - "requires": { - "ip": "^1.1.0", - "safe-buffer": "^5.0.1" - } - }, - "dns-txt": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/dns-txt/-/dns-txt-2.0.2.tgz", - "integrity": "sha1-uR2Ab10nGI5Ks+fRB9iBocxGQrY=", - "dev": true, - "requires": { - "buffer-indexof": "^1.0.0" - } - }, - "docsearch.js": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/docsearch.js/-/docsearch.js-2.6.3.tgz", - "integrity": "sha512-GN+MBozuyz664ycpZY0ecdQE0ND/LSgJKhTLA0/v3arIS3S1Rpf2OJz6A35ReMsm91V5apcmzr5/kM84cvUg+A==", - "dev": true, - "requires": { - "algoliasearch": "^3.24.5", - "autocomplete.js": "0.36.0", - "hogan.js": "^3.0.2", - "request": "^2.87.0", - "stack-utils": "^1.0.1", - "to-factory": "^1.0.0", - "zepto": "^1.2.0" - } - }, - "dom-converter": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/dom-converter/-/dom-converter-0.2.0.tgz", - "integrity": "sha512-gd3ypIPfOMr9h5jIKq8E3sHOTCjeirnl0WK5ZdS1AW0Odt0b1PaWaHdJ4Qk4klv+YB9aJBS7mESXjFoDQPu6DA==", - "dev": true, - "requires": { - "utila": "~0.4" - } - }, - "dom-serializer": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.2.2.tgz", - "integrity": "sha512-2/xPb3ORsQ42nHYiSunXkDjPLBaEj/xTwUO4B7XCZQTRk7EBtTOPaygh10YAAh2OI1Qrp6NWfpAhzswj0ydt9g==", - "dev": true, - "requires": { - "domelementtype": "^2.0.1", - "entities": "^2.0.0" - }, - "dependencies": { - "domelementtype": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.0.1.tgz", - "integrity": "sha512-5HOHUDsYZWV8FGWN0Njbr/Rn7f/eWSQi1v7+HsUVwXgn8nWWlL64zKDkS0n8ZmQ3mlWOMuXOnR+7Nx/5tMO5AQ==", - "dev": true - }, - "entities": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/entities/-/entities-2.0.3.tgz", - "integrity": "sha512-MyoZ0jgnLvB2X3Lg5HqpFmn1kybDiIfEQmKzTb5apr51Rb+T3KdmMiqa70T+bhGnyv7bQ6WMj2QMHpGMmlrUYQ==", - "dev": true - } - } - }, - "dom-walk": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/dom-walk/-/dom-walk-0.1.2.tgz", - "integrity": "sha512-6QvTW9mrGeIegrFXdtQi9pk7O/nSK6lSdXW2eqUspN5LWD7UTji2Fqw5V2YLjBpHEoU9Xl/eUWNpDeZvoyOv2w==", - "dev": true - }, - "domain-browser": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-1.2.0.tgz", - "integrity": "sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA==", - "dev": true - }, - "domelementtype": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.1.tgz", - "integrity": "sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==", - "dev": true - }, - "domhandler": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.4.2.tgz", - "integrity": "sha512-JiK04h0Ht5u/80fdLMCEmV4zkNh2BcoMFBmZ/91WtYZ8qVXSKjiw7fXMgFPnHcSZgOo3XdinHvmnDUeMf5R4wA==", - "dev": true, - "requires": { - "domelementtype": "1" - } - }, - "domutils": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.7.0.tgz", - "integrity": "sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg==", - "dev": true, - "requires": { - "dom-serializer": "0", - "domelementtype": "1" - } - }, - "dot-prop": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.2.0.tgz", - "integrity": "sha512-uEUyaDKoSQ1M4Oq8l45hSE26SnTxL6snNnqvK/VWx5wJhmff5z0FUVJDKDanor/6w3kzE3i7XZOk+7wC0EXr1A==", - "dev": true, - "requires": { - "is-obj": "^2.0.0" - } - }, - "duplexer3": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz", - "integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=", - "dev": true - }, - "duplexify": { - "version": "3.7.1", - "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.7.1.tgz", - "integrity": "sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g==", - "dev": true, - "requires": { - "end-of-stream": "^1.0.0", - "inherits": "^2.0.1", - "readable-stream": "^2.0.0", - "stream-shift": "^1.0.0" - } - }, - "ecc-jsbn": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", - "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", - "dev": true, - "requires": { - "jsbn": "~0.1.0", - "safer-buffer": "^2.1.0" - } - }, - "ee-first": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", - "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=", - "dev": true - }, - "electron-to-chromium": { - "version": "1.3.739", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.739.tgz", - "integrity": "sha512-+LPJVRsN7hGZ9EIUUiWCpO7l4E3qBYHNadazlucBfsXBbccDFNKUBAgzE68FnkWGJPwD/AfKhSzL+G+Iqb8A4A==", - "dev": true - }, - "elliptic": { - "version": "6.5.3", - "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.3.tgz", - "integrity": "sha512-IMqzv5wNQf+E6aHeIqATs0tOLeOTwj1QKbRcS3jBbYkl5oLAserA8yJTT7/VyHUYG91PRmPyeQDObKLPpeS4dw==", - "dev": true, - "requires": { - "bn.js": "^4.4.0", - "brorand": "^1.0.1", - "hash.js": "^1.0.0", - "hmac-drbg": "^1.0.0", - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0", - "minimalistic-crypto-utils": "^1.0.0" - }, - "dependencies": { - "bn.js": { - "version": "4.11.9", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz", - "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==", - "dev": true - } - } - }, - "emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true - }, - "emojis-list": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", - "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==", - "dev": true - }, - "encodeurl": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", - "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=", - "dev": true - }, - "end-of-stream": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", - "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", - "dev": true, - "requires": { - "once": "^1.4.0" - } - }, - "enhanced-resolve": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-4.1.1.tgz", - "integrity": "sha512-98p2zE+rL7/g/DzMHMTF4zZlCgeVdJ7yr6xzEpJRYwFYrGi9ANdn5DnJURg6RpBkyk60XYDnWIv51VfIhfNGuA==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "memory-fs": "^0.5.0", - "tapable": "^1.0.0" - }, - "dependencies": { - "memory-fs": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.5.0.tgz", - "integrity": "sha512-jA0rdU5KoQMC0e6ppoNRtpp6vjFq6+NY7r8hywnC7V+1Xj/MtHwGIbB1QaK/dunyjWteJzmkpd7ooeWg10T7GA==", - "dev": true, - "requires": { - "errno": "^0.1.3", - "readable-stream": "^2.0.1" - } - } - } - }, - "entities": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz", - "integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==", - "dev": true - }, - "envify": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/envify/-/envify-4.1.0.tgz", - "integrity": "sha512-IKRVVoAYr4pIx4yIWNsz9mOsboxlNXiu7TNBnem/K/uTHdkyzXWDzHCK7UTolqBbgaBz0tQHsD3YNls0uIIjiw==", - "dev": true, - "requires": { - "esprima": "^4.0.0", - "through": "~2.3.4" - } - }, - "envinfo": { - "version": "7.5.1", - "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.5.1.tgz", - "integrity": "sha512-hQBkDf2iO4Nv0CNHpCuSBeaSrveU6nThVxFGTrq/eDlV716UQk09zChaJae4mZRsos1x4YLY2TaH3LHUae3ZmQ==", - "dev": true - }, - "errno": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.7.tgz", - "integrity": "sha512-MfrRBDWzIWifgq6tJj60gkAwtLNb6sQPlcFrSOflcP1aFmmruKQ2wRnze/8V6kgyz7H3FF8Npzv78mZ7XLLflg==", - "dev": true, - "requires": { - "prr": "~1.0.1" - } - }, - "error-ex": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", - "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", - "dev": true, - "requires": { - "is-arrayish": "^0.2.1" - } - }, - "es-abstract": { - "version": "1.17.5", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.5.tgz", - "integrity": "sha512-BR9auzDbySxOcfog0tLECW8l28eRGpDpU3Dm3Hp4q/N+VtLTmyj4EUN088XZWQDW/hzj6sYRDXeOFsaAODKvpg==", - "dev": true, - "requires": { - "es-to-primitive": "^1.2.1", - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1", - "is-callable": "^1.1.5", - "is-regex": "^1.0.5", - "object-inspect": "^1.7.0", - "object-keys": "^1.1.1", - "object.assign": "^4.1.0", - "string.prototype.trimleft": "^2.1.1", - "string.prototype.trimright": "^2.1.1" - } - }, - "es-to-primitive": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", - "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", - "dev": true, - "requires": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" - } - }, - "es6-promise": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", - "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==", - "dev": true - }, - "escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", - "dev": true - }, - "escape-goat": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/escape-goat/-/escape-goat-2.1.1.tgz", - "integrity": "sha512-8/uIhbG12Csjy2JEW7D9pHbreaVaS/OpN3ycnyvElTdwM5n6GY6W6e2IPemfvGZeUMqZ9A/3GqIZMgKnBhAw/Q==", - "dev": true - }, - "escape-html": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", - "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=", - "dev": true - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", - "dev": true - }, - "eslint-scope": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.3.tgz", - "integrity": "sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg==", - "dev": true, - "requires": { - "esrecurse": "^4.1.0", - "estraverse": "^4.1.1" - } - }, - "esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", - "dev": true - }, - "esrecurse": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz", - "integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==", - "dev": true, - "requires": { - "estraverse": "^4.1.0" - } - }, - "estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", - "dev": true - }, - "esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "dev": true - }, - "etag": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", - "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=", - "dev": true - }, - "eventemitter3": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.4.tgz", - "integrity": "sha512-rlaVLnVxtxvoyLsQQFBx53YmXHDxRIzzTLbdfxqi4yocpSjAxXwkU0cScM5JgSKMqEhrZpnvQ2D9gjylR0AimQ==", - "dev": true - }, - "events": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/events/-/events-1.1.1.tgz", - "integrity": "sha1-nr23Y1rQmccNzEwqH1AEKI6L2SQ=", - "dev": true - }, - "eventsource": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/eventsource/-/eventsource-1.0.7.tgz", - "integrity": "sha512-4Ln17+vVT0k8aWq+t/bF5arcS3EpT9gYtW66EPacdj/mAFevznsnyoHLPy2BA8gbIQeIHoPsvwmfBftfcG//BQ==", - "dev": true, - "requires": { - "original": "^1.0.0" - } - }, - "evp_bytestokey": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", - "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", - "dev": true, - "requires": { - "md5.js": "^1.3.4", - "safe-buffer": "^5.1.1" - } - }, - "execa": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", - "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", - "dev": true, - "requires": { - "cross-spawn": "^6.0.0", - "get-stream": "^4.0.0", - "is-stream": "^1.1.0", - "npm-run-path": "^2.0.0", - "p-finally": "^1.0.0", - "signal-exit": "^3.0.0", - "strip-eof": "^1.0.0" - } - }, - "expand-brackets": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", - "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", - "dev": true, - "requires": { - "debug": "^2.3.3", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "posix-character-classes": "^0.1.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - } - }, - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - } - } - }, - "express": { - "version": "4.17.1", - "resolved": "https://registry.npmjs.org/express/-/express-4.17.1.tgz", - "integrity": "sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g==", - "dev": true, - "requires": { - "accepts": "~1.3.7", - "array-flatten": "1.1.1", - "body-parser": "1.19.0", - "content-disposition": "0.5.3", - "content-type": "~1.0.4", - "cookie": "0.4.0", - "cookie-signature": "1.0.6", - "debug": "2.6.9", - "depd": "~1.1.2", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "finalhandler": "~1.1.2", - "fresh": "0.5.2", - "merge-descriptors": "1.0.1", - "methods": "~1.1.2", - "on-finished": "~2.3.0", - "parseurl": "~1.3.3", - "path-to-regexp": "0.1.7", - "proxy-addr": "~2.0.5", - "qs": "6.7.0", - "range-parser": "~1.2.1", - "safe-buffer": "5.1.2", - "send": "0.17.1", - "serve-static": "1.14.1", - "setprototypeof": "1.1.1", - "statuses": "~1.5.0", - "type-is": "~1.6.18", - "utils-merge": "1.0.1", - "vary": "~1.1.2" - }, - "dependencies": { - "array-flatten": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", - "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=", - "dev": true - }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - }, - "qs": { - "version": "6.7.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz", - "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==", - "dev": true - } - } - }, - "extend": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", - "dev": true - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "extglob": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", - "dev": true, - "requires": { - "array-unique": "^0.3.2", - "define-property": "^1.0.0", - "expand-brackets": "^2.1.4", - "extend-shallow": "^2.0.1", - "fragment-cache": "^0.2.1", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - } - } - }, - "extsprintf": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", - "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=", - "dev": true - }, - "fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true - }, - "fast-glob": { - "version": "2.2.7", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-2.2.7.tgz", - "integrity": "sha512-g1KuQwHOZAmOZMuBtHdxDtju+T2RT8jgCC9aANsbpdiDDTSnjgfuVsIBNKbUeJI3oKMRExcfNDtJl4OhbffMsw==", - "dev": true, - "requires": { - "@mrmlnc/readdir-enhanced": "^2.2.1", - "@nodelib/fs.stat": "^1.1.2", - "glob-parent": "^3.1.0", - "is-glob": "^4.0.0", - "merge2": "^1.2.3", - "micromatch": "^3.1.10" - } - }, - "fast-json-stable-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", - "dev": true - }, - "faye-websocket": { - "version": "0.10.0", - "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.10.0.tgz", - "integrity": "sha1-TkkvjQTftviQA1B/btvy1QHnxvQ=", - "dev": true, - "requires": { - "websocket-driver": ">=0.5.1" - } - }, - "figgy-pudding": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/figgy-pudding/-/figgy-pudding-3.5.2.tgz", - "integrity": "sha512-0btnI/H8f2pavGMN8w40mlSKOfTK2SVJmBfBeVIj3kNw0swwgzyRq0d5TJVOwodFmtvpPeWPN/MCcfuWF0Ezbw==", - "dev": true - }, - "figures": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", - "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", - "dev": true, - "requires": { - "escape-string-regexp": "^1.0.5" - } - }, - "file-loader": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/file-loader/-/file-loader-3.0.1.tgz", - "integrity": "sha512-4sNIOXgtH/9WZq4NvlfU3Opn5ynUsqBwSLyM+I7UOwdGigTBYfVVQEwe/msZNX/j4pCJTIM14Fsw66Svo1oVrw==", - "dev": true, - "requires": { - "loader-utils": "^1.0.2", - "schema-utils": "^1.0.0" - }, - "dependencies": { - "schema-utils": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", - "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", - "dev": true, - "requires": { - "ajv": "^6.1.0", - "ajv-errors": "^1.0.0", - "ajv-keywords": "^3.1.0" - } - } - } - }, - "file-uri-to-path": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", - "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", - "dev": true, - "optional": true - }, - "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - } - }, - "finalhandler": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", - "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", - "dev": true, - "requires": { - "debug": "2.6.9", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "on-finished": "~2.3.0", - "parseurl": "~1.3.3", - "statuses": "~1.5.0", - "unpipe": "~1.0.0" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - } - } - }, - "find-cache-dir": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-2.1.0.tgz", - "integrity": "sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ==", - "dev": true, - "requires": { - "commondir": "^1.0.1", - "make-dir": "^2.0.0", - "pkg-dir": "^3.0.0" - } - }, - "find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "dev": true, - "requires": { - "locate-path": "^3.0.0" - } - }, - "flush-write-stream": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/flush-write-stream/-/flush-write-stream-1.1.1.tgz", - "integrity": "sha512-3Z4XhFZ3992uIq0XOqb9AreonueSYphE6oYbpt5+3u06JWklbsPkNv3ZKkP9Bz/r+1MWCaMoSQ28P85+1Yc77w==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "readable-stream": "^2.3.6" - } - }, - "follow-redirects": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.11.0.tgz", - "integrity": "sha512-KZm0V+ll8PfBrKwMzdo5D13b1bur9Iq9Zd/RMmAoQQcl2PxxFml8cxXPaaPYVbV0RjNjq1CU7zIzAOqtUPudmA==", - "dev": true, - "requires": { - "debug": "^3.0.0" - }, - "dependencies": { - "debug": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", - "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - } - } - }, - "for-in": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", - "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", - "dev": true - }, - "foreach": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/foreach/-/foreach-2.0.5.tgz", - "integrity": "sha1-C+4AUBiusmDQo6865ljdATbsG5k=", - "dev": true - }, - "forever-agent": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", - "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=", - "dev": true - }, - "form-data": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", - "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", - "dev": true, - "requires": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.6", - "mime-types": "^2.1.12" - } - }, - "forwarded": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz", - "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=", - "dev": true - }, - "fragment-cache": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", - "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", - "dev": true, - "requires": { - "map-cache": "^0.2.2" - } - }, - "fresh": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", - "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=", - "dev": true - }, - "from2": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/from2/-/from2-2.3.0.tgz", - "integrity": "sha1-i/tVAr3kpNNs/e6gB/zKIdfjgq8=", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "readable-stream": "^2.0.0" - } - }, - "fs-extra": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", - "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - } - }, - "fs-write-stream-atomic": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz", - "integrity": "sha1-tH31NJPvkR33VzHnCp3tAYnbQMk=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "iferr": "^0.1.5", - "imurmurhash": "^0.1.4", - "readable-stream": "1 || 2" - } - }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", - "dev": true - }, - "fsevents": { - "version": "1.2.13", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz", - "integrity": "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==", - "dev": true, - "optional": true, - "requires": { - "bindings": "^1.5.0", - "nan": "^2.12.1" - } - }, - "function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", - "dev": true - }, - "gensync": { - "version": "1.0.0-beta.1", - "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.1.tgz", - "integrity": "sha512-r8EC6NO1sngH/zdD9fiRDLdcgnbayXah+mLgManTaIZJqEC1MZstmnox8KpnI2/fxQwrp5OpCOYWLp4rBl4Jcg==", - "dev": true - }, - "get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "dev": true - }, - "get-stream": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", - "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", - "dev": true, - "requires": { - "pump": "^3.0.0" - } - }, - "get-value": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", - "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=", - "dev": true - }, - "getpass": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", - "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", - "dev": true, - "requires": { - "assert-plus": "^1.0.0" - } - }, - "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "glob-parent": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", - "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", - "dev": true, - "requires": { - "is-glob": "^3.1.0", - "path-dirname": "^1.0.0" - }, - "dependencies": { - "is-glob": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", - "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", - "dev": true, - "requires": { - "is-extglob": "^2.1.0" - } - } - } - }, - "glob-to-regexp": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.3.0.tgz", - "integrity": "sha1-jFoUlNIGbFcMw7/kSWF1rMTVAqs=", - "dev": true - }, - "global": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/global/-/global-4.4.0.tgz", - "integrity": "sha512-wv/LAoHdRE3BeTGz53FAamhGlPLhlssK45usmGFThIi4XqnBmjKQ16u+RNbP7WvigRZDxUsM0J3gcQ5yicaL0w==", - "dev": true, - "requires": { - "min-document": "^2.19.0", - "process": "^0.11.10" - } - }, - "global-dirs": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-2.0.1.tgz", - "integrity": "sha512-5HqUqdhkEovj2Of/ms3IeS/EekcO54ytHRLV4PEY2rhRwrHXLQjeVEES0Lhka0xwNDtGYn58wyC4s5+MHsOO6A==", - "dev": true, - "requires": { - "ini": "^1.3.5" - } - }, - "globals": { - "version": "11.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", - "dev": true - }, - "globby": { - "version": "9.2.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-9.2.0.tgz", - "integrity": "sha512-ollPHROa5mcxDEkwg6bPt3QbEf4pDQSNtd6JPL1YvOvAo/7/0VAm9TccUeoTmarjPw4pfUthSCqcyfNB1I3ZSg==", - "dev": true, - "requires": { - "@types/glob": "^7.1.1", - "array-union": "^1.0.2", - "dir-glob": "^2.2.2", - "fast-glob": "^2.2.6", - "glob": "^7.1.3", - "ignore": "^4.0.3", - "pify": "^4.0.1", - "slash": "^2.0.0" - } - }, - "good-listener": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/good-listener/-/good-listener-1.2.2.tgz", - "integrity": "sha1-1TswzfkxPf+33JoNR3CWqm0UXFA=", - "dev": true, - "optional": true, - "requires": { - "delegate": "^3.1.2" - } - }, - "got": { - "version": "9.6.0", - "resolved": "https://registry.npmjs.org/got/-/got-9.6.0.tgz", - "integrity": "sha512-R7eWptXuGYxwijs0eV+v3o6+XH1IqVK8dJOEecQfTmkncw9AV4dcw/Dhxi8MdlqPthxxpZyizMzyg8RTmEsG+Q==", - "dev": true, - "requires": { - "@sindresorhus/is": "^0.14.0", - "@szmarczak/http-timer": "^1.1.2", - "cacheable-request": "^6.0.0", - "decompress-response": "^3.3.0", - "duplexer3": "^0.1.4", - "get-stream": "^4.1.0", - "lowercase-keys": "^1.0.1", - "mimic-response": "^1.0.1", - "p-cancelable": "^1.0.0", - "to-readable-stream": "^1.0.0", - "url-parse-lax": "^3.0.0" - } - }, - "graceful-fs": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", - "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", - "dev": true - }, - "gray-matter": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/gray-matter/-/gray-matter-4.0.2.tgz", - "integrity": "sha512-7hB/+LxrOjq/dd8APlK0r24uL/67w7SkYnfwhNFwg/VDIGWGmduTDYf3WNstLW2fbbmRwrDGCVSJ2isuf2+4Hw==", - "dev": true, - "requires": { - "js-yaml": "^3.11.0", - "kind-of": "^6.0.2", - "section-matter": "^1.0.0", - "strip-bom-string": "^1.0.0" - } - }, - "handle-thing": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/handle-thing/-/handle-thing-2.0.1.tgz", - "integrity": "sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg==", - "dev": true - }, - "har-schema": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", - "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=", - "dev": true - }, - "har-validator": { - "version": "5.1.3", - "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.3.tgz", - "integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==", - "dev": true, - "requires": { - "ajv": "^6.5.5", - "har-schema": "^2.0.0" - } - }, - "has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "dev": true, - "requires": { - "function-bind": "^1.1.1" - } - }, - "has-ansi": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", - "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true - } - } - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true - }, - "has-symbols": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz", - "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==", - "dev": true - }, - "has-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", - "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", - "dev": true, - "requires": { - "get-value": "^2.0.6", - "has-values": "^1.0.0", - "isobject": "^3.0.0" - } - }, - "has-values": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", - "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=", - "dev": true, - "requires": { - "is-number": "^3.0.0", - "kind-of": "^4.0.0" - }, - "dependencies": { - "kind-of": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", - "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "has-yarn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/has-yarn/-/has-yarn-2.1.0.tgz", - "integrity": "sha512-UqBRqi4ju7T+TqGNdqAO0PaSVGsDGJUBQvk9eUWNGRY1CFGDzYhLWoM7JQEemnlvVcv/YEmc2wNW8BC24EnUsw==", - "dev": true - }, - "hash-base": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz", - "integrity": "sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==", - "dev": true, - "requires": { - "inherits": "^2.0.4", - "readable-stream": "^3.6.0", - "safe-buffer": "^5.2.0" - }, - "dependencies": { - "readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - }, - "safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "dev": true - } - } - }, - "hash-sum": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/hash-sum/-/hash-sum-1.0.2.tgz", - "integrity": "sha1-M7QHd3VMZDJXPBIMw4CLvRDUfwQ=", - "dev": true - }, - "hash.js": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", - "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "minimalistic-assert": "^1.0.1" - } - }, - "he": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", - "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", - "dev": true - }, - "hex-color-regex": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/hex-color-regex/-/hex-color-regex-1.1.0.tgz", - "integrity": "sha512-l9sfDFsuqtOqKDsQdqrMRk0U85RZc0RtOR9yPI7mRVOa4FsR/BVnZ0shmQRM96Ji99kYZP/7hn1cedc1+ApsTQ==", - "dev": true - }, - "hmac-drbg": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", - "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", - "dev": true, - "requires": { - "hash.js": "^1.0.3", - "minimalistic-assert": "^1.0.0", - "minimalistic-crypto-utils": "^1.0.1" - } - }, - "hogan.js": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/hogan.js/-/hogan.js-3.0.2.tgz", - "integrity": "sha1-TNnhq9QpQUbnZ55B14mHMrAse/0=", - "dev": true, - "requires": { - "mkdirp": "0.3.0", - "nopt": "1.0.10" - }, - "dependencies": { - "mkdirp": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.3.0.tgz", - "integrity": "sha1-G79asbqCevI1dRQ0kEJkVfSB/h4=", - "dev": true - } - } - }, - "hpack.js": { - "version": "2.1.6", - "resolved": "https://registry.npmjs.org/hpack.js/-/hpack.js-2.1.6.tgz", - "integrity": "sha1-h3dMCUnlE/QuhFdbPEVoH63ioLI=", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "obuf": "^1.0.0", - "readable-stream": "^2.0.1", - "wbuf": "^1.1.0" - } - }, - "hsl-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/hsl-regex/-/hsl-regex-1.0.0.tgz", - "integrity": "sha1-1JMwx4ntgZ4nakwNJy3/owsY/m4=", - "dev": true - }, - "hsla-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/hsla-regex/-/hsla-regex-1.0.0.tgz", - "integrity": "sha1-wc56MWjIxmFAM6S194d/OyJfnDg=", - "dev": true - }, - "html-comment-regex": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/html-comment-regex/-/html-comment-regex-1.1.2.tgz", - "integrity": "sha512-P+M65QY2JQ5Y0G9KKdlDpo0zK+/OHptU5AaBwUfAIDJZk1MYf32Frm84EcOytfJE0t5JvkAnKlmjsXDnWzCJmQ==", - "dev": true - }, - "html-entities": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-1.3.1.tgz", - "integrity": "sha512-rhE/4Z3hIhzHAUKbW8jVcCyuT5oJCXXqhN/6mXXVCpzTmvJnoH2HL/bt3EZ6p55jbFJBeAe1ZNpL5BugLujxNA==", - "dev": true - }, - "html-minifier": { - "version": "3.5.21", - "resolved": "https://registry.npmjs.org/html-minifier/-/html-minifier-3.5.21.tgz", - "integrity": "sha512-LKUKwuJDhxNa3uf/LPR/KVjm/l3rBqtYeCOAekvG8F1vItxMUpueGd94i/asDDr8/1u7InxzFA5EeGjhhG5mMA==", - "dev": true, - "requires": { - "camel-case": "3.0.x", - "clean-css": "4.2.x", - "commander": "2.17.x", - "he": "1.2.x", - "param-case": "2.1.x", - "relateurl": "0.2.x", - "uglify-js": "3.4.x" - } - }, - "html-tags": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/html-tags/-/html-tags-2.0.0.tgz", - "integrity": "sha1-ELMKOGCF9Dzt41PMj6fLDe7qZos=", - "dev": true - }, - "htmlparser2": { - "version": "3.10.1", - "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.10.1.tgz", - "integrity": "sha512-IgieNijUMbkDovyoKObU1DUhm1iwNYE/fuifEoEHfd1oZKZDaONBSkal7Y01shxsM49R4XaMdGez3WnF9UfiCQ==", - "dev": true, - "requires": { - "domelementtype": "^1.3.1", - "domhandler": "^2.3.0", - "domutils": "^1.5.1", - "entities": "^1.1.1", - "inherits": "^2.0.1", - "readable-stream": "^3.1.1" - }, - "dependencies": { - "readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - } - } - }, - "http-cache-semantics": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz", - "integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==", - "dev": true - }, - "http-deceiver": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/http-deceiver/-/http-deceiver-1.2.7.tgz", - "integrity": "sha1-+nFolEq5pRnTN8sL7HKE3D5yPYc=", - "dev": true - }, - "http-errors": { - "version": "1.7.2", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz", - "integrity": "sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==", - "dev": true, - "requires": { - "depd": "~1.1.2", - "inherits": "2.0.3", - "setprototypeof": "1.1.1", - "statuses": ">= 1.5.0 < 2", - "toidentifier": "1.0.0" - }, - "dependencies": { - "inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", - "dev": true - } - } - }, - "http-proxy": { - "version": "1.18.1", - "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.1.tgz", - "integrity": "sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==", - "dev": true, - "requires": { - "eventemitter3": "^4.0.0", - "follow-redirects": "^1.0.0", - "requires-port": "^1.0.0" - } - }, - "http-proxy-middleware": { - "version": "0.19.1", - "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-0.19.1.tgz", - "integrity": "sha512-yHYTgWMQO8VvwNS22eLLloAkvungsKdKTLO8AJlftYIKNfJr3GK3zK0ZCfzDDGUBttdGc8xFy1mCitvNKQtC3Q==", - "dev": true, - "requires": { - "http-proxy": "^1.17.0", - "is-glob": "^4.0.0", - "lodash": "^4.17.11", - "micromatch": "^3.1.10" - } - }, - "http-signature": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", - "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", - "dev": true, - "requires": { - "assert-plus": "^1.0.0", - "jsprim": "^1.2.2", - "sshpk": "^1.7.0" - } - }, - "https-browserify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz", - "integrity": "sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM=", - "dev": true - }, - "iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "dev": true, - "requires": { - "safer-buffer": ">= 2.1.2 < 3" - } - }, - "icss-replace-symbols": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/icss-replace-symbols/-/icss-replace-symbols-1.1.0.tgz", - "integrity": "sha1-Bupvg2ead0njhs/h/oEq5dsiPe0=", - "dev": true - }, - "icss-utils": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-4.1.1.tgz", - "integrity": "sha512-4aFq7wvWyMHKgxsH8QQtGpvbASCf+eM3wPRLI6R+MgAnTCZ6STYsRvttLvRWK0Nfif5piF394St3HeJDaljGPA==", - "dev": true, - "requires": { - "postcss": "^7.0.14" - } - }, - "ieee754": { - "version": "1.1.13", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.13.tgz", - "integrity": "sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg==", - "dev": true - }, - "iferr": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/iferr/-/iferr-0.1.5.tgz", - "integrity": "sha1-xg7taebY/bazEEofy8ocGS3FtQE=", - "dev": true - }, - "ignore": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", - "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", - "dev": true - }, - "immediate": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.3.0.tgz", - "integrity": "sha512-HR7EVodfFUdQCTIeySw+WDRFJlPcLOJbXfwwZ7Oom6tjsvZ3bOkCDJHehQC3nxJrv7+f9XecwazynjU8e4Vw3Q==", - "dev": true - }, - "import-cwd": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/import-cwd/-/import-cwd-2.1.0.tgz", - "integrity": "sha1-qmzzbnInYShcs3HsZRn1PiQ1sKk=", - "dev": true, - "requires": { - "import-from": "^2.1.0" - } - }, - "import-fresh": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-2.0.0.tgz", - "integrity": "sha1-2BNVwVYS04bGH53dOSLUMEgipUY=", - "dev": true, - "requires": { - "caller-path": "^2.0.0", - "resolve-from": "^3.0.0" - } - }, - "import-from": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/import-from/-/import-from-2.1.0.tgz", - "integrity": "sha1-M1238qev/VOqpHHUuAId7ja387E=", - "dev": true, - "requires": { - "resolve-from": "^3.0.0" - } - }, - "import-lazy": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-2.1.0.tgz", - "integrity": "sha1-BWmOPUXIjo1+nZLLBYTnfwlvPkM=", - "dev": true - }, - "import-local": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/import-local/-/import-local-2.0.0.tgz", - "integrity": "sha512-b6s04m3O+s3CGSbqDIyP4R6aAwAeYlVq9+WUWep6iHa8ETRf9yei1U48C5MmfJmV9AiLYYBKPMq/W+/WRpQmCQ==", - "dev": true, - "requires": { - "pkg-dir": "^3.0.0", - "resolve-cwd": "^2.0.0" - } - }, - "imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", - "dev": true - }, - "indexes-of": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/indexes-of/-/indexes-of-1.0.1.tgz", - "integrity": "sha1-8w9xbI4r00bHtn0985FVZqfAVgc=", - "dev": true - }, - "infer-owner": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/infer-owner/-/infer-owner-1.0.4.tgz", - "integrity": "sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A==", - "dev": true - }, - "inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "dev": true, - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true - }, - "ini": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", - "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", - "dev": true - }, - "internal-ip": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/internal-ip/-/internal-ip-4.3.0.tgz", - "integrity": "sha512-S1zBo1D6zcsyuC6PMmY5+55YMILQ9av8lotMx447Bq6SAgo/sDK6y6uUKmuYhW7eacnIhFfsPmCNYdDzsnnDCg==", - "dev": true, - "requires": { - "default-gateway": "^4.2.0", - "ipaddr.js": "^1.9.0" - } - }, - "invariant": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", - "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", - "dev": true, - "requires": { - "loose-envify": "^1.0.0" - } - }, - "ip": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.5.tgz", - "integrity": "sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo=", - "dev": true - }, - "ip-regex": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/ip-regex/-/ip-regex-2.1.0.tgz", - "integrity": "sha1-+ni/XS5pE8kRzp+BnuUUa7bYROk=", - "dev": true - }, - "ipaddr.js": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", - "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", - "dev": true - }, - "is-absolute-url": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-absolute-url/-/is-absolute-url-2.1.0.tgz", - "integrity": "sha1-UFMN+4T8yap9vnhS6Do3uTufKqY=", - "dev": true - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-arguments": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.0.4.tgz", - "integrity": "sha512-xPh0Rmt8NE65sNzvyUmWgI1tz3mKq74lGA0mL8LYZcoIzKOzDh6HmrYm3d18k60nHerC8A9Km8kYu87zfSFnLA==", - "dev": true - }, - "is-arrayish": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", - "dev": true - }, - "is-binary-path": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", - "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=", - "dev": true, - "requires": { - "binary-extensions": "^1.0.0" - } - }, - "is-buffer": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", - "dev": true - }, - "is-callable": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.0.tgz", - "integrity": "sha512-pyVD9AaGLxtg6srb2Ng6ynWJqkHU9bEM087AKck0w8QwDarTfNcpIYoU8x8Hv2Icm8u6kFJM18Dag8lyqGkviw==", - "dev": true - }, - "is-ci": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-2.0.0.tgz", - "integrity": "sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==", - "dev": true, - "requires": { - "ci-info": "^2.0.0" - } - }, - "is-color-stop": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-color-stop/-/is-color-stop-1.1.0.tgz", - "integrity": "sha1-z/9HGu5N1cnhWFmPvhKWe1za00U=", - "dev": true, - "requires": { - "css-color-names": "^0.0.4", - "hex-color-regex": "^1.1.0", - "hsl-regex": "^1.0.0", - "hsla-regex": "^1.0.0", - "rgb-regex": "^1.0.1", - "rgba-regex": "^1.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-date-object": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.2.tgz", - "integrity": "sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g==", - "dev": true - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "is-directory": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/is-directory/-/is-directory-0.3.1.tgz", - "integrity": "sha1-YTObbyR1/Hcv2cnYP1yFddwVSuE=", - "dev": true - }, - "is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", - "dev": true - }, - "is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true - }, - "is-glob": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", - "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", - "dev": true, - "requires": { - "is-extglob": "^2.1.1" - } - }, - "is-installed-globally": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.3.2.tgz", - "integrity": "sha512-wZ8x1js7Ia0kecP/CHM/3ABkAmujX7WPvQk6uu3Fly/Mk44pySulQpnHG46OMjHGXApINnV4QhY3SWnECO2z5g==", - "dev": true, - "requires": { - "global-dirs": "^2.0.1", - "is-path-inside": "^3.0.1" - } - }, - "is-npm": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/is-npm/-/is-npm-4.0.0.tgz", - "integrity": "sha512-96ECIfh9xtDDlPylNPXhzjsykHsMJZ18ASpaWzQyBr4YRTcVjUvzaHayDAES2oU/3KpljhHUjtSRNiDwi0F0ig==", - "dev": true - }, - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-obj": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz", - "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==", - "dev": true - }, - "is-path-cwd": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-2.2.0.tgz", - "integrity": "sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ==", - "dev": true - }, - "is-path-in-cwd": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-2.1.0.tgz", - "integrity": "sha512-rNocXHgipO+rvnP6dk3zI20RpOtrAM/kzbB258Uw5BWr3TpXi861yzjo16Dn4hUox07iw5AyeMLHWsujkjzvRQ==", - "dev": true, - "requires": { - "is-path-inside": "^2.1.0" - }, - "dependencies": { - "is-path-inside": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-2.1.0.tgz", - "integrity": "sha512-wiyhTzfDWsvwAW53OBWF5zuvaOGlZ6PwYxAbPVDhpm+gM09xKQGjBq/8uYN12aDvMxnAnq3dxTyoSoRNmg5YFg==", - "dev": true, - "requires": { - "path-is-inside": "^1.0.2" - } - } - } - }, - "is-path-inside": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.2.tgz", - "integrity": "sha512-/2UGPSgmtqwo1ktx8NDHjuPwZWmHhO+gj0f93EkhLB5RgW9RZevWYYlIkS6zePc6U2WpOdQYIwHe9YC4DWEBVg==", - "dev": true - }, - "is-plain-obj": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", - "integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4=", - "dev": true - }, - "is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "dev": true, - "requires": { - "isobject": "^3.0.1" - } - }, - "is-regex": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.0.tgz", - "integrity": "sha512-iI97M8KTWID2la5uYXlkbSDQIg4F6o1sYboZKKTDpnDQMLtUL86zxhgDet3Q2SriaYsyGqZ6Mn2SjbRKeLHdqw==", - "dev": true, - "requires": { - "has-symbols": "^1.0.1" - } - }, - "is-resolvable": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.1.0.tgz", - "integrity": "sha512-qgDYXFSR5WvEfuS5dMj6oTMEbrrSaM0CrFk2Yiq/gXnBvD9pMa2jGXxyhGLfvhZpuMZe18CJpFxAt3CRs42NMg==", - "dev": true - }, - "is-stream": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", - "dev": true - }, - "is-svg": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-svg/-/is-svg-3.0.0.tgz", - "integrity": "sha512-gi4iHK53LR2ujhLVVj+37Ykh9GLqYHX6JOVXbLAucaG/Cqw9xwdFOjDM2qeifLs1sF1npXXFvDu0r5HNgCMrzQ==", - "dev": true, - "requires": { - "html-comment-regex": "^1.1.0" - } - }, - "is-symbol": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.3.tgz", - "integrity": "sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ==", - "dev": true, - "requires": { - "has-symbols": "^1.0.1" - } - }, - "is-typedarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", - "dev": true - }, - "is-windows": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", - "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", - "dev": true - }, - "is-wsl": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz", - "integrity": "sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0=", - "dev": true - }, - "is-yarn-global": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/is-yarn-global/-/is-yarn-global-0.3.0.tgz", - "integrity": "sha512-VjSeb/lHmkoyd8ryPVIKvOCn4D1koMqY+vqyjjUfc3xyKtP4dYOxM44sZrnqQSzSds3xyOrUTLTC9LVCVgLngw==", - "dev": true - }, - "isarray": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", - "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", - "dev": true - }, - "isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", - "dev": true - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "isstream": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", - "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=", - "dev": true - }, - "javascript-stringify": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/javascript-stringify/-/javascript-stringify-2.0.1.tgz", - "integrity": "sha512-yV+gqbd5vaOYjqlbk16EG89xB5udgjqQF3C5FAORDg4f/IS1Yc5ERCv5e/57yBcfJYw05V5JyIXabhwb75Xxow==", - "dev": true - }, - "js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "dev": true - }, - "js-yaml": { - "version": "3.14.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.0.tgz", - "integrity": "sha512-/4IbIeHcD9VMHFqDR/gQ7EdZdLimOvW2DdcxFjdyyZ9NsbS+ccrXqVWDtab/lRl5AlUqmpBx8EhPaWR+OtY17A==", - "dev": true, - "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - } - }, - "jsbn": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", - "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", - "dev": true - }, - "jsesc": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", - "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", - "dev": true - }, - "json-buffer": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.0.tgz", - "integrity": "sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg=", - "dev": true - }, - "json-parse-better-errors": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", - "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", - "dev": true - }, - "json-schema": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", - "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=", - "dev": true - }, - "json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true - }, - "json-stringify-safe": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=", - "dev": true - }, - "json3": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/json3/-/json3-3.3.3.tgz", - "integrity": "sha512-c7/8mbUsKigAbLkD5B010BK4D9LZm7A1pNItkEwiUZRpIN66exu/e7YQWysGun+TRKaJp8MhemM+VkfWv42aCA==", - "dev": true - }, - "json5": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.1.3.tgz", - "integrity": "sha512-KXPvOm8K9IJKFM0bmdn8QXh7udDh1g/giieX0NLCaMnb4hEiVFqnop2ImTXCc5e0/oHz3LTqmHGtExn5hfMkOA==", - "dev": true, - "requires": { - "minimist": "^1.2.5" - } - }, - "jsonfile": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", - "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.6" - } - }, - "jsprim": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", - "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", - "dev": true, - "requires": { - "assert-plus": "1.0.0", - "extsprintf": "1.3.0", - "json-schema": "0.2.3", - "verror": "1.10.0" - } - }, - "keyv": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/keyv/-/keyv-3.1.0.tgz", - "integrity": "sha512-9ykJ/46SN/9KPM/sichzQ7OvXyGDYKGTaDlKMGCAlg2UK8KRy4jb0d8sFc+0Tt0YYnThq8X2RZgCg74RPxgcVA==", - "dev": true, - "requires": { - "json-buffer": "3.0.0" - } - }, - "killable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/killable/-/killable-1.0.1.tgz", - "integrity": "sha512-LzqtLKlUwirEUyl/nicirVmNiPvYs7l5n8wOPP7fyJVpUPkvCnW/vuiXGpylGUlnPDnB7311rARzAt3Mhswpjg==", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - }, - "last-call-webpack-plugin": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/last-call-webpack-plugin/-/last-call-webpack-plugin-3.0.0.tgz", - "integrity": "sha512-7KI2l2GIZa9p2spzPIVZBYyNKkN+e/SQPpnjlTiPhdbDW3F86tdKKELxKpzJ5sgU19wQWsACULZmpTPYHeWO5w==", - "dev": true, - "requires": { - "lodash": "^4.17.5", - "webpack-sources": "^1.1.0" - } - }, - "latest-version": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/latest-version/-/latest-version-5.1.0.tgz", - "integrity": "sha512-weT+r0kTkRQdCdYCNtkMwWXQTMEswKrFBkm4ckQOMVhhqhIMI1UT2hMj+1iigIhgSZm5gTmrRXBNoGUgaTY1xA==", - "dev": true, - "requires": { - "package-json": "^6.3.0" - } - }, - "leven": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", - "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", - "dev": true - }, - "levenary": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/levenary/-/levenary-1.1.1.tgz", - "integrity": "sha512-mkAdOIt79FD6irqjYSs4rdbnlT5vRonMEvBVPVb3XmevfS8kgRXwfes0dhPdEtzTWD/1eNE/Bm/G1iRt6DcnQQ==", - "dev": true, - "requires": { - "leven": "^3.1.0" - } - }, - "linkify-it": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-2.2.0.tgz", - "integrity": "sha512-GnAl/knGn+i1U/wjBz3akz2stz+HrHLsxMwHQGofCDfPvlf+gDKN58UtfmUquTY4/MXeE2x7k19KQmeoZi94Iw==", - "dev": true, - "requires": { - "uc.micro": "^1.0.1" - } - }, - "load-script": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/load-script/-/load-script-1.0.0.tgz", - "integrity": "sha1-BJGTngvuVkPuSUp+PaPSuscMbKQ=", - "dev": true - }, - "loader-runner": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-2.4.0.tgz", - "integrity": "sha512-Jsmr89RcXGIwivFY21FcRrisYZfvLMTWx5kOLc+JTxtpBOG6xML0vzbc6SEQG2FO9/4Fc3wW4LVcB5DmGflaRw==", - "dev": true - }, - "loader-utils": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.0.tgz", - "integrity": "sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA==", - "dev": true, - "requires": { - "big.js": "^5.2.2", - "emojis-list": "^3.0.0", - "json5": "^1.0.1" - }, - "dependencies": { - "json5": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", - "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", - "dev": true, - "requires": { - "minimist": "^1.2.0" - } - } - } - }, - "locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", - "dev": true, - "requires": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - } - }, - "lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", - "dev": true - }, - "lodash._reinterpolate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz", - "integrity": "sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0=", - "dev": true - }, - "lodash.clonedeep": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", - "integrity": "sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=", - "dev": true - }, - "lodash.debounce": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", - "integrity": "sha1-gteb/zCmfEAF/9XiUVMArZyk168=", - "dev": true - }, - "lodash.kebabcase": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/lodash.kebabcase/-/lodash.kebabcase-4.1.1.tgz", - "integrity": "sha1-hImxyw0p/4gZXM7KRI/21swpXDY=", - "dev": true - }, - "lodash.memoize": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", - "integrity": "sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4=", - "dev": true - }, - "lodash.template": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.template/-/lodash.template-4.5.0.tgz", - "integrity": "sha512-84vYFxIkmidUiFxidA/KjjH9pAycqW+h980j7Fuz5qxRtO9pgB7MDFTdys1N7A5mcucRiDyEq4fusljItR1T/A==", - "dev": true, - "requires": { - "lodash._reinterpolate": "^3.0.0", - "lodash.templatesettings": "^4.0.0" - } - }, - "lodash.templatesettings": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/lodash.templatesettings/-/lodash.templatesettings-4.2.0.tgz", - "integrity": "sha512-stgLz+i3Aa9mZgnjr/O+v9ruKZsPsndy7qPZOchbqk2cnTU1ZaldKK+v7m54WoKIyxiuMZTKT2H81F8BeAc3ZQ==", - "dev": true, - "requires": { - "lodash._reinterpolate": "^3.0.0" - } - }, - "lodash.uniq": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz", - "integrity": "sha1-0CJTc662Uq3BvILklFM5qEJ1R3M=", - "dev": true - }, - "loglevel": { - "version": "1.6.8", - "resolved": "https://registry.npmjs.org/loglevel/-/loglevel-1.6.8.tgz", - "integrity": "sha512-bsU7+gc9AJ2SqpzxwU3+1fedl8zAntbtC5XYlt3s2j1hJcn2PsXSmgN8TaLG/J1/2mod4+cE/3vNL70/c1RNCA==", - "dev": true - }, - "loose-envify": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", - "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", - "dev": true, - "requires": { - "js-tokens": "^3.0.0 || ^4.0.0" - } - }, - "lower-case": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-1.1.4.tgz", - "integrity": "sha1-miyr0bno4K6ZOkv31YdcOcQujqw=", - "dev": true - }, - "lowercase-keys": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz", - "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==", - "dev": true - }, - "lru-cache": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", - "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", - "dev": true, - "requires": { - "yallist": "^3.0.2" - } - }, - "make-dir": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", - "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", - "dev": true, - "requires": { - "pify": "^4.0.1", - "semver": "^5.6.0" - } - }, - "map-cache": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", - "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=", - "dev": true - }, - "map-visit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", - "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=", - "dev": true, - "requires": { - "object-visit": "^1.0.0" - } - }, - "markdown-it": { - "version": "8.4.2", - "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-8.4.2.tgz", - "integrity": "sha512-GcRz3AWTqSUphY3vsUqQSFMbgR38a4Lh3GWlHRh/7MRwz8mcu9n2IO7HOh+bXHrR9kOPDl5RNCaEsrneb+xhHQ==", - "dev": true, - "requires": { - "argparse": "^1.0.7", - "entities": "~1.1.1", - "linkify-it": "^2.0.0", - "mdurl": "^1.0.1", - "uc.micro": "^1.0.5" - } - }, - "markdown-it-anchor": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/markdown-it-anchor/-/markdown-it-anchor-5.3.0.tgz", - "integrity": "sha512-/V1MnLL/rgJ3jkMWo84UR+K+jF1cxNG1a+KwqeXqTIJ+jtA8aWSHuigx8lTzauiIjBDbwF3NcWQMotd0Dm39jA==", - "dev": true, - "requires": {} - }, - "markdown-it-chain": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/markdown-it-chain/-/markdown-it-chain-1.3.0.tgz", - "integrity": "sha512-XClV8I1TKy8L2qsT9iX3qiV+50ZtcInGXI80CA+DP62sMs7hXlyV/RM3hfwy5O3Ad0sJm9xIwQELgANfESo8mQ==", - "dev": true, - "requires": { - "webpack-chain": "^4.9.0" - }, - "dependencies": { - "javascript-stringify": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/javascript-stringify/-/javascript-stringify-1.6.0.tgz", - "integrity": "sha1-FC0RHzpuPa6PSpr9d9RYVbWpzOM=", - "dev": true - }, - "webpack-chain": { - "version": "4.12.1", - "resolved": "https://registry.npmjs.org/webpack-chain/-/webpack-chain-4.12.1.tgz", - "integrity": "sha512-BCfKo2YkDe2ByqkEWe1Rw+zko4LsyS75LVr29C6xIrxAg9JHJ4pl8kaIZ396SUSNp6b4815dRZPSTAS8LlURRQ==", - "dev": true, - "requires": { - "deepmerge": "^1.5.2", - "javascript-stringify": "^1.6.0" - } - } - } - }, - "markdown-it-container": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/markdown-it-container/-/markdown-it-container-2.0.0.tgz", - "integrity": "sha1-ABm0P9Au7+zi8ZYKKJX7qBpARpU=", - "dev": true - }, - "markdown-it-emoji": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/markdown-it-emoji/-/markdown-it-emoji-1.4.0.tgz", - "integrity": "sha1-m+4OmpkKljupbfaYDE/dsF37Tcw=", - "dev": true - }, - "markdown-it-table-of-contents": { - "version": "0.4.4", - "resolved": "https://registry.npmjs.org/markdown-it-table-of-contents/-/markdown-it-table-of-contents-0.4.4.tgz", - "integrity": "sha512-TAIHTHPwa9+ltKvKPWulm/beozQU41Ab+FIefRaQV1NRnpzwcV9QOe6wXQS5WLivm5Q/nlo0rl6laGkMDZE7Gw==", - "dev": true - }, - "md5.js": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", - "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", - "dev": true, - "requires": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "mdn-data": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.4.tgz", - "integrity": "sha512-iV3XNKw06j5Q7mi6h+9vbx23Tv7JkjEVgKHW4pimwyDGWm0OIQntJJ+u1C6mg6mK1EaTv42XQ7w76yuzH7M2cA==", - "dev": true - }, - "mdurl": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz", - "integrity": "sha1-/oWy7HWlkDfyrf7BAP1sYBdhFS4=", - "dev": true - }, - "media-typer": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", - "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=", - "dev": true - }, - "memory-fs": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.4.1.tgz", - "integrity": "sha1-OpoguEYlI+RHz7x+i7gO1me/xVI=", - "dev": true, - "requires": { - "errno": "^0.1.3", - "readable-stream": "^2.0.1" - } - }, - "merge-descriptors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", - "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=", - "dev": true - }, - "merge-source-map": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/merge-source-map/-/merge-source-map-1.1.0.tgz", - "integrity": "sha512-Qkcp7P2ygktpMPh2mCQZaf3jhN6D3Z/qVZHSdWvQ+2Ef5HgRAPBO57A77+ENm0CPx2+1Ce/MYKi3ymqdfuqibw==", - "dev": true, - "requires": { - "source-map": "^0.6.1" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - } - } - }, - "merge2": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", - "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", - "dev": true - }, - "methods": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", - "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=", - "dev": true - }, - "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - }, - "dependencies": { - "extend-shallow": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", - "dev": true, - "requires": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" - } - }, - "is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, - "requires": { - "is-plain-object": "^2.0.4" - } - } - } - }, - "miller-rabin": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz", - "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==", - "dev": true, - "requires": { - "bn.js": "^4.0.0", - "brorand": "^1.0.1" - }, - "dependencies": { - "bn.js": { - "version": "4.11.9", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz", - "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==", - "dev": true - } - } - }, - "mime": { - "version": "2.4.6", - "resolved": "https://registry.npmjs.org/mime/-/mime-2.4.6.tgz", - "integrity": "sha512-RZKhC3EmpBchfTGBVb8fb+RL2cWyw/32lshnsETttkBAyAUXSGHxbEJWWRXc751DrIxG1q04b8QwMbAwkRPpUA==", - "dev": true - }, - "mime-db": { - "version": "1.44.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.44.0.tgz", - "integrity": "sha512-/NOTfLrsPBVeH7YtFPgsVWveuL+4SjjYxaQ1xtM1KMFj7HdxlBlxeyNLzhyJVx7r4rZGJAZ/6lkKCitSc/Nmpg==", - "dev": true - }, - "mime-types": { - "version": "2.1.27", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.27.tgz", - "integrity": "sha512-JIhqnCasI9yD+SsmkquHBxTSEuZdQX5BuQnS2Vc7puQQQ+8yiP5AY5uWhpdv4YL4VM5c6iliiYWPgJ/nJQLp7w==", - "dev": true, - "requires": { - "mime-db": "1.44.0" - } - }, - "mimic-response": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", - "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==", - "dev": true - }, - "min-document": { - "version": "2.19.0", - "resolved": "https://registry.npmjs.org/min-document/-/min-document-2.19.0.tgz", - "integrity": "sha1-e9KC4/WELtKVu3SM3Z8f+iyCRoU=", - "dev": true, - "requires": { - "dom-walk": "^0.1.0" - } - }, - "mini-css-extract-plugin": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-0.6.0.tgz", - "integrity": "sha512-79q5P7YGI6rdnVyIAV4NXpBQJFWdkzJxCim3Kog4078fM0piAaFlwocqbejdWtLW1cEzCexPrh6EdyFsPgVdAw==", - "dev": true, - "requires": { - "loader-utils": "^1.1.0", - "normalize-url": "^2.0.1", - "schema-utils": "^1.0.0", - "webpack-sources": "^1.1.0" - }, - "dependencies": { - "schema-utils": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", - "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", - "dev": true, - "requires": { - "ajv": "^6.1.0", - "ajv-errors": "^1.0.0", - "ajv-keywords": "^3.1.0" - } - } - } - }, - "minimalistic-assert": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", - "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", - "dev": true - }, - "minimalistic-crypto-utils": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", - "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=", - "dev": true - }, - "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "dev": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", - "dev": true - }, - "mississippi": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/mississippi/-/mississippi-3.0.0.tgz", - "integrity": "sha512-x471SsVjUtBRtcvd4BzKE9kFC+/2TeWgKCgw0bZcw1b9l2X3QX5vCWgF+KaZaYm87Ss//rHnWryupDrgLvmSkA==", - "dev": true, - "requires": { - "concat-stream": "^1.5.0", - "duplexify": "^3.4.2", - "end-of-stream": "^1.1.0", - "flush-write-stream": "^1.0.0", - "from2": "^2.1.0", - "parallel-transform": "^1.1.0", - "pump": "^3.0.0", - "pumpify": "^1.3.3", - "stream-each": "^1.1.0", - "through2": "^2.0.0" - } - }, - "mixin-deep": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz", - "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==", - "dev": true, - "requires": { - "for-in": "^1.0.2", - "is-extendable": "^1.0.1" - }, - "dependencies": { - "is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, - "requires": { - "is-plain-object": "^2.0.4" - } - } - } - }, - "mkdirp": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", - "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", - "dev": true, - "requires": { - "minimist": "^1.2.5" - } - }, - "move-concurrently": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/move-concurrently/-/move-concurrently-1.0.1.tgz", - "integrity": "sha1-viwAX9oy4LKa8fBdfEszIUxwH5I=", - "dev": true, - "requires": { - "aproba": "^1.1.1", - "copy-concurrently": "^1.0.0", - "fs-write-stream-atomic": "^1.0.8", - "mkdirp": "^0.5.1", - "rimraf": "^2.5.4", - "run-queue": "^1.0.3" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, - "multicast-dns": { - "version": "6.2.3", - "resolved": "https://registry.npmjs.org/multicast-dns/-/multicast-dns-6.2.3.tgz", - "integrity": "sha512-ji6J5enbMyGRHIAkAOu3WdV8nggqviKCEKtXcOqfphZZtQrmHKycfynJ2V7eVPUA4NhJ6V7Wf4TmGbTwKE9B6g==", - "dev": true, - "requires": { - "dns-packet": "^1.3.1", - "thunky": "^1.0.2" - } - }, - "multicast-dns-service-types": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/multicast-dns-service-types/-/multicast-dns-service-types-1.1.0.tgz", - "integrity": "sha1-iZ8R2WhuXgXLkbNdXw5jt3PPyQE=", - "dev": true - }, - "nan": { - "version": "2.14.1", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.1.tgz", - "integrity": "sha512-isWHgVjnFjh2x2yuJ/tj3JbwoHu3UC2dX5G/88Cm24yB6YopVgxvBObDY7n5xW6ExmFhJpSEQqFPvq9zaXc8Jw==", - "dev": true, - "optional": true - }, - "nanomatch": { - "version": "1.2.13", - "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", - "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "fragment-cache": "^0.2.1", - "is-windows": "^1.0.2", - "kind-of": "^6.0.2", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", - "dev": true, - "requires": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" - } - }, - "is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, - "requires": { - "is-plain-object": "^2.0.4" - } - } - } - }, - "negotiator": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz", - "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==", - "dev": true - }, - "neo-async": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.1.tgz", - "integrity": "sha512-iyam8fBuCUpWeKPGpaNMetEocMt364qkCsfL9JuhjXX6dRnguRVOfk2GZaDpPjcOKiiXCPINZC1GczQ7iTq3Zw==", - "dev": true - }, - "nice-try": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", - "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", - "dev": true - }, - "no-case": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/no-case/-/no-case-2.3.2.tgz", - "integrity": "sha512-rmTZ9kz+f3rCvK2TD1Ue/oZlns7OGoIWP4fc3llxxRXlOkHKoWPPWJOfFYpITabSow43QJbRIoHQXtt10VldyQ==", - "dev": true, - "requires": { - "lower-case": "^1.1.1" - } - }, - "node-forge": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.9.0.tgz", - "integrity": "sha512-7ASaDa3pD+lJ3WvXFsxekJQelBKRpne+GOVbLbtHYdd7pFspyeuJHnWfLplGf3SwKGbfs/aYl5V/JCIaHVUKKQ==", - "dev": true - }, - "node-libs-browser": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/node-libs-browser/-/node-libs-browser-2.2.1.tgz", - "integrity": "sha512-h/zcD8H9kaDZ9ALUWwlBUDo6TKF8a7qBSCSEGfjTVIYeqsioSKaAX+BN7NgiMGp6iSIXZ3PxgCu8KS3b71YK5Q==", - "dev": true, - "requires": { - "assert": "^1.1.1", - "browserify-zlib": "^0.2.0", - "buffer": "^4.3.0", - "console-browserify": "^1.1.0", - "constants-browserify": "^1.0.0", - "crypto-browserify": "^3.11.0", - "domain-browser": "^1.1.1", - "events": "^3.0.0", - "https-browserify": "^1.0.0", - "os-browserify": "^0.3.0", - "path-browserify": "0.0.1", - "process": "^0.11.10", - "punycode": "^1.2.4", - "querystring-es3": "^0.2.0", - "readable-stream": "^2.3.3", - "stream-browserify": "^2.0.1", - "stream-http": "^2.7.2", - "string_decoder": "^1.0.0", - "timers-browserify": "^2.0.4", - "tty-browserify": "0.0.0", - "url": "^0.11.0", - "util": "^0.11.0", - "vm-browserify": "^1.0.1" - }, - "dependencies": { - "events": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/events/-/events-3.1.0.tgz", - "integrity": "sha512-Rv+u8MLHNOdMjTAFeT3nCjHn2aGlx435FP/sDHNaRhDEMwyI/aB22Kj2qIN8R0cw3z28psEQLYwxVKLsKrMgWg==", - "dev": true - }, - "punycode": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", - "dev": true - } - } - }, - "node-releases": { - "version": "1.1.72", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.72.tgz", - "integrity": "sha512-LLUo+PpH3dU6XizX3iVoubUNheF/owjXCZZ5yACDxNnPtgFuludV1ZL3ayK1kVep42Rmm0+R9/Y60NQbZ2bifw==", - "dev": true - }, - "nopt": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/nopt/-/nopt-1.0.10.tgz", - "integrity": "sha1-bd0hvSoxQXuScn3Vhfim83YI6+4=", - "dev": true, - "requires": { - "abbrev": "1" - } - }, - "normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true - }, - "normalize-range": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz", - "integrity": "sha1-LRDAa9/TEuqXd2laTShDlFa3WUI=", - "dev": true - }, - "normalize-url": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-2.0.1.tgz", - "integrity": "sha512-D6MUW4K/VzoJ4rJ01JFKxDrtY1v9wrgzCX5f2qj/lzH1m/lW6MhUZFKerVsnyjOhOsYzI9Kqqak+10l4LvLpMw==", - "dev": true, - "requires": { - "prepend-http": "^2.0.0", - "query-string": "^5.0.1", - "sort-keys": "^2.0.0" - } - }, - "npm-run-path": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", - "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", - "dev": true, - "requires": { - "path-key": "^2.0.0" - } - }, - "nprogress": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/nprogress/-/nprogress-0.2.0.tgz", - "integrity": "sha1-y480xTIT2JVyP8urkH6UIq28r7E=", - "dev": true - }, - "nth-check": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-1.0.2.tgz", - "integrity": "sha512-WeBOdju8SnzPN5vTUJYxYUxLeXpCaVP5i5e0LF8fg7WORF2Wd7wFX/pk0tYZk7s8T+J7VLy0Da6J1+wCT0AtHg==", - "dev": true, - "requires": { - "boolbase": "~1.0.0" - } - }, - "num2fraction": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/num2fraction/-/num2fraction-1.2.2.tgz", - "integrity": "sha1-b2gragJ6Tp3fpFZM0lidHU5mnt4=", - "dev": true - }, - "oauth-sign": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", - "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", - "dev": true - }, - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", - "dev": true - }, - "object-copy": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", - "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=", - "dev": true, - "requires": { - "copy-descriptor": "^0.1.0", - "define-property": "^0.2.5", - "kind-of": "^3.0.3" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - } - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - }, - "dependencies": { - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } - } - }, - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "object-inspect": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.7.0.tgz", - "integrity": "sha512-a7pEHdh1xKIAgTySUGgLMx/xwDZskN1Ud6egYYN3EdRW4ZMPNEDUTF+hwy2LUC+Bl+SyLXANnwz/jyh/qutKUw==", - "dev": true - }, - "object-is": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/object-is/-/object-is-1.1.2.tgz", - "integrity": "sha512-5lHCz+0uufF6wZ7CRFWJN3hp8Jqblpgve06U5CMQ3f//6iDjPr2PEo9MWCjEssDsa+UZEL4PkFpr+BMop6aKzQ==", - "dev": true, - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.5" - } - }, - "object-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", - "dev": true - }, - "object-visit": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", - "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=", - "dev": true, - "requires": { - "isobject": "^3.0.0" - } - }, - "object.assign": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz", - "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==", - "dev": true, - "requires": { - "define-properties": "^1.1.2", - "function-bind": "^1.1.1", - "has-symbols": "^1.0.0", - "object-keys": "^1.0.11" - } - }, - "object.getownpropertydescriptors": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.0.tgz", - "integrity": "sha512-Z53Oah9A3TdLoblT7VKJaTDdXdT+lQO+cNpKVnya5JDe9uLvzu1YyY1yFDFrcxrlRgWrEFH0jJtD/IbuwjcEVg==", - "dev": true, - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.0-next.1" - } - }, - "object.pick": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", - "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", - "dev": true, - "requires": { - "isobject": "^3.0.1" - } - }, - "object.values": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.1.tgz", - "integrity": "sha512-WTa54g2K8iu0kmS/us18jEmdv1a4Wi//BZ/DTVYEcH0XhLM5NYdpDHja3gt57VrZLcNAO2WGA+KpWsDBaHt6eA==", - "dev": true, - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.0-next.1", - "function-bind": "^1.1.1", - "has": "^1.0.3" - } - }, - "obuf": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/obuf/-/obuf-1.1.2.tgz", - "integrity": "sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==", - "dev": true - }, - "on-finished": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", - "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", - "dev": true, - "requires": { - "ee-first": "1.1.1" - } - }, - "on-headers": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz", - "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==", - "dev": true - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "dev": true, - "requires": { - "wrappy": "1" - } - }, - "opencollective-postinstall": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/opencollective-postinstall/-/opencollective-postinstall-2.0.3.tgz", - "integrity": "sha512-8AV/sCtuzUeTo8gQK5qDZzARrulB3egtLzFgteqB2tcT4Mw7B8Kt7JcDHmltjz6FOAHsvTevk70gZEbhM4ZS9Q==", - "dev": true - }, - "opn": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/opn/-/opn-5.5.0.tgz", - "integrity": "sha512-PqHpggC9bLV0VeWcdKhkpxY+3JTzetLSqTCWL/z/tFIbI6G8JCjondXklT1JinczLz2Xib62sSp0T/gKT4KksA==", - "dev": true, - "requires": { - "is-wsl": "^1.1.0" - } - }, - "optimize-css-assets-webpack-plugin": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/optimize-css-assets-webpack-plugin/-/optimize-css-assets-webpack-plugin-5.0.3.tgz", - "integrity": "sha512-q9fbvCRS6EYtUKKSwI87qm2IxlyJK5b4dygW1rKUBT6mMDhdG5e5bZT63v6tnJR9F9FB/H5a0HTmtw+laUBxKA==", - "dev": true, - "requires": { - "cssnano": "^4.1.10", - "last-call-webpack-plugin": "^3.0.0" - } - }, - "original": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/original/-/original-1.0.2.tgz", - "integrity": "sha512-hyBVl6iqqUOJ8FqRe+l/gS8H+kKYjrEndd5Pm1MfBtsEKA038HkkdbAl/72EAXGyonD/PFsvmVG+EvcIpliMBg==", - "dev": true, - "requires": { - "url-parse": "^1.4.3" - } - }, - "os-browserify": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz", - "integrity": "sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc=", - "dev": true - }, - "p-cancelable": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-1.1.0.tgz", - "integrity": "sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw==", - "dev": true - }, - "p-finally": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", - "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", - "dev": true - }, - "p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "requires": { - "p-try": "^2.0.0" - } - }, - "p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", - "dev": true, - "requires": { - "p-limit": "^2.0.0" - } - }, - "p-map": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-2.1.0.tgz", - "integrity": "sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==", - "dev": true - }, - "p-retry": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/p-retry/-/p-retry-3.0.1.tgz", - "integrity": "sha512-XE6G4+YTTkT2a0UWb2kjZe8xNwf8bIbnqpc/IS/idOBVhyves0mK5OJgeocjx7q5pvX/6m23xuzVPYT1uGM73w==", - "dev": true, - "requires": { - "retry": "^0.12.0" - } - }, - "p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true - }, - "package-json": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/package-json/-/package-json-6.5.0.tgz", - "integrity": "sha512-k3bdm2n25tkyxcjSKzB5x8kfVxlMdgsbPr0GkZcwHsLpba6cBjqCt1KlcChKEvxHIcTB1FVMuwoijZ26xex5MQ==", - "dev": true, - "requires": { - "got": "^9.6.0", - "registry-auth-token": "^4.0.0", - "registry-url": "^5.0.0", - "semver": "^6.2.0" - }, - "dependencies": { - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true - } - } - }, - "pako": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", - "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==", - "dev": true - }, - "parallel-transform": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/parallel-transform/-/parallel-transform-1.2.0.tgz", - "integrity": "sha512-P2vSmIu38uIlvdcU7fDkyrxj33gTUy/ABO5ZUbGowxNCopBq/OoD42bP4UmMrJoPyk4Uqf0mu3mtWBhHCZD8yg==", - "dev": true, - "requires": { - "cyclist": "^1.0.1", - "inherits": "^2.0.3", - "readable-stream": "^2.1.5" - } - }, - "param-case": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/param-case/-/param-case-2.1.1.tgz", - "integrity": "sha1-35T9jPZTHs915r75oIWPvHK+Ikc=", - "dev": true, - "requires": { - "no-case": "^2.2.0" - } - }, - "parse-asn1": { - "version": "5.1.5", - "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.5.tgz", - "integrity": "sha512-jkMYn1dcJqF6d5CpU689bq7w/b5ALS9ROVSpQDPrZsqqesUJii9qutvoT5ltGedNXMO2e16YUWIghG9KxaViTQ==", - "dev": true, - "requires": { - "asn1.js": "^4.0.0", - "browserify-aes": "^1.0.0", - "create-hash": "^1.1.0", - "evp_bytestokey": "^1.0.0", - "pbkdf2": "^3.0.3", - "safe-buffer": "^5.1.1" - } - }, - "parse-json": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", - "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", - "dev": true, - "requires": { - "error-ex": "^1.3.1", - "json-parse-better-errors": "^1.0.1" - } - }, - "parseurl": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", - "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", - "dev": true - }, - "pascalcase": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", - "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=", - "dev": true - }, - "path-browserify": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.1.tgz", - "integrity": "sha512-BapA40NHICOS+USX9SN4tyhq+A2RrN/Ws5F0Z5aMHDp98Fl86lX8Oti8B7uN93L4Ifv4fHOEA+pQw87gmMO/lQ==", - "dev": true - }, - "path-dirname": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz", - "integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=", - "dev": true - }, - "path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", - "dev": true - }, - "path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", - "dev": true - }, - "path-is-inside": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", - "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=", - "dev": true - }, - "path-key": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", - "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", - "dev": true - }, - "path-parse": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", - "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", - "dev": true - }, - "path-to-regexp": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", - "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=", - "dev": true - }, - "path-type": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", - "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", - "dev": true, - "requires": { - "pify": "^3.0.0" - }, - "dependencies": { - "pify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", - "dev": true - } - } - }, - "pbkdf2": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.1.tgz", - "integrity": "sha512-4Ejy1OPxi9f2tt1rRV7Go7zmfDQ+ZectEQz3VGUQhgq62HtIRPDyG/JtnwIxs6x3uNMwo2V7q1fMvKjb+Tnpqg==", - "dev": true, - "requires": { - "create-hash": "^1.1.2", - "create-hmac": "^1.1.4", - "ripemd160": "^2.0.1", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - } - }, - "performance-now": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", - "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=", - "dev": true - }, - "picomatch": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz", - "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==", - "dev": true, - "optional": true - }, - "pify": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", - "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", - "dev": true - }, - "pinkie": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", - "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=", - "dev": true - }, - "pinkie-promise": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", - "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", - "dev": true, - "requires": { - "pinkie": "^2.0.0" - } - }, - "pkg-dir": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz", - "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==", - "dev": true, - "requires": { - "find-up": "^3.0.0" - } - }, - "portfinder": { - "version": "1.0.26", - "resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.26.tgz", - "integrity": "sha512-Xi7mKxJHHMI3rIUrnm/jjUgwhbYMkp/XKEcZX3aG4BrumLpq3nmoQMX+ClYnDZnZ/New7IatC1no5RX0zo1vXQ==", - "dev": true, - "requires": { - "async": "^2.6.2", - "debug": "^3.1.1", - "mkdirp": "^0.5.1" - }, - "dependencies": { - "debug": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", - "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - } - } - }, - "posix-character-classes": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", - "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=", - "dev": true - }, - "postcss": { - "version": "7.0.32", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.32.tgz", - "integrity": "sha512-03eXong5NLnNCD05xscnGKGDZ98CyzoqPSMjOe6SuoQY7Z2hIj0Ld1g/O/UQRuOle2aRtiIRDg9tDcTGAkLfKw==", - "dev": true, - "requires": { - "chalk": "^2.4.2", - "source-map": "^0.6.1", - "supports-color": "^6.1.0" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - }, - "supports-color": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", - "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "postcss-calc": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/postcss-calc/-/postcss-calc-7.0.2.tgz", - "integrity": "sha512-rofZFHUg6ZIrvRwPeFktv06GdbDYLcGqh9EwiMutZg+a0oePCCw1zHOEiji6LCpyRcjTREtPASuUqeAvYlEVvQ==", - "dev": true, - "requires": { - "postcss": "^7.0.27", - "postcss-selector-parser": "^6.0.2", - "postcss-value-parser": "^4.0.2" - } - }, - "postcss-colormin": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/postcss-colormin/-/postcss-colormin-4.0.3.tgz", - "integrity": "sha512-WyQFAdDZpExQh32j0U0feWisZ0dmOtPl44qYmJKkq9xFWY3p+4qnRzCHeNrkeRhwPHz9bQ3mo0/yVkaply0MNw==", - "dev": true, - "requires": { - "browserslist": "^4.0.0", - "color": "^3.0.0", - "has": "^1.0.0", - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0" - }, - "dependencies": { - "postcss-value-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", - "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", - "dev": true - } - } - }, - "postcss-convert-values": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/postcss-convert-values/-/postcss-convert-values-4.0.1.tgz", - "integrity": "sha512-Kisdo1y77KUC0Jmn0OXU/COOJbzM8cImvw1ZFsBgBgMgb1iL23Zs/LXRe3r+EZqM3vGYKdQ2YJVQ5VkJI+zEJQ==", - "dev": true, - "requires": { - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0" - }, - "dependencies": { - "postcss-value-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", - "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", - "dev": true - } - } - }, - "postcss-discard-comments": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/postcss-discard-comments/-/postcss-discard-comments-4.0.2.tgz", - "integrity": "sha512-RJutN259iuRf3IW7GZyLM5Sw4GLTOH8FmsXBnv8Ab/Tc2k4SR4qbV4DNbyyY4+Sjo362SyDmW2DQ7lBSChrpkg==", - "dev": true, - "requires": { - "postcss": "^7.0.0" - } - }, - "postcss-discard-duplicates": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/postcss-discard-duplicates/-/postcss-discard-duplicates-4.0.2.tgz", - "integrity": "sha512-ZNQfR1gPNAiXZhgENFfEglF93pciw0WxMkJeVmw8eF+JZBbMD7jp6C67GqJAXVZP2BWbOztKfbsdmMp/k8c6oQ==", - "dev": true, - "requires": { - "postcss": "^7.0.0" - } - }, - "postcss-discard-empty": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/postcss-discard-empty/-/postcss-discard-empty-4.0.1.tgz", - "integrity": "sha512-B9miTzbznhDjTfjvipfHoqbWKwd0Mj+/fL5s1QOz06wufguil+Xheo4XpOnc4NqKYBCNqqEzgPv2aPBIJLox0w==", - "dev": true, - "requires": { - "postcss": "^7.0.0" - } - }, - "postcss-discard-overridden": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/postcss-discard-overridden/-/postcss-discard-overridden-4.0.1.tgz", - "integrity": "sha512-IYY2bEDD7g1XM1IDEsUT4//iEYCxAmP5oDSFMVU/JVvT7gh+l4fmjciLqGgwjdWpQIdb0Che2VX00QObS5+cTg==", - "dev": true, - "requires": { - "postcss": "^7.0.0" - } - }, - "postcss-load-config": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-2.1.0.tgz", - "integrity": "sha512-4pV3JJVPLd5+RueiVVB+gFOAa7GWc25XQcMp86Zexzke69mKf6Nx9LRcQywdz7yZI9n1udOxmLuAwTBypypF8Q==", - "dev": true, - "requires": { - "cosmiconfig": "^5.0.0", - "import-cwd": "^2.0.0" - } - }, - "postcss-loader": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/postcss-loader/-/postcss-loader-3.0.0.tgz", - "integrity": "sha512-cLWoDEY5OwHcAjDnkyRQzAXfs2jrKjXpO/HQFcc5b5u/r7aa471wdmChmwfnv7x2u840iat/wi0lQ5nbRgSkUA==", - "dev": true, - "requires": { - "loader-utils": "^1.1.0", - "postcss": "^7.0.0", - "postcss-load-config": "^2.0.0", - "schema-utils": "^1.0.0" - }, - "dependencies": { - "schema-utils": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", - "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", - "dev": true, - "requires": { - "ajv": "^6.1.0", - "ajv-errors": "^1.0.0", - "ajv-keywords": "^3.1.0" - } - } - } - }, - "postcss-merge-longhand": { - "version": "4.0.11", - "resolved": "https://registry.npmjs.org/postcss-merge-longhand/-/postcss-merge-longhand-4.0.11.tgz", - "integrity": "sha512-alx/zmoeXvJjp7L4mxEMjh8lxVlDFX1gqWHzaaQewwMZiVhLo42TEClKaeHbRf6J7j82ZOdTJ808RtN0ZOZwvw==", - "dev": true, - "requires": { - "css-color-names": "0.0.4", - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0", - "stylehacks": "^4.0.0" - }, - "dependencies": { - "postcss-value-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", - "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", - "dev": true - } - } - }, - "postcss-merge-rules": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/postcss-merge-rules/-/postcss-merge-rules-4.0.3.tgz", - "integrity": "sha512-U7e3r1SbvYzO0Jr3UT/zKBVgYYyhAz0aitvGIYOYK5CPmkNih+WDSsS5tvPrJ8YMQYlEMvsZIiqmn7HdFUaeEQ==", - "dev": true, - "requires": { - "browserslist": "^4.0.0", - "caniuse-api": "^3.0.0", - "cssnano-util-same-parent": "^4.0.0", - "postcss": "^7.0.0", - "postcss-selector-parser": "^3.0.0", - "vendors": "^1.0.0" - }, - "dependencies": { - "postcss-selector-parser": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-3.1.2.tgz", - "integrity": "sha512-h7fJ/5uWuRVyOtkO45pnt1Ih40CEleeyCHzipqAZO2e5H20g25Y48uYnFUiShvY4rZWNJ/Bib/KVPmanaCtOhA==", - "dev": true, - "requires": { - "dot-prop": "^5.2.0", - "indexes-of": "^1.0.1", - "uniq": "^1.0.1" - } - } - } - }, - "postcss-minify-font-values": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/postcss-minify-font-values/-/postcss-minify-font-values-4.0.2.tgz", - "integrity": "sha512-j85oO6OnRU9zPf04+PZv1LYIYOprWm6IA6zkXkrJXyRveDEuQggG6tvoy8ir8ZwjLxLuGfNkCZEQG7zan+Hbtg==", - "dev": true, - "requires": { - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0" - }, - "dependencies": { - "postcss-value-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", - "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", - "dev": true - } - } - }, - "postcss-minify-gradients": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/postcss-minify-gradients/-/postcss-minify-gradients-4.0.2.tgz", - "integrity": "sha512-qKPfwlONdcf/AndP1U8SJ/uzIJtowHlMaSioKzebAXSG4iJthlWC9iSWznQcX4f66gIWX44RSA841HTHj3wK+Q==", - "dev": true, - "requires": { - "cssnano-util-get-arguments": "^4.0.0", - "is-color-stop": "^1.0.0", - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0" - }, - "dependencies": { - "postcss-value-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", - "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", - "dev": true - } - } - }, - "postcss-minify-params": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/postcss-minify-params/-/postcss-minify-params-4.0.2.tgz", - "integrity": "sha512-G7eWyzEx0xL4/wiBBJxJOz48zAKV2WG3iZOqVhPet/9geefm/Px5uo1fzlHu+DOjT+m0Mmiz3jkQzVHe6wxAWg==", - "dev": true, - "requires": { - "alphanum-sort": "^1.0.0", - "browserslist": "^4.0.0", - "cssnano-util-get-arguments": "^4.0.0", - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0", - "uniqs": "^2.0.0" - }, - "dependencies": { - "postcss-value-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", - "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", - "dev": true - } - } - }, - "postcss-minify-selectors": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/postcss-minify-selectors/-/postcss-minify-selectors-4.0.2.tgz", - "integrity": "sha512-D5S1iViljXBj9kflQo4YutWnJmwm8VvIsU1GeXJGiG9j8CIg9zs4voPMdQDUmIxetUOh60VilsNzCiAFTOqu3g==", - "dev": true, - "requires": { - "alphanum-sort": "^1.0.0", - "has": "^1.0.0", - "postcss": "^7.0.0", - "postcss-selector-parser": "^3.0.0" - }, - "dependencies": { - "postcss-selector-parser": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-3.1.2.tgz", - "integrity": "sha512-h7fJ/5uWuRVyOtkO45pnt1Ih40CEleeyCHzipqAZO2e5H20g25Y48uYnFUiShvY4rZWNJ/Bib/KVPmanaCtOhA==", - "dev": true, - "requires": { - "dot-prop": "^5.2.0", - "indexes-of": "^1.0.1", - "uniq": "^1.0.1" - } - } - } - }, - "postcss-modules-extract-imports": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-2.0.0.tgz", - "integrity": "sha512-LaYLDNS4SG8Q5WAWqIJgdHPJrDDr/Lv775rMBFUbgjTz6j34lUznACHcdRWroPvXANP2Vj7yNK57vp9eFqzLWQ==", - "dev": true, - "requires": { - "postcss": "^7.0.5" - } - }, - "postcss-modules-local-by-default": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-2.0.6.tgz", - "integrity": "sha512-oLUV5YNkeIBa0yQl7EYnxMgy4N6noxmiwZStaEJUSe2xPMcdNc8WmBQuQCx18H5psYbVxz8zoHk0RAAYZXP9gA==", - "dev": true, - "requires": { - "postcss": "^7.0.6", - "postcss-selector-parser": "^6.0.0", - "postcss-value-parser": "^3.3.1" - }, - "dependencies": { - "postcss-value-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", - "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", - "dev": true - } - } - }, - "postcss-modules-scope": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-2.2.0.tgz", - "integrity": "sha512-YyEgsTMRpNd+HmyC7H/mh3y+MeFWevy7V1evVhJWewmMbjDHIbZbOXICC2y+m1xI1UVfIT1HMW/O04Hxyu9oXQ==", - "dev": true, - "requires": { - "postcss": "^7.0.6", - "postcss-selector-parser": "^6.0.0" - } - }, - "postcss-modules-values": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/postcss-modules-values/-/postcss-modules-values-2.0.0.tgz", - "integrity": "sha512-Ki7JZa7ff1N3EIMlPnGTZfUMe69FFwiQPnVSXC9mnn3jozCRBYIxiZd44yJOV2AmabOo4qFf8s0dC/+lweG7+w==", - "dev": true, - "requires": { - "icss-replace-symbols": "^1.1.0", - "postcss": "^7.0.6" - } - }, - "postcss-normalize-charset": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/postcss-normalize-charset/-/postcss-normalize-charset-4.0.1.tgz", - "integrity": "sha512-gMXCrrlWh6G27U0hF3vNvR3w8I1s2wOBILvA87iNXaPvSNo5uZAMYsZG7XjCUf1eVxuPfyL4TJ7++SGZLc9A3g==", - "dev": true, - "requires": { - "postcss": "^7.0.0" - } - }, - "postcss-normalize-display-values": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/postcss-normalize-display-values/-/postcss-normalize-display-values-4.0.2.tgz", - "integrity": "sha512-3F2jcsaMW7+VtRMAqf/3m4cPFhPD3EFRgNs18u+k3lTJJlVe7d0YPO+bnwqo2xg8YiRpDXJI2u8A0wqJxMsQuQ==", - "dev": true, - "requires": { - "cssnano-util-get-match": "^4.0.0", - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0" - }, - "dependencies": { - "postcss-value-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", - "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", - "dev": true - } - } - }, - "postcss-normalize-positions": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/postcss-normalize-positions/-/postcss-normalize-positions-4.0.2.tgz", - "integrity": "sha512-Dlf3/9AxpxE+NF1fJxYDeggi5WwV35MXGFnnoccP/9qDtFrTArZ0D0R+iKcg5WsUd8nUYMIl8yXDCtcrT8JrdA==", - "dev": true, - "requires": { - "cssnano-util-get-arguments": "^4.0.0", - "has": "^1.0.0", - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0" - }, - "dependencies": { - "postcss-value-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", - "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", - "dev": true - } - } - }, - "postcss-normalize-repeat-style": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/postcss-normalize-repeat-style/-/postcss-normalize-repeat-style-4.0.2.tgz", - "integrity": "sha512-qvigdYYMpSuoFs3Is/f5nHdRLJN/ITA7huIoCyqqENJe9PvPmLhNLMu7QTjPdtnVf6OcYYO5SHonx4+fbJE1+Q==", - "dev": true, - "requires": { - "cssnano-util-get-arguments": "^4.0.0", - "cssnano-util-get-match": "^4.0.0", - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0" - }, - "dependencies": { - "postcss-value-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", - "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", - "dev": true - } - } - }, - "postcss-normalize-string": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/postcss-normalize-string/-/postcss-normalize-string-4.0.2.tgz", - "integrity": "sha512-RrERod97Dnwqq49WNz8qo66ps0swYZDSb6rM57kN2J+aoyEAJfZ6bMx0sx/F9TIEX0xthPGCmeyiam/jXif0eA==", - "dev": true, - "requires": { - "has": "^1.0.0", - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0" - }, - "dependencies": { - "postcss-value-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", - "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", - "dev": true - } - } - }, - "postcss-normalize-timing-functions": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/postcss-normalize-timing-functions/-/postcss-normalize-timing-functions-4.0.2.tgz", - "integrity": "sha512-acwJY95edP762e++00Ehq9L4sZCEcOPyaHwoaFOhIwWCDfik6YvqsYNxckee65JHLKzuNSSmAdxwD2Cud1Z54A==", - "dev": true, - "requires": { - "cssnano-util-get-match": "^4.0.0", - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0" - }, - "dependencies": { - "postcss-value-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", - "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", - "dev": true - } - } - }, - "postcss-normalize-unicode": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/postcss-normalize-unicode/-/postcss-normalize-unicode-4.0.1.tgz", - "integrity": "sha512-od18Uq2wCYn+vZ/qCOeutvHjB5jm57ToxRaMeNuf0nWVHaP9Hua56QyMF6fs/4FSUnVIw0CBPsU0K4LnBPwYwg==", - "dev": true, - "requires": { - "browserslist": "^4.0.0", - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0" - }, - "dependencies": { - "postcss-value-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", - "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", - "dev": true - } - } - }, - "postcss-normalize-url": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/postcss-normalize-url/-/postcss-normalize-url-4.0.1.tgz", - "integrity": "sha512-p5oVaF4+IHwu7VpMan/SSpmpYxcJMtkGppYf0VbdH5B6hN8YNmVyJLuY9FmLQTzY3fag5ESUUHDqM+heid0UVA==", - "dev": true, - "requires": { - "is-absolute-url": "^2.0.0", - "normalize-url": "^3.0.0", - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0" - }, - "dependencies": { - "normalize-url": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-3.3.0.tgz", - "integrity": "sha512-U+JJi7duF1o+u2pynbp2zXDW2/PADgC30f0GsHZtRh+HOcXHnw137TrNlyxxRvWW5fjKd3bcLHPxofWuCjaeZg==", - "dev": true - }, - "postcss-value-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", - "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", - "dev": true - } - } - }, - "postcss-normalize-whitespace": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/postcss-normalize-whitespace/-/postcss-normalize-whitespace-4.0.2.tgz", - "integrity": "sha512-tO8QIgrsI3p95r8fyqKV+ufKlSHh9hMJqACqbv2XknufqEDhDvbguXGBBqxw9nsQoXWf0qOqppziKJKHMD4GtA==", - "dev": true, - "requires": { - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0" - }, - "dependencies": { - "postcss-value-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", - "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", - "dev": true - } - } - }, - "postcss-ordered-values": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/postcss-ordered-values/-/postcss-ordered-values-4.1.2.tgz", - "integrity": "sha512-2fCObh5UanxvSxeXrtLtlwVThBvHn6MQcu4ksNT2tsaV2Fg76R2CV98W7wNSlX+5/pFwEyaDwKLLoEV7uRybAw==", - "dev": true, - "requires": { - "cssnano-util-get-arguments": "^4.0.0", - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0" - }, - "dependencies": { - "postcss-value-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", - "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", - "dev": true - } - } - }, - "postcss-reduce-initial": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/postcss-reduce-initial/-/postcss-reduce-initial-4.0.3.tgz", - "integrity": "sha512-gKWmR5aUulSjbzOfD9AlJiHCGH6AEVLaM0AV+aSioxUDd16qXP1PCh8d1/BGVvpdWn8k/HiK7n6TjeoXN1F7DA==", - "dev": true, - "requires": { - "browserslist": "^4.0.0", - "caniuse-api": "^3.0.0", - "has": "^1.0.0", - "postcss": "^7.0.0" - } - }, - "postcss-reduce-transforms": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/postcss-reduce-transforms/-/postcss-reduce-transforms-4.0.2.tgz", - "integrity": "sha512-EEVig1Q2QJ4ELpJXMZR8Vt5DQx8/mo+dGWSR7vWXqcob2gQLyQGsionYcGKATXvQzMPn6DSN1vTN7yFximdIAg==", - "dev": true, - "requires": { - "cssnano-util-get-match": "^4.0.0", - "has": "^1.0.0", - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0" - }, - "dependencies": { - "postcss-value-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", - "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", - "dev": true - } - } - }, - "postcss-safe-parser": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/postcss-safe-parser/-/postcss-safe-parser-4.0.2.tgz", - "integrity": "sha512-Uw6ekxSWNLCPesSv/cmqf2bY/77z11O7jZGPax3ycZMFU/oi2DMH9i89AdHc1tRwFg/arFoEwX0IS3LCUxJh1g==", - "dev": true, - "requires": { - "postcss": "^7.0.26" - } - }, - "postcss-selector-parser": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.2.tgz", - "integrity": "sha512-36P2QR59jDTOAiIkqEprfJDsoNrvwFei3eCqKd1Y0tUsBimsq39BLp7RD+JWny3WgB1zGhJX8XVePwm9k4wdBg==", - "dev": true, - "requires": { - "cssesc": "^3.0.0", - "indexes-of": "^1.0.1", - "uniq": "^1.0.1" - } - }, - "postcss-svgo": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/postcss-svgo/-/postcss-svgo-4.0.2.tgz", - "integrity": "sha512-C6wyjo3VwFm0QgBy+Fu7gCYOkCmgmClghO+pjcxvrcBKtiKt0uCF+hvbMO1fyv5BMImRK90SMb+dwUnfbGd+jw==", - "dev": true, - "requires": { - "is-svg": "^3.0.0", - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0", - "svgo": "^1.0.0" - }, - "dependencies": { - "postcss-value-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", - "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", - "dev": true - } - } - }, - "postcss-unique-selectors": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/postcss-unique-selectors/-/postcss-unique-selectors-4.0.1.tgz", - "integrity": "sha512-+JanVaryLo9QwZjKrmJgkI4Fn8SBgRO6WXQBJi7KiAVPlmxikB5Jzc4EvXMT2H0/m0RjrVVm9rGNhZddm/8Spg==", - "dev": true, - "requires": { - "alphanum-sort": "^1.0.0", - "postcss": "^7.0.0", - "uniqs": "^2.0.0" - } - }, - "postcss-value-parser": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.1.0.tgz", - "integrity": "sha512-97DXOFbQJhk71ne5/Mt6cOu6yxsSfM0QGQyl0L25Gca4yGWEGJaig7l7gbCX623VqTBNGLRLaVUCnNkcedlRSQ==", - "dev": true - }, - "prepend-http": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-2.0.0.tgz", - "integrity": "sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc=", - "dev": true - }, - "prettier": { - "version": "1.19.1", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-1.19.1.tgz", - "integrity": "sha512-s7PoyDv/II1ObgQunCbB9PdLmUcBZcnWOcxDh7O0N/UwDEsHyqkW+Qh28jW+mVuCdx7gLB0BotYI1Y6uI9iyew==", - "dev": true, - "optional": true - }, - "pretty-error": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/pretty-error/-/pretty-error-2.1.1.tgz", - "integrity": "sha1-X0+HyPkeWuPzuoerTPXgOxoX8aM=", - "dev": true, - "requires": { - "renderkid": "^2.0.1", - "utila": "~0.4" - } - }, - "pretty-time": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/pretty-time/-/pretty-time-1.1.0.tgz", - "integrity": "sha512-28iF6xPQrP8Oa6uxE6a1biz+lWeTOAPKggvjB8HAs6nVMKZwf5bG++632Dx614hIWgUPkgivRfG+a8uAXGTIbA==", - "dev": true - }, - "prismjs": { - "version": "1.23.0", - "resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.23.0.tgz", - "integrity": "sha512-c29LVsqOaLbBHuIbsTxaKENh1N2EQBOHaWv7gkHN4dgRbxSREqDnDbtFJYdpPauS4YCplMSNCABQ6Eeor69bAA==", - "dev": true, - "requires": { - "clipboard": "^2.0.0" - } - }, - "private": { - "version": "0.1.8", - "resolved": "https://registry.npmjs.org/private/-/private-0.1.8.tgz", - "integrity": "sha512-VvivMrbvd2nKkiG38qjULzlc+4Vx4wm/whI9pQD35YrARNnhxeiRktSOhSukRLFNlzg6Br/cJPet5J/u19r/mg==", - "dev": true - }, - "process": { - "version": "0.11.10", - "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", - "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=", - "dev": true - }, - "process-nextick-args": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", - "dev": true - }, - "promise-inflight": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz", - "integrity": "sha1-mEcocL8igTL8vdhoEputEsPAKeM=", - "dev": true - }, - "proxy-addr": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.6.tgz", - "integrity": "sha512-dh/frvCBVmSsDYzw6n926jv974gddhkFPfiN8hPOi30Wax25QZyZEGveluCgliBnqmuM+UJmBErbAUFIoDbjOw==", - "dev": true, - "requires": { - "forwarded": "~0.1.2", - "ipaddr.js": "1.9.1" - } - }, - "prr": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", - "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=", - "dev": true - }, - "pseudomap": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", - "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=", - "dev": true - }, - "psl": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", - "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==", - "dev": true - }, - "public-encrypt": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz", - "integrity": "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==", - "dev": true, - "requires": { - "bn.js": "^4.1.0", - "browserify-rsa": "^4.0.0", - "create-hash": "^1.1.0", - "parse-asn1": "^5.0.0", - "randombytes": "^2.0.1", - "safe-buffer": "^5.1.2" - }, - "dependencies": { - "bn.js": { - "version": "4.11.9", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz", - "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==", - "dev": true - } - } - }, - "pump": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", - "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", - "dev": true, - "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, - "pumpify": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/pumpify/-/pumpify-1.5.1.tgz", - "integrity": "sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ==", - "dev": true, - "requires": { - "duplexify": "^3.6.0", - "inherits": "^2.0.3", - "pump": "^2.0.0" - }, - "dependencies": { - "pump": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pump/-/pump-2.0.1.tgz", - "integrity": "sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==", - "dev": true, - "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - } - } - }, - "punycode": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", - "dev": true - }, - "pupa": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pupa/-/pupa-2.0.1.tgz", - "integrity": "sha512-hEJH0s8PXLY/cdXh66tNEQGndDrIKNqNC5xmrysZy3i5C3oEoLna7YAOad+7u125+zH1HNXUmGEkrhb3c2VriA==", - "dev": true, - "requires": { - "escape-goat": "^2.0.0" - } - }, - "q": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", - "integrity": "sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc=", - "dev": true - }, - "qs": { - "version": "6.5.2", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", - "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==", - "dev": true - }, - "query-string": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/query-string/-/query-string-5.1.1.tgz", - "integrity": "sha512-gjWOsm2SoGlgLEdAGt7a6slVOk9mGiXmPFMqrEhLQ68rhQuBnpfs3+EmlvqKyxnCo9/PPlF+9MtY02S1aFg+Jw==", - "dev": true, - "requires": { - "decode-uri-component": "^0.2.0", - "object-assign": "^4.1.0", - "strict-uri-encode": "^1.0.0" - } - }, - "querystring": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", - "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=", - "dev": true - }, - "querystring-es3": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz", - "integrity": "sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM=", - "dev": true - }, - "querystringify": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", - "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==", - "dev": true - }, - "randombytes": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", - "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", - "dev": true, - "requires": { - "safe-buffer": "^5.1.0" - } - }, - "randomfill": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz", - "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==", - "dev": true, - "requires": { - "randombytes": "^2.0.5", - "safe-buffer": "^5.1.0" - } - }, - "range-parser": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", - "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", - "dev": true - }, - "raw-body": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.0.tgz", - "integrity": "sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q==", - "dev": true, - "requires": { - "bytes": "3.1.0", - "http-errors": "1.7.2", - "iconv-lite": "0.4.24", - "unpipe": "1.0.0" - }, - "dependencies": { - "bytes": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", - "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==", - "dev": true - } - } - }, - "rc": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", - "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", - "dev": true, - "requires": { - "deep-extend": "^0.6.0", - "ini": "~1.3.0", - "minimist": "^1.2.0", - "strip-json-comments": "~2.0.1" - } - }, - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - }, - "dependencies": { - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - } - } - }, - "readdirp": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz", - "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.11", - "micromatch": "^3.1.10", - "readable-stream": "^2.0.2" - } - }, - "reduce": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/reduce/-/reduce-1.0.2.tgz", - "integrity": "sha512-xX7Fxke/oHO5IfZSk77lvPa/7bjMh9BuCk4OOoX5XTXrM7s0Z+MkPfSDfz0q7r91BhhGSs8gii/VEN/7zhCPpQ==", - "dev": true, - "requires": { - "object-keys": "^1.1.0" - } - }, - "regenerate": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.1.tgz", - "integrity": "sha512-j2+C8+NtXQgEKWk49MMP5P/u2GhnahTtVkRIHr5R5lVRlbKvmQ+oS+A5aLKWp2ma5VkT8sh6v+v4hbH0YHR66A==", - "dev": true - }, - "regenerate-unicode-properties": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-8.2.0.tgz", - "integrity": "sha512-F9DjY1vKLo/tPePDycuH3dn9H1OTPIkVD9Kz4LODu+F2C75mgjAJ7x/gwy6ZcSNRAAkhNlJSOHRe8k3p+K9WhA==", - "dev": true, - "requires": { - "regenerate": "^1.4.0" - } - }, - "regenerator-runtime": { - "version": "0.13.5", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.5.tgz", - "integrity": "sha512-ZS5w8CpKFinUzOwW3c83oPeVXoNsrLsaCoLtJvAClH135j/R77RuymhiSErhm2lKcwSCIpmvIWSbDkIfAqKQlA==", - "dev": true - }, - "regenerator-transform": { - "version": "0.14.4", - "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.14.4.tgz", - "integrity": "sha512-EaJaKPBI9GvKpvUz2mz4fhx7WPgvwRLY9v3hlNHWmAuJHI13T4nwKnNvm5RWJzEdnI5g5UwtOww+S8IdoUC2bw==", - "dev": true, - "requires": { - "@babel/runtime": "^7.8.4", - "private": "^0.1.8" - } - }, - "regex-not": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", - "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", - "dev": true, - "requires": { - "extend-shallow": "^3.0.2", - "safe-regex": "^1.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", - "dev": true, - "requires": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" - } - }, - "is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, - "requires": { - "is-plain-object": "^2.0.4" - } - } - } - }, - "regexp.prototype.flags": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.3.0.tgz", - "integrity": "sha512-2+Q0C5g951OlYlJz6yu5/M33IcsESLlLfsyIaLJaG4FA2r4yP8MvVMJUUP/fVBkSpbbbZlS5gynbEWLipiiXiQ==", - "dev": true, - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.0-next.1" - } - }, - "regexpu-core": { - "version": "4.7.0", - "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-4.7.0.tgz", - "integrity": "sha512-TQ4KXRnIn6tz6tjnrXEkD/sshygKH/j5KzK86X8MkeHyZ8qst/LZ89j3X4/8HEIfHANTFIP/AbXakeRhWIl5YQ==", - "dev": true, - "requires": { - "regenerate": "^1.4.0", - "regenerate-unicode-properties": "^8.2.0", - "regjsgen": "^0.5.1", - "regjsparser": "^0.6.4", - "unicode-match-property-ecmascript": "^1.0.4", - "unicode-match-property-value-ecmascript": "^1.2.0" - } - }, - "registry-auth-token": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-4.1.1.tgz", - "integrity": "sha512-9bKS7nTl9+/A1s7tnPeGrUpRcVY+LUh7bfFgzpndALdPfXQBfQV77rQVtqgUV3ti4vc/Ik81Ex8UJDWDQ12zQA==", - "dev": true, - "requires": { - "rc": "^1.2.8" - } - }, - "registry-url": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/registry-url/-/registry-url-5.1.0.tgz", - "integrity": "sha512-8acYXXTI0AkQv6RAOjE3vOaIXZkT9wo4LOFbBKYQEEnnMNBpKqdUrI6S4NT0KPIo/WVvJ5tE/X5LF/TQUf0ekw==", - "dev": true, - "requires": { - "rc": "^1.2.8" - } - }, - "regjsgen": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.5.2.tgz", - "integrity": "sha512-OFFT3MfrH90xIW8OOSyUrk6QHD5E9JOTeGodiJeBS3J6IwlgzJMNE/1bZklWz5oTg+9dCMyEetclvCVXOPoN3A==", - "dev": true - }, - "regjsparser": { - "version": "0.6.4", - "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.6.4.tgz", - "integrity": "sha512-64O87/dPDgfk8/RQqC4gkZoGyyWFIEUTTh80CU6CWuK5vkCGyekIx+oKcEIYtP/RAxSQltCZHCNu/mdd7fqlJw==", - "dev": true, - "requires": { - "jsesc": "~0.5.0" - }, - "dependencies": { - "jsesc": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", - "integrity": "sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=", - "dev": true - } - } - }, - "relateurl": { - "version": "0.2.7", - "resolved": "https://registry.npmjs.org/relateurl/-/relateurl-0.2.7.tgz", - "integrity": "sha1-VNvzd+UUQKypCkzSdGANP/LYiKk=", - "dev": true - }, - "remove-trailing-separator": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", - "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=", - "dev": true - }, - "renderkid": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/renderkid/-/renderkid-2.0.3.tgz", - "integrity": "sha512-z8CLQp7EZBPCwCnncgf9C4XAi3WR0dv+uWu/PjIyhhAb5d6IJ/QZqlHFprHeKT+59//V6BNUsLbvN8+2LarxGA==", - "dev": true, - "requires": { - "css-select": "^1.1.0", - "dom-converter": "^0.2", - "htmlparser2": "^3.3.0", - "strip-ansi": "^3.0.0", - "utila": "^0.4.0" - }, - "dependencies": { - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true - }, - "css-select": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/css-select/-/css-select-1.2.0.tgz", - "integrity": "sha1-KzoRBTnFNV8c2NMUYj6HCxIeyFg=", - "dev": true, - "requires": { - "boolbase": "~1.0.0", - "css-what": "2.1", - "domutils": "1.5.1", - "nth-check": "~1.0.1" - } - }, - "css-what": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/css-what/-/css-what-2.1.3.tgz", - "integrity": "sha512-a+EPoD+uZiNfh+5fxw2nO9QwFa6nJe2Or35fGY6Ipw1R3R4AGz1d1TEZrCegvw2YTmZ0jXirGYlzxxpYSHwpEg==", - "dev": true - }, - "domutils": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.5.1.tgz", - "integrity": "sha1-3NhIiib1Y9YQeeSMn3t+Mjc2gs8=", - "dev": true, - "requires": { - "dom-serializer": "0", - "domelementtype": "1" - } - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } - } - } - }, - "repeat-element": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.3.tgz", - "integrity": "sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g==", - "dev": true - }, - "repeat-string": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", - "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", - "dev": true - }, - "request": { - "version": "2.88.2", - "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", - "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", - "dev": true, - "requires": { - "aws-sign2": "~0.7.0", - "aws4": "^1.8.0", - "caseless": "~0.12.0", - "combined-stream": "~1.0.6", - "extend": "~3.0.2", - "forever-agent": "~0.6.1", - "form-data": "~2.3.2", - "har-validator": "~5.1.3", - "http-signature": "~1.2.0", - "is-typedarray": "~1.0.0", - "isstream": "~0.1.2", - "json-stringify-safe": "~5.0.1", - "mime-types": "~2.1.19", - "oauth-sign": "~0.9.0", - "performance-now": "^2.1.0", - "qs": "~6.5.2", - "safe-buffer": "^5.1.2", - "tough-cookie": "~2.5.0", - "tunnel-agent": "^0.6.0", - "uuid": "^3.3.2" - } - }, - "require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", - "dev": true - }, - "require-main-filename": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", - "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", - "dev": true - }, - "requires-port": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", - "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=", - "dev": true - }, - "resolve": { - "version": "1.17.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", - "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", - "dev": true, - "requires": { - "path-parse": "^1.0.6" - } - }, - "resolve-cwd": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-2.0.0.tgz", - "integrity": "sha1-AKn3OHVW4nA46uIyyqNypqWbZlo=", - "dev": true, - "requires": { - "resolve-from": "^3.0.0" - } - }, - "resolve-from": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", - "integrity": "sha1-six699nWiBvItuZTM17rywoYh0g=", - "dev": true - }, - "resolve-url": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", - "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=", - "dev": true - }, - "responselike": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/responselike/-/responselike-1.0.2.tgz", - "integrity": "sha1-kYcg7ztjHFZCvgaPFa3lpG9Loec=", - "dev": true, - "requires": { - "lowercase-keys": "^1.0.0" - } - }, - "ret": { - "version": "0.1.15", - "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", - "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", - "dev": true - }, - "retry": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz", - "integrity": "sha1-G0KmJmoh8HQh0bC1S33BZ7AcATs=", - "dev": true - }, - "rgb-regex": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/rgb-regex/-/rgb-regex-1.0.1.tgz", - "integrity": "sha1-wODWiC3w4jviVKR16O3UGRX+rrE=", - "dev": true - }, - "rgba-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/rgba-regex/-/rgba-regex-1.0.0.tgz", - "integrity": "sha1-QzdOLiyglosO8VI0YLfXMP8i7rM=", - "dev": true - }, - "rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", - "dev": true, - "requires": { - "glob": "^7.1.3" - } - }, - "ripemd160": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", - "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", - "dev": true, - "requires": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1" - } - }, - "run-queue": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/run-queue/-/run-queue-1.0.3.tgz", - "integrity": "sha1-6Eg5bwV9Ij8kOGkkYY4laUFh7Ec=", - "dev": true, - "requires": { - "aproba": "^1.1.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "safe-regex": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", - "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", - "dev": true, - "requires": { - "ret": "~0.1.10" - } - }, - "safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "dev": true - }, - "sax": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", - "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==", - "dev": true - }, - "schema-utils": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.0.tgz", - "integrity": "sha512-0ilKFI6QQF5nxDZLFn2dMjvc4hjg/Wkg7rHd3jK6/A4a1Hl9VFdQWvgB1UMGoU94pad1P/8N7fMcEnLnSiju8A==", - "dev": true, - "requires": { - "@types/json-schema": "^7.0.4", - "ajv": "^6.12.2", - "ajv-keywords": "^3.4.1" - } - }, - "section-matter": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/section-matter/-/section-matter-1.0.0.tgz", - "integrity": "sha512-vfD3pmTzGpufjScBh50YHKzEu2lxBWhVEHsNGoEXmCmn2hKGfeNLYMzCJpe8cD7gqX7TJluOVpBkAequ6dgMmA==", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "kind-of": "^6.0.0" - } - }, - "select": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/select/-/select-1.1.2.tgz", - "integrity": "sha1-DnNQrN7ICxEIUoeG7B1EGNEbOW0=", - "dev": true, - "optional": true - }, - "select-hose": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz", - "integrity": "sha1-Yl2GWPhlr0Psliv8N2o3NZpJlMo=", - "dev": true - }, - "selfsigned": { - "version": "1.10.7", - "resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-1.10.7.tgz", - "integrity": "sha512-8M3wBCzeWIJnQfl43IKwOmC4H/RAp50S8DF60znzjW5GVqTcSe2vWclt7hmYVPkKPlHWOu5EaWOMZ2Y6W8ZXTA==", - "dev": true, - "requires": { - "node-forge": "0.9.0" - } - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - }, - "semver-diff": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/semver-diff/-/semver-diff-3.1.1.tgz", - "integrity": "sha512-GX0Ix/CJcHyB8c4ykpHGIAvLyOwOobtM/8d+TQkAd81/bEjgPHrfba41Vpesr7jX/t8Uh+R3EX9eAS5be+jQYg==", - "dev": true, - "requires": { - "semver": "^6.3.0" - }, - "dependencies": { - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true - } - } - }, - "send": { - "version": "0.17.1", - "resolved": "https://registry.npmjs.org/send/-/send-0.17.1.tgz", - "integrity": "sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg==", - "dev": true, - "requires": { - "debug": "2.6.9", - "depd": "~1.1.2", - "destroy": "~1.0.4", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "fresh": "0.5.2", - "http-errors": "~1.7.2", - "mime": "1.6.0", - "ms": "2.1.1", - "on-finished": "~2.3.0", - "range-parser": "~1.2.1", - "statuses": "~1.5.0" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - }, - "dependencies": { - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - } - } - }, - "mime": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", - "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", - "dev": true - }, - "ms": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", - "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", - "dev": true - } - } - }, - "serialize-javascript": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-2.1.2.tgz", - "integrity": "sha512-rs9OggEUF0V4jUSecXazOYsLfu7OGK2qIn3c7IPBiffz32XniEp/TX9Xmc9LQfK2nQ2QKHvZ2oygKUGU0lG4jQ==", - "dev": true - }, - "serve-index": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/serve-index/-/serve-index-1.9.1.tgz", - "integrity": "sha1-03aNabHn2C5c4FD/9bRTvqEqkjk=", - "dev": true, - "requires": { - "accepts": "~1.3.4", - "batch": "0.6.1", - "debug": "2.6.9", - "escape-html": "~1.0.3", - "http-errors": "~1.6.2", - "mime-types": "~2.1.17", - "parseurl": "~1.3.2" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "http-errors": { - "version": "1.6.3", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", - "integrity": "sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0=", - "dev": true, - "requires": { - "depd": "~1.1.2", - "inherits": "2.0.3", - "setprototypeof": "1.1.0", - "statuses": ">= 1.4.0 < 2" - } - }, - "inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", - "dev": true - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - }, - "setprototypeof": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", - "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==", - "dev": true - } - } - }, - "serve-static": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.1.tgz", - "integrity": "sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg==", - "dev": true, - "requires": { - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "parseurl": "~1.3.3", - "send": "0.17.1" - } - }, - "set-blocking": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", - "dev": true - }, - "set-value": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz", - "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-extendable": "^0.1.1", - "is-plain-object": "^2.0.3", - "split-string": "^3.0.1" - } - }, - "setimmediate": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", - "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=", - "dev": true - }, - "setprototypeof": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz", - "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==", - "dev": true - }, - "sha.js": { - "version": "2.4.11", - "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", - "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "shebang-command": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", - "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", - "dev": true, - "requires": { - "shebang-regex": "^1.0.0" - } - }, - "shebang-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", - "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", - "dev": true - }, - "signal-exit": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz", - "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==", - "dev": true - }, - "simple-swizzle": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz", - "integrity": "sha1-pNprY1/8zMoz9w0Xy5JZLeleVXo=", - "dev": true, - "requires": { - "is-arrayish": "^0.3.1" - }, - "dependencies": { - "is-arrayish": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz", - "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==", - "dev": true - } - } - }, - "slash": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz", - "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==", - "dev": true - }, - "smoothscroll-polyfill": { - "version": "0.4.4", - "resolved": "https://registry.npmjs.org/smoothscroll-polyfill/-/smoothscroll-polyfill-0.4.4.tgz", - "integrity": "sha512-TK5ZA9U5RqCwMpfoMq/l1mrH0JAR7y7KRvOBx0n2869aLxch+gT9GhN3yUfjiw+d/DiF1mKo14+hd62JyMmoBg==", - "dev": true - }, - "snapdragon": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", - "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", - "dev": true, - "requires": { - "base": "^0.11.1", - "debug": "^2.2.0", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "map-cache": "^0.2.2", - "source-map": "^0.5.6", - "source-map-resolve": "^0.5.0", - "use": "^3.1.0" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - } - }, - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - } - } - }, - "snapdragon-node": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", - "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", - "dev": true, - "requires": { - "define-property": "^1.0.0", - "isobject": "^3.0.0", - "snapdragon-util": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - } - } - }, - "snapdragon-util": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", - "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", - "dev": true, - "requires": { - "kind-of": "^3.2.0" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "sockjs": { - "version": "0.3.20", - "resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.20.tgz", - "integrity": "sha512-SpmVOVpdq0DJc0qArhF3E5xsxvaiqGNb73XfgBpK1y3UD5gs8DSo8aCTsuT5pX8rssdc2NDIzANwP9eCAiSdTA==", - "dev": true, - "requires": { - "faye-websocket": "^0.10.0", - "uuid": "^3.4.0", - "websocket-driver": "0.6.5" - } - }, - "sockjs-client": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/sockjs-client/-/sockjs-client-1.4.0.tgz", - "integrity": "sha512-5zaLyO8/nri5cua0VtOrFXBPK1jbL4+1cebT/mmKA1E1ZXOvJrII75bPu0l0k843G/+iAbhEqzyKr0w/eCCj7g==", - "dev": true, - "requires": { - "debug": "^3.2.5", - "eventsource": "^1.0.7", - "faye-websocket": "~0.11.1", - "inherits": "^2.0.3", - "json3": "^3.3.2", - "url-parse": "^1.4.3" - }, - "dependencies": { - "debug": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", - "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - }, - "faye-websocket": { - "version": "0.11.3", - "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.3.tgz", - "integrity": "sha512-D2y4bovYpzziGgbHYtGCMjlJM36vAl/y+xUyn1C+FVx8szd1E+86KwVw6XvYSzOP8iMpm1X0I4xJD+QtUb36OA==", - "dev": true, - "requires": { - "websocket-driver": ">=0.5.1" - } - } - } - }, - "sort-keys": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/sort-keys/-/sort-keys-2.0.0.tgz", - "integrity": "sha1-ZYU1WEhh7JfXMNbPQYIuH1ZoQSg=", - "dev": true, - "requires": { - "is-plain-obj": "^1.0.0" - } - }, - "source-list-map": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.1.tgz", - "integrity": "sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw==", - "dev": true - }, - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true - }, - "source-map-resolve": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz", - "integrity": "sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==", - "dev": true, - "requires": { - "atob": "^2.1.2", - "decode-uri-component": "^0.2.0", - "resolve-url": "^0.2.1", - "source-map-url": "^0.4.0", - "urix": "^0.1.0" - } - }, - "source-map-support": { - "version": "0.5.19", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz", - "integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==", - "dev": true, - "requires": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - } - } - }, - "source-map-url": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz", - "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=", - "dev": true - }, - "spdy": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/spdy/-/spdy-4.0.2.tgz", - "integrity": "sha512-r46gZQZQV+Kl9oItvl1JZZqJKGr+oEkB08A6BzkiR7593/7IbtuncXHd2YoYeTsG4157ZssMu9KYvUHLcjcDoA==", - "dev": true, - "requires": { - "debug": "^4.1.0", - "handle-thing": "^2.0.0", - "http-deceiver": "^1.2.7", - "select-hose": "^2.0.0", - "spdy-transport": "^3.0.0" - } - }, - "spdy-transport": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/spdy-transport/-/spdy-transport-3.0.0.tgz", - "integrity": "sha512-hsLVFE5SjA6TCisWeJXFKniGGOpBgMLmerfO2aCyCU5s7nJ/rpAepqmFifv/GCbSbueEeAJJnmSQ2rKC/g8Fcw==", - "dev": true, - "requires": { - "debug": "^4.1.0", - "detect-node": "^2.0.4", - "hpack.js": "^2.1.6", - "obuf": "^1.1.2", - "readable-stream": "^3.0.6", - "wbuf": "^1.7.3" - }, - "dependencies": { - "readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - } - } - }, - "split-string": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", - "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", - "dev": true, - "requires": { - "extend-shallow": "^3.0.0" - }, - "dependencies": { - "extend-shallow": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", - "dev": true, - "requires": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" - } - }, - "is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, - "requires": { - "is-plain-object": "^2.0.4" - } - } - } - }, - "sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", - "dev": true - }, - "sshpk": { - "version": "1.16.1", - "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", - "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", - "dev": true, - "requires": { - "asn1": "~0.2.3", - "assert-plus": "^1.0.0", - "bcrypt-pbkdf": "^1.0.0", - "dashdash": "^1.12.0", - "ecc-jsbn": "~0.1.1", - "getpass": "^0.1.1", - "jsbn": "~0.1.0", - "safer-buffer": "^2.0.2", - "tweetnacl": "~0.14.0" - } - }, - "ssri": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/ssri/-/ssri-6.0.2.tgz", - "integrity": "sha512-cepbSq/neFK7xB6A50KHN0xHDotYzq58wWCa5LeWqnPrHG8GzfEjO/4O8kpmcGW+oaxkvhEJCWgbgNk4/ZV93Q==", - "dev": true, - "requires": { - "figgy-pudding": "^3.5.1" - } - }, - "stable": { - "version": "0.1.8", - "resolved": "https://registry.npmjs.org/stable/-/stable-0.1.8.tgz", - "integrity": "sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w==", - "dev": true - }, - "stack-utils": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-1.0.2.tgz", - "integrity": "sha512-MTX+MeG5U994cazkjd/9KNAapsHnibjMLnfXodlkXw76JEea0UiNzrqidzo1emMwk7w5Qhc9jd4Bn9TBb1MFwA==", - "dev": true - }, - "static-extend": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", - "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=", - "dev": true, - "requires": { - "define-property": "^0.2.5", - "object-copy": "^0.1.0" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - } - }, - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } - } - }, - "statuses": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", - "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=", - "dev": true - }, - "std-env": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/std-env/-/std-env-2.2.1.tgz", - "integrity": "sha512-IjYQUinA3lg5re/YMlwlfhqNRTzMZMqE+pezevdcTaHceqx8ngEi1alX9nNCk9Sc81fy1fLDeQoaCzeiW1yBOQ==", - "dev": true, - "requires": { - "ci-info": "^1.6.0" - }, - "dependencies": { - "ci-info": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-1.6.0.tgz", - "integrity": "sha512-vsGdkwSCDpWmP80ncATX7iea5DWQemg1UgCW5J8tqjU3lYw4FBYuj89J0CTVomA7BEfvSZd84GmHko+MxFQU2A==", - "dev": true - } - } - }, - "stream-browserify": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.2.tgz", - "integrity": "sha512-nX6hmklHs/gr2FuxYDltq8fJA1GDlxKQCz8O/IM4atRqBH8OORmBNgfvW5gG10GT/qQ9u0CzIvr2X5Pkt6ntqg==", - "dev": true, - "requires": { - "inherits": "~2.0.1", - "readable-stream": "^2.0.2" - } - }, - "stream-each": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/stream-each/-/stream-each-1.2.3.tgz", - "integrity": "sha512-vlMC2f8I2u/bZGqkdfLQW/13Zihpej/7PmSiMQsbYddxuTsJp8vRe2x2FvVExZg7FaOds43ROAuFJwPR4MTZLw==", - "dev": true, - "requires": { - "end-of-stream": "^1.1.0", - "stream-shift": "^1.0.0" - } - }, - "stream-http": { - "version": "2.8.3", - "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-2.8.3.tgz", - "integrity": "sha512-+TSkfINHDo4J+ZobQLWiMouQYB+UVYFttRA94FpEzzJ7ZdqcL4uUUQ7WkdkI4DSozGmgBUE/a47L+38PenXhUw==", - "dev": true, - "requires": { - "builtin-status-codes": "^3.0.0", - "inherits": "^2.0.1", - "readable-stream": "^2.3.6", - "to-arraybuffer": "^1.0.0", - "xtend": "^4.0.0" - } - }, - "stream-shift": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.1.tgz", - "integrity": "sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ==", - "dev": true - }, - "strict-uri-encode": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz", - "integrity": "sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM=", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - }, - "string-width": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", - "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", - "dev": true, - "requires": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.0" - } - }, - "string.prototype.trimend": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.1.tgz", - "integrity": "sha512-LRPxFUaTtpqYsTeNKaFOw3R4bxIzWOnbQ837QfBylo8jIxtcbK/A/sMV7Q+OAV/vWo+7s25pOE10KYSjaSO06g==", - "dev": true, - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.5" - } - }, - "string.prototype.trimleft": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/string.prototype.trimleft/-/string.prototype.trimleft-2.1.2.tgz", - "integrity": "sha512-gCA0tza1JBvqr3bfAIFJGqfdRTyPae82+KTnm3coDXkZN9wnuW3HjGgN386D7hfv5CHQYCI022/rJPVlqXyHSw==", - "dev": true, - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.5", - "string.prototype.trimstart": "^1.0.0" - } - }, - "string.prototype.trimright": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/string.prototype.trimright/-/string.prototype.trimright-2.1.2.tgz", - "integrity": "sha512-ZNRQ7sY3KroTaYjRS6EbNiiHrOkjihL9aQE/8gfQ4DtAC/aEBRHFJa44OmoWxGGqXuJlfKkZW4WcXErGr+9ZFg==", - "dev": true, - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.5", - "string.prototype.trimend": "^1.0.0" - } - }, - "string.prototype.trimstart": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.1.tgz", - "integrity": "sha512-XxZn+QpvrBI1FOcg6dIpxUPgWCPuNXvMD72aaRaUQv1eD4e/Qy8i/hFTe0BUmD60p/QA6bh1avmuPTfNjqVWRw==", - "dev": true, - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.5" - } - }, - "strip-ansi": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", - "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", - "dev": true, - "requires": { - "ansi-regex": "^5.0.0" - } - }, - "strip-bom-string": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/strip-bom-string/-/strip-bom-string-1.0.0.tgz", - "integrity": "sha1-5SEekiQ2n7uB1jOi8ABE3IztrZI=", - "dev": true - }, - "strip-eof": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", - "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=", - "dev": true - }, - "strip-json-comments": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", - "dev": true - }, - "stylehacks": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/stylehacks/-/stylehacks-4.0.3.tgz", - "integrity": "sha512-7GlLk9JwlElY4Y6a/rmbH2MhVlTyVmiJd1PfTCqFaIBEGMYNsrO/v3SeGTdhBThLg4Z+NbOk/qFMwCa+J+3p/g==", - "dev": true, - "requires": { - "browserslist": "^4.0.0", - "postcss": "^7.0.0", - "postcss-selector-parser": "^3.0.0" - }, - "dependencies": { - "postcss-selector-parser": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-3.1.2.tgz", - "integrity": "sha512-h7fJ/5uWuRVyOtkO45pnt1Ih40CEleeyCHzipqAZO2e5H20g25Y48uYnFUiShvY4rZWNJ/Bib/KVPmanaCtOhA==", - "dev": true, - "requires": { - "dot-prop": "^5.2.0", - "indexes-of": "^1.0.1", - "uniq": "^1.0.1" - } - } - } - }, - "stylus": { - "version": "0.54.7", - "resolved": "https://registry.npmjs.org/stylus/-/stylus-0.54.7.tgz", - "integrity": "sha512-Yw3WMTzVwevT6ZTrLCYNHAFmanMxdylelL3hkWNgPMeTCpMwpV3nXjpOHuBXtFv7aiO2xRuQS6OoAdgkNcSNug==", - "dev": true, - "requires": { - "css-parse": "~2.0.0", - "debug": "~3.1.0", - "glob": "^7.1.3", - "mkdirp": "~0.5.x", - "safer-buffer": "^2.1.2", - "sax": "~1.2.4", - "semver": "^6.0.0", - "source-map": "^0.7.3" - }, - "dependencies": { - "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - }, - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true - }, - "source-map": { - "version": "0.7.3", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", - "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==", - "dev": true - } - } - }, - "stylus-loader": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/stylus-loader/-/stylus-loader-3.0.2.tgz", - "integrity": "sha512-+VomPdZ6a0razP+zinir61yZgpw2NfljeSsdUF5kJuEzlo3khXhY19Fn6l8QQz1GRJGtMCo8nG5C04ePyV7SUA==", - "dev": true, - "requires": { - "loader-utils": "^1.0.2", - "lodash.clonedeep": "^4.5.0", - "when": "~3.6.x" - } - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - }, - "svg-tags": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/svg-tags/-/svg-tags-1.0.0.tgz", - "integrity": "sha1-WPcc7jvVGbWdSyqEO2x95krAR2Q=", - "dev": true - }, - "svgo": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/svgo/-/svgo-1.3.2.tgz", - "integrity": "sha512-yhy/sQYxR5BkC98CY7o31VGsg014AKLEPxdfhora76l36hD9Rdy5NZA/Ocn6yayNPgSamYdtX2rFJdcv07AYVw==", - "dev": true, - "requires": { - "chalk": "^2.4.1", - "coa": "^2.0.2", - "css-select": "^2.0.0", - "css-select-base-adapter": "^0.1.1", - "css-tree": "1.0.0-alpha.37", - "csso": "^4.0.2", - "js-yaml": "^3.13.1", - "mkdirp": "~0.5.1", - "object.values": "^1.1.0", - "sax": "~1.2.4", - "stable": "^0.1.8", - "unquote": "~1.1.1", - "util.promisify": "~1.0.0" - } - }, - "tapable": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-1.1.3.tgz", - "integrity": "sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA==", - "dev": true - }, - "term-size": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/term-size/-/term-size-2.2.0.tgz", - "integrity": "sha512-a6sumDlzyHVJWb8+YofY4TW112G6p2FCPEAFk+59gIYHv3XHRhm9ltVQ9kli4hNWeQBwSpe8cRN25x0ROunMOw==", - "dev": true - }, - "terser": { - "version": "4.7.0", - "resolved": "https://registry.npmjs.org/terser/-/terser-4.7.0.tgz", - "integrity": "sha512-Lfb0RiZcjRDXCC3OSHJpEkxJ9Qeqs6mp2v4jf2MHfy8vGERmVDuvjXdd/EnP5Deme5F2yBRBymKmKHCBg2echw==", - "dev": true, - "requires": { - "commander": "^2.20.0", - "source-map": "~0.6.1", - "source-map-support": "~0.5.12" - }, - "dependencies": { - "commander": { - "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", - "dev": true - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - } - } - }, - "terser-webpack-plugin": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-1.4.4.tgz", - "integrity": "sha512-U4mACBHIegmfoEe5fdongHESNJWqsGU+W0S/9+BmYGVQDw1+c2Ow05TpMhxjPK1sRb7cuYq1BPl1e5YHJMTCqA==", - "dev": true, - "requires": { - "cacache": "^12.0.2", - "find-cache-dir": "^2.1.0", - "is-wsl": "^1.1.0", - "schema-utils": "^1.0.0", - "serialize-javascript": "^3.1.0", - "source-map": "^0.6.1", - "terser": "^4.1.2", - "webpack-sources": "^1.4.0", - "worker-farm": "^1.7.0" - }, - "dependencies": { - "schema-utils": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", - "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", - "dev": true, - "requires": { - "ajv": "^6.1.0", - "ajv-errors": "^1.0.0", - "ajv-keywords": "^3.1.0" - } - }, - "serialize-javascript": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-3.1.0.tgz", - "integrity": "sha512-JIJT1DGiWmIKhzRsG91aS6Ze4sFUrYbltlkg2onR5OrnNM02Kl/hnY/T4FN2omvyeBbQmMJv+K4cPOpGzOTFBg==", - "dev": true, - "requires": { - "randombytes": "^2.1.0" - } - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - } - } - }, - "text-table": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", - "dev": true - }, - "through": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", - "dev": true - }, - "through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "dev": true, - "requires": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - } - }, - "thunky": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/thunky/-/thunky-1.1.0.tgz", - "integrity": "sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==", - "dev": true - }, - "timers-browserify": { - "version": "2.0.11", - "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.11.tgz", - "integrity": "sha512-60aV6sgJ5YEbzUdn9c8kYGIqOubPoUdqQCul3SBAsRCZ40s6Y5cMcrW4dt3/k/EsbLVJNl9n6Vz3fTc+k2GeKQ==", - "dev": true, - "requires": { - "setimmediate": "^1.0.4" - } - }, - "timsort": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/timsort/-/timsort-0.3.0.tgz", - "integrity": "sha1-QFQRqOfmM5/mTbmiNN4R3DHgK9Q=", - "dev": true - }, - "tiny-emitter": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/tiny-emitter/-/tiny-emitter-2.1.0.tgz", - "integrity": "sha512-NB6Dk1A9xgQPMoGqC5CVXn123gWyte215ONT5Pp5a0yt4nlEoO1ZWeCwpncaekPHXO60i47ihFnZPiRPjRMq4Q==", - "dev": true, - "optional": true - }, - "to-arraybuffer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz", - "integrity": "sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M=", - "dev": true - }, - "to-factory": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/to-factory/-/to-factory-1.0.0.tgz", - "integrity": "sha1-hzivi9lxIK0dQEeXKtpVY7+UebE=", - "dev": true - }, - "to-fast-properties": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", - "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", - "dev": true - }, - "to-object-path": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", - "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "to-readable-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/to-readable-stream/-/to-readable-stream-1.0.0.tgz", - "integrity": "sha512-Iq25XBt6zD5npPhlLVXGFN3/gyR2/qODcKNNyTMd4vbm39HUaOiAM4PMq0eMVC/Tkxz+Zjdsc55g9yyz+Yq00Q==", - "dev": true - }, - "to-regex": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", - "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", - "dev": true, - "requires": { - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "regex-not": "^1.0.2", - "safe-regex": "^1.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", - "dev": true, - "requires": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" - } - }, - "is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, - "requires": { - "is-plain-object": "^2.0.4" - } - } - } - }, - "to-regex-range": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", - "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", - "dev": true, - "requires": { - "is-number": "^3.0.0", - "repeat-string": "^1.6.1" - } - }, - "toidentifier": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz", - "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==", - "dev": true - }, - "toml": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/toml/-/toml-3.0.0.tgz", - "integrity": "sha512-y/mWCZinnvxjTKYhJ+pYxwD0mRLVvOtdS2Awbgxln6iEnt4rk0yBxeSBHkGJcPucRiG0e55mwWp+g/05rsrd6w==", - "dev": true - }, - "toposort": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/toposort/-/toposort-1.0.7.tgz", - "integrity": "sha1-LmhELZ9k7HILjMieZEOsbKqVACk=", - "dev": true - }, - "tough-cookie": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", - "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", - "dev": true, - "requires": { - "psl": "^1.1.28", - "punycode": "^2.1.1" - } - }, - "tslib": { - "version": "1.13.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.13.0.tgz", - "integrity": "sha512-i/6DQjL8Xf3be4K/E6Wgpekn5Qasl1usyw++dAA35Ue5orEn65VIxOA+YvNNl9HV3qv70T7CNwjODHZrLwvd1Q==", - "dev": true - }, - "tty-browserify": { - "version": "0.0.0", - "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz", - "integrity": "sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY=", - "dev": true - }, - "tunnel-agent": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", - "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", - "dev": true, - "requires": { - "safe-buffer": "^5.0.1" - } - }, - "tweetnacl": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", - "dev": true - }, - "type-fest": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", - "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", - "dev": true - }, - "type-is": { - "version": "1.6.18", - "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", - "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", - "dev": true, - "requires": { - "media-typer": "0.3.0", - "mime-types": "~2.1.24" - } - }, - "typedarray": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", - "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", - "dev": true - }, - "typedarray-to-buffer": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", - "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", - "dev": true, - "requires": { - "is-typedarray": "^1.0.0" - } - }, - "uc.micro": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.6.tgz", - "integrity": "sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==", - "dev": true - }, - "uglify-js": { - "version": "3.4.10", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.4.10.tgz", - "integrity": "sha512-Y2VsbPVs0FIshJztycsO2SfPk7/KAF/T72qzv9u5EpQ4kB2hQoHlhNQTsNyy6ul7lQtqJN/AoWeS23OzEiEFxw==", - "dev": true, - "requires": { - "commander": "~2.19.0", - "source-map": "~0.6.1" - }, - "dependencies": { - "commander": { - "version": "2.19.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.19.0.tgz", - "integrity": "sha512-6tvAOO+D6OENvRAh524Dh9jcfKTYDQAqvqezbCW82xj5X0pSrcpxtvRKHLG0yBY6SD7PSDrJaj+0AiOcKVd1Xg==", - "dev": true - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - } - } - }, - "unicode-canonical-property-names-ecmascript": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-1.0.4.tgz", - "integrity": "sha512-jDrNnXWHd4oHiTZnx/ZG7gtUTVp+gCcTTKr8L0HjlwphROEW3+Him+IpvC+xcJEFegapiMZyZe02CyuOnRmbnQ==", - "dev": true - }, - "unicode-match-property-ecmascript": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-1.0.4.tgz", - "integrity": "sha512-L4Qoh15vTfntsn4P1zqnHulG0LdXgjSO035fEpdtp6YxXhMT51Q6vgM5lYdG/5X3MjS+k/Y9Xw4SFCY9IkR0rg==", - "dev": true, - "requires": { - "unicode-canonical-property-names-ecmascript": "^1.0.4", - "unicode-property-aliases-ecmascript": "^1.0.4" - } - }, - "unicode-match-property-value-ecmascript": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-1.2.0.tgz", - "integrity": "sha512-wjuQHGQVofmSJv1uVISKLE5zO2rNGzM/KCYZch/QQvez7C1hUhBIuZ701fYXExuufJFMPhv2SyL8CyoIfMLbIQ==", - "dev": true - }, - "unicode-property-aliases-ecmascript": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-1.1.0.tgz", - "integrity": "sha512-PqSoPh/pWetQ2phoj5RLiaqIk4kCNwoV3CI+LfGmWLKI3rE3kl1h59XpX2BjgDrmbxD9ARtQobPGU1SguCYuQg==", - "dev": true - }, - "union-value": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", - "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==", - "dev": true, - "requires": { - "arr-union": "^3.1.0", - "get-value": "^2.0.6", - "is-extendable": "^0.1.1", - "set-value": "^2.0.1" - } - }, - "uniq": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/uniq/-/uniq-1.0.1.tgz", - "integrity": "sha1-sxxa6CVIRKOoKBVBzisEuGWnNP8=", - "dev": true - }, - "uniqs": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/uniqs/-/uniqs-2.0.0.tgz", - "integrity": "sha1-/+3ks2slKQaW5uFl1KWe25mOawI=", - "dev": true - }, - "unique-filename": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-1.1.1.tgz", - "integrity": "sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ==", - "dev": true, - "requires": { - "unique-slug": "^2.0.0" - } - }, - "unique-slug": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-2.0.2.tgz", - "integrity": "sha512-zoWr9ObaxALD3DOPfjPSqxt4fnZiWblxHIgeWqW8x7UqDzEtHEQLzji2cuJYQFCU6KmoJikOYAZlrTHHebjx2w==", - "dev": true, - "requires": { - "imurmurhash": "^0.1.4" - } - }, - "unique-string": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-2.0.0.tgz", - "integrity": "sha512-uNaeirEPvpZWSgzwsPGtU2zVSTrn/8L5q/IexZmH0eH6SA73CmAA5U4GwORTxQAZs95TAXLNqeLoPPNO5gZfWg==", - "dev": true, - "requires": { - "crypto-random-string": "^2.0.0" - } - }, - "universalify": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", - "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", - "dev": true - }, - "unpipe": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", - "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=", - "dev": true - }, - "unquote": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/unquote/-/unquote-1.1.1.tgz", - "integrity": "sha1-j97XMk7G6IoP+LkF58CYzcCG1UQ=", - "dev": true - }, - "unset-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", - "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=", - "dev": true, - "requires": { - "has-value": "^0.3.1", - "isobject": "^3.0.0" - }, - "dependencies": { - "has-value": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", - "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=", - "dev": true, - "requires": { - "get-value": "^2.0.3", - "has-values": "^0.1.4", - "isobject": "^2.0.0" - }, - "dependencies": { - "isobject": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", - "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", - "dev": true, - "requires": { - "isarray": "1.0.0" - } - } - } - }, - "has-values": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", - "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=", - "dev": true - }, - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - } - } - }, - "upath": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz", - "integrity": "sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==", - "dev": true - }, - "update-notifier": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-4.1.0.tgz", - "integrity": "sha512-w3doE1qtI0/ZmgeoDoARmI5fjDoT93IfKgEGqm26dGUOh8oNpaSTsGNdYRN/SjOuo10jcJGwkEL3mroKzktkew==", - "dev": true, - "requires": { - "boxen": "^4.2.0", - "chalk": "^3.0.0", - "configstore": "^5.0.1", - "has-yarn": "^2.1.0", - "import-lazy": "^2.1.0", - "is-ci": "^2.0.0", - "is-installed-globally": "^0.3.1", - "is-npm": "^4.0.0", - "is-yarn-global": "^0.3.0", - "latest-version": "^5.0.0", - "pupa": "^2.0.1", - "semver-diff": "^3.1.1", - "xdg-basedir": "^4.0.0" - }, - "dependencies": { - "ansi-styles": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", - "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", - "dev": true, - "requires": { - "@types/color-name": "^1.1.1", - "color-convert": "^2.0.1" - } - }, - "chalk": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", - "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, - "supports-color": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", - "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - } - } - }, - "upper-case": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/upper-case/-/upper-case-1.1.3.tgz", - "integrity": "sha1-9rRQHC7EzdJrp4vnIilh3ndiFZg=", - "dev": true - }, - "uri-js": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", - "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", - "dev": true, - "requires": { - "punycode": "^2.1.0" - } - }, - "urix": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", - "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=", - "dev": true - }, - "url": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz", - "integrity": "sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE=", - "dev": true, - "requires": { - "punycode": "1.3.2", - "querystring": "0.2.0" - }, - "dependencies": { - "punycode": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", - "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=", - "dev": true - } - } - }, - "url-loader": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/url-loader/-/url-loader-1.1.2.tgz", - "integrity": "sha512-dXHkKmw8FhPqu8asTc1puBfe3TehOCo2+RmOOev5suNCIYBcT626kxiWg1NBVkwc4rO8BGa7gP70W7VXuqHrjg==", - "dev": true, - "requires": { - "loader-utils": "^1.1.0", - "mime": "^2.0.3", - "schema-utils": "^1.0.0" - }, - "dependencies": { - "schema-utils": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", - "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", - "dev": true, - "requires": { - "ajv": "^6.1.0", - "ajv-errors": "^1.0.0", - "ajv-keywords": "^3.1.0" - } - } - } - }, - "url-parse": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.1.tgz", - "integrity": "sha512-HOfCOUJt7iSYzEx/UqgtwKRMC6EU91NFhsCHMv9oM03VJcVo2Qrp8T8kI9D7amFf1cu+/3CEhgb3rF9zL7k85Q==", - "dev": true, - "requires": { - "querystringify": "^2.1.1", - "requires-port": "^1.0.0" - } - }, - "url-parse-lax": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-3.0.0.tgz", - "integrity": "sha1-FrXK/Afb42dsGxmZF3gj1lA6yww=", - "dev": true, - "requires": { - "prepend-http": "^2.0.0" - } - }, - "use": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", - "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==", - "dev": true - }, - "util": { - "version": "0.11.1", - "resolved": "https://registry.npmjs.org/util/-/util-0.11.1.tgz", - "integrity": "sha512-HShAsny+zS2TZfaXxD9tYj4HQGlBezXZMZuM/S5PKLLoZkShZiGk9o5CzukI1LVHZvjdvZ2Sj1aW/Ndn2NB/HQ==", - "dev": true, - "requires": { - "inherits": "2.0.3" - }, - "dependencies": { - "inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", - "dev": true - } - } - }, - "util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", - "dev": true - }, - "util.promisify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/util.promisify/-/util.promisify-1.0.1.tgz", - "integrity": "sha512-g9JpC/3He3bm38zsLupWryXHoEcS22YHthuPQSJdMy6KNrzIRzWqcsHzD/WUnqe45whVou4VIsPew37DoXWNrA==", - "dev": true, - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.2", - "has-symbols": "^1.0.1", - "object.getownpropertydescriptors": "^2.1.0" - } - }, - "utila": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/utila/-/utila-0.4.0.tgz", - "integrity": "sha1-ihagXURWV6Oupe7MWxKk+lN5dyw=", - "dev": true - }, - "utils-merge": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", - "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=", - "dev": true - }, - "uuid": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", - "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", - "dev": true - }, - "vary": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", - "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=", - "dev": true - }, - "vendors": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/vendors/-/vendors-1.0.4.tgz", - "integrity": "sha512-/juG65kTL4Cy2su4P8HjtkTxk6VmJDiOPBufWniqQ6wknac6jNiXS9vU+hO3wgusiyqWlzTbVHi0dyJqRONg3w==", - "dev": true - }, - "verror": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", - "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", - "dev": true, - "requires": { - "assert-plus": "^1.0.0", - "core-util-is": "1.0.2", - "extsprintf": "^1.2.0" - } - }, - "vm-browserify": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-1.1.2.tgz", - "integrity": "sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==", - "dev": true - }, - "vue": { - "version": "2.6.11", - "resolved": "https://registry.npmjs.org/vue/-/vue-2.6.11.tgz", - "integrity": "sha512-VfPwgcGABbGAue9+sfrD4PuwFar7gPb1yl1UK1MwXoQPAw0BKSqWfoYCT/ThFrdEVWoI51dBuyCoiNU9bZDZxQ==", - "dev": true - }, - "vue-hot-reload-api": { - "version": "2.3.4", - "resolved": "https://registry.npmjs.org/vue-hot-reload-api/-/vue-hot-reload-api-2.3.4.tgz", - "integrity": "sha512-BXq3jwIagosjgNVae6tkHzzIk6a8MHFtzAdwhnV5VlvPTFxDCvIttgSiHWjdGoTJvXtmRu5HacExfdarRcFhog==", - "dev": true - }, - "vue-loader": { - "version": "15.9.2", - "resolved": "https://registry.npmjs.org/vue-loader/-/vue-loader-15.9.2.tgz", - "integrity": "sha512-oXBubaY//CYEISBlHX+c2YPJbmOH68xXPXjFv4MAgPqQvUsnjrBAjCJi8HXZ/r/yfn0tPL5VZj1Zcp8mJPI8VA==", - "dev": true, - "requires": { - "@vue/component-compiler-utils": "^3.1.0", - "hash-sum": "^1.0.2", - "loader-utils": "^1.1.0", - "vue-hot-reload-api": "^2.3.0", - "vue-style-loader": "^4.1.0" - } - }, - "vue-router": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/vue-router/-/vue-router-3.3.2.tgz", - "integrity": "sha512-5sEbcfb7MW8mY8lbUVbF4kgcipGXsagkM/X+pb6n0MhjP+RorWIUTPAPSqgPaiPOxVCXgAItBl8Vwz8vq78faA==", - "dev": true - }, - "vue-server-renderer": { - "version": "2.6.11", - "resolved": "https://registry.npmjs.org/vue-server-renderer/-/vue-server-renderer-2.6.11.tgz", - "integrity": "sha512-V3faFJHr2KYfdSIalL+JjinZSHYUhlrvJ9pzCIjjwSh77+pkrsXpK4PucdPcng57+N77pd1LrKqwbqjQdktU1A==", - "dev": true, - "requires": { - "chalk": "^1.1.3", - "hash-sum": "^1.0.2", - "he": "^1.1.0", - "lodash.template": "^4.5.0", - "lodash.uniq": "^4.5.0", - "resolve": "^1.2.0", - "serialize-javascript": "^2.1.2", - "source-map": "0.5.6" - }, - "dependencies": { - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true - }, - "ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", - "dev": true - }, - "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "dev": true, - "requires": { - "ansi-styles": "^2.2.1", - "escape-string-regexp": "^1.0.2", - "has-ansi": "^2.0.0", - "strip-ansi": "^3.0.0", - "supports-color": "^2.0.0" - } - }, - "source-map": { - "version": "0.5.6", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.6.tgz", - "integrity": "sha1-dc449SvwczxafwwRjYEzSiu19BI=", - "dev": true - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "supports-color": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", - "dev": true - } - } - }, - "vue-style-loader": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/vue-style-loader/-/vue-style-loader-4.1.2.tgz", - "integrity": "sha512-0ip8ge6Gzz/Bk0iHovU9XAUQaFt/G2B61bnWa2tCcqqdgfHs1lF9xXorFbE55Gmy92okFT+8bfmySuUOu13vxQ==", - "dev": true, - "requires": { - "hash-sum": "^1.0.2", - "loader-utils": "^1.0.2" - } - }, - "vue-template-compiler": { - "version": "2.6.11", - "resolved": "https://registry.npmjs.org/vue-template-compiler/-/vue-template-compiler-2.6.11.tgz", - "integrity": "sha512-KIq15bvQDrcCjpGjrAhx4mUlyyHfdmTaoNfeoATHLAiWB+MU3cx4lOzMwrnUh9cCxy0Lt1T11hAFY6TQgroUAA==", - "dev": true, - "requires": { - "de-indent": "^1.0.2", - "he": "^1.1.0" - } - }, - "vue-template-es2015-compiler": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/vue-template-es2015-compiler/-/vue-template-es2015-compiler-1.9.1.tgz", - "integrity": "sha512-4gDntzrifFnCEvyoO8PqyJDmguXgVPxKiIxrBKjIowvL9l+N66196+72XVYR8BBf1Uv1Fgt3bGevJ+sEmxfZzw==", - "dev": true - }, - "vuepress": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/vuepress/-/vuepress-1.5.1.tgz", - "integrity": "sha512-UB5YHwcS1t0XVPfMN4pcKanH2Wb9XvhRNJMGt4O9wiUauwlgC6cwnwhatR3AmsbiwybQYgiOSj+CJKuhjYgAeQ==", - "dev": true, - "requires": { - "@vuepress/core": "1.5.1", - "@vuepress/theme-default": "1.5.1", - "cac": "^6.5.6", - "envinfo": "^7.2.0", - "opencollective-postinstall": "^2.0.2", - "update-notifier": "^4.0.0" - } - }, - "vuepress-html-webpack-plugin": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/vuepress-html-webpack-plugin/-/vuepress-html-webpack-plugin-3.2.0.tgz", - "integrity": "sha512-BebAEl1BmWlro3+VyDhIOCY6Gef2MCBllEVAP3NUAtMguiyOwo/dClbwJ167WYmcxHJKLl7b0Chr9H7fpn1d0A==", - "dev": true, - "requires": { - "html-minifier": "^3.2.3", - "loader-utils": "^0.2.16", - "lodash": "^4.17.3", - "pretty-error": "^2.0.2", - "tapable": "^1.0.0", - "toposort": "^1.0.0", - "util.promisify": "1.0.0" - }, - "dependencies": { - "big.js": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/big.js/-/big.js-3.2.0.tgz", - "integrity": "sha512-+hN/Zh2D08Mx65pZ/4g5bsmNiZUuChDiQfTUQ7qJr4/kuopCr88xZsAXv6mBoZEsUI4OuGHlX59qE94K2mMW8Q==", - "dev": true - }, - "emojis-list": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-2.1.0.tgz", - "integrity": "sha1-TapNnbAPmBmIDHn6RXrlsJof04k=", - "dev": true - }, - "json5": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-0.5.1.tgz", - "integrity": "sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE=", - "dev": true - }, - "loader-utils": { - "version": "0.2.17", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-0.2.17.tgz", - "integrity": "sha1-+G5jdNQyBabmxg6RlvF8Apm/s0g=", - "dev": true, - "requires": { - "big.js": "^3.1.3", - "emojis-list": "^2.0.0", - "json5": "^0.5.0", - "object-assign": "^4.0.1" - } - }, - "util.promisify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/util.promisify/-/util.promisify-1.0.0.tgz", - "integrity": "sha512-i+6qA2MPhvoKLuxnJNpXAGhg7HphQOSUq2LKMZD0m15EiskXUkMvKdF4Uui0WYeCUGea+o2cw/ZuwehtfsrNkA==", - "dev": true, - "requires": { - "define-properties": "^1.1.2", - "object.getownpropertydescriptors": "^2.0.3" - } - } - } - }, - "vuepress-plugin-container": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/vuepress-plugin-container/-/vuepress-plugin-container-2.1.4.tgz", - "integrity": "sha512-l+EkeL+rC6DJch1wAZUFIkNDaz2TNOg4NQTHa3yMAsYkC+QaSRubGdN6YwOSmfjxVmM9s9D3gwBWw0O7OBhqRg==", - "dev": true, - "requires": { - "markdown-it-container": "^2.0.0" - } - }, - "vuepress-plugin-smooth-scroll": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/vuepress-plugin-smooth-scroll/-/vuepress-plugin-smooth-scroll-0.0.3.tgz", - "integrity": "sha512-qsQkDftLVFLe8BiviIHaLV0Ea38YLZKKonDGsNQy1IE0wllFpFIEldWD8frWZtDFdx6b/O3KDMgVQ0qp5NjJCg==", - "dev": true, - "requires": { - "smoothscroll-polyfill": "^0.4.3" - } - }, - "watchpack": { - "version": "1.7.2", - "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.7.2.tgz", - "integrity": "sha512-ymVbbQP40MFTp+cNMvpyBpBtygHnPzPkHqoIwRRj/0B8KhqQwV8LaKjtbaxF2lK4vl8zN9wCxS46IFCU5K4W0g==", - "dev": true, - "requires": { - "chokidar": "^3.4.0", - "graceful-fs": "^4.1.2", - "neo-async": "^2.5.0", - "watchpack-chokidar2": "^2.0.0" - }, - "dependencies": { - "anymatch": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz", - "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==", - "dev": true, - "optional": true, - "requires": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - } - }, - "binary-extensions": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.0.0.tgz", - "integrity": "sha512-Phlt0plgpIIBOGTT/ehfFnbNlfsDEiqmzE2KRXoX1bLIlir4X/MR+zSyBEkL05ffWgnRSf/DXv+WrUAVr93/ow==", - "dev": true, - "optional": true - }, - "braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "dev": true, - "optional": true, - "requires": { - "fill-range": "^7.0.1" - } - }, - "chokidar": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.4.0.tgz", - "integrity": "sha512-aXAaho2VJtisB/1fg1+3nlLJqGOuewTzQpd/Tz0yTg2R0e4IGtshYvtjowyEumcBv2z+y4+kc75Mz7j5xJskcQ==", - "dev": true, - "optional": true, - "requires": { - "anymatch": "~3.1.1", - "braces": "~3.0.2", - "fsevents": "~2.1.2", - "glob-parent": "~5.1.0", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.4.0" - } - }, - "fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "dev": true, - "optional": true, - "requires": { - "to-regex-range": "^5.0.1" - } - }, - "fsevents": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz", - "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==", - "dev": true, - "optional": true - }, - "glob-parent": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz", - "integrity": "sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==", - "dev": true, - "optional": true, - "requires": { - "is-glob": "^4.0.1" - } - }, - "is-binary-path": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", - "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "dev": true, - "optional": true, - "requires": { - "binary-extensions": "^2.0.0" - } - }, - "is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true, - "optional": true - }, - "readdirp": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.4.0.tgz", - "integrity": "sha512-0xe001vZBnJEK+uKcj8qOhyAKPzIT+gStxWr3LCB0DwcXR5NZJ3IaC+yGnHCYzB/S7ov3m3EEbZI2zeNvX+hGQ==", - "dev": true, - "optional": true, - "requires": { - "picomatch": "^2.2.1" - } - }, - "to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, - "optional": true, - "requires": { - "is-number": "^7.0.0" - } - } - } - }, - "watchpack-chokidar2": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/watchpack-chokidar2/-/watchpack-chokidar2-2.0.0.tgz", - "integrity": "sha512-9TyfOyN/zLUbA288wZ8IsMZ+6cbzvsNyEzSBp6e/zkifi6xxbl8SmQ/CxQq32k8NNqrdVEVUVSEf56L4rQ/ZxA==", - "dev": true, - "optional": true, - "requires": { - "chokidar": "^2.1.8" - } - }, - "wbuf": { - "version": "1.7.3", - "resolved": "https://registry.npmjs.org/wbuf/-/wbuf-1.7.3.tgz", - "integrity": "sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA==", - "dev": true, - "requires": { - "minimalistic-assert": "^1.0.0" - } - }, - "webpack": { - "version": "4.43.0", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-4.43.0.tgz", - "integrity": "sha512-GW1LjnPipFW2Y78OOab8NJlCflB7EFskMih2AHdvjbpKMeDJqEgSx24cXXXiPS65+WSwVyxtDsJH6jGX2czy+g==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.9.0", - "@webassemblyjs/helper-module-context": "1.9.0", - "@webassemblyjs/wasm-edit": "1.9.0", - "@webassemblyjs/wasm-parser": "1.9.0", - "acorn": "^6.4.1", - "ajv": "^6.10.2", - "ajv-keywords": "^3.4.1", - "chrome-trace-event": "^1.0.2", - "enhanced-resolve": "^4.1.0", - "eslint-scope": "^4.0.3", - "json-parse-better-errors": "^1.0.2", - "loader-runner": "^2.4.0", - "loader-utils": "^1.2.3", - "memory-fs": "^0.4.1", - "micromatch": "^3.1.10", - "mkdirp": "^0.5.3", - "neo-async": "^2.6.1", - "node-libs-browser": "^2.2.1", - "schema-utils": "^1.0.0", - "tapable": "^1.1.3", - "terser-webpack-plugin": "^1.4.3", - "watchpack": "^1.6.1", - "webpack-sources": "^1.4.1" - }, - "dependencies": { - "schema-utils": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", - "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", - "dev": true, - "requires": { - "ajv": "^6.1.0", - "ajv-errors": "^1.0.0", - "ajv-keywords": "^3.1.0" - } - } - } - }, - "webpack-chain": { - "version": "6.4.0", - "resolved": "https://registry.npmjs.org/webpack-chain/-/webpack-chain-6.4.0.tgz", - "integrity": "sha512-f97PYqxU+9/u0IUqp/ekAHRhBD1IQwhBv3wlJo2nvyELpr2vNnUqO3XQEk+qneg0uWGP54iciotszpjfnEExFA==", - "dev": true, - "requires": { - "deepmerge": "^1.5.2", - "javascript-stringify": "^2.0.1" - } - }, - "webpack-dev-middleware": { - "version": "3.7.2", - "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-3.7.2.tgz", - "integrity": "sha512-1xC42LxbYoqLNAhV6YzTYacicgMZQTqRd27Sim9wn5hJrX3I5nxYy1SxSd4+gjUFsz1dQFj+yEe6zEVmSkeJjw==", - "dev": true, - "requires": { - "memory-fs": "^0.4.1", - "mime": "^2.4.4", - "mkdirp": "^0.5.1", - "range-parser": "^1.2.1", - "webpack-log": "^2.0.0" - } - }, - "webpack-dev-server": { - "version": "3.11.0", - "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-3.11.0.tgz", - "integrity": "sha512-PUxZ+oSTxogFQgkTtFndEtJIPNmml7ExwufBZ9L2/Xyyd5PnOL5UreWe5ZT7IU25DSdykL9p1MLQzmLh2ljSeg==", - "dev": true, - "requires": { - "ansi-html": "0.0.7", - "bonjour": "^3.5.0", - "chokidar": "^2.1.8", - "compression": "^1.7.4", - "connect-history-api-fallback": "^1.6.0", - "debug": "^4.1.1", - "del": "^4.1.1", - "express": "^4.17.1", - "html-entities": "^1.3.1", - "http-proxy-middleware": "0.19.1", - "import-local": "^2.0.0", - "internal-ip": "^4.3.0", - "ip": "^1.1.5", - "is-absolute-url": "^3.0.3", - "killable": "^1.0.1", - "loglevel": "^1.6.8", - "opn": "^5.5.0", - "p-retry": "^3.0.1", - "portfinder": "^1.0.26", - "schema-utils": "^1.0.0", - "selfsigned": "^1.10.7", - "semver": "^6.3.0", - "serve-index": "^1.9.1", - "sockjs": "0.3.20", - "sockjs-client": "1.4.0", - "spdy": "^4.0.2", - "strip-ansi": "^3.0.1", - "supports-color": "^6.1.0", - "url": "^0.11.0", - "webpack-dev-middleware": "^3.7.2", - "webpack-log": "^2.0.0", - "ws": "^6.2.1", - "yargs": "^13.3.2" - }, - "dependencies": { - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true - }, - "is-absolute-url": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/is-absolute-url/-/is-absolute-url-3.0.3.tgz", - "integrity": "sha512-opmNIX7uFnS96NtPmhWQgQx6/NYFgsUXYMllcfzwWKUMwfo8kku1TvE6hkNcH+Q1ts5cMVrsY7j0bxXQDciu9Q==", - "dev": true - }, - "schema-utils": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", - "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", - "dev": true, - "requires": { - "ajv": "^6.1.0", - "ajv-errors": "^1.0.0", - "ajv-keywords": "^3.1.0" - } - }, - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "supports-color": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", - "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "webpack-log": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/webpack-log/-/webpack-log-2.0.0.tgz", - "integrity": "sha512-cX8G2vR/85UYG59FgkoMamwHUIkSSlV3bBMRsbxVXVUk2j6NleCKjQ/WE9eYg9WY4w25O9w8wKP4rzNZFmUcUg==", - "dev": true, - "requires": { - "ansi-colors": "^3.0.0", - "uuid": "^3.3.2" - } - }, - "webpack-merge": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-4.2.2.tgz", - "integrity": "sha512-TUE1UGoTX2Cd42j3krGYqObZbOD+xF7u28WB7tfUordytSjbWTIjK/8V0amkBfTYN4/pB/GIDlJZZ657BGG19g==", - "dev": true, - "requires": { - "lodash": "^4.17.15" - } - }, - "webpack-sources": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.4.3.tgz", - "integrity": "sha512-lgTS3Xhv1lCOKo7SA5TjKXMjpSM4sBjNV5+q2bqesbSPs5FjGmU6jjtBSkX9b4qW87vDIsCIlUPOEhbZrMdjeQ==", - "dev": true, - "requires": { - "source-list-map": "^2.0.0", - "source-map": "~0.6.1" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - } - } - }, - "webpackbar": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/webpackbar/-/webpackbar-3.2.0.tgz", - "integrity": "sha512-PC4o+1c8gWWileUfwabe0gqptlXUDJd5E0zbpr2xHP1VSOVlZVPBZ8j6NCR8zM5zbKdxPhctHXahgpNK1qFDPw==", - "dev": true, - "requires": { - "ansi-escapes": "^4.1.0", - "chalk": "^2.4.1", - "consola": "^2.6.0", - "figures": "^3.0.0", - "pretty-time": "^1.1.0", - "std-env": "^2.2.1", - "text-table": "^0.2.0", - "wrap-ansi": "^5.1.0" - } - }, - "websocket-driver": { - "version": "0.6.5", - "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.6.5.tgz", - "integrity": "sha1-XLJVbOuF9Dc8bYI4qmkchFThOjY=", - "dev": true, - "requires": { - "websocket-extensions": ">=0.1.1" - } - }, - "websocket-extensions": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.4.tgz", - "integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==", - "dev": true - }, - "when": { - "version": "3.6.4", - "resolved": "https://registry.npmjs.org/when/-/when-3.6.4.tgz", - "integrity": "sha1-RztRfsFZ4rhQBUl6E5g/CVQS404=", - "dev": true - }, - "which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } - }, - "which-module": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", - "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", - "dev": true - }, - "widest-line": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-3.1.0.tgz", - "integrity": "sha512-NsmoXalsWVDMGupxZ5R08ka9flZjjiLvHVAWYOKtiKM8ujtZWr9cRffak+uSE48+Ob8ObalXpwyeUiyDD6QFgg==", - "dev": true, - "requires": { - "string-width": "^4.0.0" - } - }, - "worker-farm": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/worker-farm/-/worker-farm-1.7.0.tgz", - "integrity": "sha512-rvw3QTZc8lAxyVrqcSGVm5yP/IJ2UcB3U0graE3LCFoZ0Yn2x4EoVSqJKdB/T5M+FLcRPjz4TDacRf3OCfNUzw==", - "dev": true, - "requires": { - "errno": "~0.1.7" - } - }, - "wrap-ansi": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", - "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.0", - "string-width": "^3.0.0", - "strip-ansi": "^5.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true - }, - "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - } - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "requires": { - "ansi-regex": "^4.1.0" - } - } - } - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", - "dev": true - }, - "write-file-atomic": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", - "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", - "dev": true, - "requires": { - "imurmurhash": "^0.1.4", - "is-typedarray": "^1.0.0", - "signal-exit": "^3.0.2", - "typedarray-to-buffer": "^3.1.5" - } - }, - "ws": { - "version": "6.2.2", - "resolved": "https://registry.npmjs.org/ws/-/ws-6.2.2.tgz", - "integrity": "sha512-zmhltoSR8u1cnDsD43TX59mzoMZsLKqUweyYBAIvTngR3shc0W6aOZylZmq/7hqyVxPdi+5Ud2QInblgyE72fw==", - "dev": true, - "requires": { - "async-limiter": "~1.0.0" - } - }, - "xdg-basedir": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-4.0.0.tgz", - "integrity": "sha512-PSNhEJDejZYV7h50BohL09Er9VaIefr2LMAf3OEmpCkjOi34eYyQYAXUTjEQtZJTKcF0E2UKTh+osDLsgNim9Q==", - "dev": true - }, - "xtend": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", - "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", - "dev": true - }, - "y18n": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.1.tgz", - "integrity": "sha512-wNcy4NvjMYL8gogWWYAO7ZFWFfHcbdbE57tZO8e4cbpj8tfUcwrwqSl3ad8HxpYWCdXcJUCeKKZS62Av1affwQ==", - "dev": true - }, - "yallist": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", - "dev": true - }, - "yargs": { - "version": "13.3.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", - "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", - "dev": true, - "requires": { - "cliui": "^5.0.0", - "find-up": "^3.0.0", - "get-caller-file": "^2.0.1", - "require-directory": "^2.1.1", - "require-main-filename": "^2.0.0", - "set-blocking": "^2.0.0", - "string-width": "^3.0.0", - "which-module": "^2.0.0", - "y18n": "^4.0.0", - "yargs-parser": "^13.1.2" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true - }, - "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - } - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "requires": { - "ansi-regex": "^4.1.0" - } - } - } - }, - "yargs-parser": { - "version": "13.1.2", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", - "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", - "dev": true, - "requires": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - } - }, - "zepto": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/zepto/-/zepto-1.2.0.tgz", - "integrity": "sha1-4Se9nmb9hGvl6rSME5SIL3wOT5g=", - "dev": true - } - } -} diff --git a/package.json b/package.json deleted file mode 100644 index ca9de118d..000000000 --- a/package.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "license": "AGPL-3.0-or-later", - "scripts": { - "docs:dev": "vuepress dev docs", - "docs:build": "vuepress build docs" - }, - "devDependencies": { - "vuepress": "^1.5.1" - } -} diff --git a/x/compute/internal/keeper/keeper_test.go b/x/compute/internal/keeper/keeper_test.go index c4cb36bb6..67ce6cd38 100644 --- a/x/compute/internal/keeper/keeper_test.go +++ b/x/compute/internal/keeper/keeper_test.go @@ -22,7 +22,7 @@ import ( reg "github.com/enigmampc/SecretNetwork/x/registration" ) -const SupportedFeatures = "staking" +const SupportedFeatures = "staking,stargate" var wasmCtx = wasmUtils.WASMContext{ TestKeyPairPath: "/tmp/id_tx_io.json", @@ -458,69 +458,69 @@ func TestInstantiateWithDeposit(t *testing.T) { } /* -func TestInstantiateWithPermissions(t *testing.T) { - wasmCode, err := ioutil.ReadFile("./testdata/contract.wasm") - require.NoError(t, err) - - var ( - deposit = sdk.NewCoins(sdk.NewInt64Coin("denom", 100000)) - myAddr = bytes.Repeat([]byte{1}, sdk.AddrLen) - otherAddr = bytes.Repeat([]byte{2}, sdk.AddrLen) - anyAddr = bytes.Repeat([]byte{3}, sdk.AddrLen) - ) - - initMsg := InitMsg{ - Verifier: anyAddr, - Beneficiary: anyAddr, - } - initMsgBz, err := json.Marshal(initMsg) - require.NoError(t, err) - - specs := map[string]struct { - srcPermission types.AccessConfig - srcActor sdk.AccAddress - expError *sdkerrors.Error - }{ - "default": { - srcPermission: types.DefaultUploadAccess, - srcActor: anyAddr, - }, - "everybody": { - srcPermission: types.AllowEverybody, - srcActor: anyAddr, - }, - "nobody": { - srcPermission: types.AllowNobody, - srcActor: myAddr, - expError: sdkerrors.ErrUnauthorized, - }, - "onlyAddress with matching address": { - srcPermission: types.OnlyAddress.With(myAddr), - srcActor: myAddr, - }, - "onlyAddress with non matching address": { - srcPermission: types.OnlyAddress.With(otherAddr), - expError: sdkerrors.ErrUnauthorized, - }, - } - for msg, spec := range specs { - t.Run(msg, func(t *testing.T) { - tempDir, err := ioutil.TempDir("", "wasm") - require.NoError(t, err) - defer os.RemoveAll(tempDir) - - ctx, keepers := CreateTestInput(t, false, tempDir, SupportedFeatures, nil, nil) - accKeeper, keeper := keepers.AccountKeeper, keepers.WasmKeeper - fundAccounts(ctx, accKeeper, spec.srcActor, deposit) - - contractID, err := keeper.Create(ctx, myAddr, wasmCode, "https://github.com/CosmWasm/wasmd/blob/master/x/wasm/testdata/escrow.wasm", "") - require.NoError(t, err) - - _,_, err = keeper.Instantiate(ctx, contractID, spec.srcActor, nil, initMsgBz, "demo contract 1", nil) - assert.True(t, spec.expError.Is(err), "got %+v", err) - }) + func TestInstantiateWithPermissions(t *testing.T) { + wasmCode, err := ioutil.ReadFile("./testdata/contract.wasm") + require.NoError(t, err) + + var ( + deposit = sdk.NewCoins(sdk.NewInt64Coin("denom", 100000)) + myAddr = bytes.Repeat([]byte{1}, sdk.AddrLen) + otherAddr = bytes.Repeat([]byte{2}, sdk.AddrLen) + anyAddr = bytes.Repeat([]byte{3}, sdk.AddrLen) + ) + + initMsg := InitMsg{ + Verifier: anyAddr, + Beneficiary: anyAddr, + } + initMsgBz, err := json.Marshal(initMsg) + require.NoError(t, err) + + specs := map[string]struct { + srcPermission types.AccessConfig + srcActor sdk.AccAddress + expError *sdkerrors.Error + }{ + "default": { + srcPermission: types.DefaultUploadAccess, + srcActor: anyAddr, + }, + "everybody": { + srcPermission: types.AllowEverybody, + srcActor: anyAddr, + }, + "nobody": { + srcPermission: types.AllowNobody, + srcActor: myAddr, + expError: sdkerrors.ErrUnauthorized, + }, + "onlyAddress with matching address": { + srcPermission: types.OnlyAddress.With(myAddr), + srcActor: myAddr, + }, + "onlyAddress with non matching address": { + srcPermission: types.OnlyAddress.With(otherAddr), + expError: sdkerrors.ErrUnauthorized, + }, + } + for msg, spec := range specs { + t.Run(msg, func(t *testing.T) { + tempDir, err := ioutil.TempDir("", "wasm") + require.NoError(t, err) + defer os.RemoveAll(tempDir) + + ctx, keepers := CreateTestInput(t, false, tempDir, SupportedFeatures, nil, nil) + accKeeper, keeper := keepers.AccountKeeper, keepers.WasmKeeper + fundAccounts(ctx, accKeeper, spec.srcActor, deposit) + + contractID, err := keeper.Create(ctx, myAddr, wasmCode, "https://github.com/CosmWasm/wasmd/blob/master/x/wasm/testdata/escrow.wasm", "") + require.NoError(t, err) + + _,_, err = keeper.Instantiate(ctx, contractID, spec.srcActor, nil, initMsgBz, "demo contract 1", nil) + assert.True(t, spec.expError.Is(err), "got %+v", err) + }) + } } -} */ func TestInstantiateWithNonExistingCodeID(t *testing.T) { encodingConfig := MakeEncodingConfig() From 84174bf5c2e19fb5bfb37da7d88459e2b264c4a8 Mon Sep 17 00:00:00 2001 From: Assaf Morami Date: Mon, 22 Aug 2022 13:03:57 +0300 Subject: [PATCH 37/93] Add integration tests to the CI --- .github/workflows/ci.yaml | 8 +++++++- integration-tests/Makefile | 5 ++++- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 24523d1fb..90e6d89be 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -294,10 +294,16 @@ jobs: runs-on: ubuntu-20.04 steps: - uses: actions/checkout@v2 - - name: Build docker testnet + - name: Build LocalSecret run: | echo not_a_key | tee {api_key,spid}.txt DOCKER_TAG=v0.0.0 make build-localsecret + - name: Run integration tests + run: | + cd integration-tests + yarn + TAG=v0.0.0 make run-localsecret & + yarn test - name: Run secret.js tests run: | git clone --depth 1 https://github.com/scrtlabs/secret.js diff --git a/integration-tests/Makefile b/integration-tests/Makefile index e4944e836..c774040ab 100644 --- a/integration-tests/Makefile +++ b/integration-tests/Makefile @@ -1,2 +1,5 @@ all: - $(MAKE) -C contract-v1 \ No newline at end of file + $(MAKE) -C contract-v1 + +run-localsecret: + docker run --rm -it -p 9091:9091 --name localsecret ghcr.io/scrtlabs/localsecret:"$(TAG)" \ No newline at end of file From 8755a43f672be302d1923e46f5556c6ef8c19340 Mon Sep 17 00:00:00 2001 From: Assaf Morami Date: Mon, 22 Aug 2022 15:19:48 +0300 Subject: [PATCH 38/93] Make StargateMsg work (with tests) By compiling enclave's cosmwasm-std types with stargate, wasm3 & staking features --- app/app.go | 2 +- .../src/contract_validation.rs | 2 +- .../shared/cosmwasm-v1-types/src/ibc.rs | 319 ++++++++++++++++++ .../shared/cosmwasm-v1-types/src/lib.rs | 1 + .../src/results/cosmos_msg.rs | 108 +++--- .../cosmwasm-v1-types/src/results/mod.rs | 16 +- go-cosmwasm/cmd/main.go | 2 +- integration-tests/contract-v1/Cargo.toml | 4 +- integration-tests/contract-v1/src/contract.rs | 149 ++++++-- integration-tests/contract-v1/src/msg.rs | 62 +++- integration-tests/test.ts | 2 +- x/compute/internal/keeper/keeper_test.go | 2 +- 12 files changed, 555 insertions(+), 114 deletions(-) create mode 100644 cosmwasm/enclaves/shared/cosmwasm-v1-types/src/ibc.rs diff --git a/app/app.go b/app/app.go index 65eefd6f6..df08d75bd 100644 --- a/app/app.go +++ b/app/app.go @@ -418,7 +418,7 @@ func NewSecretNetworkApp( // The last arguments can contain custom message handlers, and custom query handlers, // if we want to allow any custom callbacks - supportedFeatures := "staking,stargate" + supportedFeatures := "staking,stargate,ibc3" app.computeKeeper = compute.NewKeeper( appCodec, diff --git a/cosmwasm/enclaves/shared/contract-engine/src/contract_validation.rs b/cosmwasm/enclaves/shared/contract-engine/src/contract_validation.rs index 4faf8d350..31671051c 100644 --- a/cosmwasm/enclaves/shared/contract-engine/src/contract_validation.rs +++ b/cosmwasm/enclaves/shared/contract-engine/src/contract_validation.rs @@ -63,7 +63,7 @@ pub fn extract_contract_key(env: &Env) -> Result<[u8; CONTRACT_KEY_LENGTH], Encl let contract_key = base64::decode(env.contract_key.as_ref().unwrap().as_bytes()).map_err(|err| { warn!( - "got an error while trying to deserialize output bytes into json {:?}: {}", + "got an error while trying to decode contract key {:?}: {}", env, err ); EnclaveError::FailedContractAuthentication diff --git a/cosmwasm/enclaves/shared/cosmwasm-v1-types/src/ibc.rs b/cosmwasm/enclaves/shared/cosmwasm-v1-types/src/ibc.rs new file mode 100644 index 000000000..cbb02ec70 --- /dev/null +++ b/cosmwasm/enclaves/shared/cosmwasm-v1-types/src/ibc.rs @@ -0,0 +1,319 @@ +use crate::addresses::Addr; +use crate::results::{Event, SubMsg}; +use crate::timestamp::Timestamp; +use enclave_cosmwasm_v010_types::{encoding::Binary, types::Empty, types::LogAttribute}; +use serde::{Deserialize, Serialize}; +use std::fmt; + +/// The message that is passed into `ibc_channel_open` +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] +#[serde(rename_all = "snake_case")] +pub enum IbcChannelOpenMsg { + /// The ChanOpenInit step from https://github.com/cosmos/ibc/tree/master/spec/core/ics-004-channel-and-packet-semantics#channel-lifecycle-management + OpenInit { channel: IbcChannel }, + /// The ChanOpenTry step from https://github.com/cosmos/ibc/tree/master/spec/core/ics-004-channel-and-packet-semantics#channel-lifecycle-management + OpenTry { + channel: IbcChannel, + counterparty_version: String, + }, +} + +/// IbcChannel defines all information on a channel. +/// This is generally used in the hand-shake process, but can be queried directly. +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] +pub struct IbcChannel { + pub endpoint: IbcEndpoint, + pub counterparty_endpoint: IbcEndpoint, + pub order: IbcOrder, + /// Note: in ibcv3 this may be "", in the IbcOpenChannel handshake messages + pub version: String, + /// The connection upon which this channel was created. If this is a multi-hop + /// channel, we only expose the first hop. + pub connection_id: String, +} + +/// This is the return value for the majority of the ibc handlers. +/// That are able to dispatch messages / events on their own, +/// but have no meaningful return value to the calling code. +/// +/// Callbacks that have return values (like receive_packet) +/// or that cannot redispatch messages (like the handshake callbacks) +/// will use other Response types +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] +#[non_exhaustive] +pub struct IbcBasicResponse +where + T: Clone + fmt::Debug + PartialEq, +{ + /// Optional list of messages to pass. These will be executed in order. + /// If the ReplyOn member is set, they will invoke this contract's `reply` entry point + /// after execution. Otherwise, they act like "fire and forget". + /// Use `SubMsg::new` to create messages with the older "fire and forget" semantics. + pub messages: Vec>, + /// The attributes that will be emitted as part of a `wasm` event. + /// + /// More info about events (and their attributes) can be found in [*Cosmos SDK* docs]. + /// + /// [*Cosmos SDK* docs]: https://docs.cosmos.network/v0.42/core/events.html + pub attributes: Vec, + /// Extra, custom events separate from the main `wasm` one. These will have + /// `wasm-` prepended to the type. + /// + /// More info about events can be found in [*Cosmos SDK* docs]. + /// + /// [*Cosmos SDK* docs]: https://docs.cosmos.network/v0.42/core/events.html + pub events: Vec, +} + +// This defines the return value on packet response processing. +// This "success" case should be returned even in application-level errors, +// Where the acknowledgement bytes contain an encoded error message to be returned to +// the calling chain. (Returning ContractResult::Err will abort processing of this packet +// and not inform the calling chain). +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] +#[non_exhaustive] +pub struct IbcReceiveResponse +where + T: Clone + fmt::Debug + PartialEq, +{ + /// The bytes we return to the contract that sent the packet. + /// This may represent a success or error of exection + pub acknowledgement: Binary, + /// Optional list of messages to pass. These will be executed in order. + /// If the ReplyOn member is set, they will invoke this contract's `reply` entry point + /// after execution. Otherwise, they act like "fire and forget". + /// Use `call` or `msg.into()` to create messages with the older "fire and forget" semantics. + pub messages: Vec>, + /// The attributes that will be emitted as part of a "wasm" event. + /// + /// More info about events (and their attributes) can be found in [*Cosmos SDK* docs]. + /// + /// [*Cosmos SDK* docs]: https://docs.cosmos.network/v0.42/core/events.html + pub attributes: Vec, + /// Extra, custom events separate from the main `wasm` one. These will have + /// `wasm-` prepended to the type. + /// + /// More info about events can be found in [*Cosmos SDK* docs]. + /// + /// [*Cosmos SDK* docs]: https://docs.cosmos.network/v0.42/core/events.html + pub events: Vec, +} + +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] +pub struct IbcEndpoint { + pub port_id: String, + pub channel_id: String, +} + +impl IbcEndpoint { + pub fn default() -> Self { + IbcEndpoint { + port_id: String::default(), + channel_id: String::default(), + } + } +} + +/// IbcOrder defines if a channel is ORDERED or UNORDERED +/// Values come from https://github.com/cosmos/cosmos-sdk/blob/v0.40.0/proto/ibc/core/channel/v1/channel.proto#L69-L80 +/// Naming comes from the protobuf files and go translations. +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] +pub enum IbcOrder { + #[serde(rename = "ORDER_UNORDERED")] + Unordered, + #[serde(rename = "ORDER_ORDERED")] + Ordered, +} + +/// The message that is passed into `ibc_channel_connect` +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] +#[serde(rename_all = "snake_case")] +pub enum IbcChannelConnectMsg { + /// The ChanOpenAck step from https://github.com/cosmos/ibc/tree/master/spec/core/ics-004-channel-and-packet-semantics#channel-lifecycle-management + OpenAck { + channel: IbcChannel, + counterparty_version: String, + }, + /// The ChanOpenConfirm step from https://github.com/cosmos/ibc/tree/master/spec/core/ics-004-channel-and-packet-semantics#channel-lifecycle-management + OpenConfirm { channel: IbcChannel }, +} + +/// The message that is passed into `ibc_channel_close` +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] +#[serde(rename_all = "snake_case")] +pub enum IbcChannelCloseMsg { + /// The ChanCloseInit step from https://github.com/cosmos/ibc/tree/master/spec/core/ics-004-channel-and-packet-semantics#channel-lifecycle-management + CloseInit { channel: IbcChannel }, + /// The ChanCloseConfirm step from https://github.com/cosmos/ibc/tree/master/spec/core/ics-004-channel-and-packet-semantics#channel-lifecycle-management + CloseConfirm { channel: IbcChannel }, // pub channel: IbcChannel, +} + +/// The message that is passed into `ibc_packet_receive` +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] +pub struct IbcPacketReceiveMsg { + pub packet: IbcPacket, + pub relayer: Addr, +} + +pub trait IbcPacketTrait { + type Data; + fn get_packet(&self) -> &Self::Data; + fn set_packet(&mut self, data: Self::Data); + fn get_ack(&self) -> Option; + fn set_ack(&mut self, data: Self::Data); +} + +macro_rules! impl_IbcPacketTrait { + ($($t:ty),+) => { + $(impl IbcPacketTrait for $t { + type Data = Binary; + fn get_packet(&self) -> &Self::Data { + &self.packet.data + } + fn set_packet(&mut self, data: Self::Data) { + self.packet.data = data; + } + fn get_ack(&self) -> Option { + return None; + } + fn set_ack(&mut self, _: Self::Data) { + // Nothing to do here + } + })* + } +} + +impl_IbcPacketTrait! {IbcPacketReceiveMsg, IbcPacketTimeoutMsg} + +impl IbcPacketTrait for IbcPacketAckMsg { + type Data = Binary; + fn get_packet(&self) -> &Self::Data { + &self.original_packet.data + } + fn set_packet(&mut self, data: Self::Data) { + self.original_packet.data = data; + } + fn get_ack(&self) -> Option { + return Some(self.acknowledgement.data.clone()); + } + fn set_ack(&mut self, data: Self::Data) { + self.acknowledgement.data = data; + } +} + +impl IbcPacketReceiveMsg { + pub fn default() -> Self { + Self { + packet: IbcPacket::default(), + relayer: Addr::unchecked("".to_string()), + } + } +} + +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] +pub struct IbcPacket { + /// The raw data sent from the other side in the packet + pub data: Binary, + /// identifies the channel and port on the sending chain. + pub src: IbcEndpoint, + /// identifies the channel and port on the receiving chain. + pub dest: IbcEndpoint, + /// The sequence number of the packet on the given channel + pub sequence: u64, + pub timeout: IbcTimeout, +} + +impl IbcPacket { + pub fn default() -> Self { + Self { + data: vec![].as_slice().into(), + src: IbcEndpoint::default(), + dest: IbcEndpoint::default(), + sequence: 0, + timeout: IbcTimeout::default(), + } + } +} + +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] +#[non_exhaustive] +pub struct IbcAcknowledgement { + pub data: Binary, +} + +impl IbcAcknowledgement { + pub fn default() -> Self { + Self { + data: vec![].as_slice().into(), + } + } +} + +/// In IBC each package must set at least one type of timeout: +/// the timestamp or the block height. Using this rather complex enum instead of +/// two timeout fields we ensure that at least one timeout is set. +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] +#[serde(rename_all = "snake_case")] +pub struct IbcTimeout { + // use private fields to enforce the use of constructors, which ensure that at least one is set + block: Option, + timestamp: Option, +} + +impl IbcTimeout { + pub fn default() -> Self { + Self { + block: None, + timestamp: None, + } + } +} + +/// IBCTimeoutHeight Height is a monotonically increasing data type +/// that can be compared against another Height for the purposes of updating and +/// freezing clients. +/// Ordering is (revision_number, timeout_height) +#[derive(Serialize, Deserialize, Copy, Clone, Debug, PartialEq, Eq)] +pub struct IbcTimeoutBlock { + /// the version that the client is currently on + /// (eg. after reseting the chain this could increment 1 as height drops to 0) + pub revision: u64, + /// block height after which the packet times out. + /// the height within the given revision + pub height: u64, +} + +/// The message that is passed into `ibc_packet_ack` +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] +pub struct IbcPacketAckMsg { + pub acknowledgement: IbcAcknowledgement, + pub original_packet: IbcPacket, + pub relayer: Addr, +} + +impl IbcPacketAckMsg { + pub fn default() -> Self { + Self { + acknowledgement: IbcAcknowledgement::default(), + original_packet: IbcPacket::default(), + relayer: Addr::unchecked("".to_string()), + } + } +} + +/// The message that is passed into `ibc_packet_timeout` +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] +#[non_exhaustive] +pub struct IbcPacketTimeoutMsg { + pub packet: IbcPacket, + pub relayer: Addr, +} + +impl IbcPacketTimeoutMsg { + pub fn default() -> Self { + Self { + packet: IbcPacket::default(), + relayer: Addr::unchecked("".to_string()), + } + } +} diff --git a/cosmwasm/enclaves/shared/cosmwasm-v1-types/src/lib.rs b/cosmwasm/enclaves/shared/cosmwasm-v1-types/src/lib.rs index 310434644..62f52dc66 100644 --- a/cosmwasm/enclaves/shared/cosmwasm-v1-types/src/lib.rs +++ b/cosmwasm/enclaves/shared/cosmwasm-v1-types/src/lib.rs @@ -2,6 +2,7 @@ pub mod addresses; pub mod coins; pub mod errors; +pub mod ibc; pub mod math; pub mod results; pub mod timestamp; diff --git a/cosmwasm/enclaves/shared/cosmwasm-v1-types/src/results/cosmos_msg.rs b/cosmwasm/enclaves/shared/cosmwasm-v1-types/src/results/cosmos_msg.rs index f141bff5f..cf6185e5a 100644 --- a/cosmwasm/enclaves/shared/cosmwasm-v1-types/src/results/cosmos_msg.rs +++ b/cosmwasm/enclaves/shared/cosmwasm-v1-types/src/results/cosmos_msg.rs @@ -1,9 +1,8 @@ use serde::{Deserialize, Serialize}; use std::fmt; -use crate::coins::Coin; -#[cfg(feature = "stargate")] -use crate::ibc::IbcMsg; +use crate::{coins::Coin, ibc::IbcTimeout}; + use enclave_cosmwasm_v010_types::encoding::Binary; use super::Empty; @@ -19,21 +18,16 @@ where // by default we use RawMsg, but a contract can override that // to call into more app-specific code (whatever they define) Custom(T), - #[cfg(feature = "staking")] Staking(StakingMsg), - #[cfg(feature = "staking")] Distribution(DistributionMsg), /// A Stargate message encoded the same way as a protobuf [Any](https://github.com/protocolbuffers/protobuf/blob/master/src/google/protobuf/any.proto). /// This is the same structure as messages in `TxBody` from [ADR-020](https://github.com/cosmos/cosmos-sdk/blob/master/docs/architecture/adr-020-protobuf-transaction-encoding.md) - #[cfg(feature = "stargate")] Stargate { type_url: String, value: Binary, }, - #[cfg(feature = "stargate")] Ibc(IbcMsg), Wasm(WasmMsg), - #[cfg(feature = "stargate")] Gov(GovMsg), } @@ -57,12 +51,47 @@ pub enum BankMsg { Burn { amount: Vec }, } +/// These are messages in the IBC lifecycle. Only usable by IBC-enabled contracts +/// (contracts that directly speak the IBC protocol via 6 entry points) +#[non_exhaustive] +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] +#[serde(rename_all = "snake_case")] +pub enum IbcMsg { + /// Sends bank tokens owned by the contract to the given address on another chain. + /// The channel must already be established between the ibctransfer module on this chain + /// and a matching module on the remote chain. + /// We cannot select the port_id, this is whatever the local chain has bound the ibctransfer + /// module to. + Transfer { + /// exisiting channel to send the tokens over + channel_id: String, + /// address on the remote chain to receive these tokens + to_address: String, + /// packet data only supports one coin + /// https://github.com/cosmos/cosmos-sdk/blob/v0.40.0/proto/ibc/applications/transfer/v1/transfer.proto#L11-L20 + amount: Coin, + /// when packet times out, measured on remote chain + timeout: IbcTimeout, + }, + /// Sends an IBC packet with given data over the existing channel. + /// Data should be encoded in a format defined by the channel version, + /// and the module on the other side should know how to parse this. + SendPacket { + channel_id: String, + data: Binary, + /// when packet times out, measured on remote chain + timeout: IbcTimeout, + }, + /// This will close an existing channel that is owned by this contract. + /// Port is auto-assigned to the contract's IBC port + CloseChannel { channel_id: String }, +} + pub const REPLY_ENCRYPTION_MAGIC_BYTES: &[u8] = b"REPLY01"; /// The message types of the staking module. /// /// See https://github.com/cosmos/cosmos-sdk/blob/v0.40.0/proto/cosmos/staking/v1beta1/tx.proto -#[cfg(feature = "staking")] #[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] #[serde(rename_all = "snake_case")] pub enum StakingMsg { @@ -84,7 +113,6 @@ pub enum StakingMsg { /// The message types of the distribution module. /// /// See https://github.com/cosmos/cosmos-sdk/blob/v0.42.4/proto/cosmos/distribution/v1beta1/tx.proto -#[cfg(feature = "staking")] #[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] #[serde(rename_all = "snake_case")] pub enum DistributionMsg { @@ -147,7 +175,6 @@ pub enum WasmMsg { }, } -#[cfg(feature = "stargate")] #[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] #[serde(rename_all = "snake_case")] pub enum GovMsg { @@ -155,7 +182,6 @@ pub enum GovMsg { Vote { proposal_id: u64, vote: VoteOption }, } -#[cfg(feature = "stargate")] #[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] #[serde(rename_all = "snake_case")] pub enum VoteOption { @@ -164,61 +190,3 @@ pub enum VoteOption { Abstain, NoWithVeto, } - -impl From for CosmosMsg -where - T: Clone + fmt::Debug + PartialEq, -{ - fn from(msg: BankMsg) -> Self { - CosmosMsg::Bank(msg) - } -} - -#[cfg(feature = "staking")] -impl From for CosmosMsg -where - T: Clone + fmt::Debug + PartialEq, -{ - fn from(msg: StakingMsg) -> Self { - CosmosMsg::Staking(msg) - } -} - -#[cfg(feature = "staking")] -impl From for CosmosMsg -where - T: Clone + fmt::Debug + PartialEq, -{ - fn from(msg: DistributionMsg) -> Self { - CosmosMsg::Distribution(msg) - } -} - -impl From for CosmosMsg -where - T: Clone + fmt::Debug + PartialEq, -{ - fn from(msg: WasmMsg) -> Self { - CosmosMsg::Wasm(msg) - } -} - -#[cfg(feature = "stargate")] -impl From for CosmosMsg -where - T: Clone + fmt::Debug + PartialEq, -{ - fn from(msg: IbcMsg) -> Self { - CosmosMsg::Ibc(msg) - } -} - -#[cfg(feature = "stargate")] -impl From for CosmosMsg -where - T: Clone + fmt::Debug + PartialEq, -{ - fn from(msg: GovMsg) -> Self { - CosmosMsg::Gov(msg) - } -} diff --git a/cosmwasm/enclaves/shared/cosmwasm-v1-types/src/results/mod.rs b/cosmwasm/enclaves/shared/cosmwasm-v1-types/src/results/mod.rs index 21b5d7b74..2476e5bf6 100644 --- a/cosmwasm/enclaves/shared/cosmwasm-v1-types/src/results/mod.rs +++ b/cosmwasm/enclaves/shared/cosmwasm-v1-types/src/results/mod.rs @@ -7,13 +7,9 @@ mod events; mod response; mod submessages; -pub use contract_result::ContractResult; -pub use cosmos_msg::{BankMsg, CosmosMsg, WasmMsg, REPLY_ENCRYPTION_MAGIC_BYTES}; -#[cfg(feature = "staking")] -pub use cosmos_msg::{DistributionMsg, StakingMsg}; -#[cfg(feature = "stargate")] -pub use cosmos_msg::{GovMsg, VoteOption}; -pub use empty::Empty; -pub use events::Event; -pub use response::Response; -pub use submessages::{DecryptedReply, Reply, SubMsgResponse, SubMsgResult, ReplyOn, SubMsg, SubMsgExecutionResponse}; +pub use contract_result::*; +pub use cosmos_msg::*; +pub use empty::*; +pub use events::*; +pub use response::*; +pub use submessages::*; diff --git a/go-cosmwasm/cmd/main.go b/go-cosmwasm/cmd/main.go index d1f06fa75..115e7c2be 100644 --- a/go-cosmwasm/cmd/main.go +++ b/go-cosmwasm/cmd/main.go @@ -19,7 +19,7 @@ func main() { fmt.Println("Loaded!") os.MkdirAll("tmp", 0o755) - wasmer, err := wasm.NewWasmer("tmp", "staking,stargate", 0, 15) + wasmer, err := wasm.NewWasmer("tmp", "staking,stargate,ibc3", 0, 15) if err != nil { panic(err) } diff --git a/integration-tests/contract-v1/Cargo.toml b/integration-tests/contract-v1/Cargo.toml index ecec318c2..c25108483 100644 --- a/integration-tests/contract-v1/Cargo.toml +++ b/integration-tests/contract-v1/Cargo.toml @@ -28,7 +28,9 @@ with_floats = [] [dependencies] cosmwasm-std = { git = "https://github.com/scrtlabs/cosmwasm", branch = "secret", features = [ - "stargate" + "stargate", + "staking", + "ibc3" ] } cosmwasm-storage = { git = "https://github.com/scrtlabs/cosmwasm", branch = "secret" } schemars = "0.8.1" diff --git a/integration-tests/contract-v1/src/contract.rs b/integration-tests/contract-v1/src/contract.rs index 21e622b82..5657eb608 100644 --- a/integration-tests/contract-v1/src/contract.rs +++ b/integration-tests/contract-v1/src/contract.rs @@ -1,37 +1,146 @@ use cosmwasm_std::{ - entry_point, BankMsg, Binary, CosmosMsg, Deps, DepsMut, Env, MessageInfo, Response, StdResult, + entry_point, BankMsg, Binary, CosmosMsg, Deps, DepsMut, DistributionMsg, Env, GovMsg, IbcMsg, + MessageInfo, Response, StakingMsg, StdResult, WasmMsg, }; -use crate::msg::{ExecuteMsg, InstantiateMsg, QueryMsg}; +use crate::msg::{Msg, QueryMsg}; #[entry_point] -pub fn instantiate( - _deps: DepsMut, - _env: Env, - _info: MessageInfo, - _msg: InstantiateMsg, -) -> StdResult { - Ok(Response::new()) +pub fn instantiate(deps: DepsMut, env: Env, info: MessageInfo, msg: Msg) -> StdResult { + return handle_msg(deps, env, info, msg); } #[entry_point] -pub fn execute( - _deps: DepsMut, - _env: Env, - _info: MessageInfo, - msg: ExecuteMsg, -) -> StdResult { +pub fn execute(deps: DepsMut, env: Env, info: MessageInfo, msg: Msg) -> StdResult { + return handle_msg(deps, env, info, msg); +} + +fn handle_msg(_deps: DepsMut, _env: Env, _info: MessageInfo, msg: Msg) -> StdResult { match msg { - ExecuteMsg::BankMsg { to_address, amount } => { - Ok(Response::new().add_message(CosmosMsg::Bank(BankMsg::Send { to_address, amount }))) + Msg::Nop {} => { + return Ok(Response::new()); + } + Msg::BankMsgSend { to_address, amount } => { + return Ok( + Response::new().add_message(CosmosMsg::Bank(BankMsg::Send { to_address, amount })) + ); + } + Msg::StargateMsg { type_url, value } => { + return Ok(Response::new().add_message(CosmosMsg::Stargate { type_url, value })); + } + Msg::StakingMsgDelegate { validator, amount } => { + return Ok( + Response::new().add_message(CosmosMsg::Staking(StakingMsg::Delegate { + validator, + amount, + })), + ); + } + Msg::StakingMsgUndelegate { validator, amount } => { + return Ok( + Response::new().add_message(CosmosMsg::Staking(StakingMsg::Undelegate { + validator, + amount, + })), + ); + } + Msg::StakingMsgRedelegate { + src_validator, + dst_validator, + amount, + } => { + return Ok( + Response::new().add_message(CosmosMsg::Staking(StakingMsg::Redelegate { + src_validator, + dst_validator, + amount, + })), + ); + } + Msg::GovVote { proposal_id, vote } => { + return Ok( + Response::new().add_message(CosmosMsg::Gov(GovMsg::Vote { proposal_id, vote })) + ); + } + Msg::DistributionMsgSetWithdrawAddress { address } => { + return Ok(Response::new().add_message(CosmosMsg::Distribution( + DistributionMsg::SetWithdrawAddress { address }, + ))); + } + Msg::DistributionMsgWithdrawDelegatorReward { validator } => { + return Ok(Response::new().add_message(CosmosMsg::Distribution( + DistributionMsg::WithdrawDelegatorReward { validator }, + ))); + } + Msg::IbcMsgTransfer { + channel_id, + to_address, + amount, + timeout, + } => { + return Ok( + Response::new().add_message(CosmosMsg::Ibc(IbcMsg::Transfer { + channel_id, + to_address, + amount, + timeout, + })), + ); + } + Msg::IbcMsgSendPacket { + channel_id, + data, + timeout, + } => { + return Ok( + Response::new().add_message(CosmosMsg::Ibc(IbcMsg::SendPacket { + channel_id, + data, + timeout, + })), + ); + } + Msg::IbcMsgCloseChannel { channel_id } => { + return Ok( + Response::new().add_message(CosmosMsg::Ibc(IbcMsg::CloseChannel { channel_id })) + ); + } + Msg::WasmMsgInstantiate { + code_id, + code_hash, + msg, + funds, + label, + } => { + return Ok( + Response::new().add_message(CosmosMsg::Wasm(WasmMsg::Instantiate { + code_id, + code_hash, + msg, + funds, + label, + })), + ); } - ExecuteMsg::StargateMsg { type_url, value } => { - Ok(Response::new().add_message(CosmosMsg::Stargate { type_url, value })) + Msg::WasmMsgExecute { + contract_addr, + code_hash, + msg, + funds, + } => { + return Ok( + Response::new().add_message(CosmosMsg::Wasm(WasmMsg::Execute { + contract_addr, + code_hash, + msg, + funds, + })), + ); } } } #[entry_point] pub fn query(_deps: Deps, _env: Env, _msg: QueryMsg) -> StdResult { - Ok(Binary(vec![])) + return Ok(Binary(vec![])); } diff --git a/integration-tests/contract-v1/src/msg.rs b/integration-tests/contract-v1/src/msg.rs index f477637eb..580b0596b 100644 --- a/integration-tests/contract-v1/src/msg.rs +++ b/integration-tests/contract-v1/src/msg.rs @@ -1,17 +1,12 @@ -use cosmwasm_std::{Binary, Coin}; +use cosmwasm_std::{Binary, Coin, IbcTimeout, VoteOption}; use schemars::JsonSchema; use serde::{Deserialize, Serialize}; #[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] #[serde(rename_all = "snake_case")] -pub enum InstantiateMsg { +pub enum Msg { Nop {}, -} - -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] -#[serde(rename_all = "snake_case")] -pub enum ExecuteMsg { - BankMsg { + BankMsgSend { to_address: String, amount: Vec, }, @@ -19,6 +14,57 @@ pub enum ExecuteMsg { type_url: String, value: Binary, }, + StakingMsgDelegate { + validator: String, + amount: Coin, + }, + StakingMsgUndelegate { + validator: String, + amount: Coin, + }, + StakingMsgRedelegate { + src_validator: String, + dst_validator: String, + amount: Coin, + }, + GovVote { + proposal_id: u64, + vote: VoteOption, + }, + DistributionMsgSetWithdrawAddress { + address: String, + }, + DistributionMsgWithdrawDelegatorReward { + validator: String, + }, + + IbcMsgTransfer { + channel_id: String, + to_address: String, + amount: Coin, + timeout: IbcTimeout, + }, + IbcMsgSendPacket { + channel_id: String, + data: Binary, + timeout: IbcTimeout, + }, + IbcMsgCloseChannel { + channel_id: String, + }, + WasmMsgInstantiate { + code_id: u64, + code_hash: String, + msg: Binary, + funds: Vec, + label: String, + }, + WasmMsgExecute { + contract_addr: String, + code_hash: String, + msg: Binary, + funds: Vec, + }, } #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] diff --git a/integration-tests/test.ts b/integration-tests/test.ts index 1b5d0f781..8b95de37d 100644 --- a/integration-tests/test.ts +++ b/integration-tests/test.ts @@ -125,7 +125,7 @@ describe("BankMsg::Send", () => { contractAddress: v1Address, codeHash: v1CodeHash, msg: { - bank_msg: { + bank_msg_send: { to_address: accounts.b.address, amount: [{ amount: "1", denom: "uscrt" }], }, diff --git a/x/compute/internal/keeper/keeper_test.go b/x/compute/internal/keeper/keeper_test.go index 67ce6cd38..79b6e4a48 100644 --- a/x/compute/internal/keeper/keeper_test.go +++ b/x/compute/internal/keeper/keeper_test.go @@ -22,7 +22,7 @@ import ( reg "github.com/enigmampc/SecretNetwork/x/registration" ) -const SupportedFeatures = "staking,stargate" +const SupportedFeatures = "staking,stargate,ibc3" var wasmCtx = wasmUtils.WASMContext{ TestKeyPairPath: "/tmp/id_tx_io.json", From 40c02fefe416cfd38b1a7e52b7c233892fbee657 Mon Sep 17 00:00:00 2001 From: Assaf Morami Date: Mon, 22 Aug 2022 20:12:34 +0300 Subject: [PATCH 39/93] Implement all missing v1 QueryPlugins --- .../shared/cosmwasm-v010-types/src/query.rs | 42 ++++ go-cosmwasm/types/queries.go | 181 +++++++++++++++++- integration-tests/contract-v1/src/contract.rs | 14 +- integration-tests/contract-v1/src/msg.rs | 8 +- integration-tests/test.ts | 27 ++- x/compute/internal/keeper/keeper.go | 55 +----- x/compute/internal/keeper/query_plugins.go | 118 +++++++++++- x/compute/internal/types/expected_keepers.go | 19 +- 8 files changed, 398 insertions(+), 66 deletions(-) diff --git a/cosmwasm/enclaves/shared/cosmwasm-v010-types/src/query.rs b/cosmwasm/enclaves/shared/cosmwasm-v010-types/src/query.rs index 5154ddb15..d27053ffc 100644 --- a/cosmwasm/enclaves/shared/cosmwasm-v010-types/src/query.rs +++ b/cosmwasm/enclaves/shared/cosmwasm-v010-types/src/query.rs @@ -17,6 +17,33 @@ pub enum QueryRequest { Dist(DistQuery), Mint(MintQuery), Gov(GovQuery), + Ibc(IbcQuery), +} + +/// These are queries to the various IBC modules to see the state of the contract's +/// IBC connection. These will return errors if the contract is not "ibc enabled" +#[non_exhaustive] +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] +#[serde(rename_all = "snake_case")] +pub enum IbcQuery { + /// Gets the Port ID the current contract is bound to. + /// + /// Returns a `PortIdResponse`. + PortId {}, + /// Lists all channels that are bound to a given port. + /// If `port_id` is omitted, this list all channels bound to the contract's port. + /// + /// Returns a `ListChannelsResponse`. + ListChannels { port_id: Option }, + /// Lists all information for a (portID, channelID) pair. + /// If port_id is omitted, it will default to the contract's own channel. + /// (To save a PortId{} call) + /// + /// Returns a `ChannelResponse`. + Channel { + channel_id: String, + port_id: Option, + }, } #[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] @@ -97,6 +124,8 @@ pub enum WasmQuery { /// Key is the raw key used in the contracts Storage key: Binary, }, + /// returns a ContractInfoResponse with metadata on the contract from the runtime + ContractInfo { contract_addr: String }, } impl From for QueryRequest { @@ -153,6 +182,19 @@ pub enum StakingQuery { Validators {}, /// Returns all the unbonding delegations by the delegator UnbondingDelegations { delegator: HumanAddr }, + + /// Returns all validators in the currently active validator set. + /// + /// The query response type is `AllValidatorsResponse`. + AllValidators {}, + /// Returns the validator at the given address. Returns None if the validator is + /// not part of the currently active validator set. + /// + /// The query response type is `ValidatorResponse`. + Validator { + /// The validator's address (e.g. (e.g. cosmosvaloper1...)) + address: String, + }, } /// Delegation is basic (cheap to query) data about a delegation diff --git a/go-cosmwasm/types/queries.go b/go-cosmwasm/types/queries.go index d3909c6d5..34a9cd56c 100644 --- a/go-cosmwasm/types/queries.go +++ b/go-cosmwasm/types/queries.go @@ -101,8 +101,27 @@ type StakingQuery struct { Validators *ValidatorsQuery `json:"validators,omitempty"` AllDelegations *AllDelegationsQuery `json:"all_delegations,omitempty"` Delegation *DelegationQuery `json:"delegation,omitempty"` - UnBondingDelegations *UnbondingDeletionsQuery `json:"unbonding_delegations, omitempty"` + UnBondingDelegations *UnbondingDeletionsQuery `json:"unbonding_delegations,omitempty"` BondedDenom *struct{} `json:"bonded_denom,omitempty"` + AllValidators *AllValidatorsQuery `json:"all_validators,omitempty"` + Validator *ValidatorQuery `json:"validator,omitempty"` +} + +type AllValidatorsQuery struct{} + +// AllValidatorsResponse is the expected response to AllValidatorsQuery +type AllValidatorsResponse struct { + Validators Validators `json:"validators"` +} + +type ValidatorQuery struct { + /// Address is the validator's address (e.g. cosmosvaloper1...) + Address string `json:"address"` +} + +// ValidatorResponse is the expected response to ValidatorQuery +type ValidatorResponse struct { + Validator *Validator `json:"validator"` // serializes to `null` when unset which matches Rust's Option::None serialization } type UnbondingDeletionsQuery struct { @@ -219,22 +238,40 @@ type BondedDenomResponse struct { } type WasmQuery struct { - Smart *SmartQuery `json:"smart,omitempty"` - Raw *RawQuery `json:"raw,omitempty"` + Smart *SmartQuery `json:"smart,omitempty"` + Raw *RawQuery `json:"raw,omitempty"` + ContractInfo *ContractInfoQuery `json:"contract_info,omitempty"` } // SmartQuery respone is raw bytes ([]byte) type SmartQuery struct { + // Bech32 encoded sdk.AccAddress of the contract ContractAddr string `json:"contract_addr"` Msg []byte `json:"msg"` } // RawQuery response is raw bytes ([]byte) type RawQuery struct { + // Bech32 encoded sdk.AccAddress of the contract ContractAddr string `json:"contract_addr"` Key []byte `json:"key"` } +type ContractInfoQuery struct { + // Bech32 encoded sdk.AccAddress of the contract + ContractAddr string `json:"contract_addr"` +} + +type ContractInfoResponse struct { + CodeID uint64 `json:"code_id"` + Creator string `json:"creator"` + // Set to the admin who can migrate contract, if any + Admin string `json:"admin,omitempty"` + Pinned bool `json:"pinned"` + // Set if the contract is IBC enabled + IBCPort string `json:"ibc_port,omitempty"` +} + type DistQuery struct { Rewards *RewardsQuery `json:"rewards,omitempty"` } @@ -255,6 +292,144 @@ type StargateQuery struct { Data []byte `json:"data"` } +// IBCQuery defines a query request from the contract into the chain. +// This is the counterpart of [IbcQuery](https://github.com/CosmWasm/cosmwasm/blob/v0.14.0-beta1/packages/std/src/ibc.rs#L61-L83). +type IBCQuery struct { + PortID *PortIDQuery `json:"port_id,omitempty"` + ListChannels *ListChannelsQuery `json:"list_channels,omitempty"` + Channel *ChannelQuery `json:"channel,omitempty"` +} + +type PortIDQuery struct{} + +type PortIDResponse struct { + PortID string `json:"port_id"` +} + +// ListChannelsQuery is an IBCQuery that lists all channels that are bound to a given port. +// If `PortID` is unset, this list all channels bound to the contract's port. +// Returns a `ListChannelsResponse`. +// This is the counterpart of [IbcQuery::ListChannels](https://github.com/CosmWasm/cosmwasm/blob/v0.14.0-beta1/packages/std/src/ibc.rs#L70-L73). +type ListChannelsQuery struct { + // optional argument + PortID string `json:"port_id,omitempty"` +} + +type ListChannelsResponse struct { + Channels IBCChannels `json:"channels"` +} + +type IBCEndpoint struct { + PortID string `json:"port_id"` + ChannelID string `json:"channel_id"` +} + +// TODO: test what the sdk Order.String() represents and how to parse back +// Proto files: https://github.com/cosmos/cosmos-sdk/blob/v0.40.0/proto/ibc/core/channel/v1/channel.proto#L69-L80 +// Auto-gen code: https://github.com/cosmos/cosmos-sdk/blob/v0.40.0/x/ibc/core/04-channel/types/channel.pb.go#L70-L101 +type IBCOrder = string + +// These are the only two valid values for IbcOrder +const Unordered = "ORDER_UNORDERED" +const Ordered = "ORDER_ORDERED" + +type IBCChannel struct { + Endpoint IBCEndpoint `json:"endpoint"` + CounterpartyEndpoint IBCEndpoint `json:"counterparty_endpoint"` + Order IBCOrder `json:"order"` + Version string `json:"version"` + ConnectionID string `json:"connection_id"` +} + +type IBCOpenInit struct { + Channel IBCChannel `json:"channel"` +} + +func (m *IBCOpenInit) ToMsg() IBCChannelOpenMsg { + return IBCChannelOpenMsg{ + OpenInit: m, + } +} + +type IBCOpenTry struct { + Channel IBCChannel `json:"channel"` + CounterpartyVersion string `json:"counterparty_version"` +} + +func (m *IBCOpenTry) ToMsg() IBCChannelOpenMsg { + return IBCChannelOpenMsg{ + OpenTry: m, + } +} + +type IBCChannelOpenMsg struct { + OpenInit *IBCOpenInit `json:"open_init,omitempty"` + OpenTry *IBCOpenTry `json:"open_try,omitempty"` +} + +// IBCChannels must JSON encode empty array as [] (not null) for consistency with Rust parser +type IBCChannels []IBCChannel + +// MarshalJSON ensures that we get [] for empty arrays +func (e IBCChannels) MarshalJSON() ([]byte, error) { + if len(e) == 0 { + return []byte("[]"), nil + } + var raw []IBCChannel = e + return json.Marshal(raw) +} + +// UnmarshalJSON ensures that we get [] for empty arrays +func (e *IBCChannels) UnmarshalJSON(data []byte) error { + // make sure we deserialize [] back to null + if string(data) == "[]" || string(data) == "null" { + return nil + } + var raw []IBCChannel + if err := json.Unmarshal(data, &raw); err != nil { + return err + } + *e = raw + return nil +} + +// IBCEndpoints must JSON encode empty array as [] (not null) for consistency with Rust parser +type IBCEndpoints []IBCEndpoint + +// MarshalJSON ensures that we get [] for empty arrays +func (e IBCEndpoints) MarshalJSON() ([]byte, error) { + if len(e) == 0 { + return []byte("[]"), nil + } + var raw []IBCEndpoint = e + return json.Marshal(raw) +} + +// UnmarshalJSON ensures that we get [] for empty arrays +func (e *IBCEndpoints) UnmarshalJSON(data []byte) error { + // make sure we deserialize [] back to null + if string(data) == "[]" || string(data) == "null" { + return nil + } + var raw []IBCEndpoint + if err := json.Unmarshal(data, &raw); err != nil { + return err + } + *e = raw + return nil +} + +type ChannelQuery struct { + // optional argument + PortID string `json:"port_id,omitempty"` + ChannelID string `json:"channel_id"` +} + +type ChannelResponse struct { + // may be empty if there is no matching channel + Channel *IBCChannel `json:"channel,omitempty"` +} + type MintQuery struct { Inflation *MintingInflationQuery `json:"inflation,omitempty"` BondedRatio *MintingBondedRatioQuery `json:"bonded_ratio,omitempty"` diff --git a/integration-tests/contract-v1/src/contract.rs b/integration-tests/contract-v1/src/contract.rs index 5657eb608..94e6247ca 100644 --- a/integration-tests/contract-v1/src/contract.rs +++ b/integration-tests/contract-v1/src/contract.rs @@ -1,6 +1,6 @@ use cosmwasm_std::{ entry_point, BankMsg, Binary, CosmosMsg, Deps, DepsMut, DistributionMsg, Env, GovMsg, IbcMsg, - MessageInfo, Response, StakingMsg, StdResult, WasmMsg, + MessageInfo, QueryRequest, Response, StakingMsg, StdResult, WasmMsg, }; use crate::msg::{Msg, QueryMsg}; @@ -141,6 +141,14 @@ fn handle_msg(_deps: DepsMut, _env: Env, _info: MessageInfo, msg: Msg) -> StdRes } #[entry_point] -pub fn query(_deps: Deps, _env: Env, _msg: QueryMsg) -> StdResult { - return Ok(Binary(vec![])); +pub fn query(deps: Deps, _env: Env, msg: QueryMsg) -> StdResult { + match msg { + QueryMsg::StargateQuery { path, data } => { + let res = deps + .querier + .query::(&QueryRequest::Stargate { path, data }); + deps.api.debug(&format!("ASSAF {:?}", res)); + return Ok(res?); + } + } } diff --git a/integration-tests/contract-v1/src/msg.rs b/integration-tests/contract-v1/src/msg.rs index 580b0596b..6f298da88 100644 --- a/integration-tests/contract-v1/src/msg.rs +++ b/integration-tests/contract-v1/src/msg.rs @@ -69,8 +69,6 @@ pub enum Msg { #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] #[serde(rename_all = "snake_case")] -pub enum QueryMsg {} - -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] -#[serde(rename_all = "snake_case")] -pub enum QueryRes {} +pub enum QueryMsg { + StargateQuery { path: String, data: Binary }, +} diff --git a/integration-tests/test.ts b/integration-tests/test.ts index 8b95de37d..b84cb102d 100644 --- a/integration-tests/test.ts +++ b/integration-tests/test.ts @@ -1,5 +1,9 @@ import { SecretNetworkClient, toBase64, toHex, Wallet } from "secretjs"; import { MsgSend } from "secretjs/dist/protobuf_stuff/cosmos/bank/v1beta1/tx"; +import { + QueryBalanceRequest, + QueryBalanceResponse, +} from "secretjs/dist/protobuf_stuff/cosmos/bank/v1beta1/query"; import { sha256 } from "@noble/hashes/sha256"; import * as fs from "fs"; @@ -117,7 +121,7 @@ async function waitForBlocks() { } } -describe("BankMsg::Send", () => { +describe("Bank::MsgSend", () => { test("v1", async () => { const tx = await accounts.a.tx.compute.executeContract( { @@ -241,8 +245,25 @@ describe("StargateMsg", () => { ] ); }); +}); - test("v0.10", async () => { - // TODO +describe("StargateQuery", () => { + test("v1", async () => { + const result = await accounts.a.query.compute.queryContract({ + contractAddress: v1Address, + codeHash: v1CodeHash, + query: { + stargate_query: { + path: "/cosmos.bank.v1beta1.Query.Balance", + data: toBase64( + QueryBalanceRequest.encode({ + address: accounts.a.address, + denom: "uscrt", + }).finish() + ), + }, + }, + }); + console.log(result); }); }); diff --git a/x/compute/internal/keeper/keeper.go b/x/compute/internal/keeper/keeper.go index c1627e869..658e187a0 100644 --- a/x/compute/internal/keeper/keeper.go +++ b/x/compute/internal/keeper/keeper.go @@ -112,13 +112,6 @@ func NewKeeper( panic(err) } - /* - // set KeyTable if it has not already been set - if !paramSpace.HasKeyTable() { - paramSpace = paramSpace.WithKeyTable(types.ParamKeyTable()) - } - */ - keeper := Keeper{ storeKey: storeKey, cdc: cdc, @@ -131,47 +124,13 @@ func NewKeeper( messenger: NewMessageHandler(msgRouter, customEncoders, channelKeeper, capabilityKeeper, portSource, cdc), queryGasLimit: wasmConfig.SmartQueryGasLimit, } - keeper.queryPlugins = DefaultQueryPlugins(govKeeper, distKeeper, mintKeeper, bankKeeper, stakingKeeper, queryRouter, &keeper).Merge(customPlugins) + keeper.queryPlugins = DefaultQueryPlugins(govKeeper, distKeeper, mintKeeper, bankKeeper, stakingKeeper, queryRouter, &keeper, channelKeeper).Merge(customPlugins) return keeper } -/* -func (k Keeper) getUploadAccessConfig(ctx sdk.Context) types.AccessConfig { - var a types.AccessConfig - k.paramSpace.Get(ctx, types.ParamStoreKeyUploadAccess, &a) - return a -} - -func (k Keeper) getInstantiateAccessConfig(ctx sdk.Context) types.AccessType { - var a types.AccessType - k.paramSpace.Get(ctx, types.ParamStoreKeyInstantiateAccess, &a) - return a -} - -// GetParams returns the total set of wasm parameters. -func (k Keeper) GetParams(ctx sdk.Context) types.Params { - var params types.Params - k.paramSpace.GetParamSet(ctx, ¶ms) - return params -} - -func (k Keeper) setParams(ctx sdk.Context, ps types.Params) { - k.paramSpace.SetParamSet(ctx, &ps) -} -*/ - // Create uploads and compiles a WASM contract, returning a short identifier for the contract func (k Keeper) Create(ctx sdk.Context, creator sdk.AccAddress, wasmCode []byte, source string, builder string) (codeID uint64, err error) { - /* - return k.create(ctx, creator, wasmCode, source, builder, &types.AccessConfig{Type: types.Everybody} , k.authZPolicy ) - } - - func (k Keeper) create(ctx sdk.Context, creator sdk.AccAddress, wasmCode []byte, source string, builder string, instantiateAccess *types.AccessConfig ) (codeID uint64, err error) { - if !authZ.CanCreateCode(k.getUploadAccessConfig(ctx), creator) { - return 0, sdkerrors.Wrap(sdkerrors.ErrUnauthorized, "can not create code") - } - */ wasmCode, err = uncompress(wasmCode) if err != nil { return 0, sdkerrors.Wrap(types.ErrCreateFailed, err.Error()) @@ -185,13 +144,8 @@ func (k Keeper) Create(ctx sdk.Context, creator sdk.AccAddress, wasmCode []byte, } store := ctx.KVStore(k.storeKey) codeID = k.autoIncrementID(ctx, types.KeyLastCodeID) - /* - if instantiateAccess == nil { - defaultAccessConfig := k.getInstantiateAccessConfig(ctx).With(creator) - instantiateAccess = &defaultAccessConfig - } - */ - codeInfo := types.NewCodeInfo(codeHash, creator, source, builder /* , *instantiateAccess */) + + codeInfo := types.NewCodeInfo(codeHash, creator, source, builder) // 0x01 | codeID (uint64) -> ContractInfo store.Set(types.GetCodeKey(codeID), k.cdc.MustMarshal(&codeInfo)) @@ -264,6 +218,9 @@ func (k Keeper) GetSignerInfo(ctx sdk.Context, signer sdk.AccAddress) ([]byte, s } signatures, err := protobufTx.GetSignaturesV2() + if err != nil { + return nil, 0, nil, nil, nil, sdkerrors.Wrap(types.ErrSigFailed, "couldn't GetSignaturesV2") + } var signMode sdktxsigning.SignMode switch signData := signatures[pkIndex].Data.(type) { case *sdktxsigning.SingleSignatureData: diff --git a/x/compute/internal/keeper/query_plugins.go b/x/compute/internal/keeper/query_plugins.go index 1f21db699..0f58d6ce5 100644 --- a/x/compute/internal/keeper/query_plugins.go +++ b/x/compute/internal/keeper/query_plugins.go @@ -5,6 +5,7 @@ import ( "fmt" "strings" + channeltypes "github.com/cosmos/ibc-go/v3/modules/core/04-channel/types" "github.com/enigmampc/SecretNetwork/x/compute/internal/types" "github.com/cosmos/cosmos-sdk/baseapp" @@ -83,11 +84,12 @@ type QueryPlugins struct { Wasm func(ctx sdk.Context, request *wasmTypes.WasmQuery) ([]byte, error) Dist func(ctx sdk.Context, request *wasmTypes.DistQuery) ([]byte, error) Mint func(ctx sdk.Context, request *wasmTypes.MintQuery) ([]byte, error) - Stargate func(ctx sdk.Context, request *wasmTypes.StargateQuery) ([]byte, error) Gov func(ctx sdk.Context, request *wasmTypes.GovQuery) ([]byte, error) + IBC func(ctx sdk.Context, caller sdk.AccAddress, request *wasmTypes.IBCQuery) ([]byte, error) + Stargate func(ctx sdk.Context, request *wasmTypes.StargateQuery) ([]byte, error) } -func DefaultQueryPlugins(gov govkeeper.Keeper, dist distrkeeper.Keeper, mint mintkeeper.Keeper, bank bankkeeper.Keeper, staking stakingkeeper.Keeper, stargateQueryRouter GRPCQueryRouter, wasm *Keeper) QueryPlugins { +func DefaultQueryPlugins(gov govkeeper.Keeper, dist distrkeeper.Keeper, mint mintkeeper.Keeper, bank bankkeeper.Keeper, staking stakingkeeper.Keeper, stargateQueryRouter GRPCQueryRouter, wasm *Keeper, channelKeeper types.ChannelKeeper) QueryPlugins { return QueryPlugins{ Bank: BankQuerier(bank), Custom: NoCustomQuerier, @@ -97,6 +99,7 @@ func DefaultQueryPlugins(gov govkeeper.Keeper, dist distrkeeper.Keeper, mint min Mint: MintQuerier(mint), Gov: GovQuerier(gov), Stargate: StargateQuerier(stargateQueryRouter), + IBC: IBCQuerier(wasm, channelKeeper), } } @@ -126,6 +129,12 @@ func (e QueryPlugins) Merge(o *QueryPlugins) QueryPlugins { if o.Gov != nil { e.Gov = o.Gov } + if o.IBC != nil { + e.IBC = o.IBC + } + if o.Stargate != nil { + e.Stargate = o.Stargate + } return e } @@ -268,6 +277,77 @@ func GovQuerier(keeper govkeeper.Keeper) func(ctx sdk.Context, request *wasmType } } +func IBCQuerier(wasm *Keeper, channelKeeper types.ChannelKeeper) func(ctx sdk.Context, caller sdk.AccAddress, request *wasmTypes.IBCQuery) ([]byte, error) { + return func(ctx sdk.Context, caller sdk.AccAddress, request *wasmTypes.IBCQuery) ([]byte, error) { + if request.PortID != nil { + contractInfo := wasm.GetContractInfo(ctx, caller) + res := wasmTypes.PortIDResponse{ + PortID: contractInfo.IBCPortID, + } + return json.Marshal(res) + } + if request.ListChannels != nil { + portID := request.ListChannels.PortID + channels := make(wasmTypes.IBCChannels, 0) + channelKeeper.IterateChannels(ctx, func(ch channeltypes.IdentifiedChannel) bool { + // it must match the port and be in open state + if (portID == "" || portID == ch.PortId) && ch.State == channeltypes.OPEN { + newChan := wasmTypes.IBCChannel{ + Endpoint: wasmTypes.IBCEndpoint{ + PortID: ch.PortId, + ChannelID: ch.ChannelId, + }, + CounterpartyEndpoint: wasmTypes.IBCEndpoint{ + PortID: ch.Counterparty.PortId, + ChannelID: ch.Counterparty.ChannelId, + }, + Order: ch.Ordering.String(), + Version: ch.Version, + ConnectionID: ch.ConnectionHops[0], + } + channels = append(channels, newChan) + } + return false + }) + res := wasmTypes.ListChannelsResponse{ + Channels: channels, + } + return json.Marshal(res) + } + if request.Channel != nil { + channelID := request.Channel.ChannelID + portID := request.Channel.PortID + if portID == "" { + contractInfo := wasm.GetContractInfo(ctx, caller) + portID = contractInfo.IBCPortID + } + got, found := channelKeeper.GetChannel(ctx, portID, channelID) + var channel *wasmTypes.IBCChannel + // it must be in open state + if found && got.State == channeltypes.OPEN { + channel = &wasmTypes.IBCChannel{ + Endpoint: wasmTypes.IBCEndpoint{ + PortID: portID, + ChannelID: channelID, + }, + CounterpartyEndpoint: wasmTypes.IBCEndpoint{ + PortID: got.Counterparty.PortId, + ChannelID: got.Counterparty.ChannelId, + }, + Order: got.Ordering.String(), + Version: got.Version, + ConnectionID: got.ConnectionHops[0], + } + } + res := wasmTypes.ChannelResponse{ + Channel: channel, + } + return json.Marshal(res) + } + return nil, wasmTypes.UnsupportedRequest{Kind: "unknown IBCQuery variant"} + } +} + func MintQuerier(keeper mintkeeper.Keeper) func(ctx sdk.Context, request *wasmTypes.MintQuery) ([]byte, error) { return func(ctx sdk.Context, request *wasmTypes.MintQuery) ([]byte, error) { if request.BondedRatio != nil { @@ -471,6 +551,40 @@ func StakingQuerier(keeper stakingkeeper.Keeper, distKeeper distrkeeper.Keeper) return json.Marshal(res) } + if request.Validator != nil { + valAddr, err := sdk.ValAddressFromBech32(request.Validator.Address) + if err != nil { + return nil, err + } + v, found := keeper.GetValidator(ctx, valAddr) + res := wasmTypes.ValidatorResponse{} + if found { + res.Validator = &wasmTypes.Validator{ + Address: v.OperatorAddress, + Commission: v.Commission.Rate.String(), + MaxCommission: v.Commission.MaxRate.String(), + MaxChangeRate: v.Commission.MaxChangeRate.String(), + } + } + return json.Marshal(res) + } + if request.AllValidators != nil { + validators := keeper.GetBondedValidatorsByPower(ctx) + // validators := keeper.GetAllValidators(ctx) + wasmVals := make([]wasmTypes.Validator, len(validators)) + for i, v := range validators { + wasmVals[i] = wasmTypes.Validator{ + Address: v.OperatorAddress, + Commission: v.Commission.Rate.String(), + MaxCommission: v.Commission.MaxRate.String(), + MaxChangeRate: v.Commission.MaxChangeRate.String(), + } + } + res := wasmTypes.AllValidatorsResponse{ + Validators: wasmVals, + } + return json.Marshal(res) + } return nil, wasmTypes.UnsupportedRequest{Kind: "unknown Staking variant"} } } diff --git a/x/compute/internal/types/expected_keepers.go b/x/compute/internal/types/expected_keepers.go index 1bef78e26..04355c92a 100644 --- a/x/compute/internal/types/expected_keepers.go +++ b/x/compute/internal/types/expected_keepers.go @@ -1,8 +1,25 @@ package types -import sdk "github.com/cosmos/cosmos-sdk/types" +import ( + sdk "github.com/cosmos/cosmos-sdk/types" + + capabilitytypes "github.com/cosmos/cosmos-sdk/x/capability/types" + channeltypes "github.com/cosmos/ibc-go/v3/modules/core/04-channel/types" + ibcexported "github.com/cosmos/ibc-go/v3/modules/core/exported" +) // ICS20TransferPortSource is a subset of the ibc transfer keeper. type ICS20TransferPortSource interface { GetPort(ctx sdk.Context) string } + +// ChannelKeeper defines the expected IBC channel keeper +type ChannelKeeper interface { + GetChannel(ctx sdk.Context, srcPort, srcChan string) (channel channeltypes.Channel, found bool) + GetNextSequenceSend(ctx sdk.Context, portID, channelID string) (uint64, bool) + SendPacket(ctx sdk.Context, channelCap *capabilitytypes.Capability, packet ibcexported.PacketI) error + ChanCloseInit(ctx sdk.Context, portID, channelID string, chanCap *capabilitytypes.Capability) error + GetAllChannels(ctx sdk.Context) (channels []channeltypes.IdentifiedChannel) + IterateChannels(ctx sdk.Context, cb func(channeltypes.IdentifiedChannel) bool) + SetChannel(ctx sdk.Context, portID, channelID string, channel channeltypes.Channel) +} From 9f55427987b934113c1b0fa0008a74a2200cca31 Mon Sep 17 00:00:00 2001 From: Assaf Morami Date: Mon, 22 Aug 2022 20:43:07 +0300 Subject: [PATCH 40/93] Continue fixing the v1 querier --- .../shared/cosmwasm-v010-types/src/query.rs | 1 + go-cosmwasm/types/queries.go | 16 +++++++++------- x/compute/internal/keeper/keeper.go | 14 +++++++++----- x/compute/internal/keeper/query_plugins.go | 7 +++++++ 4 files changed, 26 insertions(+), 12 deletions(-) diff --git a/cosmwasm/enclaves/shared/cosmwasm-v010-types/src/query.rs b/cosmwasm/enclaves/shared/cosmwasm-v010-types/src/query.rs index d27053ffc..51b800cba 100644 --- a/cosmwasm/enclaves/shared/cosmwasm-v010-types/src/query.rs +++ b/cosmwasm/enclaves/shared/cosmwasm-v010-types/src/query.rs @@ -18,6 +18,7 @@ pub enum QueryRequest { Mint(MintQuery), Gov(GovQuery), Ibc(IbcQuery), + Stargate { path: String, data: Binary }, } /// These are queries to the various IBC modules to see the state of the contract's diff --git a/go-cosmwasm/types/queries.go b/go-cosmwasm/types/queries.go index 34a9cd56c..b4f4c31db 100644 --- a/go-cosmwasm/types/queries.go +++ b/go-cosmwasm/types/queries.go @@ -64,13 +64,15 @@ func ToQuerierResult(response []byte, err error) QuerierResult { // QueryRequest is an rust enum and only (exactly) one of the fields should be set // Should we do a cleaner approach in Go? (type/data?) type QueryRequest struct { - Bank *BankQuery `json:"bank,omitempty"` - Custom json.RawMessage `json:"custom,omitempty"` - Staking *StakingQuery `json:"staking,omitempty"` - Wasm *WasmQuery `json:"wasm,omitempty"` - Dist *DistQuery `json:"dist,omitempty"` - Mint *MintQuery `json:"mint,omitempty"` - Gov *GovQuery `json:"gov,omitempty"` + Bank *BankQuery `json:"bank,omitempty"` + Custom json.RawMessage `json:"custom,omitempty"` + Staking *StakingQuery `json:"staking,omitempty"` + Wasm *WasmQuery `json:"wasm,omitempty"` + Dist *DistQuery `json:"dist,omitempty"` + Mint *MintQuery `json:"mint,omitempty"` + Gov *GovQuery `json:"gov,omitempty"` + IBC *IBCQuery `json:"ibc,omitempty"` + Stargate *StargateQuery `json:"stargate,omitempty"` } type BankQuery struct { diff --git a/x/compute/internal/keeper/keeper.go b/x/compute/internal/keeper/keeper.go index 658e187a0..cebc195ea 100644 --- a/x/compute/internal/keeper/keeper.go +++ b/x/compute/internal/keeper/keeper.go @@ -391,6 +391,7 @@ func (k Keeper) Instantiate(ctx sdk.Context, codeID uint64, creator sdk.AccAddre querier := QueryHandler{ Ctx: ctx, Plugins: k.queryPlugins, + Caller: contractAddress, } // instantiate wasm contract @@ -527,6 +528,7 @@ func (k Keeper) Execute(ctx sdk.Context, contractAddress sdk.AccAddress, caller querier := QueryHandler{ Ctx: ctx, Plugins: k.queryPlugins, + Caller: contractAddress, } gas := gasForContract(ctx) @@ -590,7 +592,7 @@ func (k Keeper) querySmartRecursive(ctx sdk.Context, contractAddr sdk.AccAddress return k.querySmartImpl(ctx, contractAddr, req, useDefaultGasLimit, true) } -func (k Keeper) querySmartImpl(ctx sdk.Context, contractAddr sdk.AccAddress, req []byte, useDefaultGasLimit bool, recursive bool) ([]byte, error) { +func (k Keeper) querySmartImpl(ctx sdk.Context, contractAddress sdk.AccAddress, req []byte, useDefaultGasLimit bool, recursive bool) ([]byte, error) { defer telemetry.MeasureSince(time.Now(), "compute", "keeper", "query") if useDefaultGasLimit { @@ -599,7 +601,7 @@ func (k Keeper) querySmartImpl(ctx sdk.Context, contractAddr sdk.AccAddress, req ctx.GasMeter().ConsumeGas(types.InstanceCost, "Loading CosmWasm module: query") - _, codeInfo, prefixStore, err := k.contractInstance(ctx, contractAddr) + _, codeInfo, prefixStore, err := k.contractInstance(ctx, contractAddress) if err != nil { return nil, err } @@ -608,16 +610,17 @@ func (k Keeper) querySmartImpl(ctx sdk.Context, contractAddr sdk.AccAddress, req querier := QueryHandler{ Ctx: ctx, Plugins: k.queryPlugins, + Caller: contractAddress, } store := ctx.KVStore(k.storeKey) // 0x01 | codeID (uint64) -> ContractInfo - contractKey := store.Get(types.GetContractEnclaveKey(contractAddr)) + contractKey := store.Get(types.GetContractEnclaveKey(contractAddress)) params := types.NewEnv( ctx, sdk.AccAddress{}, /* empty because it's unused in queries */ []sdk.Coin{}, /* empty because it's unused in queries */ - contractAddr, + contractAddress, contractKey, ) params.Recursive = recursive @@ -625,7 +628,7 @@ func (k Keeper) querySmartImpl(ctx sdk.Context, contractAddr sdk.AccAddress, req queryResult, gasUsed, qErr := k.wasmer.Query(codeInfo.CodeHash, params, req, prefixStore, cosmwasmAPI, querier, gasMeter(ctx), gasForContract(ctx)) consumeGas(ctx, gasUsed) - telemetry.SetGauge(float32(gasUsed), "compute", "keeper", "query", contractAddr.String(), "gasUsed") + telemetry.SetGauge(float32(gasUsed), "compute", "keeper", "query", contractAddress.String(), "gasUsed") if qErr != nil { return nil, sdkerrors.Wrap(types.ErrQueryFailed, qErr.Error()) @@ -1030,6 +1033,7 @@ func (k Keeper) reply(ctx sdk.Context, contractAddress sdk.AccAddress, reply v1w querier := QueryHandler{ Ctx: ctx, Plugins: k.queryPlugins, + Caller: contractAddress, } // instantiate wasm contract diff --git a/x/compute/internal/keeper/query_plugins.go b/x/compute/internal/keeper/query_plugins.go index 0f58d6ce5..abb11f0a0 100644 --- a/x/compute/internal/keeper/query_plugins.go +++ b/x/compute/internal/keeper/query_plugins.go @@ -32,6 +32,7 @@ type GRPCQueryRouter interface { type QueryHandler struct { Ctx sdk.Context Plugins QueryPlugins + Caller sdk.AccAddress } var _ wasmTypes.Querier = QueryHandler{} @@ -68,6 +69,12 @@ func (q QueryHandler) Query(request wasmTypes.QueryRequest, gasLimit uint64) ([] if request.Gov != nil { return q.Plugins.Gov(q.Ctx, request.Gov) } + if request.IBC != nil { + return q.Plugins.IBC(q.Ctx, q.Caller, request.IBC) + } + if request.Stargate != nil { + return q.Plugins.Stargate(q.Ctx, request.Stargate) + } return nil, wasmTypes.Unknown{} } From 8b5ff3d9f51c7f9b702148bca56a40a68e7049d3 Mon Sep 17 00:00:00 2001 From: Assaf Morami Date: Mon, 22 Aug 2022 21:04:02 +0300 Subject: [PATCH 41/93] Fix StargateQuery paths --- integration-tests/test.ts | 2 +- x/compute/internal/keeper/query_plugins.go | 146 ++++++++++----------- 2 files changed, 74 insertions(+), 74 deletions(-) diff --git a/integration-tests/test.ts b/integration-tests/test.ts index b84cb102d..e78917820 100644 --- a/integration-tests/test.ts +++ b/integration-tests/test.ts @@ -254,7 +254,7 @@ describe("StargateQuery", () => { codeHash: v1CodeHash, query: { stargate_query: { - path: "/cosmos.bank.v1beta1.Query.Balance", + path: "/cosmos.bank.v1beta1.Query/Balance", data: toBase64( QueryBalanceRequest.encode({ address: accounts.a.address, diff --git a/x/compute/internal/keeper/query_plugins.go b/x/compute/internal/keeper/query_plugins.go index abb11f0a0..fdf23142b 100644 --- a/x/compute/internal/keeper/query_plugins.go +++ b/x/compute/internal/keeper/query_plugins.go @@ -159,79 +159,79 @@ func (e QueryPlugins) Merge(o *QueryPlugins) QueryPlugins { // used this to find all query paths: // find -name query.proto | sort | xargs grep -Poin 'package [a-z0-9.]+;|rpc [a-zA-Z]+\(' var stargateQueryAllowlist = map[string]bool{ - "/cosmos.auth.v1beta1.Query.Account": true, - "/cosmos.auth.v1beta1.Query.Accounts": true, - "/cosmos.auth.v1beta1.Query.Params": true, - - "/cosmos.authz.v1beta1.Query.Grants": true, - "/cosmos.authz.v1beta1.Query.GranterGrants": true, - "/cosmos.authz.v1beta1.Query.GranteeGrants": true, - - "/cosmos.bank.v1beta1.Query.Balance": true, - "/cosmos.bank.v1beta1.Query.AllBalances": true, - "/cosmos.bank.v1beta1.Query.SpendableBalances": true, - "/cosmos.bank.v1beta1.Query.TotalSupply": true, - "/cosmos.bank.v1beta1.Query.SupplyOf": true, - "/cosmos.bank.v1beta1.Query.Params": true, - "/cosmos.bank.v1beta1.Query.DenomMetadata": true, - "/cosmos.bank.v1beta1.Query.DenomsMetadata": true, - - "/cosmos.distribution.v1beta1.Query.Params": true, - "/cosmos.distribution.v1beta1.Query.ValidatorOutstandingRewards": true, - "/cosmos.distribution.v1beta1.Query.ValidatorCommission": true, - "/cosmos.distribution.v1beta1.Query.ValidatorSlashes": true, - "/cosmos.distribution.v1beta1.Query.DelegationRewards": true, - "/cosmos.distribution.v1beta1.Query.DelegationTotalRewards": true, - "/cosmos.distribution.v1beta1.Query.DelegatorValidators": true, - "/cosmos.distribution.v1beta1.Query.DelegatorWithdrawAddress": true, - "/cosmos.distribution.v1beta1.Query.CommunityPool": true, - "/cosmos.distribution.v1beta1.Query.FoundationTax": true, - - "/cosmos.feegrant.v1beta1.Query.Allowance": true, - "/cosmos.feegrant.v1beta1.Query.Allowances": true, - - "/cosmos.gov.v1beta1.Query.Proposal": true, - "/cosmos.gov.v1beta1.Query.Proposals": true, - "/cosmos.gov.v1beta1.Query.Vote": true, - "/cosmos.gov.v1beta1.Query.Votes": true, - "/cosmos.gov.v1beta1.Query.Params": true, - "/cosmos.gov.v1beta1.Query.Deposit": true, - "/cosmos.gov.v1beta1.Query.Deposits": true, - "/cosmos.gov.v1beta1.Query.TallyResult": true, - - "/cosmos.mint.v1beta1.Query.Params": true, - "/cosmos.mint.v1beta1.Query.Inflation": true, - "/cosmos.mint.v1beta1.Query.AnnualProvisions": true, - - "/cosmos.params.v1beta1.Query.Params": true, - - "/cosmos.slashing.v1beta1.Query.Params": true, - "/cosmos.slashing.v1beta1.Query.SigningInfo": true, - "/cosmos.slashing.v1beta1.Query.SigningInfos": true, - - "/cosmos.staking.v1beta1.Query.Validators": true, - "/cosmos.staking.v1beta1.Query.Validator": true, - "/cosmos.staking.v1beta1.Query.ValidatorDelegations": true, - "/cosmos.staking.v1beta1.Query.ValidatorUnbondingDelegations": true, - "/cosmos.staking.v1beta1.Query.Delegation": true, - "/cosmos.staking.v1beta1.Query.UnbondingDelegation": true, - "/cosmos.staking.v1beta1.Query.DelegatorDelegations": true, - "/cosmos.staking.v1beta1.Query.DelegatorUnbondingDelegations": true, - "/cosmos.staking.v1beta1.Query.Redelegations": true, - "/cosmos.staking.v1beta1.Query.DelegatorValidators": true, - "/cosmos.staking.v1beta1.Query.DelegatorValidator": true, - "/cosmos.staking.v1beta1.Query.HistoricalInfo": true, - "/cosmos.staking.v1beta1.Query.Pool": true, - "/cosmos.staking.v1beta1.Query.Params": true, - - "/ibc.applications.transfer.v1.Query.DenomTrace": true, - "/ibc.applications.transfer.v1.Query.DenomTraces": true, - "/ibc.applications.transfer.v1.Query.Params": true, - "/ibc.applications.transfer.v1.Query.DenomHash": true, - - "/secret.compute.v1beta1.Query.ContractInfo": true, - "/secret.compute.v1beta1.Query.ContractsByCode": true, - "/secret.compute.v1beta1.Query.Codes": true, + "/cosmos.auth.v1beta1.Query/Account": true, + "/cosmos.auth.v1beta1.Query/Accounts": true, + "/cosmos.auth.v1beta1.Query/Params": true, + + "/cosmos.authz.v1beta1.Query/Grants": true, + "/cosmos.authz.v1beta1.Query/GranterGrants": true, + "/cosmos.authz.v1beta1.Query/GranteeGrants": true, + + "/cosmos.bank.v1beta1.Query/Balance": true, + "/cosmos.bank.v1beta1.Query/AllBalances": true, + "/cosmos.bank.v1beta1.Query/SpendableBalances": true, + "/cosmos.bank.v1beta1.Query/TotalSupply": true, + "/cosmos.bank.v1beta1.Query/SupplyOf": true, + "/cosmos.bank.v1beta1.Query/Params": true, + "/cosmos.bank.v1beta1.Query/DenomMetadata": true, + "/cosmos.bank.v1beta1.Query/DenomsMetadata": true, + + "/cosmos.distribution.v1beta1.Query/Params": true, + "/cosmos.distribution.v1beta1.Query/ValidatorOutstandingRewards": true, + "/cosmos.distribution.v1beta1.Query/ValidatorCommission": true, + "/cosmos.distribution.v1beta1.Query/ValidatorSlashes": true, + "/cosmos.distribution.v1beta1.Query/DelegationRewards": true, + "/cosmos.distribution.v1beta1.Query/DelegationTotalRewards": true, + "/cosmos.distribution.v1beta1.Query/DelegatorValidators": true, + "/cosmos.distribution.v1beta1.Query/DelegatorWithdrawAddress": true, + "/cosmos.distribution.v1beta1.Query/CommunityPool": true, + "/cosmos.distribution.v1beta1.Query/FoundationTax": true, + + "/cosmos.feegrant.v1beta1.Query/Allowance": true, + "/cosmos.feegrant.v1beta1.Query/Allowances": true, + + "/cosmos.gov.v1beta1.Query/Proposal": true, + "/cosmos.gov.v1beta1.Query/Proposals": true, + "/cosmos.gov.v1beta1.Query/Vote": true, + "/cosmos.gov.v1beta1.Query/Votes": true, + "/cosmos.gov.v1beta1.Query/Params": true, + "/cosmos.gov.v1beta1.Query/Deposit": true, + "/cosmos.gov.v1beta1.Query/Deposits": true, + "/cosmos.gov.v1beta1.Query/TallyResult": true, + + "/cosmos.mint.v1beta1.Query/Params": true, + "/cosmos.mint.v1beta1.Query/Inflation": true, + "/cosmos.mint.v1beta1.Query/AnnualProvisions": true, + + "/cosmos.params.v1beta1.Query/Params": true, + + "/cosmos.slashing.v1beta1.Query/Params": true, + "/cosmos.slashing.v1beta1.Query/SigningInfo": true, + "/cosmos.slashing.v1beta1.Query/SigningInfos": true, + + "/cosmos.staking.v1beta1.Query/Validators": true, + "/cosmos.staking.v1beta1.Query/Validator": true, + "/cosmos.staking.v1beta1.Query/ValidatorDelegations": true, + "/cosmos.staking.v1beta1.Query/ValidatorUnbondingDelegations": true, + "/cosmos.staking.v1beta1.Query/Delegation": true, + "/cosmos.staking.v1beta1.Query/UnbondingDelegation": true, + "/cosmos.staking.v1beta1.Query/DelegatorDelegations": true, + "/cosmos.staking.v1beta1.Query/DelegatorUnbondingDelegations": true, + "/cosmos.staking.v1beta1.Query/Redelegations": true, + "/cosmos.staking.v1beta1.Query/DelegatorValidators": true, + "/cosmos.staking.v1beta1.Query/DelegatorValidator": true, + "/cosmos.staking.v1beta1.Query/HistoricalInfo": true, + "/cosmos.staking.v1beta1.Query/Pool": true, + "/cosmos.staking.v1beta1.Query/Params": true, + + "/ibc.applications.transfer.v1.Query/DenomTrace": true, + "/ibc.applications.transfer.v1.Query/DenomTraces": true, + "/ibc.applications.transfer.v1.Query/Params": true, + "/ibc.applications.transfer.v1.Query/DenomHash": true, + + "/secret.compute.v1beta1.Query/ContractInfo": true, + "/secret.compute.v1beta1.Query/ContractsByCode": true, + "/secret.compute.v1beta1.Query/Codes": true, } func StargateQuerier(queryRouter GRPCQueryRouter) func(ctx sdk.Context, request *wasmTypes.StargateQuery) ([]byte, error) { From f512b1c1f2227edd8d761086d94954cd349d2607 Mon Sep 17 00:00:00 2001 From: Lior Bondarevski Date: Mon, 22 Aug 2022 21:17:37 +0300 Subject: [PATCH 42/93] Fix possible null dref in tests --- x/compute/internal/keeper/keeper.go | 12 +++++++--- x/compute/internal/keeper/keeper_test.go | 8 +++++-- x/compute/internal/keeper/recurse_test.go | 23 ++++++++++++++----- .../internal/keeper/secret_contracts_test.go | 16 ++++++++++--- 4 files changed, 45 insertions(+), 14 deletions(-) diff --git a/x/compute/internal/keeper/keeper.go b/x/compute/internal/keeper/keeper.go index 9fd58eb6e..261f2bda3 100644 --- a/x/compute/internal/keeper/keeper.go +++ b/x/compute/internal/keeper/keeper.go @@ -712,12 +712,18 @@ func (k Keeper) GetContractAddress(ctx sdk.Context, label string) sdk.AccAddress return contractAddress } -func (k Keeper) GetContractHash(ctx sdk.Context, contractAddress sdk.AccAddress) []byte { - codeId := k.GetContractInfo(ctx, contractAddress).CodeID +func (k Keeper) GetContractHash(ctx sdk.Context, contractAddress sdk.AccAddress) ([]byte, error) { + contractInfo := k.GetContractInfo(ctx, contractAddress) + + if contractInfo == nil { + return nil, fmt.Errorf("failed to contract info for the following address: %s", contractAddress.String()) + } + + codeId := contractInfo.CodeID hash := k.GetCodeInfo(ctx, codeId).CodeHash - return hash + return hash, nil } func (k Keeper) GetContractInfo(ctx sdk.Context, contractAddress sdk.AccAddress) *types.ContractInfo { diff --git a/x/compute/internal/keeper/keeper_test.go b/x/compute/internal/keeper/keeper_test.go index c4cb36bb6..30c431d06 100644 --- a/x/compute/internal/keeper/keeper_test.go +++ b/x/compute/internal/keeper/keeper_test.go @@ -916,7 +916,9 @@ func TestExecuteWithCpuLoop(t *testing.T) { ctx = ctx.WithGasMeter(sdk.NewGasMeter(gasLimit)) require.Equal(t, uint64(0), ctx.GasMeter().GasConsumed()) - codeHash := keeper.GetContractHash(ctx, addr) + codeHash, err := keeper.GetContractHash(ctx, addr) + require.NoError(t, err) + codeHashStr := hex.EncodeToString(codeHash) msg2 := types.SecretMsg{ @@ -1002,7 +1004,9 @@ func TestExecuteWithStorageLoop(t *testing.T) { require.True(t, ok, "%+v", r) }() - codeHash := keeper.GetContractHash(ctx, addr) + codeHash, err := keeper.GetContractHash(ctx, addr) + require.NoError(t, err) + codeHashStr := hex.EncodeToString(codeHash) msg := types.SecretMsg{ diff --git a/x/compute/internal/keeper/recurse_test.go b/x/compute/internal/keeper/recurse_test.go index 51efdfd50..3e9cdb52b 100644 --- a/x/compute/internal/keeper/recurse_test.go +++ b/x/compute/internal/keeper/recurse_test.go @@ -155,7 +155,10 @@ func TestGasCostOnQuery(t *testing.T) { recurse := tc.msg recurse.Contract = contractAddr - msg := buildQuery(t, recurse, hex.EncodeToString(keeper.GetContractHash(ctx, contractAddr))) + codeHash, err := keeper.GetContractHash(ctx, contractAddr) + require.NoError(t, err) + + msg := buildQuery(t, recurse, hex.EncodeToString(codeHash)) data, qErr := queryHelper(t, keeper, ctx, contractAddr, string(msg), true, false, tc.gasLimit) require.Empty(t, qErr) @@ -169,7 +172,7 @@ func TestGasCostOnQuery(t *testing.T) { // assert result is 32 byte sha256 hash (if hashed), or contractAddr if not var resp recurseResponse - err := json.Unmarshal([]byte(data), &resp) + err = json.Unmarshal([]byte(data), &resp) require.NoError(t, err) if recurse.Work == 0 { assert.Equal(t, len(resp.Hashed), len(creator.String())) @@ -233,14 +236,18 @@ func TestGasOnExternalQuery(t *testing.T) { recurse := tc.msg recurse.Contract = contractAddr - msg := buildQuery(t, recurse, hex.EncodeToString(keeper.GetContractHash(ctx, contractAddr))) + + codeHash, err := keeper.GetContractHash(ctx, contractAddr) + require.NoError(t, err) + + msg := buildQuery(t, recurse, hex.EncodeToString(codeHash)) secretMsg := types.SecretMsg{ - CodeHash: []byte(hex.EncodeToString(keeper.GetContractHash(ctx, contractAddr))), + CodeHash: []byte(hex.EncodeToString(codeHash)), Msg: msg, } - msg, err := wasmCtx.Encrypt(secretMsg.Serialize()) + msg, err = wasmCtx.Encrypt(secretMsg.Serialize()) require.NoError(t, err) // do the query @@ -349,7 +356,11 @@ func TestLimitRecursiveQueryGas(t *testing.T) { // prepare the query recurse := tc.msg recurse.Contract = contractAddr - msg := buildQuery(t, recurse, hex.EncodeToString(keeper.GetContractHash(ctx, contractAddr))) + + codeHash, err := keeper.GetContractHash(ctx, contractAddr) + require.NoError(t, err) + + msg := buildQuery(t, recurse, hex.EncodeToString(codeHash)) // if we expect out of gas, make sure this panics if tc.expectOutOfGas { diff --git a/x/compute/internal/keeper/secret_contracts_test.go b/x/compute/internal/keeper/secret_contracts_test.go index bb3a70a7a..03caffbf0 100644 --- a/x/compute/internal/keeper/secret_contracts_test.go +++ b/x/compute/internal/keeper/secret_contracts_test.go @@ -53,10 +53,14 @@ var testContracts = []TestContract{ // if codeID isn't 0, it will try to use that. Otherwise will take the contractAddress func testEncrypt(t *testing.T, keeper Keeper, ctx sdk.Context, contractAddress sdk.AccAddress, codeId uint64, msg []byte) ([]byte, error) { var hash []byte + var err error + if codeId != 0 { hash = keeper.GetCodeInfo(ctx, codeId).CodeHash } else { - hash = keeper.GetContractHash(ctx, contractAddress) + hash, err = keeper.GetContractHash(ctx, contractAddress) + require.NoError(t, err) + } if hash == nil { @@ -400,7 +404,10 @@ func queryHelperImpl( contractAddr sdk.AccAddress, input string, isErrorEncrypted bool, isV1Contract bool, gas uint64, wasmCallCount int64, ) (string, cosmwasm.StdError) { - hashStr := hex.EncodeToString(keeper.GetContractHash(ctx, contractAddr)) + hash, err := keeper.GetContractHash(ctx, contractAddr) + require.NoError(t, err) + + hashStr := hex.EncodeToString(hash) msg := types.SecretMsg{ CodeHash: []byte(hashStr), @@ -473,7 +480,10 @@ func execHelperMultipleCoinsImpl( contractAddress sdk.AccAddress, txSender sdk.AccAddress, senderPrivKey crypto.PrivKey, execMsg string, isErrorEncrypted bool, isV1Contract bool, gas uint64, coins sdk.Coins, wasmCallCount int64, shouldSkipAttributes ...bool, ) ([]byte, sdk.Context, []byte, []ContractEvent, uint64, cosmwasm.StdError) { - hashStr := hex.EncodeToString(keeper.GetContractHash(ctx, contractAddress)) + hash, err := keeper.GetContractHash(ctx, contractAddress) + require.NoError(t, err) + + hashStr := hex.EncodeToString(hash) msg := types.SecretMsg{ CodeHash: []byte(hashStr), From 68b8a00cf0b0f630c0048ab9064d4c90b109153c Mon Sep 17 00:00:00 2001 From: Lior Bondarevski Date: Mon, 22 Aug 2022 21:58:39 +0300 Subject: [PATCH 43/93] Fix second optional null dref --- x/compute/internal/keeper/ibc_test.go | 12 +- x/compute/internal/keeper/keeper.go | 15 ++- x/compute/internal/keeper/keeper_test.go | 119 +++--------------- x/compute/internal/keeper/querier.go | 46 +++---- x/compute/internal/keeper/querier_test.go | 15 ++- .../internal/keeper/secret_contracts_test.go | 68 +++++++--- 6 files changed, 109 insertions(+), 166 deletions(-) diff --git a/x/compute/internal/keeper/ibc_test.go b/x/compute/internal/keeper/ibc_test.go index 9092290b1..c5a16e000 100644 --- a/x/compute/internal/keeper/ibc_test.go +++ b/x/compute/internal/keeper/ibc_test.go @@ -180,7 +180,9 @@ func ibcPacketReceiveHelper( internalPacket := packet if shouldEncryptMsg { - hashStr := hex.EncodeToString(keeper.GetContractHash(ctx, contractAddr)) + contractHash, err := keeper.GetContractHash(ctx, contractAddr) + require.NoError(t, err) + hashStr := hex.EncodeToString(contractHash) msg := types.SecretMsg{ CodeHash: []byte(hashStr), @@ -232,7 +234,9 @@ func ibcPacketAckHelper( var nonce []byte if shouldEncryptMsg { - hashStr := hex.EncodeToString(keeper.GetContractHash(ctx, contractAddr)) + contractHash, err := keeper.GetContractHash(ctx, contractAddr) + require.NoError(t, err) + hashStr := hex.EncodeToString(contractHash) msg := types.SecretMsg{ CodeHash: []byte(hashStr), @@ -287,7 +291,9 @@ func ibcPacketTimeoutHelper( var nonce []byte if shouldEncryptMsg { - hashStr := hex.EncodeToString(keeper.GetContractHash(ctx, contractAddr)) + contractHash, err := keeper.GetContractHash(ctx, contractAddr) + require.NoError(t, err) + hashStr := hex.EncodeToString(contractHash) msg := types.SecretMsg{ CodeHash: []byte(hashStr), diff --git a/x/compute/internal/keeper/keeper.go b/x/compute/internal/keeper/keeper.go index 261f2bda3..5f1b3a01f 100644 --- a/x/compute/internal/keeper/keeper.go +++ b/x/compute/internal/keeper/keeper.go @@ -716,14 +716,17 @@ func (k Keeper) GetContractHash(ctx sdk.Context, contractAddress sdk.AccAddress) contractInfo := k.GetContractInfo(ctx, contractAddress) if contractInfo == nil { - return nil, fmt.Errorf("failed to contract info for the following address: %s", contractAddress.String()) + return nil, fmt.Errorf("failed to get contract info for the following address: %s", contractAddress.String()) } codeId := contractInfo.CodeID - hash := k.GetCodeInfo(ctx, codeId).CodeHash + codeInfo, err := k.GetCodeInfo(ctx, codeId) + if err != nil { + return nil, err + } - return hash, nil + return codeInfo.CodeHash, nil } func (k Keeper) GetContractInfo(ctx sdk.Context, contractAddress sdk.AccAddress) *types.ContractInfo { @@ -825,15 +828,15 @@ func (k Keeper) fixContractState(ctx sdk.Context, contractAddress sdk.AccAddress return nil } -func (k Keeper) GetCodeInfo(ctx sdk.Context, codeID uint64) *types.CodeInfo { +func (k Keeper) GetCodeInfo(ctx sdk.Context, codeID uint64) (types.CodeInfo, error) { store := ctx.KVStore(k.storeKey) var codeInfo types.CodeInfo codeInfoBz := store.Get(types.GetCodeKey(codeID)) if codeInfoBz == nil { - return nil + return types.CodeInfo{}, fmt.Errorf("failed to get code info for code id %d", codeID) } k.cdc.MustUnmarshal(codeInfoBz, &codeInfo) - return &codeInfo + return codeInfo, nil } func (k Keeper) containsCodeInfo(ctx sdk.Context, codeID uint64) bool { diff --git a/x/compute/internal/keeper/keeper_test.go b/x/compute/internal/keeper/keeper_test.go index 30c431d06..8b69ed572 100644 --- a/x/compute/internal/keeper/keeper_test.go +++ b/x/compute/internal/keeper/keeper_test.go @@ -89,104 +89,6 @@ func TestCreate(t *testing.T) { require.Equal(t, wasmCode, storedCode) } -/* -func TestCreateStoresInstantiatePermission(t *testing.T) { - wasmCode, err := ioutil.ReadFile("./testdata/contract.wasm") - require.NoError(t, err) - var ( - deposit = sdk.NewCoins(sdk.NewInt64Coin("denom", 100000)) - myAddr = bytes.Repeat([]byte{1}, sdk.AddrLen) - ) - - specs := map[string]struct { - srcPermission types.AccessType - expInstConf types.AccessConfig - }{ - "default": { - srcPermission: types.DefaultParams().DefaultInstantiatePermission, - expInstConf: types.AllowEverybody, - }, - "everybody": { - srcPermission: types.Everybody, - expInstConf: types.AllowEverybody, - }, - "nobody": { - srcPermission: types.Nobody, - expInstConf: types.AllowNobody, - }, - "onlyAddress with matching address": { - srcPermission: types.OnlyAddress, - expInstConf: types.AccessConfig{Type: types.OnlyAddress, Address: myAddr}, - }, - } - for msg, spec := range specs { - t.Run(msg, func(t *testing.T) { - tempDir, err := ioutil.TempDir("", "wasm") - require.NoError(t, err) - defer os.RemoveAll(tempDir) - - ctx, keepers := CreateTestInput(t, false, tempDir, SupportedFeatures, nil, nil) - accKeeper, keeper := keepers.AccountKeeper, keepers.WasmKeeper - fundAccounts(ctx, accKeeper, myAddr, deposit) - - codeID, err := keeper.Create(ctx, myAddr, wasmCode, "https://github.com/CosmWasm/wasmd/blob/master/x/wasm/testdata/escrow.wasm", "any/builder:tag") - require.NoError(t, err) - - codeInfo := keeper.GetCodeInfo(ctx, codeID) - require.NotNil(t, codeInfo) - assert.True(t, spec.expInstConf.Equals(codeInfo.InstantiateConfig), "got %#v", codeInfo.InstantiateConfig) - }) - } -} - -func TestCreateWithParamPermissions(t *testing.T) { - tempDir, err := ioutil.TempDir("", "wasm") - require.NoError(t, err) - defer os.RemoveAll(tempDir) - ctx, keepers := CreateTestInput(t, false, tempDir, SupportedFeatures, nil, nil) - accKeeper, keeper := keepers.AccountKeeper, keepers.WasmKeeper - - deposit := sdk.NewCoins(sdk.NewInt64Coin("denom", 100000)) - creator := CreateFakeFundedAccount(ctx, accKeeper, deposit) - otherAddr := CreateFakeFundedAccount(ctx, accKeeper, deposit) - - wasmCode, err := ioutil.ReadFile("./testdata/contract.wasm") - require.NoError(t, err) - - specs := map[string]struct { - srcPermission types.AccessConfig - expError *sdkerrors.Error - }{ - "default": { - srcPermission: types.DefaultUploadAccess, - }, - "everybody": { - srcPermission: types.AllowEverybody, - }, - "nobody": { - srcPermission: types.AllowNobody, - expError: sdkerrors.ErrUnauthorized, - }, - "onlyAddress with matching address": { - srcPermission: types.OnlyAddress.With(creator), - }, - "onlyAddress with non matching address": { - srcPermission: types.OnlyAddress.With(otherAddr), - expError: sdkerrors.ErrUnauthorized, - }, - } - for msg, spec := range specs { - t.Run(msg, func(t *testing.T) { - _, err := keeper.Create(ctx, creator, wasmCode, "https://github.com/CosmWasm/wasmd/blob/master/x/wasm/testdata/escrow.wasm", "any/builder:tag") - require.True(t, spec.expError.Is(err), err) - if spec.expError != nil { - return - } - }) - } -} -*/ - func TestCreateDuplicate(t *testing.T) { encodingConfig := MakeEncodingConfig() var transferPortSource types.ICS20TransferPortSource @@ -340,7 +242,10 @@ func TestInstantiate(t *testing.T) { initMsgBz, err := json.Marshal(initMsg) require.NoError(t, err) - key := keeper.GetCodeInfo(ctx, contractID).CodeHash + codeInfo, err := keeper.GetCodeInfo(ctx, contractID) + require.NoError(t, err) + + key := codeInfo.CodeHash msg := types.SecretMsg{ CodeHash: []byte(hex.EncodeToString(key)), @@ -595,8 +500,10 @@ func TestExecute(t *testing.T) { } initMsgBz, err := json.Marshal(initMsg) - key := keeper.GetCodeInfo(ctx, contractID).CodeHash - // keyStr := hex.EncodeToString(key) + codeInfo, err := keeper.GetCodeInfo(ctx, contractID) + require.NoError(t, err) + + key := codeInfo.CodeHash msg := types.SecretMsg{ CodeHash: []byte(hex.EncodeToString(key)), @@ -651,8 +558,7 @@ func TestExecute(t *testing.T) { initMsgBz = []byte(`{"release":{}}`) - key = keeper.GetCodeInfo(ctx, contractID).CodeHash - // keyStr := hex.EncodeToString(key) + require.NoError(t, err) msg = types.SecretMsg{ CodeHash: []byte(hex.EncodeToString(key)), @@ -880,7 +786,10 @@ func TestExecuteWithCpuLoop(t *testing.T) { initMsgBz, err := json.Marshal(initMsg) require.NoError(t, err) - hash := keeper.GetCodeInfo(ctx, contractID).CodeHash + codeInfo, err := keeper.GetCodeInfo(ctx, contractID) + require.NoError(t, err) + + hash := codeInfo.CodeHash msg := types.SecretMsg{ CodeHash: []byte(hex.EncodeToString(hash)), @@ -918,7 +827,7 @@ func TestExecuteWithCpuLoop(t *testing.T) { codeHash, err := keeper.GetContractHash(ctx, addr) require.NoError(t, err) - + codeHashStr := hex.EncodeToString(codeHash) msg2 := types.SecretMsg{ diff --git a/x/compute/internal/keeper/querier.go b/x/compute/internal/keeper/querier.go index 5a30da3cf..1e14d66b0 100644 --- a/x/compute/internal/keeper/querier.go +++ b/x/compute/internal/keeper/querier.go @@ -233,17 +233,18 @@ func queryCode(ctx sdk.Context, codeID uint64, keeper Keeper) (*types.QueryCodeR if codeID == 0 { return nil, nil } - res := keeper.GetCodeInfo(ctx, codeID) - if res == nil { - // nil, nil leads to 404 in rest handler + + codeInfo, err := keeper.GetCodeInfo(ctx, codeID) + if err != nil { return nil, nil } + info := types.CodeInfoResponse{ CodeID: codeID, - Creator: res.Creator, - DataHash: res.CodeHash, - Source: res.Source, - Builder: res.Builder, + Creator: codeInfo.Creator, + DataHash: codeInfo.CodeHash, + Source: codeInfo.Source, + Builder: codeInfo.Builder, } code, err := keeper.GetByteCode(ctx, codeID) @@ -269,30 +270,6 @@ func queryCodeList(ctx sdk.Context, keeper Keeper) ([]types.CodeInfoResponse, er return info, nil } -/* -func queryContractHistory(ctx sdk.Context, bech string, keeper Keeper) ([]byte, error) { - contractAddr, err := sdk.AccAddressFromBech32(bech) - if err != nil { - return nil, sdkerrors.Wrap(sdkerrors.ErrInvalidAddress, err.Error()) - } - entries := keeper.GetContractHistory(ctx, contractAddr) - if entries == nil { - // nil, nil leads to 404 in rest handler - return nil, nil - } - // redact response - for i := range entries { - entries[i].Updated = nil - } - - bz, err := json.MarshalIndent(entries, "", " ") - if err != nil { - return nil, sdkerrors.Wrap(sdkerrors.ErrJSONMarshal, err.Error()) - } - return bz, nil -} -*/ - func queryContractAddress(ctx sdk.Context, label string, keeper Keeper) (sdk.AccAddress, error) { res := keeper.GetContractAddress(ctx, label) if res == nil { @@ -317,5 +294,10 @@ func queryContractHash(ctx sdk.Context, address sdk.AccAddress, keeper Keeper) ( return nil, nil } - return keeper.GetCodeInfo(ctx, res.CodeID).CodeHash, nil + codeInfo, err := keeper.GetCodeInfo(ctx, res.CodeID) + if err != nil { + return nil, nil + } + + return codeInfo.CodeHash, nil } diff --git a/x/compute/internal/keeper/querier_test.go b/x/compute/internal/keeper/querier_test.go index e92d834a3..aaddbd5b0 100644 --- a/x/compute/internal/keeper/querier_test.go +++ b/x/compute/internal/keeper/querier_test.go @@ -48,7 +48,10 @@ func TestQueryContractLabel(t *testing.T) { initMsgBz, err := json.Marshal(initMsg) require.NoError(t, err) - hash := keeper.GetCodeInfo(ctx, contractID).CodeHash + codeInfo, err := keeper.GetCodeInfo(ctx, contractID) + require.NoError(t, err) + + hash := codeInfo.CodeHash msg := types.SecretMsg{ CodeHash: []byte(hex.EncodeToString(hash)), @@ -149,7 +152,10 @@ func TestQueryContractState(t *testing.T) { initMsgBz, err := json.Marshal(initMsg) require.NoError(t, err) - key := keeper.GetCodeInfo(ctx, contractID).CodeHash + codeInfo, err := keeper.GetCodeInfo(ctx, contractID) + require.NoError(t, err) + + key := codeInfo.CodeHash keyStr := hex.EncodeToString(key) msg := types.SecretMsg{ @@ -290,7 +296,10 @@ func TestListContractByCodeOrdering(t *testing.T) { initMsgBz, err := json.Marshal(initMsg) require.NoError(t, err) - key := keeper.GetCodeInfo(ctx, codeID).CodeHash + codeInfo, err := keeper.GetCodeInfo(ctx, codeID) + require.NoError(t, err) + + key := codeInfo.CodeHash keyStr := hex.EncodeToString(key) msg := types.SecretMsg{ diff --git a/x/compute/internal/keeper/secret_contracts_test.go b/x/compute/internal/keeper/secret_contracts_test.go index 03caffbf0..50f833e46 100644 --- a/x/compute/internal/keeper/secret_contracts_test.go +++ b/x/compute/internal/keeper/secret_contracts_test.go @@ -56,7 +56,10 @@ func testEncrypt(t *testing.T, keeper Keeper, ctx sdk.Context, contractAddress s var err error if codeId != 0 { - hash = keeper.GetCodeInfo(ctx, codeId).CodeHash + codeInfo, err := keeper.GetCodeInfo(ctx, codeId) + require.NoError(t, err) + + hash = codeInfo.CodeHash } else { hash, err = keeper.GetContractHash(ctx, contractAddress) require.NoError(t, err) @@ -85,7 +88,10 @@ func uploadCode(ctx sdk.Context, t *testing.T, keeper Keeper, wasmPath string, w codeID, err := keeper.Create(ctx, walletA, wasmCode, "", "") require.NoError(t, err) - codeHash := hex.EncodeToString(keeper.GetCodeInfo(ctx, codeID).CodeHash) + codeInfo, err := keeper.GetCodeInfo(ctx, codeID) + require.NoError(t, err) + + codeHash := hex.EncodeToString(codeInfo.CodeHash) return codeID, codeHash } @@ -547,7 +553,10 @@ func initHelperImpl( codeID uint64, creator sdk.AccAddress, creatorPrivKey crypto.PrivKey, initMsg string, isErrorEncrypted bool, isV1Contract bool, gas uint64, wasmCallCount int64, sentFunds sdk.Coins, shouldSkipAttributes ...bool, ) ([]byte, sdk.Context, sdk.AccAddress, []ContractEvent, cosmwasm.StdError) { - hashStr := hex.EncodeToString(keeper.GetCodeInfo(ctx, codeID).CodeHash) + codeInfo, err := keeper.GetCodeInfo(ctx, codeID) + require.NoError(t, err) + + hashStr := hex.EncodeToString(codeInfo.CodeHash) msg := types.SecretMsg{ CodeHash: []byte(hashStr), @@ -3700,7 +3709,6 @@ func TestSendFunds(t *testing.T) { originType, destinationType := callTypes[0], callTypes[1] t.Run(originType+"->"+destinationType, func(t *testing.T) { - alreadyTested := make(map[string]bool) alreadyTested["useruser->useruser"] = true // we are only testing contracts here for _, currentSubjects := range multisetsFrom(testContracts, 2) { @@ -3945,7 +3953,9 @@ func TestWasmMsgStructure(t *testing.T) { require.NoError(t, err) toCodeID, err := keeper.Create(ctx, walletA, wasmCode, "", "") - toCodeHash := hex.EncodeToString(keeper.GetCodeInfo(ctx, toCodeID).CodeHash) + codeInfo, err := keeper.GetCodeInfo(ctx, toCodeID) + require.NoError(t, err) + toCodeHash := hex.EncodeToString(codeInfo.CodeHash) require.NoError(t, err) toAddress := sdk.AccAddress{} @@ -4114,7 +4124,9 @@ func TestV1InitV010ContractWithReply(t *testing.T) { v010CodeID, err := keeper.Create(ctx, walletA, wasmCode, "", "") require.NoError(t, err) - v010CodeHash := hex.EncodeToString(keeper.GetCodeInfo(ctx, v010CodeID).CodeHash) + codeInfo, err := keeper.GetCodeInfo(ctx, v010CodeID) + require.NoError(t, err) + v010CodeHash := hex.EncodeToString(codeInfo.CodeHash) _, _, contractAddress, _, _ := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"counter":{"counter":10, "expires":100}}`, true, true, defaultGasForTests) msg := fmt.Sprintf(`{"init_v10":{"counter":80, "code_id":%d, "code_hash":"%s"}}`, v010CodeID, v010CodeHash) @@ -4143,7 +4155,9 @@ func TestV1ExecuteV010ContractWithReply(t *testing.T) { v010CodeID, err := keeper.Create(ctx, walletA, wasmCode, "", "") require.NoError(t, err) - v010CodeHash := hex.EncodeToString(keeper.GetCodeInfo(ctx, v010CodeID).CodeHash) + codeInfo, err := keeper.GetCodeInfo(ctx, v010CodeID) + require.NoError(t, err) + v010CodeHash := hex.EncodeToString(codeInfo.CodeHash) _, _, contractAddress, _, err := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, true, defaultGasForTests) require.Empty(t, err) @@ -4167,7 +4181,9 @@ func TestV1InitV010ContractNoReply(t *testing.T) { v010CodeID, err := keeper.Create(ctx, walletA, wasmCode, "", "") require.NoError(t, err) - v010CodeHash := hex.EncodeToString(keeper.GetCodeInfo(ctx, v010CodeID).CodeHash) + codeInfo, err := keeper.GetCodeInfo(ctx, v010CodeID) + require.NoError(t, err) + v010CodeHash := hex.EncodeToString(codeInfo.CodeHash) _, _, contractAddress, _, _ := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"counter":{"counter":10, "expires":100}}`, true, true, defaultGasForTests) msg := fmt.Sprintf(`{"init_v10_no_reply":{"counter":180, "code_id":%d, "code_hash":"%s"}}`, v010CodeID, v010CodeHash) @@ -4196,7 +4212,9 @@ func TestV1ExecuteV010ContractNoReply(t *testing.T) { v010CodeID, err := keeper.Create(ctx, walletA, wasmCode, "", "") require.NoError(t, err) - v010CodeHash := hex.EncodeToString(keeper.GetCodeInfo(ctx, v010CodeID).CodeHash) + codeInfo, err := keeper.GetCodeInfo(ctx, v010CodeID) + require.NoError(t, err) + v010CodeHash := hex.EncodeToString(codeInfo.CodeHash) _, _, contractAddress, _, err := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, true, defaultGasForTests) require.Empty(t, err) @@ -4225,7 +4243,9 @@ func TestV1QueryV010Contract(t *testing.T) { v010CodeID, err := keeper.Create(ctx, walletA, wasmCode, "", "") require.NoError(t, err) - v010CodeHash := hex.EncodeToString(keeper.GetCodeInfo(ctx, v010CodeID).CodeHash) + codeInfo, err := keeper.GetCodeInfo(ctx, v010CodeID) + require.NoError(t, err) + v010CodeHash := hex.EncodeToString(codeInfo.CodeHash) _, _, contractAddress, _, err := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, true, defaultGasForTests) require.Empty(t, err) @@ -4249,7 +4269,9 @@ func TestV1InitV010ContractWithReplyWithError(t *testing.T) { v010CodeID, err := keeper.Create(ctx, walletA, wasmCode, "", "") require.NoError(t, err) - v010CodeHash := hex.EncodeToString(keeper.GetCodeInfo(ctx, v010CodeID).CodeHash) + codeInfo, err := keeper.GetCodeInfo(ctx, v010CodeID) + require.NoError(t, err) + v010CodeHash := hex.EncodeToString(codeInfo.CodeHash) _, _, contractAddress, _, _ := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"counter":{"counter":10, "expires":100}}`, true, true, defaultGasForTests) msg := fmt.Sprintf(`{"init_v10_with_error":{"code_id":%d, "code_hash":"%s"}}`, v010CodeID, v010CodeHash) @@ -4268,7 +4290,9 @@ func TestV1ExecuteV010ContractWithReplyWithError(t *testing.T) { v010CodeID, err := keeper.Create(ctx, walletA, wasmCode, "", "") require.NoError(t, err) - v010CodeHash := hex.EncodeToString(keeper.GetCodeInfo(ctx, v010CodeID).CodeHash) + codeInfo, err := keeper.GetCodeInfo(ctx, v010CodeID) + require.NoError(t, err) + v010CodeHash := hex.EncodeToString(codeInfo.CodeHash) _, _, contractAddress, _, err := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, true, defaultGasForTests) require.Empty(t, err) @@ -4291,7 +4315,9 @@ func TestV1InitV010ContractNoReplyWithError(t *testing.T) { v010CodeID, err := keeper.Create(ctx, walletA, wasmCode, "", "") require.NoError(t, err) - v010CodeHash := hex.EncodeToString(keeper.GetCodeInfo(ctx, v010CodeID).CodeHash) + codeInfo, err := keeper.GetCodeInfo(ctx, v010CodeID) + require.NoError(t, err) + v010CodeHash := hex.EncodeToString(codeInfo.CodeHash) _, _, contractAddress, _, _ := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"counter":{"counter":10, "expires":100}}`, true, true, defaultGasForTests) msg := fmt.Sprintf(`{"init_v10_no_reply_with_error":{"code_id":%d, "code_hash":"%s"}}`, v010CodeID, v010CodeHash) @@ -4311,7 +4337,9 @@ func TestV1ExecuteV010ContractNoReplyWithError(t *testing.T) { v010CodeID, err := keeper.Create(ctx, walletA, wasmCode, "", "") require.NoError(t, err) - v010CodeHash := hex.EncodeToString(keeper.GetCodeInfo(ctx, v010CodeID).CodeHash) + codeInfo, err := keeper.GetCodeInfo(ctx, v010CodeID) + require.NoError(t, err) + v010CodeHash := hex.EncodeToString(codeInfo.CodeHash) _, _, contractAddress, _, err := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, true, defaultGasForTests) require.Empty(t, err) @@ -4335,7 +4363,9 @@ func TestV1QueryV010ContractWithError(t *testing.T) { v010CodeID, err := keeper.Create(ctx, walletA, wasmCode, "", "") require.NoError(t, err) - v010CodeHash := hex.EncodeToString(keeper.GetCodeInfo(ctx, v010CodeID).CodeHash) + codeInfo, err := keeper.GetCodeInfo(ctx, v010CodeID) + require.NoError(t, err) + v010CodeHash := hex.EncodeToString(codeInfo.CodeHash) _, _, contractAddress, _, err := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, true, defaultGasForTests) require.Empty(t, err) @@ -5873,7 +5903,9 @@ func TestV1SendsLogsMixedWithV010WithoutReply(t *testing.T) { v010CodeID, err := keeper.Create(ctx, walletA, wasmCode, "", "") require.NoError(t, err) - v010CodeHash := hex.EncodeToString(keeper.GetCodeInfo(ctx, v010CodeID).CodeHash) + codeInfo, err := keeper.GetCodeInfo(ctx, v010CodeID) + require.NoError(t, err) + v010CodeHash := hex.EncodeToString(codeInfo.CodeHash) _, _, v010ContractAddress, _, err := initHelper(t, keeper, ctx, v010CodeID, walletA, privKeyA, `{"nop":{}}`, true, false, defaultGasForTests) require.Empty(t, err) @@ -5933,7 +5965,9 @@ func TestV1SendsLogsMixedWithV010WithReply(t *testing.T) { v010CodeID, err := keeper.Create(ctx, walletA, wasmCode, "", "") require.NoError(t, err) - v010CodeHash := hex.EncodeToString(keeper.GetCodeInfo(ctx, v010CodeID).CodeHash) + codeInfo, err := keeper.GetCodeInfo(ctx, v010CodeID) + require.NoError(t, err) + v010CodeHash := hex.EncodeToString(codeInfo.CodeHash) _, _, v010ContractAddress, _, err := initHelper(t, keeper, ctx, v010CodeID, walletA, privKeyA, `{"nop":{}}`, true, false, defaultGasForTests) require.Empty(t, err) From 2adda1d077d2f06ad531f8bde0765410420460c1 Mon Sep 17 00:00:00 2001 From: Assaf Morami Date: Tue, 23 Aug 2022 10:20:55 +0300 Subject: [PATCH 44/93] Remove unused code --- x/compute/internal/keeper/keeper.go | 24 ------------------------ 1 file changed, 24 deletions(-) diff --git a/x/compute/internal/keeper/keeper.go b/x/compute/internal/keeper/keeper.go index cebc195ea..ad03c3c10 100644 --- a/x/compute/internal/keeper/keeper.go +++ b/x/compute/internal/keeper/keeper.go @@ -775,30 +775,6 @@ func (k Keeper) importContractState(ctx sdk.Context, contractAddress sdk.AccAddr return nil } -func (k Keeper) fixContractState(ctx sdk.Context, contractAddress sdk.AccAddress, models []types.Model) error { - prefixStoreKey := types.GetContractStorePrefixKey(contractAddress) - prefixStore := prefix.NewStore(ctx.KVStore(k.storeKey), prefixStoreKey) - for _, model := range models { - if model.Value == nil { - model.Value = []byte{} - } - - if !prefixStore.Has(model.Key) { - prefixStore.Set(model.Key, model.Value) - continue - } - - existingValue := prefixStore.Get(model.Key) - if bytes.Equal(existingValue, model.Value) { - continue - } else { - prefixStore.Set(model.Key, model.Value) - } - - } - return nil -} - func (k Keeper) GetCodeInfo(ctx sdk.Context, codeID uint64) *types.CodeInfo { store := ctx.KVStore(k.storeKey) var codeInfo types.CodeInfo From dad0b26421a0d0ef7b9d1e3b10b00c7a32a8e5e7 Mon Sep 17 00:00:00 2001 From: Assaf Morami Date: Tue, 23 Aug 2022 10:22:12 +0300 Subject: [PATCH 45/93] LocalSecret: expose LOG_LEVEL as env var --- deployment/docker/devimage/bootstrap_init_no_stop.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/deployment/docker/devimage/bootstrap_init_no_stop.sh b/deployment/docker/devimage/bootstrap_init_no_stop.sh index 486a1d4ff..318da5e3a 100755 --- a/deployment/docker/devimage/bootstrap_init_no_stop.sh +++ b/deployment/docker/devimage/bootstrap_init_no_stop.sh @@ -8,6 +8,7 @@ then rm -rf /opt/secret/.sgx_secrets/* chain_id=${CHAINID:-secretdev-1} + LOG_LEVEL=${LOG_LEVEL:-INFO} mkdir -p ./.sgx_secrets secretd config chain-id "$chain_id" @@ -67,5 +68,5 @@ setsid node faucet_server.js & # Setup secretcli cp $(which secretd) $(dirname $(which secretd))/secretcli -source /opt/sgxsdk/environment && RUST_BACKTRACE=1 LOG_LEVEL=INFO secretd start --rpc.laddr tcp://0.0.0.0:26657 --bootstrap +source /opt/sgxsdk/environment && RUST_BACKTRACE=1 LOG_LEVEL="$LOG_LEVEL" secretd start --rpc.laddr tcp://0.0.0.0:26657 --bootstrap From ff4250a5738e91e7ecc630ad961cdca4967405f9 Mon Sep 17 00:00:00 2001 From: Assaf Morami Date: Tue, 23 Aug 2022 12:12:53 +0300 Subject: [PATCH 46/93] StargateQuery test --- .vscode/settings.json | 1 + integration-tests/Makefile | 1 + integration-tests/contract-v0.10/Cargo.lock | 41 +- integration-tests/contract-v0.10/Cargo.toml | 5 +- integration-tests/contract-v0.10/Makefile | 20 +- integration-tests/contract-v0.10/build.rs | 3 - .../contract-v0.10/rust-toolchain | 1 + .../contract-v0.10/src/contract.rs | 1826 +---------------- integration-tests/contract-v1/rust-toolchain | 2 +- integration-tests/contract-v1/src/contract.rs | 23 +- integration-tests/contract-v1/src/msg.rs | 3 +- integration-tests/test.ts | 129 +- 12 files changed, 194 insertions(+), 1861 deletions(-) delete mode 100644 integration-tests/contract-v0.10/build.rs create mode 100644 integration-tests/contract-v0.10/rust-toolchain diff --git a/.vscode/settings.json b/.vscode/settings.json index 576d88a73..d45448e2b 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -5,6 +5,7 @@ "x/compute/internal/keeper/testdata/v1-sanity-contract/Cargo.toml", "x/compute/internal/keeper/testdata/test-contract/Cargo.toml", "integration-tests/contract-v1/Cargo.toml", + "integration-tests/contract-v0.10/Cargo.toml", "go-cosmwasm/Cargo.toml" ], "rust-analyzer.diagnostics.experimental.enable": true, diff --git a/integration-tests/Makefile b/integration-tests/Makefile index c774040ab..0774137ce 100644 --- a/integration-tests/Makefile +++ b/integration-tests/Makefile @@ -1,5 +1,6 @@ all: $(MAKE) -C contract-v1 + $(MAKE) -C contract-v0.10 run-localsecret: docker run --rm -it -p 9091:9091 --name localsecret ghcr.io/scrtlabs/localsecret:"$(TAG)" \ No newline at end of file diff --git a/integration-tests/contract-v0.10/Cargo.lock b/integration-tests/contract-v0.10/Cargo.lock index 7400d17f0..ff55b2b42 100644 --- a/integration-tests/contract-v0.10/Cargo.lock +++ b/integration-tests/contract-v0.10/Cargo.lock @@ -50,6 +50,17 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +[[package]] +name = "contract-v010" +version = "0.0.1" +dependencies = [ + "schemars", + "secret-cosmwasm-std", + "secret-cosmwasm-storage", + "serde", + "serde-json-wasm", +] + [[package]] name = "doc-comment" version = "0.3.3" @@ -151,24 +162,6 @@ dependencies = [ "syn", ] -[[package]] -name = "secp256k1" -version = "0.20.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97d03ceae636d0fed5bae6a7f4f664354c5f4fcedf6eef053fef17e49f837d0a" -dependencies = [ - "secp256k1-sys", -] - -[[package]] -name = "secp256k1-sys" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "957da2573cde917463ece3570eab4a0b3f19de6f1646cde62e6fd3868f566036" -dependencies = [ - "cc", -] - [[package]] name = "secret-cosmwasm-std" version = "0.10.1" @@ -276,18 +269,6 @@ dependencies = [ "unicode-ident", ] -[[package]] -name = "test-contract" -version = "0.0.1" -dependencies = [ - "schemars", - "secp256k1", - "secret-cosmwasm-std", - "secret-cosmwasm-storage", - "serde", - "serde-json-wasm", -] - [[package]] name = "unicode-ident" version = "1.0.1" diff --git a/integration-tests/contract-v0.10/Cargo.toml b/integration-tests/contract-v0.10/Cargo.toml index 36251d8b3..d74eb335b 100644 --- a/integration-tests/contract-v0.10/Cargo.toml +++ b/integration-tests/contract-v0.10/Cargo.toml @@ -1,9 +1,9 @@ [package] -name = "test-contract" +name = "contract-v010" version = "0.0.1" authors = ["Enigma "] edition = "2018" -description = "A Test contract intended to use in system tests for the Secret Netowrk" +description = "A test contract intended to use in integration tests for the Secret Netowrk" license = "MIT" exclude = [ # Those files are cosmwasm-opt artifacts. You might want to commit them for convenience but they should not be part of the source code publication. @@ -40,4 +40,3 @@ serde = { version = "1.0.114", default-features = false, features = [ "alloc" ] } serde-json-wasm = "0.2.1" -secp256k1 = "0.20.3" diff --git a/integration-tests/contract-v0.10/Makefile b/integration-tests/contract-v0.10/Makefile index cbabda449..a253e86d4 100644 --- a/integration-tests/contract-v0.10/Makefile +++ b/integration-tests/contract-v0.10/Makefile @@ -1,25 +1,7 @@ all: src/contract.rs src/lib.rs Cargo.toml Cargo.lock rustup target add wasm32-unknown-unknown - RUSTFLAGS='-C link-arg=-s' cargo build --release --target wasm32-unknown-unknown - cp ./target/wasm32-unknown-unknown/release/test_contract.wasm ./contract.wasm - - # Compile with floats - RUSTFLAGS='-C link-arg=-s' cargo build --release --target wasm32-unknown-unknown --features with_floats - cp ./target/wasm32-unknown-unknown/release/test_contract.wasm ./contract_with_floats.wasm - - # Create a wasm with more than 192 memory pages (fails in init, handle & query, this is our limit) - # https://github.com/enigmampc/SecretNetwork/blob/9eef8591b2c04c586ceee12f424b92062598123e/cosmwasm/packages/wasmi-runtime/src/wasm/memory.rs#L39 - wasm2wat ./contract.wasm | perl -pe 's/\(memory \(;0;\) 17\)/(memory (;0;) 193)/' > /tmp/too-high-initial-memory.wat - wat2wasm /tmp/too-high-initial-memory.wat -o ./too-high-initial-memory.wasm - - # Create a wasm with more than 512 memory pages (fails in store, this is cosmwasm's limit) - # https://github.com/enigmampc/SecretNetwork/blob/9eef8591b2c04c586ceee12f424b92062598123e/cosmwasm/packages/sgx-vm/src/compatability.rs#L36 - wasm2wat ./contract.wasm | perl -pe 's/\(memory \(;0;\) 17\)/(memory (;0;) 513)/' > /tmp/static-too-high-initial-memory.wat - wat2wasm /tmp/static-too-high-initial-memory.wat -o ./static-too-high-initial-memory.wasm - -setup: - apt-get install wabt + cp ./target/wasm32-unknown-unknown/release/contract_v010.wasm ./contract.wasm clean: cargo clean diff --git a/integration-tests/contract-v0.10/build.rs b/integration-tests/contract-v0.10/build.rs deleted file mode 100644 index 88fb06f33..000000000 --- a/integration-tests/contract-v0.10/build.rs +++ /dev/null @@ -1,3 +0,0 @@ -fn main() { - println!("cargo:rerun-if-changed=./src/contract.rs"); -} diff --git a/integration-tests/contract-v0.10/rust-toolchain b/integration-tests/contract-v0.10/rust-toolchain new file mode 100644 index 000000000..6cb4a6feb --- /dev/null +++ b/integration-tests/contract-v0.10/rust-toolchain @@ -0,0 +1 @@ +1.63 \ No newline at end of file diff --git a/integration-tests/contract-v0.10/src/contract.rs b/integration-tests/contract-v0.10/src/contract.rs index 3419e4d16..1abce32af 100644 --- a/integration-tests/contract-v0.10/src/contract.rs +++ b/integration-tests/contract-v0.10/src/contract.rs @@ -1,1829 +1,111 @@ -use cosmwasm_storage::{PrefixedStorage, ReadonlySingleton, Singleton}; - use cosmwasm_std::{ - log, plaintext_log, to_binary, Api, BankMsg, Binary, Coin, CosmosMsg, Empty, Env, Extern, - HandleResponse, HandleResult, HumanAddr, InitResponse, InitResult, Querier, QueryRequest, - QueryResult, ReadonlyStorage, StdError, StdResult, Storage, Uint128, WasmMsg, WasmQuery, + to_binary, Api, BalanceResponse, BankQuery, Binary, Coin, Env, Extern, HandleResponse, + HandleResult, HumanAddr, InitResponse, InitResult, Querier, QueryRequest, QueryResult, Storage, + VoteOption, }; -use secp256k1::Secp256k1; /////////////////////////////// Messages /////////////////////////////// -use core::time; -use mem::MaybeUninit; use schemars::JsonSchema; use serde::{Deserialize, Serialize}; -use std::{mem, thread}; - -//// consts - -const REALLY_LONG: &[u8] = b"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"; #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] #[serde(rename_all = "snake_case")] -pub enum InitMsg { - WasmMsg { - ty: String, - }, +pub enum Msg { Nop {}, - Callback { - contract_addr: HumanAddr, - code_hash: String, - }, - CallbackContractError { - contract_addr: HumanAddr, - code_hash: String, - }, - ContractError { - error_type: String, - }, - NoLogs {}, - CallbackToInit { - code_id: u64, - code_hash: String, - }, - CallbackBadParams { - contract_addr: HumanAddr, - code_hash: String, - }, - Panic {}, - SendExternalQueryDepthCounter { - to: HumanAddr, - depth: u8, - code_hash: String, - }, - SendExternalQueryRecursionLimit { - to: HumanAddr, - depth: u8, - code_hash: String, - }, - CallToInit { - code_id: u64, - code_hash: String, - label: String, - msg: String, - }, - CallToExec { - addr: HumanAddr, - code_hash: String, - msg: String, - }, - CallToQuery { - addr: HumanAddr, - code_hash: String, - msg: String, - }, - InitFromV1 { - counter: u64, - }, - Counter { - counter: u64, - }, - AddAttributes {}, - AddAttributesWithSubmessage {}, - AddPlaintextAttributes {}, - AddPlaintextAttributesWithSubmessage {}, - AddMixedEventsAndAttributesFromV1 { - addr: HumanAddr, - code_hash: String, - }, BankMsgSend { + to_address: String, amount: Vec, - to: HumanAddr, - from: Option, - }, - CosmosMsgCustom {}, -} - -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] -#[serde(rename_all = "snake_case")] -pub enum HandleMsg { - WasmMsg { - ty: String, - }, - A { - contract_addr: HumanAddr, - code_hash: String, - x: u8, - y: u8, - }, - B { - contract_addr: HumanAddr, - code_hash: String, - x: u8, - y: u8, - }, - C { - x: u8, - y: u8, - }, - UnicodeData {}, - EmptyLogKeyValue {}, - EmptyData {}, - NoData {}, - ContractError { - error_type: String, - }, - NoLogs {}, - CallbackToInit { - code_id: u64, - code_hash: String, - }, - CallbackContractError { - contract_addr: HumanAddr, - code_hash: String, - }, - CallbackBadParams { - contract_addr: HumanAddr, - code_hash: String, - }, - SetState { - key: String, - value: String, - }, - GetState { - key: String, - }, - RemoveState { - key: String, - }, - TestCanonicalizeAddressErrors {}, - Panic {}, - AllocateOnHeap { - bytes: u32, - }, - PassNullPointerToImportsShouldThrow { - pass_type: String, - }, - SendExternalQuery { - to: HumanAddr, - code_hash: String, }, - SendExternalQueryPanic { - to: HumanAddr, - code_hash: String, + StargateMsg { + type_url: String, + value: Binary, }, - SendExternalQueryError { - to: HumanAddr, - code_hash: String, + StakingMsgDelegate { + validator: String, + amount: Coin, }, - SendExternalQueryBadAbi { - to: HumanAddr, - code_hash: String, + StakingMsgUndelegate { + validator: String, + amount: Coin, }, - SendExternalQueryBadAbiReceiver { - to: HumanAddr, - code_hash: String, + StakingMsgRedelegate { + src_validator: String, + dst_validator: String, + amount: Coin, }, - LogMsgSender {}, - CallbackToLogMsgSender { - to: HumanAddr, - code_hash: String, + GovVote { + proposal_id: u64, + vote: VoteOption, }, - DepositToContract {}, - SendFunds { - amount: u32, - denom: String, - to: HumanAddr, - from: HumanAddr, + DistributionMsgSetWithdrawAddress { + address: String, }, - BankMsgSend { - amount: Vec, - to: HumanAddr, - from: Option, - }, - SendFundsToInitCallback { - amount: u32, - denom: String, - code_id: u64, - code_hash: String, + DistributionMsgWithdrawDelegatorReward { + validator: String, }, - SendFundsToExecCallback { - amount: u32, - denom: String, - to: HumanAddr, - code_hash: String, - }, - Sleep { - ms: u64, - }, - SendExternalQueryDepthCounter { - to: HumanAddr, - code_hash: String, - depth: u8, - }, - SendExternalQueryRecursionLimit { - to: HumanAddr, - code_hash: String, - depth: u8, - }, - WithFloats { - x: u8, - y: u8, - }, - CallToInit { + + WasmMsgInstantiate { code_id: u64, code_hash: String, + msg: Binary, + funds: Vec, label: String, - msg: String, }, - CallToExec { - addr: HumanAddr, + WasmMsgExecute { + contract_addr: String, code_hash: String, - msg: String, - }, - CallToQuery { - addr: HumanAddr, - code_hash: String, - msg: String, - }, - StoreReallyLongKey {}, - StoreReallyShortKey {}, - StoreReallyLongValue {}, - Secp256k1Verify { - pubkey: Binary, - sig: Binary, - msg_hash: Binary, - iterations: u32, - }, - Secp256k1VerifyFromCrate { - pubkey: Binary, - sig: Binary, - msg_hash: Binary, - iterations: u32, - }, - Ed25519Verify { - pubkey: Binary, - sig: Binary, - msg: Binary, - iterations: u32, - }, - Ed25519BatchVerify { - pubkeys: Vec, - sigs: Vec, - msgs: Vec, - iterations: u32, - }, - Secp256k1RecoverPubkey { - msg_hash: Binary, - sig: Binary, - recovery_param: u8, - iterations: u32, - }, - Secp256k1Sign { - msg: Binary, - privkey: Binary, - iterations: u32, - }, - Ed25519Sign { msg: Binary, - privkey: Binary, - iterations: u32, + funds: Vec, }, - ExecuteFromV1 { - counter: u64, - }, - IncrementFromV1 { - addition: u64, - }, - AddAttributes {}, - AddAttributesWithSubmessage {}, - AddMoreAttributes {}, - AddPlaintextAttributes {}, - AddPlaintextAttributesWithSubmessage {}, - AddMorePlaintextAttributes {}, - AddMixedEventsAndAttributesFromV1 { - addr: HumanAddr, - code_hash: String, - }, - CosmosMsgCustom {}, - InitNewContract {}, } #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] #[serde(rename_all = "snake_case")] pub enum QueryMsg { - ContractError { - error_type: String, - }, - Panic {}, - ReceiveExternalQuery { - num: u8, - }, - SendExternalQueryInfiniteLoop { - to: HumanAddr, - code_hash: String, - }, - WriteToStorage {}, - RemoveFromStorage {}, - SendExternalQueryDepthCounter { - to: HumanAddr, - depth: u8, - code_hash: String, - }, - SendExternalQueryRecursionLimit { - to: HumanAddr, - depth: u8, - code_hash: String, - }, - CallToQuery { - addr: HumanAddr, - code_hash: String, - msg: String, - }, - GetCountFromV1 {}, - Get {}, - GetContractVersion {}, -} - -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] -#[serde(rename_all = "snake_case")] -pub enum QueryRes { - Get { count: u64 }, + BankBalance { address: HumanAddr, denom: String }, } /////////////////////////////// Init /////////////////////////////// pub fn init( - deps: &mut Extern, - env: Env, - msg: InitMsg, -) -> InitResult { - match msg { - InitMsg::WasmMsg { ty } => { - if ty == "success" { - return Ok(InitResponse::default()); - } else if ty == "err" { - return Err(StdError::generic_err("custom error")); - } else if ty == "panic" { - panic!() - } - - return Err(StdError::generic_err("custom error")); - } - InitMsg::Nop {} => Ok(InitResponse { - messages: vec![], - log: vec![log("init", "🌈")], - }), - InitMsg::Callback { - contract_addr, - code_hash, - } => Ok(init_with_callback(deps, env, contract_addr, code_hash)), - InitMsg::ContractError { error_type } => Err(map_string_to_error(error_type)), - InitMsg::NoLogs {} => Ok(InitResponse::default()), - InitMsg::CallbackToInit { code_id, code_hash } => { - Ok(init_callback_to_init(deps, env, code_id, code_hash)) - } - InitMsg::CallbackContractError { - contract_addr, - code_hash, - } => Ok(init_with_callback_contract_error(contract_addr, code_hash)), - InitMsg::CallbackBadParams { - contract_addr, - code_hash, - } => Ok(init_callback_bad_params(contract_addr, code_hash)), - InitMsg::Panic {} => panic!("panic in init"), - InitMsg::SendExternalQueryDepthCounter { - to, - depth, - code_hash, - } => Ok(InitResponse { - messages: vec![], - log: vec![log( - format!( - "{}", - send_external_query_depth_counter(deps, to, depth, code_hash) - ), - "", - )], - }), - InitMsg::SendExternalQueryRecursionLimit { - to, - depth, - code_hash, - } => Ok(InitResponse { - messages: vec![], - log: vec![log( - "message", - send_external_query_recursion_limit(deps, to, depth, code_hash)?, - )], - }), - InitMsg::CallToInit { - code_id, - code_hash, - label, - msg, - } => Ok(InitResponse { - messages: vec![CosmosMsg::Wasm(WasmMsg::Instantiate { - code_id, - callback_code_hash: code_hash, - msg: Binary(msg.as_bytes().into()), - send: vec![], - label: label, - })], - log: vec![log("a", "a")], - }), - InitMsg::CallToExec { - addr, - code_hash, - msg, - } => Ok(InitResponse { - messages: vec![CosmosMsg::Wasm(WasmMsg::Execute { - contract_addr: addr, - callback_code_hash: code_hash, - msg: Binary(msg.as_bytes().into()), - send: vec![], - })], - log: vec![log("b", "b")], - }), - InitMsg::CallToQuery { - addr, - code_hash, - msg, - } => { - let answer: u32 = deps - .querier - .query(&QueryRequest::Wasm(WasmQuery::Smart { - contract_addr: addr, - callback_code_hash: code_hash, - msg: Binary::from(msg.as_bytes().to_vec()), - })) - .map_err(|err| { - StdError::generic_err(format!("Got an error from query: {:?}", err)) - })?; - - Ok(InitResponse { - messages: vec![], - log: vec![log("c", format!("{}", answer))], - }) - } - InitMsg::InitFromV1 { counter } => { - count(&mut deps.storage).save(&counter)?; - - Ok(InitResponse { - messages: vec![], - log: vec![], - }) - } - InitMsg::Counter { counter } => { - count(&mut deps.storage).save(&counter)?; - - Ok(InitResponse { - messages: vec![], - log: vec![], - }) - } - InitMsg::AddAttributes {} => Ok(InitResponse { - messages: vec![], - log: vec![log("attr1", "🦄"), log("attr2", "🌈")], - }), - InitMsg::AddAttributesWithSubmessage {} => Ok(InitResponse { - messages: vec![CosmosMsg::Wasm(WasmMsg::Execute { - contract_addr: env.contract.address, - callback_code_hash: env.contract_code_hash, - msg: Binary::from(r#"{"add_more_attributes":{}}"#.as_bytes().to_vec()), - send: vec![], - })], - log: vec![log("attr1", "🦄"), log("attr2", "🌈")], - }), - InitMsg::AddPlaintextAttributes {} => Ok(InitResponse { - messages: vec![], - log: vec![plaintext_log("attr1", "🦄"), plaintext_log("attr2", "🌈")], - }), - InitMsg::AddPlaintextAttributesWithSubmessage {} => Ok(InitResponse { - messages: vec![CosmosMsg::Wasm(WasmMsg::Execute { - contract_addr: env.contract.address, - callback_code_hash: env.contract_code_hash, - msg: Binary::from(r#"{"add_more_plaintext_attributes":{}}"#.as_bytes().to_vec()), - send: vec![], - })], - log: vec![plaintext_log("attr1", "🦄"), plaintext_log("attr2", "🌈")], - }), - InitMsg::AddMixedEventsAndAttributesFromV1 { addr, code_hash } => Ok(InitResponse { - messages: vec![CosmosMsg::Wasm(WasmMsg::Execute { - contract_addr: addr, - callback_code_hash: code_hash, - msg: Binary::from( - r#"{"add_more_mixed_attributes_and_events":{}}"#.as_bytes().to_vec(), - ), - send: vec![], - })], - log: vec![plaintext_log("attr1", "🦄"), plaintext_log("attr2", "🌈")], - }), - InitMsg::BankMsgSend { - to, - amount: coins, - from, - } => Ok(InitResponse { - messages: vec![CosmosMsg::Bank(BankMsg::Send { - from_address: from.unwrap_or(env.contract.address), - to_address: to, - amount: coins, - })], - log: vec![], - }), - InitMsg::CosmosMsgCustom {} => Ok(InitResponse { - messages: vec![CosmosMsg::Custom(Empty {})], - log: vec![], - }), - } -} - -pub const COUNT_KEY: &[u8] = b"count"; - -pub fn count(storage: &mut S) -> Singleton { - Singleton::new(storage, COUNT_KEY) -} - -pub fn count_read(storage: &S) -> ReadonlySingleton { - ReadonlySingleton::new(storage, COUNT_KEY) -} - -fn map_string_to_error(error_type: String) -> StdError { - let as_str: &str = &error_type[..]; - match as_str { - "generic_err" => StdError::generic_err("la la 🤯"), - "invalid_base64" => StdError::invalid_base64("ra ra 🤯"), - "invalid_utf8" => StdError::invalid_utf8("ka ka 🤯"), - "not_found" => StdError::not_found("za za 🤯"), - "parse_err" => StdError::parse_err("na na 🤯", "pa pa 🤯"), - "serialize_err" => StdError::serialize_err("ba ba 🤯", "ga ga 🤯"), - "unauthorized" => StdError::unauthorized(), - "underflow" => StdError::underflow("minuend 🤯", "subtrahend 🤯"), - _ => StdError::generic_err("catch-all 🤯"), - } -} - -fn init_with_callback_contract_error(contract_addr: HumanAddr, code_hash: String) -> InitResponse { - InitResponse { - messages: vec![CosmosMsg::Wasm(WasmMsg::Execute { - contract_addr: contract_addr.clone(), - callback_code_hash: code_hash, - msg: Binary::from(r#"{"contract_error":{"error_type":"generic_err"}}"#.as_bytes()), - send: vec![], - })], - log: vec![log("init with a callback with contract error", "🤷‍♀️")], - } -} - -fn init_callback_bad_params(contract_addr: HumanAddr, code_hash: String) -> InitResponse { - InitResponse { - messages: vec![CosmosMsg::Wasm(WasmMsg::Execute { - contract_addr: contract_addr.clone(), - callback_code_hash: code_hash, - msg: Binary::from(r#"{"c":{"x":"banana","y":3}}"#.as_bytes().to_vec()), - send: vec![], - })], - log: vec![], - } -} - -fn init_with_callback( - _deps: &mut Extern, - _env: Env, - contract_addr: HumanAddr, - code_hash: String, -) -> InitResponse { - InitResponse { - messages: vec![CosmosMsg::Wasm(WasmMsg::Execute { - callback_code_hash: code_hash, - contract_addr: contract_addr.clone(), - msg: Binary::from("{\"c\":{\"x\":0,\"y\":13}}".as_bytes().to_vec()), - send: vec![], - })], - log: vec![log("init with a callback", "🦄")], - } -} - -pub fn init_callback_to_init( - _deps: &mut Extern, - _env: Env, - code_id: u64, - code_hash: String, -) -> InitResponse { - InitResponse { - messages: vec![CosmosMsg::Wasm(WasmMsg::Instantiate { - code_id, - msg: Binary::from("{\"nop\":{}}".as_bytes().to_vec()), - callback_code_hash: code_hash, - send: vec![], - label: String::from("fi"), - })], - log: vec![log("instantiating a new contract from init!", "🐙")], - } -} - -/////////////////////////////// Handle /////////////////////////////// - -pub fn handle( - deps: &mut Extern, - env: Env, - msg: HandleMsg, -) -> HandleResult { - match msg { - HandleMsg::WasmMsg { ty } => { - if ty == "success" { - return Ok(HandleResponse::default()); - } else if ty == "err" { - return Err(StdError::generic_err("custom error")); - } else if ty == "panic" { - panic!() - } - - return Err(StdError::generic_err("custom error")); - } - HandleMsg::A { - contract_addr, - code_hash, - x, - y, - } => Ok(a(deps, env, contract_addr, code_hash, x, y)), - HandleMsg::B { - contract_addr, - code_hash, - x, - y, - } => Ok(b(deps, env, contract_addr, code_hash, x, y)), - HandleMsg::C { x, y } => Ok(c(deps, env, x, y)), - HandleMsg::UnicodeData {} => Ok(unicode_data(deps, env)), - HandleMsg::EmptyLogKeyValue {} => Ok(empty_log_key_value(deps, env)), - HandleMsg::EmptyData {} => Ok(empty_data(deps, env)), - HandleMsg::NoData {} => Ok(no_data(deps, env)), - HandleMsg::ContractError { error_type } => Err(map_string_to_error(error_type)), - HandleMsg::NoLogs {} => Ok(HandleResponse::default()), - HandleMsg::CallbackToInit { code_id, code_hash } => { - Ok(exec_callback_to_init(deps, env, code_id, code_hash)) - } - HandleMsg::CallbackBadParams { - contract_addr, - code_hash, - } => Ok(exec_callback_bad_params(contract_addr, code_hash)), - HandleMsg::CallbackContractError { - contract_addr, - code_hash, - } => Ok(exec_with_callback_contract_error(contract_addr, code_hash)), - HandleMsg::SetState { key, value } => Ok(set_state(deps, key, value)), - HandleMsg::GetState { key } => Ok(get_state(deps, key)), - HandleMsg::RemoveState { key } => Ok(remove_state(deps, key)), - HandleMsg::TestCanonicalizeAddressErrors {} => test_canonicalize_address_errors(deps), - HandleMsg::Panic {} => panic!("panic in exec"), - HandleMsg::AllocateOnHeap { bytes } => Ok(allocate_on_heap(bytes as usize)), - HandleMsg::PassNullPointerToImportsShouldThrow { pass_type } => { - Ok(pass_null_pointer_to_imports_should_throw(deps, pass_type)) - } - HandleMsg::SendExternalQuery { to, code_hash } => Ok(HandleResponse { - messages: vec![], - log: vec![], - data: Some(vec![send_external_query(deps, to, code_hash)].into()), - }), - HandleMsg::SendExternalQueryDepthCounter { - to, - code_hash, - depth, - } => Ok(HandleResponse { - messages: vec![], - log: vec![], - data: Some( - vec![send_external_query_depth_counter( - deps, to, depth, code_hash, - )] - .into(), - ), - }), - HandleMsg::SendExternalQueryRecursionLimit { - to, - code_hash, - depth, - } => Ok(HandleResponse { - messages: vec![], - log: vec![], - data: Some(to_binary(&send_external_query_recursion_limit( - deps, to, depth, code_hash, - )?)?), - }), - HandleMsg::SendExternalQueryPanic { to, code_hash } => { - send_external_query_panic(deps, to, code_hash) - } - HandleMsg::SendExternalQueryError { to, code_hash } => { - send_external_query_stderror(deps, to, code_hash) - } - HandleMsg::SendExternalQueryBadAbi { to, code_hash } => { - send_external_query_bad_abi(deps, to, code_hash) - } - HandleMsg::SendExternalQueryBadAbiReceiver { to, code_hash } => { - send_external_query_bad_abi_receiver(deps, to, code_hash) - } - HandleMsg::LogMsgSender {} => Ok(HandleResponse { - messages: vec![], - log: vec![log("msg.sender", env.message.sender.to_string())], - data: None, - }), - HandleMsg::CallbackToLogMsgSender { to, code_hash } => Ok(HandleResponse { - messages: vec![CosmosMsg::Wasm(WasmMsg::Execute { - contract_addr: to.clone(), - callback_code_hash: code_hash, - msg: Binary::from(r#"{"log_msg_sender":{}}"#.as_bytes().to_vec()), - send: vec![], - })], - log: vec![log("hi", "hey")], - data: None, - }), - HandleMsg::DepositToContract {} => Ok(HandleResponse { - messages: vec![], - log: vec![], - data: Some(to_binary(&env.message.sent_funds).unwrap()), - }), - HandleMsg::SendFunds { - amount, - from, - to, - denom, - } => Ok(HandleResponse { - messages: vec![CosmosMsg::Bank(BankMsg::Send { - from_address: from, - to_address: to, - amount: vec![Coin { - amount: Uint128(amount as u128), - denom: denom, - }], - })], - log: vec![], - data: None, - }), - HandleMsg::BankMsgSend { to, amount, from } => Ok(HandleResponse { - messages: vec![CosmosMsg::Bank(BankMsg::Send { - from_address: from.unwrap_or(env.contract.address), - to_address: to, - amount, - })], - log: vec![], - data: None, - }), - HandleMsg::CosmosMsgCustom {} => Ok(HandleResponse { - messages: vec![CosmosMsg::Custom(Empty {})], - log: vec![], - data: None, - }), - HandleMsg::SendFundsToInitCallback { - amount, - denom, - code_id, - code_hash, - } => Ok(HandleResponse { - messages: vec![CosmosMsg::Wasm(WasmMsg::Instantiate { - msg: Binary("{\"nop\":{}}".as_bytes().to_vec()), - code_id: code_id, - callback_code_hash: code_hash, - label: String::from("yo"), - send: vec![Coin { - amount: Uint128(amount as u128), - denom: denom, - }], - })], - log: vec![], - data: None, - }), - HandleMsg::SendFundsToExecCallback { - amount, - denom, - to, - code_hash, - } => Ok(HandleResponse { - messages: vec![CosmosMsg::Wasm(WasmMsg::Execute { - msg: Binary("{\"no_data\":{}}".as_bytes().to_vec()), - contract_addr: to, - callback_code_hash: code_hash, - send: vec![Coin { - amount: Uint128(amount as u128), - denom: denom, - }], - })], - log: vec![], - data: None, - }), - HandleMsg::Sleep { ms } => { - thread::sleep(time::Duration::from_millis(ms)); - - Ok(HandleResponse { - messages: vec![], - log: vec![], - data: None, - }) - } - HandleMsg::WithFloats { x, y } => Ok(HandleResponse { - messages: vec![], - log: vec![], - data: Some(use_floats(x, y)), - }), - HandleMsg::CallToInit { - code_id, - code_hash, - label, - msg, - } => Ok(HandleResponse { - messages: vec![CosmosMsg::Wasm(WasmMsg::Instantiate { - code_id, - callback_code_hash: code_hash, - msg: Binary(msg.as_bytes().into()), - send: vec![], - label: label, - })], - log: vec![log("a", "a")], - data: None, - }), - HandleMsg::CallToExec { - addr, - code_hash, - msg, - } => Ok(HandleResponse { - messages: vec![CosmosMsg::Wasm(WasmMsg::Execute { - contract_addr: addr, - callback_code_hash: code_hash, - msg: Binary(msg.as_bytes().into()), - send: vec![], - })], - log: vec![log("b", "b")], - data: None, - }), - HandleMsg::CallToQuery { - addr, - code_hash, - msg, - } => { - let answer: u32 = deps - .querier - .query(&QueryRequest::Wasm(WasmQuery::Smart { - contract_addr: addr, - callback_code_hash: code_hash, - msg: Binary::from(msg.as_bytes().to_vec()), - })) - .map_err(|err| { - StdError::generic_err(format!("Got an error from query: {:?}", err)) - })?; - - Ok(HandleResponse { - messages: vec![], - log: vec![log("c", format!("{}", answer))], - data: None, - }) - } - HandleMsg::StoreReallyLongKey {} => { - let mut store = PrefixedStorage::new(b"my_prefix", &mut deps.storage); - store.set(REALLY_LONG, b"hello"); - Ok(HandleResponse::default()) - } - HandleMsg::StoreReallyShortKey {} => { - let mut store = PrefixedStorage::new(b"my_prefix", &mut deps.storage); - store.set(b"a", b"hello"); - Ok(HandleResponse::default()) - } - HandleMsg::StoreReallyLongValue {} => { - let mut store = PrefixedStorage::new(b"my_prefix", &mut deps.storage); - store.set(b"hello", REALLY_LONG); - Ok(HandleResponse::default()) - } - HandleMsg::Secp256k1Verify { - pubkey, - sig, - msg_hash, - iterations, - } => { - let mut res: HandleResult = Ok(HandleResponse { - messages: vec![], - log: vec![], - data: None, - }); - - // loop for benchmarking - for _ in 0..iterations { - res = match deps.api.secp256k1_verify( - msg_hash.as_slice(), - sig.as_slice(), - pubkey.as_slice(), - ) { - Ok(result) => Ok(HandleResponse { - messages: vec![], - log: vec![log("result", format!("{}", result))], - data: None, - }), - Err(err) => Err(StdError::generic_err(format!("{:?}", err))), - }; - } - - return res; - } - HandleMsg::Secp256k1VerifyFromCrate { - pubkey, - sig, - msg_hash, - iterations, - } => { - let mut res: HandleResult = Ok(HandleResponse { - messages: vec![], - log: vec![], - data: None, - }); - - // loop for benchmarking - for _ in 0..iterations { - let secp256k1_verifier = Secp256k1::verification_only(); - - let secp256k1_signature = - secp256k1::Signature::from_compact(&sig.0).map_err(|err| { - StdError::generic_err(format!("Malformed signature: {:?}", err)) - })?; - let secp256k1_pubkey = secp256k1::PublicKey::from_slice(pubkey.0.as_slice()) - .map_err(|err| StdError::generic_err(format!("Malformed pubkey: {:?}", err)))?; - let secp256k1_msg = - secp256k1::Message::from_slice(&msg_hash.as_slice()).map_err(|err| { - StdError::generic_err(format!( - "Failed to create a secp256k1 message from signed_bytes: {:?}", - err - )) - })?; - - res = match secp256k1_verifier.verify( - &secp256k1_msg, - &secp256k1_signature, - &secp256k1_pubkey, - ) { - Ok(()) => Ok(HandleResponse { - messages: vec![], - log: vec![log("result", "true")], - data: None, - }), - Err(_err) => Ok(HandleResponse { - messages: vec![], - log: vec![log("result", "false")], - data: None, - }), - }; - } - - return res; - } - HandleMsg::Ed25519Verify { - pubkey, - sig, - msg, - iterations, - } => { - let mut res: HandleResult = Ok(HandleResponse { - messages: vec![], - log: vec![], - data: None, - }); - - // loop for benchmarking - for _ in 0..iterations { - res = - match deps - .api - .ed25519_verify(msg.as_slice(), sig.as_slice(), pubkey.as_slice()) - { - Ok(result) => Ok(HandleResponse { - messages: vec![], - log: vec![log("result", format!("{}", result))], - data: None, - }), - Err(err) => Err(StdError::generic_err(format!("{:?}", err))), - }; - } - - return res; - } - HandleMsg::Ed25519BatchVerify { - pubkeys, - sigs, - msgs, - iterations, - } => { - let mut res: HandleResult = Ok(HandleResponse { - messages: vec![], - log: vec![], - data: None, - }); - - // loop for benchmarking - for _ in 0..iterations { - res = match deps.api.ed25519_batch_verify( - msgs.iter() - .map(|m| m.as_slice()) - .collect::>() - .as_slice(), - sigs.iter() - .map(|s| s.as_slice()) - .collect::>() - .as_slice(), - pubkeys - .iter() - .map(|p| p.as_slice()) - .collect::>() - .as_slice(), - ) { - Ok(result) => Ok(HandleResponse { - messages: vec![], - log: vec![log("result", format!("{}", result))], - data: None, - }), - Err(err) => Err(StdError::generic_err(format!("{:?}", err))), - }; - } - - return res; - } - HandleMsg::Secp256k1RecoverPubkey { - msg_hash, - sig, - recovery_param, - iterations, - } => { - let mut res: HandleResult = Ok(HandleResponse { - messages: vec![], - log: vec![], - data: None, - }); - - // loop for benchmarking - for _ in 0..iterations { - res = match deps.api.secp256k1_recover_pubkey( - msg_hash.as_slice(), - sig.as_slice(), - recovery_param, - ) { - Ok(result) => Ok(HandleResponse { - messages: vec![], - log: vec![log("result", format!("{}", Binary(result).to_base64()))], - data: None, - }), - Err(err) => Err(StdError::generic_err(format!("{:?}", err))), - }; - } - - return res; - } - HandleMsg::Secp256k1Sign { - msg, - privkey, - iterations, - } => { - let mut res: HandleResult = Ok(HandleResponse { - messages: vec![], - log: vec![], - data: None, - }); - - // loop for benchmarking - for _ in 0..iterations { - res = match deps.api.secp256k1_sign(msg.as_slice(), privkey.as_slice()) { - Ok(result) => Ok(HandleResponse { - messages: vec![], - log: vec![log("result", format!("{}", Binary(result).to_base64()))], - data: None, - }), - Err(err) => Err(StdError::generic_err(format!("{:?}", err))), - }; - } - - return res; - } - HandleMsg::Ed25519Sign { - msg, - privkey, - iterations, - } => { - let mut res: HandleResult = Ok(HandleResponse { - messages: vec![], - log: vec![], - data: None, - }); - - // loop for benchmarking - for _ in 0..iterations { - res = match deps.api.ed25519_sign(msg.as_slice(), privkey.as_slice()) { - Ok(result) => Ok(HandleResponse { - messages: vec![], - log: vec![log("result", format!("{}", Binary(result).to_base64()))], - data: None, - }), - Err(err) => Err(StdError::generic_err(format!("{:?}", err))), - }; - } - - return res; - } - HandleMsg::ExecuteFromV1 { counter } => { - count(&mut deps.storage).save(&counter)?; - - let mut resp = HandleResponse::default(); - resp.data = Some( - (count_read(&deps.storage).load()? as u32) - .to_be_bytes() - .into(), - ); - - Ok(resp) - } - HandleMsg::IncrementFromV1 { addition } => { - if addition == 0 { - return Err(StdError::generic_err("got wrong counter")); - } - - let new_count = count(&mut deps.storage).load()? + addition; - count(&mut deps.storage).save(&new_count)?; - - let mut resp = HandleResponse::default(); - resp.data = Some((new_count as u32).to_be_bytes().into()); - - Ok(resp) - } - HandleMsg::AddAttributes {} => Ok(HandleResponse { - messages: vec![], - log: vec![log("attr1", "🦄"), log("attr2", "🌈")], - data: None, - }), - HandleMsg::AddMoreAttributes {} => Ok(HandleResponse { - messages: vec![], - log: vec![log("attr3", "🍉"), log("attr4", "🥝")], - data: None, - }), - HandleMsg::AddAttributesWithSubmessage {} => Ok(HandleResponse { - messages: vec![CosmosMsg::Wasm(WasmMsg::Execute { - contract_addr: env.contract.address, - callback_code_hash: env.contract_code_hash, - msg: Binary::from(r#"{"add_more_attributes":{}}"#.as_bytes().to_vec()), - send: vec![], - })], - log: vec![log("attr1", "🦄"), log("attr2", "🌈")], - data: None, - }), - HandleMsg::AddPlaintextAttributes {} => Ok(HandleResponse { - messages: vec![], - log: vec![plaintext_log("attr1", "🦄"), plaintext_log("attr2", "🌈")], - data: None, - }), - HandleMsg::AddMorePlaintextAttributes {} => Ok(HandleResponse { - messages: vec![], - log: vec![plaintext_log("attr3", "🍉"), plaintext_log("attr4", "🥝")], - data: None, - }), - HandleMsg::AddPlaintextAttributesWithSubmessage {} => Ok(HandleResponse { - messages: vec![CosmosMsg::Wasm(WasmMsg::Execute { - contract_addr: env.contract.address, - callback_code_hash: env.contract_code_hash, - msg: Binary::from(r#"{"add_more_plaintext_attributes":{}}"#.as_bytes().to_vec()), - send: vec![], - })], - log: vec![plaintext_log("attr1", "🦄"), plaintext_log("attr2", "🌈")], - data: None, - }), - HandleMsg::AddMixedEventsAndAttributesFromV1 { addr, code_hash } => Ok(HandleResponse { - messages: vec![CosmosMsg::Wasm(WasmMsg::Execute { - contract_addr: addr, - callback_code_hash: code_hash, - msg: Binary::from( - r#"{"add_more_mixed_attributes_and_events":{}}"#.as_bytes().to_vec(), - ), - send: vec![], - })], - log: vec![plaintext_log("attr1", "🦄"), plaintext_log("attr2", "🌈")], - data: None, - }), - HandleMsg::InitNewContract {} => Ok(HandleResponse { - messages: vec![CosmosMsg::Wasm(WasmMsg::Instantiate { - code_id: 1, - msg: Binary::from( - "{\"counter\":{\"counter\":150, \"expires\":100}}" - .as_bytes() - .to_vec(), - ), - callback_code_hash: env.contract_code_hash, - send: vec![], - label: String::from("fi"), - })], - log: vec![], - data: None, - }), - } -} - -#[cfg(feature = "with_floats")] -fn use_floats(x: u8, y: u8) -> Binary { - let res: f64 = (x as f64) / (y as f64); - to_binary(&format!("{}", res)).unwrap() -} - -#[cfg(not(feature = "with_floats"))] -fn use_floats(x: u8, y: u8) -> Binary { - Binary(vec![x, y]) -} - -fn send_external_query( - deps: &Extern, - contract_addr: HumanAddr, - code_hash: String, -) -> u8 { - let answer: u8 = deps - .querier - .query(&QueryRequest::Wasm(WasmQuery::Smart { - contract_addr, - callback_code_hash: code_hash, - msg: Binary::from(r#"{"receive_external_query":{"num":2}}"#.as_bytes().to_vec()), - })) - .unwrap(); - answer -} - -fn send_external_query_depth_counter( - deps: &Extern, - contract_addr: HumanAddr, - depth: u8, - code_hash: String, -) -> u8 { - if depth == 0 { - return 0; - } - - let answer: u8 = deps - .querier - .query(&QueryRequest::Wasm(WasmQuery::Smart { - contract_addr: contract_addr.clone(), - callback_code_hash: code_hash.clone(), - msg: Binary( - format!( - r#"{{"send_external_query_depth_counter":{{"to":"{}","code_hash":"{}","depth":{}}}}}"#, - contract_addr.clone().to_string(), - code_hash.clone().to_string(), - depth - 1 - ) - .into(), - ), - })) - .unwrap(); - - answer + 1 -} - -fn send_external_query_recursion_limit( - deps: &Extern, - contract_addr: HumanAddr, - depth: u8, - code_hash: String, -) -> StdResult { - let result = deps - .querier - .query(&QueryRequest::Wasm(WasmQuery::Smart { - contract_addr: contract_addr.clone(), - callback_code_hash: code_hash.clone(), - msg: Binary( - format!( - r#"{{"send_external_query_recursion_limit":{{"to":"{}","code_hash":"{}","depth":{}}}}}"#, - contract_addr.clone().to_string(), - code_hash.clone().to_string(), - depth + 1 - ) - .into_bytes(), - ), - })); - - // 10 is the current recursion limit. - if depth != 10 { - result - } else { - match result { - Err(StdError::GenericErr { msg, .. }) - if msg == "Querier system error: Query recursion limit exceeded" => - { - Ok(String::from("Recursion limit was correctly enforced")) - } - _ => Err(StdError::generic_err( - "Recursion limit was bypassed! this is a bug!", - )), - } - } -} - -fn send_external_query_panic( - deps: &mut Extern, - contract_addr: HumanAddr, - code_hash: String, -) -> HandleResult { - let err = deps - .querier - .query::(&QueryRequest::Wasm(WasmQuery::Smart { - contract_addr, - msg: Binary::from(r#"{"panic":{}}"#.as_bytes().to_vec()), - callback_code_hash: code_hash, - })) - .unwrap_err(); - - Err(err) -} - -fn send_external_query_stderror( - deps: &mut Extern, - contract_addr: HumanAddr, - code_hash: String, -) -> HandleResult { - let answer = deps - .querier - .query::(&QueryRequest::Wasm(WasmQuery::Smart { - contract_addr, - msg: Binary::from( - r#"{"contract_error":{"error_type":"generic_err"}}"# - .as_bytes() - .to_vec(), - ), - callback_code_hash: code_hash, - })); - - match answer { - Ok(wtf) => Ok(HandleResponse { - messages: vec![], - log: vec![], - data: Some(wtf), - }), - Err(e) => Err(e), - } -} - -fn send_external_query_bad_abi( - deps: &mut Extern, - contract_addr: HumanAddr, - code_hash: String, -) -> HandleResult { - let answer = deps - .querier - .query::(&QueryRequest::Wasm(WasmQuery::Smart { - contract_addr, - callback_code_hash: code_hash, - msg: Binary::from( - r#""contract_error":{"error_type":"generic_err"}}"#.as_bytes().to_vec(), - ), - })); - - match answer { - Ok(wtf) => Ok(HandleResponse { - messages: vec![], - log: vec![], - data: Some(wtf), - }), - Err(e) => Err(e), - } -} - -fn send_external_query_bad_abi_receiver( - deps: &mut Extern, - contract_addr: HumanAddr, - code_hash: String, -) -> HandleResult { - let answer = deps - .querier - .query::(&QueryRequest::Wasm(WasmQuery::Smart { - contract_addr, - msg: Binary::from(r#"{"receive_external_query":{"num":25}}"#.as_bytes().to_vec()), - callback_code_hash: code_hash, - })); - - match answer { - Ok(wtf) => Ok(HandleResponse { - messages: vec![], - log: vec![log("wtf", wtf)], - data: None, - }), - Err(e) => Err(e), - } -} - -fn exec_callback_bad_params(contract_addr: HumanAddr, code_hash: String) -> HandleResponse { - HandleResponse { - messages: vec![CosmosMsg::Wasm(WasmMsg::Execute { - contract_addr: contract_addr.clone(), - callback_code_hash: code_hash, - msg: Binary::from(r#"{"c":{"x":"banana","y":3}}"#.as_bytes().to_vec()), - send: vec![], - })], - log: vec![], - data: None, - } -} - -pub fn a( _deps: &mut Extern, _env: Env, - contract_addr: HumanAddr, - code_hash: String, - x: u8, - y: u8, -) -> HandleResponse { - HandleResponse { - messages: vec![CosmosMsg::Wasm(WasmMsg::Execute { - contract_addr: contract_addr.clone(), - callback_code_hash: code_hash.clone(), - msg: Binary::from(format!( - "{{\"b\":{{\"x\":{} ,\"y\": {},\"contract_addr\": \"{}\",\"code_hash\": \"{}\" }}}}", - x, - y, - contract_addr.as_str(), - &code_hash - ) - .as_bytes() - .to_vec()), - send: vec![], - })], - log: vec![log("banana", "🍌")], - data: Some(Binary(vec![x, y])), - } -} - -pub fn b( - _deps: &mut Extern, - _env: Env, - contract_addr: HumanAddr, - code_hash: String, - x: u8, - y: u8, -) -> HandleResponse { - HandleResponse { - messages: vec![CosmosMsg::Wasm(WasmMsg::Execute { - contract_addr: contract_addr.clone(), - callback_code_hash: code_hash, - msg: Binary::from( - format!("{{\"c\":{{\"x\":{} ,\"y\": {} }}}}", x + 1, y + 1) - .as_bytes() - .to_vec(), - ), - send: vec![], - })], - log: vec![log("kiwi", "🥝")], - data: Some(Binary(vec![x + y])), - } -} - -pub fn c( - _deps: &mut Extern, - _env: Env, - x: u8, - y: u8, -) -> HandleResponse { - HandleResponse { - messages: vec![], - log: vec![log("watermelon", "🍉")], - data: Some(Binary(vec![x + y])), - } -} - -pub fn empty_log_key_value( - _deps: &mut Extern, - _env: Env, -) -> HandleResponse { - HandleResponse { - messages: vec![], - log: vec![log("my value is empty", ""), log("", "my key is empty")], - data: None, - } -} - -pub fn empty_data( - _deps: &mut Extern, - _env: Env, -) -> HandleResponse { - HandleResponse { + _msg: Msg, +) -> InitResult { + return Ok(InitResponse { messages: vec![], log: vec![], - data: Some(Binary(vec![])), - } + }); } -pub fn unicode_data( - _deps: &mut Extern, - _env: Env, -) -> HandleResponse { - HandleResponse { - messages: vec![], - log: vec![], - data: Some(Binary("🍆🥑🍄".as_bytes().to_vec())), - } -} +/////////////////////////////// Handle /////////////////////////////// -pub fn no_data( +pub fn handle( _deps: &mut Extern, _env: Env, -) -> HandleResponse { - HandleResponse { + _msg: Msg, +) -> HandleResult { + // match msg {} + return Ok(HandleResponse { messages: vec![], log: vec![], data: None, - } -} - -pub fn exec_callback_to_init( - _deps: &mut Extern, - _env: Env, - code_id: u64, - code_hash: String, -) -> HandleResponse { - HandleResponse { - messages: vec![CosmosMsg::Wasm(WasmMsg::Instantiate { - code_id, - msg: Binary::from("{\"nop\":{}}".as_bytes().to_vec()), - callback_code_hash: code_hash, - send: vec![], - label: String::from("hi"), - })], - log: vec![log("instantiating a new contract", "🪂")], - data: None, - } -} - -fn exec_with_callback_contract_error( - contract_addr: HumanAddr, - code_hash: String, -) -> HandleResponse { - HandleResponse { - messages: vec![CosmosMsg::Wasm(WasmMsg::Execute { - contract_addr: contract_addr.clone(), - callback_code_hash: code_hash, - msg: Binary::from( - r#"{"contract_error":{"error_type":"generic_err"}}"# - .as_bytes() - .to_vec(), - ), - send: vec![], - })], - log: vec![log("exec with a callback with contract error", "🤷‍♂️")], - data: None, - } -} - -fn allocate_on_heap(bytes: usize) -> HandleResponse { - let mut values: Vec = vec![0; bytes]; - values[bytes - 1] = 1; - - HandleResponse { - data: Some(Binary("😅".as_bytes().to_vec())), - log: vec![], - messages: vec![], - } -} - -fn get_state( - deps: &mut Extern, - key: String, -) -> HandleResponse { - let store = PrefixedStorage::new(b"my_prefix", &mut deps.storage); - - match store.get(key.as_bytes()) { - Some(value) => HandleResponse { - data: Some(Binary(value)), - log: vec![], - messages: vec![], - }, - None => HandleResponse::default(), - } -} - -fn set_state( - deps: &mut Extern, - key: String, - value: String, -) -> HandleResponse { - let mut store = PrefixedStorage::new(b"my_prefix", &mut deps.storage); - store.set(key.as_bytes(), value.as_bytes()); - HandleResponse::default() -} - -fn remove_state( - deps: &mut Extern, - key: String, -) -> HandleResponse { - let mut store = PrefixedStorage::new(b"my_prefix", &mut deps.storage); - store.remove(key.as_bytes()); - HandleResponse::default() -} - -#[allow(invalid_value)] -#[allow(unused_must_use)] -fn pass_null_pointer_to_imports_should_throw( - deps: &mut Extern, - pass_type: String, -) -> HandleResponse { - let null_ptr_slice: &[u8] = unsafe { MaybeUninit::zeroed().assume_init() }; - - match &pass_type[..] { - "read_db_key" => { - deps.storage.get(null_ptr_slice); - } - "write_db_key" => { - deps.storage.set(null_ptr_slice, b"write value"); - } - "write_db_value" => { - deps.storage.set(b"write key", null_ptr_slice); - } - "remove_db_key" => { - deps.storage.remove(null_ptr_slice); - } - "canonicalize_address_input" => { - deps.api - .canonical_address(unsafe { MaybeUninit::zeroed().assume_init() }); - } - "canonicalize_address_output" => { /* TODO */ } - "humanize_address_input" => { - deps.api - .human_address(unsafe { MaybeUninit::zeroed().assume_init() }); - } - "humanize_address_output" => { /* TODO */ } - _ => {} - }; - - HandleResponse::default() -} - -fn test_canonicalize_address_errors( - deps: &mut Extern, -) -> HandleResult { - match deps.api.canonical_address(&HumanAddr(String::from(""))) { - Err(StdError::GenericErr { msg, backtrace: _ }) => { - if msg != String::from("canonicalize_address errored: input is empty") { - return Err(StdError::generic_err( - "empty address should have failed with 'canonicalize_address errored: input is empty'", - )); - } - // all is good, continue - } - _ => return Err(StdError::generic_err( - "empty address should have failed with 'canonicalize_address errored: input is empty'", - )), - } - - match deps.api.canonical_address(&HumanAddr(String::from(" "))) { - Err(StdError::GenericErr { msg, backtrace: _ }) => { - if msg != String::from("canonicalize_address errored: input is empty") { - return Err(StdError::generic_err( - "empty trimmed address should have failed with 'canonicalize_address errored: input is empty'", - )); - } - // all is good, continue - } - _ => { - return Err(StdError::generic_err( - "empty trimmed address should have failed with 'canonicalize_address errored: input is empty'", - )) - } - } - - match deps - .api - .canonical_address(&HumanAddr(String::from("cosmos1h99hrcc54ms9lxxxx"))) - { - Err(StdError::GenericErr { msg, backtrace: _ }) => { - if msg != String::from("canonicalize_address errored: invalid checksum") { - return Err(StdError::generic_err( - "bad bech32 should have failed with 'canonicalize_address errored: invalid checksum'", - )); - } - // all is good, continue - } - _ => return Err(StdError::generic_err( - "bad bech32 should have failed with 'canonicalize_address errored: invalid checksum'", - )), - } - - match deps.api.canonical_address(&HumanAddr(String::from( - "cosmos1h99hrcc54ms9luwpex9kw0rwdt7etvfdyxh6gu", - ))) { - Err(StdError::GenericErr { msg, backtrace: _ }) => { - if msg != String::from("canonicalize_address errored: wrong address prefix: \"cosmos\"") - { - return Err(StdError::generic_err( - "bad prefix should have failed with 'canonicalize_address errored: wrong address prefix: \"cosmos\"'", - )); - } - // all is good, continue - } - _ => { - return Err(StdError::generic_err( - "bad prefix should have failed with 'canonicalize_address errored: wrong address prefix: \"cosmos\"'", - )) - } - } - - Ok(HandleResponse { - data: Some(Binary("🤟".as_bytes().to_vec())), - log: vec![], - messages: vec![], - }) + }); } /////////////////////////////// Query /////////////////////////////// -pub fn query( - deps: &Extern, - _msg: QueryMsg, -) -> QueryResult { - match _msg { - QueryMsg::ContractError { error_type } => Err(map_string_to_error(error_type)), - QueryMsg::Panic {} => panic!("panic in query"), - QueryMsg::ReceiveExternalQuery { num } => { - Ok(Binary(serde_json_wasm::to_vec(&(num + 1)).unwrap())) - } - QueryMsg::SendExternalQueryInfiniteLoop { to, code_hash } => { - send_external_query_infinite_loop(deps, to, code_hash) - } - QueryMsg::WriteToStorage {} => write_to_storage_in_query(deps), - QueryMsg::RemoveFromStorage {} => remove_from_storage_in_query(deps), - QueryMsg::SendExternalQueryDepthCounter { - to, - depth, - code_hash, - } => Ok(to_binary(&send_external_query_depth_counter( - deps, to, depth, code_hash, - )) - .unwrap()), - QueryMsg::SendExternalQueryRecursionLimit { - to, - depth, - code_hash, - } => to_binary(&send_external_query_recursion_limit( - deps, to, depth, code_hash, - )?), - QueryMsg::CallToQuery { - addr, - code_hash, - msg, - } => { - let answer: u32 = deps - .querier - .query(&QueryRequest::Wasm(WasmQuery::Smart { - contract_addr: addr, - callback_code_hash: code_hash, - msg: Binary::from(msg.as_bytes().to_vec()), - })) - .map_err(|err| { - StdError::generic_err(format!("Got an error from query: {:?}", err)) - })?; - return Ok(to_binary(&answer)?); - } - QueryMsg::GetCountFromV1 {} => { - let count = count_read(&deps.storage).load()?; - - Ok(to_binary(&QueryRes::Get { count })?) - } - QueryMsg::Get {} => { - let count = count_read(&deps.storage).load()?; - - Ok(to_binary(&QueryRes::Get { count })?) - } - QueryMsg::GetContractVersion {} => { - let answer: u8 = 10; - return Ok(to_binary(&answer)?); +pub fn query(deps: &Extern, msg: QueryMsg) -> QueryResult { + match msg { + QueryMsg::BankBalance { address, denom } => { + let res = + deps.querier + .query::(&QueryRequest::Bank(BankQuery::Balance { + address, + denom, + }))?; + return Ok(to_binary(&res)?); } } } - -fn send_external_query_infinite_loop( - deps: &Extern, - contract_addr: HumanAddr, - code_hash: String, -) -> QueryResult { - let answer = deps - .querier - .query::(&QueryRequest::Wasm(WasmQuery::Smart { - contract_addr: contract_addr.clone(), - callback_code_hash: code_hash.clone(), - msg: Binary::from( - format!( - r#"{{"send_external_query_infinite_loop":{{"to":"{}", "code_hash":"{}"}}}}"#, - contract_addr.clone().to_string(), - &code_hash - ) - .as_bytes() - .to_vec(), - ), - })); - - match answer { - Ok(wtf) => Ok(Binary(wtf.into())), - Err(e) => Err(e), - } -} - -fn write_to_storage_in_query( - deps: &Extern, -) -> StdResult { - #[allow(clippy::cast_ref_to_mut)] - let deps = unsafe { &mut *(deps as *const _ as *mut Extern) }; - deps.storage.set(b"abcd", b"dcba"); - - Ok(Binary(vec![])) -} - -fn remove_from_storage_in_query( - deps: &Extern, -) -> StdResult { - #[allow(clippy::cast_ref_to_mut)] - let deps = unsafe { &mut *(deps as *const _ as *mut Extern) }; - deps.storage.remove(b"abcd"); - - Ok(Binary(vec![])) -} diff --git a/integration-tests/contract-v1/rust-toolchain b/integration-tests/contract-v1/rust-toolchain index a7efc46ca..6cb4a6feb 100644 --- a/integration-tests/contract-v1/rust-toolchain +++ b/integration-tests/contract-v1/rust-toolchain @@ -1 +1 @@ -1.61 \ No newline at end of file +1.63 \ No newline at end of file diff --git a/integration-tests/contract-v1/src/contract.rs b/integration-tests/contract-v1/src/contract.rs index 94e6247ca..5293bc366 100644 --- a/integration-tests/contract-v1/src/contract.rs +++ b/integration-tests/contract-v1/src/contract.rs @@ -1,6 +1,7 @@ use cosmwasm_std::{ - entry_point, BankMsg, Binary, CosmosMsg, Deps, DepsMut, DistributionMsg, Env, GovMsg, IbcMsg, - MessageInfo, QueryRequest, Response, StakingMsg, StdResult, WasmMsg, + entry_point, to_binary, to_vec, BalanceResponse, BankMsg, BankQuery, Binary, CosmosMsg, Deps, + DepsMut, DistributionMsg, Empty, Env, GovMsg, IbcMsg, MessageInfo, QueryRequest, Response, + StakingMsg, StdResult, WasmMsg, }; use crate::msg::{Msg, QueryMsg}; @@ -143,12 +144,22 @@ fn handle_msg(_deps: DepsMut, _env: Env, _info: MessageInfo, msg: Msg) -> StdRes #[entry_point] pub fn query(deps: Deps, _env: Env, msg: QueryMsg) -> StdResult { match msg { - QueryMsg::StargateQuery { path, data } => { + QueryMsg::Stargate { path, data } => { let res = deps .querier - .query::(&QueryRequest::Stargate { path, data }); - deps.api.debug(&format!("ASSAF {:?}", res)); - return Ok(res?); + .raw_query(&to_vec(&QueryRequest::::Stargate { path, data })?) + .unwrap() + .unwrap(); + return Ok(to_binary(&res)?); + } + QueryMsg::BankBalance { address, denom } => { + let res = + deps.querier + .query::(&QueryRequest::Bank(BankQuery::Balance { + address, + denom, + }))?; + return Ok(to_binary(&res)?); } } } diff --git a/integration-tests/contract-v1/src/msg.rs b/integration-tests/contract-v1/src/msg.rs index 6f298da88..b84b25a12 100644 --- a/integration-tests/contract-v1/src/msg.rs +++ b/integration-tests/contract-v1/src/msg.rs @@ -70,5 +70,6 @@ pub enum Msg { #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] #[serde(rename_all = "snake_case")] pub enum QueryMsg { - StargateQuery { path: String, data: Binary }, + BankBalance { address: String, denom: String }, + Stargate { path: String, data: Binary }, } diff --git a/integration-tests/test.ts b/integration-tests/test.ts index e78917820..ff3217054 100644 --- a/integration-tests/test.ts +++ b/integration-tests/test.ts @@ -1,9 +1,17 @@ -import { SecretNetworkClient, toBase64, toHex, Wallet } from "secretjs"; +import { + fromBase64, + MsgInstantiateContract, + MsgStoreCode, + SecretNetworkClient, + toBase64, + toHex, + Wallet, +} from "secretjs"; import { MsgSend } from "secretjs/dist/protobuf_stuff/cosmos/bank/v1beta1/tx"; import { QueryBalanceRequest, QueryBalanceResponse, -} from "secretjs/dist/protobuf_stuff/cosmos/bank/v1beta1/query"; +} from "secretjs//dist/protobuf_stuff/cosmos/bank/v1beta1/query"; import { sha256 } from "@noble/hashes/sha256"; import * as fs from "fs"; @@ -19,6 +27,10 @@ let v1CodeID: number; let v1Address: string; let v1CodeHash: string; +let v010CodeID: number; +let v010Address: string; +let v010CodeHash: string; + beforeAll(async () => { accounts.a = await SecretNetworkClient.create({ chainId: "secretdev-1", @@ -64,38 +76,66 @@ beforeAll(async () => { ) as Uint8Array; v1CodeHash = toHex(sha256(v1Wasm)); - let tx = await accounts.a.tx.compute.storeCode( - { - sender: accounts.a.address, - wasmByteCode: v1Wasm, - source: "", - builder: "", - }, + const v010Wasm = fs.readFileSync( + `${__dirname}/contract-v0.10/contract.wasm` + ) as Uint8Array; + v010CodeHash = toHex(sha256(v010Wasm)); + + let tx = await accounts.a.tx.broadcast( + [ + new MsgStoreCode({ + sender: accounts.a.address, + wasmByteCode: v1Wasm, + source: "", + builder: "", + }), + new MsgStoreCode({ + sender: accounts.a.address, + wasmByteCode: v010Wasm, + source: "", + builder: "", + }), + ], { gasLimit: 5_000_000 } ); if (tx.code !== 0) { - console.log(tx.rawLog); + console.error(tx.rawLog); } expect(tx.code).toBe(0); v1CodeID = Number(tx.arrayLog.find((x) => x.key === "code_id").value); + v010CodeID = Number( + tx.arrayLog.reverse().find((x) => x.key === "code_id").value + ); - tx = await accounts.a.tx.compute.instantiateContract( - { - sender: accounts.a.address, - codeId: v1CodeID, - codeHash: v1CodeHash, - initMsg: { nop: {} }, - label: `v1-${Math.random()}`, - }, - { gasLimit: 100_000 } + tx = await accounts.a.tx.broadcast( + [ + new MsgInstantiateContract({ + sender: accounts.a.address, + codeId: v1CodeID, + codeHash: v1CodeHash, + initMsg: { nop: {} }, + label: `v1-${Math.random()}`, + }), + new MsgInstantiateContract({ + sender: accounts.a.address, + codeId: v010CodeID, + codeHash: v010CodeHash, + initMsg: { nop: {} }, + label: `v010-${Math.random()}`, + }), + ], + { gasLimit: 200_000 } ); if (tx.code !== 0) { - console.log(tx.rawLog); + console.error(tx.rawLog); } expect(tx.code).toBe(0); v1Address = tx.arrayLog.find((x) => x.key === "contract_address").value; + v010Address = tx.arrayLog + .reverse() + .find((x) => x.key === "contract_address").value; }); async function sleep(ms: number) { @@ -117,7 +157,7 @@ async function waitForBlocks() { } catch (e) { // console.error(e); } - await sleep(250); + await sleep(100); } } @@ -139,7 +179,7 @@ describe("Bank::MsgSend", () => { { gasLimit: 250_000 } ); if (tx.code !== 0) { - console.log(tx.rawLog); + console.error(tx.rawLog); } expect(tx.code).toBe(0); expect(tx.arrayLog.filter((x) => x.type === "coin_spent")).toStrictEqual([ @@ -207,7 +247,7 @@ describe("StargateMsg", () => { { gasLimit: 250_000 } ); if (tx.code !== 0) { - console.log(tx.rawLog); + console.error(tx.rawLog); } expect(tx.code).toBe(0); expect(tx.arrayLog.filter((x) => x.type === "coin_spent")).toStrictEqual([ @@ -249,11 +289,11 @@ describe("StargateMsg", () => { describe("StargateQuery", () => { test("v1", async () => { - const result = await accounts.a.query.compute.queryContract({ + const result: any = await accounts.a.query.compute.queryContract({ contractAddress: v1Address, codeHash: v1CodeHash, query: { - stargate_query: { + stargate: { path: "/cosmos.bank.v1beta1.Query/Balance", data: toBase64( QueryBalanceRequest.encode({ @@ -264,6 +304,43 @@ describe("StargateQuery", () => { }, }, }); - console.log(result); + + const response = QueryBalanceResponse.decode(fromBase64(result)); + expect(response?.balance?.denom).toBe("uscrt"); + expect(Number(response?.balance?.amount)).toBeGreaterThanOrEqual(1); + }); +}); + +describe("BankQuery", () => { + describe("Balance", () => { + test("v1", async () => { + const result: any = await accounts.a.query.compute.queryContract({ + contractAddress: v1Address, + codeHash: v1CodeHash, + query: { + bank_balance: { + address: accounts.a.address, + denom: "uscrt", + }, + }, + }); + expect(result?.amount?.denom).toBe("uscrt"); + expect(Number(result?.amount?.amount)).toBeGreaterThanOrEqual(1); + }); + + test("v0.10", async () => { + const result: any = await accounts.a.query.compute.queryContract({ + contractAddress: v010Address, + codeHash: v010CodeHash, + query: { + bank_balance: { + address: accounts.a.address, + denom: "uscrt", + }, + }, + }); + expect(result?.amount?.denom).toBe("uscrt"); + expect(Number(result?.amount?.amount)).toBeGreaterThanOrEqual(1); + }); }); }); From be350cc6991e48de44ec954c0ab772ee0bab8e66 Mon Sep 17 00:00:00 2001 From: Assaf Morami Date: Tue, 23 Aug 2022 12:56:19 +0300 Subject: [PATCH 47/93] Implement all queries for v1 integration tests contract --- integration-tests/contract-v1/src/contract.rs | 107 +++++++++++++++--- integration-tests/contract-v1/src/msg.rs | 41 ++++++- 2 files changed, 130 insertions(+), 18 deletions(-) diff --git a/integration-tests/contract-v1/src/contract.rs b/integration-tests/contract-v1/src/contract.rs index 5293bc366..09949c2f5 100644 --- a/integration-tests/contract-v1/src/contract.rs +++ b/integration-tests/contract-v1/src/contract.rs @@ -1,7 +1,10 @@ use cosmwasm_std::{ - entry_point, to_binary, to_vec, BalanceResponse, BankMsg, BankQuery, Binary, CosmosMsg, Deps, - DepsMut, DistributionMsg, Empty, Env, GovMsg, IbcMsg, MessageInfo, QueryRequest, Response, - StakingMsg, StdResult, WasmMsg, + entry_point, to_binary, to_vec, AllBalanceResponse, AllDelegationsResponse, + AllValidatorsResponse, BalanceResponse, BankMsg, BankQuery, Binary, BondedDenomResponse, + ChannelResponse, ContractInfoResponse, CosmosMsg, DelegationResponse, Deps, DepsMut, + DistributionMsg, Empty, Env, GovMsg, IbcMsg, IbcQuery, ListChannelsResponse, MessageInfo, + PortIdResponse, QueryRequest, Response, StakingMsg, StakingQuery, StdResult, ValidatorResponse, + WasmMsg, WasmQuery, }; use crate::msg::{Msg, QueryMsg}; @@ -145,21 +148,93 @@ fn handle_msg(_deps: DepsMut, _env: Env, _info: MessageInfo, msg: Msg) -> StdRes pub fn query(deps: Deps, _env: Env, msg: QueryMsg) -> StdResult { match msg { QueryMsg::Stargate { path, data } => { - let res = deps - .querier - .raw_query(&to_vec(&QueryRequest::::Stargate { path, data })?) - .unwrap() - .unwrap(); - return Ok(to_binary(&res)?); + return Ok(to_binary( + &deps + .querier + .raw_query(&to_vec(&QueryRequest::::Stargate { path, data })?) + .unwrap() + .unwrap(), + )?); } QueryMsg::BankBalance { address, denom } => { - let res = - deps.querier - .query::(&QueryRequest::Bank(BankQuery::Balance { - address, - denom, - }))?; - return Ok(to_binary(&res)?); + return Ok(to_binary(&deps.querier.query::( + &QueryRequest::Bank(BankQuery::Balance { address, denom }), + )?)?); + } + QueryMsg::BankAllBalances { address } => { + return Ok(to_binary(&deps.querier.query::( + &QueryRequest::Bank(BankQuery::AllBalances { address }), + )?)?); + } + QueryMsg::StakingBondedDenom {} => { + return Ok(to_binary(&deps.querier.query::( + &QueryRequest::Staking(StakingQuery::BondedDenom {}), + )?)?); + } + QueryMsg::StakingAllDelegations { delegator } => { + return Ok(to_binary(&deps.querier.query::( + &QueryRequest::Staking(StakingQuery::AllDelegations { delegator }), + )?)?); + } + QueryMsg::StakingDelegation { + delegator, + validator, + } => { + return Ok(to_binary(&deps.querier.query::( + &QueryRequest::Staking(StakingQuery::Delegation { + delegator, + validator, + }), + )?)?); + } + QueryMsg::StakingAllValidators {} => { + return Ok(to_binary(&deps.querier.query::( + &QueryRequest::Staking(StakingQuery::AllValidators {}), + )?)?); + } + QueryMsg::StakingValidator { address } => { + return Ok(to_binary(&deps.querier.query::( + &QueryRequest::Staking(StakingQuery::Validator { address }), + )?)?); + } + QueryMsg::IbcPortId {} => { + return Ok(to_binary(&deps.querier.query::( + &QueryRequest::Ibc(IbcQuery::PortId {}), + )?)?); + } + QueryMsg::IbcListChannels { port_id } => { + return Ok(to_binary(&deps.querier.query::( + &QueryRequest::Ibc(IbcQuery::ListChannels { port_id }), + )?)?); + } + QueryMsg::IbcChannel { + channel_id, + port_id, + } => { + return Ok(to_binary(&deps.querier.query::( + &QueryRequest::Ibc(IbcQuery::Channel { + channel_id, + port_id, + }), + )?)?); + } + QueryMsg::WasmSmart { + contract_addr, + code_hash, + msg, + } => { + return Ok(to_binary(&deps.querier.query::( + &QueryRequest::Wasm(WasmQuery::Smart { + contract_addr, + code_hash, + msg, + }), + )?)?); + } + QueryMsg::WasmContractInfo { contract_addr } => { + return Ok(to_binary(&deps.querier.query::( + &QueryRequest::Wasm(WasmQuery::ContractInfo { contract_addr }), + )?)?); } } } diff --git a/integration-tests/contract-v1/src/msg.rs b/integration-tests/contract-v1/src/msg.rs index b84b25a12..8721720a7 100644 --- a/integration-tests/contract-v1/src/msg.rs +++ b/integration-tests/contract-v1/src/msg.rs @@ -70,6 +70,43 @@ pub enum Msg { #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] #[serde(rename_all = "snake_case")] pub enum QueryMsg { - BankBalance { address: String, denom: String }, - Stargate { path: String, data: Binary }, + BankBalance { + address: String, + denom: String, + }, + BankAllBalances { + address: String, + }, + StakingBondedDenom {}, + StakingAllDelegations { + delegator: String, + }, + StakingDelegation { + delegator: String, + validator: String, + }, + StakingAllValidators {}, + StakingValidator { + address: String, + }, + Stargate { + path: String, + data: Binary, + }, + IbcPortId {}, + IbcListChannels { + port_id: Option, + }, + IbcChannel { + channel_id: String, + port_id: Option, + }, + WasmSmart { + contract_addr: String, + code_hash: String, + msg: Binary, + }, + WasmContractInfo { + contract_addr: String, + }, } From 4873d34e4d55cb0a98386573a40effc9e26a8aa8 Mon Sep 17 00:00:00 2001 From: Cashmaney Date: Tue, 23 Aug 2022 19:59:43 +0300 Subject: [PATCH 48/93] Refactored v010/v1 env parsing in the enclave to make it a little more generic and readable. If Also refactored verification to be a little more performant (removed redundant human->canonical and some other stuff) --- cosmwasm/enclaves/Cargo.lock | 82 +++++----- cosmwasm/enclaves/Cargo.toml | 14 +- .../shared/contract-engine/Cargo.toml | 5 +- .../src/contract_operations.rs | 128 +++++++++------- .../src/contract_validation.rs | 112 +++++++------- .../enclaves/shared/contract-engine/src/io.rs | 38 ++--- .../shared/contract-engine/src/query_chain.rs | 2 +- .../contract-engine/src/wasm/contract.rs | 12 +- .../shared/contract-engine/src/wasm/engine.rs | 4 +- .../shared/contract-engine/src/wasm/mod.rs | 3 +- .../enclaves/shared/cosmos-types/Cargo.toml | 2 +- .../shared/cosmos-types/src/multisig.rs | 2 +- .../shared/cosmos-types/src/single_address.rs | 2 +- .../shared/cosmos-types/src/traits.rs | 2 +- .../enclaves/shared/cosmos-types/src/types.rs | 2 +- .../shared/cosmwasm-types/generic/Cargo.toml | 20 +++ .../shared/cosmwasm-types/generic/src/lib.rs | 143 ++++++++++++++++++ .../v0.10}/Cargo.toml | 4 +- .../v0.10}/Makefile | 2 +- .../v0.10}/src/coins.rs | 0 .../v0.10}/src/consts.rs | 0 .../v0.10}/src/encoding.rs | 0 .../v0.10}/src/lib.rs | 0 .../v0.10}/src/math.rs | 0 .../v0.10}/src/query.rs | 0 .../v0.10}/src/std_error.rs | 0 .../v0.10}/src/system_error.rs | 0 .../v0.10}/src/types.rs | 0 .../v1.0}/Cargo.toml | 6 +- .../v1.0}/Makefile | 2 +- .../v1.0}/src/addresses.rs | 0 .../v1.0}/src/coins.rs | 11 ++ .../v1.0}/src/errors/crypto_error.rs | 0 .../v1.0}/src/errors/mod.rs | 0 .../v1.0}/src/errors/recover_pubkey_error.rs | 0 .../v1.0}/src/errors/std_error.rs | 0 .../v1.0}/src/errors/verification_error.rs | 0 .../v1.0}/src/lib.rs | 0 .../v1.0}/src/math/mod.rs | 0 .../v1.0}/src/math/uint128.rs | 8 + .../v1.0}/src/math/uint64.rs | 0 .../v1.0}/src/results/contract_result.rs | 0 .../v1.0}/src/results/cosmos_msg.rs | 2 +- .../v1.0}/src/results/empty.rs | 0 .../v1.0}/src/results/events.rs | 2 +- .../v1.0}/src/results/mod.rs | 0 .../v1.0}/src/results/response.rs | 2 +- .../v1.0}/src/results/submessages.rs | 2 +- .../v1.0}/src/timestamp.rs | 0 .../v1.0}/src/types.rs | 6 +- 50 files changed, 416 insertions(+), 204 deletions(-) create mode 100644 cosmwasm/enclaves/shared/cosmwasm-types/generic/Cargo.toml create mode 100644 cosmwasm/enclaves/shared/cosmwasm-types/generic/src/lib.rs rename cosmwasm/enclaves/shared/{cosmwasm-v010-types => cosmwasm-types/v0.10}/Cargo.toml (91%) rename cosmwasm/enclaves/shared/{cosmwasm-v010-types => cosmwasm-types/v0.10}/Makefile (89%) rename cosmwasm/enclaves/shared/{cosmwasm-v010-types => cosmwasm-types/v0.10}/src/coins.rs (100%) rename cosmwasm/enclaves/shared/{cosmwasm-v010-types => cosmwasm-types/v0.10}/src/consts.rs (100%) rename cosmwasm/enclaves/shared/{cosmwasm-v010-types => cosmwasm-types/v0.10}/src/encoding.rs (100%) rename cosmwasm/enclaves/shared/{cosmwasm-v010-types => cosmwasm-types/v0.10}/src/lib.rs (100%) rename cosmwasm/enclaves/shared/{cosmwasm-v010-types => cosmwasm-types/v0.10}/src/math.rs (100%) rename cosmwasm/enclaves/shared/{cosmwasm-v010-types => cosmwasm-types/v0.10}/src/query.rs (100%) rename cosmwasm/enclaves/shared/{cosmwasm-v010-types => cosmwasm-types/v0.10}/src/std_error.rs (100%) rename cosmwasm/enclaves/shared/{cosmwasm-v010-types => cosmwasm-types/v0.10}/src/system_error.rs (100%) rename cosmwasm/enclaves/shared/{cosmwasm-v010-types => cosmwasm-types/v0.10}/src/types.rs (100%) rename cosmwasm/enclaves/shared/{cosmwasm-v1-types => cosmwasm-types/v1.0}/Cargo.toml (86%) rename cosmwasm/enclaves/shared/{cosmwasm-v1-types => cosmwasm-types/v1.0}/Makefile (89%) rename cosmwasm/enclaves/shared/{cosmwasm-v1-types => cosmwasm-types/v1.0}/src/addresses.rs (100%) rename cosmwasm/enclaves/shared/{cosmwasm-v1-types => cosmwasm-types/v1.0}/src/coins.rs (79%) rename cosmwasm/enclaves/shared/{cosmwasm-v1-types => cosmwasm-types/v1.0}/src/errors/crypto_error.rs (100%) rename cosmwasm/enclaves/shared/{cosmwasm-v1-types => cosmwasm-types/v1.0}/src/errors/mod.rs (100%) rename cosmwasm/enclaves/shared/{cosmwasm-v1-types => cosmwasm-types/v1.0}/src/errors/recover_pubkey_error.rs (100%) rename cosmwasm/enclaves/shared/{cosmwasm-v1-types => cosmwasm-types/v1.0}/src/errors/std_error.rs (100%) rename cosmwasm/enclaves/shared/{cosmwasm-v1-types => cosmwasm-types/v1.0}/src/errors/verification_error.rs (100%) rename cosmwasm/enclaves/shared/{cosmwasm-v1-types => cosmwasm-types/v1.0}/src/lib.rs (100%) rename cosmwasm/enclaves/shared/{cosmwasm-v1-types => cosmwasm-types/v1.0}/src/math/mod.rs (100%) rename cosmwasm/enclaves/shared/{cosmwasm-v1-types => cosmwasm-types/v1.0}/src/math/uint128.rs (98%) rename cosmwasm/enclaves/shared/{cosmwasm-v1-types => cosmwasm-types/v1.0}/src/math/uint64.rs (100%) rename cosmwasm/enclaves/shared/{cosmwasm-v1-types => cosmwasm-types/v1.0}/src/results/contract_result.rs (100%) rename cosmwasm/enclaves/shared/{cosmwasm-v1-types => cosmwasm-types/v1.0}/src/results/cosmos_msg.rs (99%) rename cosmwasm/enclaves/shared/{cosmwasm-v1-types => cosmwasm-types/v1.0}/src/results/empty.rs (100%) rename cosmwasm/enclaves/shared/{cosmwasm-v1-types => cosmwasm-types/v1.0}/src/results/events.rs (94%) rename cosmwasm/enclaves/shared/{cosmwasm-v1-types => cosmwasm-types/v1.0}/src/results/mod.rs (100%) rename cosmwasm/enclaves/shared/{cosmwasm-v1-types => cosmwasm-types/v1.0}/src/results/response.rs (97%) rename cosmwasm/enclaves/shared/{cosmwasm-v1-types => cosmwasm-types/v1.0}/src/results/submessages.rs (98%) rename cosmwasm/enclaves/shared/{cosmwasm-v1-types => cosmwasm-types/v1.0}/src/timestamp.rs (100%) rename cosmwasm/enclaves/shared/{cosmwasm-v1-types => cosmwasm-types/v1.0}/src/types.rs (97%) diff --git a/cosmwasm/enclaves/Cargo.lock b/cosmwasm/enclaves/Cargo.lock index 26a972389..8fe1057c5 100644 --- a/cosmwasm/enclaves/Cargo.lock +++ b/cosmwasm/enclaves/Cargo.lock @@ -315,6 +315,50 @@ dependencies = [ "zeroize", ] +[[package]] +name = "cw_types_generic" +version = "0.1.0" +dependencies = [ + "cw_types_v010", + "cw_types_v1", + "enclave-ffi-types", + "hex", + "log", + "serde 1.0.118", + "serde_json 1.0.60", +] + +[[package]] +name = "cw_types_v010" +version = "1.2.4" +dependencies = [ + "base64 0.13.0 (git+https://github.com/mesalock-linux/rust-base64-sgx?rev=dc7389e10817b078f289386b3b6a852ab6c4c021)", + "bech32", + "derive_more", + "enclave-ffi-types", + "log", + "serde 1.0.118", + "serde_json 1.0.60", + "sgx_tstd 1.1.3 (git+https://github.com/apache/teaclave-sgx-sdk.git?rev=a37ffb9449ba6d5b6e4a9d586bbab864ae732269)", +] + +[[package]] +name = "cw_types_v1" +version = "1.2.4" +dependencies = [ + "base64 0.13.0 (git+https://github.com/mesalock-linux/rust-base64-sgx?rev=dc7389e10817b078f289386b3b6a852ab6c4c021)", + "bech32", + "cw_types_v010", + "derive_more", + "enclave-ffi-types", + "log", + "serde 1.0.118", + "serde_json 1.0.60", + "sgx_tstd 1.1.3 (git+https://github.com/apache/teaclave-sgx-sdk.git?rev=a37ffb9449ba6d5b6e4a9d586bbab864ae732269)", + "thiserror", + "uint", +] + [[package]] name = "dbl" version = "0.3.2" @@ -416,12 +460,13 @@ dependencies = [ "base64 0.13.0 (git+https://github.com/mesalock-linux/rust-base64-sgx?rev=dc7389e10817b078f289386b3b6a852ab6c4c021)", "bech32", "cosmos_proto", + "cw_types_generic", + "cw_types_v010", + "cw_types_v1", "derive_more", "ed25519-zebra", "enclave-ffi-types", "enclave_cosmos_types", - "enclave_cosmwasm_v010_types", - "enclave_cosmwasm_v1_types", "enclave_crypto", "enclave_utils", "hex", @@ -447,9 +492,9 @@ name = "enclave_cosmos_types" version = "1.2.4" dependencies = [ "cosmos_proto", + "cw_types_v010", "derive_more", "enclave-ffi-types", - "enclave_cosmwasm_v010_types", "enclave_crypto", "log", "num_enum", @@ -460,37 +505,6 @@ dependencies = [ "sha2 0.8.2", ] -[[package]] -name = "enclave_cosmwasm_v010_types" -version = "1.2.4" -dependencies = [ - "base64 0.13.0 (git+https://github.com/mesalock-linux/rust-base64-sgx?rev=dc7389e10817b078f289386b3b6a852ab6c4c021)", - "bech32", - "derive_more", - "enclave-ffi-types", - "log", - "serde 1.0.118", - "serde_json 1.0.60", - "sgx_tstd 1.1.3 (git+https://github.com/apache/teaclave-sgx-sdk.git?rev=a37ffb9449ba6d5b6e4a9d586bbab864ae732269)", -] - -[[package]] -name = "enclave_cosmwasm_v1_types" -version = "1.2.4" -dependencies = [ - "base64 0.13.0 (git+https://github.com/mesalock-linux/rust-base64-sgx?rev=dc7389e10817b078f289386b3b6a852ab6c4c021)", - "bech32", - "derive_more", - "enclave-ffi-types", - "enclave_cosmwasm_v010_types", - "log", - "serde 1.0.118", - "serde_json 1.0.60", - "sgx_tstd 1.1.3 (git+https://github.com/apache/teaclave-sgx-sdk.git?rev=a37ffb9449ba6d5b6e4a9d586bbab864ae732269)", - "thiserror", - "uint", -] - [[package]] name = "enclave_crypto" version = "1.2.4" diff --git a/cosmwasm/enclaves/Cargo.toml b/cosmwasm/enclaves/Cargo.toml index c812d3ad2..d818d4c6d 100644 --- a/cosmwasm/enclaves/Cargo.toml +++ b/cosmwasm/enclaves/Cargo.toml @@ -1,5 +1,17 @@ [workspace] -members = ["ffi-types", "execute", "query", "shared/*"] +members = [ + "ffi-types", + "execute", + "query", + "shared/contract-engine", + "shared/cosmos-proto", + "shared/cosmos-types", + "shared/crypto", + "shared/utils", + "shared/cosmwasm-types/v1.0", + "shared/cosmwasm-types/v0.10", + "shared/cosmwasm-types/generic" +] exclude = ["test"] [profile.release] diff --git a/cosmwasm/enclaves/shared/contract-engine/Cargo.toml b/cosmwasm/enclaves/shared/contract-engine/Cargo.toml index 972de3966..7c567c99f 100644 --- a/cosmwasm/enclaves/shared/contract-engine/Cargo.toml +++ b/cosmwasm/enclaves/shared/contract-engine/Cargo.toml @@ -23,8 +23,9 @@ enclave-ffi-types = { path = "../../ffi-types" } cosmos_proto = { path = "../cosmos-proto" } enclave_crypto = { path = "../crypto" } enclave_cosmos_types = { path = "../cosmos-types" } -enclave_cosmwasm_v010_types = { path = "../cosmwasm-v010-types" } -enclave_cosmwasm_v1_types = { path = "../cosmwasm-v1-types" } +cw_types_v010 = { path = "../cosmwasm-types/v0.10" } +cw_types_v1 = { path = "../cosmwasm-types/v1.0" } +cw_types_generic = {path = "../cosmwasm-types/generic"} enclave_utils = { path = "../utils" } serde = { git = "https://github.com/mesalock-linux/serde-sgx", features = [ "derive" diff --git a/cosmwasm/enclaves/shared/contract-engine/src/contract_operations.rs b/cosmwasm/enclaves/shared/contract-engine/src/contract_operations.rs index 7e0381f44..95a96a81b 100644 --- a/cosmwasm/enclaves/shared/contract-engine/src/contract_operations.rs +++ b/cosmwasm/enclaves/shared/contract-engine/src/contract_operations.rs @@ -6,15 +6,14 @@ use crate::contract_validation::{ReplyParams, ValidatedMessage}; use crate::external::results::{HandleSuccess, InitSuccess, QuerySuccess}; use crate::wasm::CosmWasmApiVersion; use cosmos_proto::tx::signing::SignMode; -use cosmwasm_v010_types::types::CanonicalAddr; +use cw_types_generic::{BaseEnv, CwEnv}; +use cw_types_v010; +use cw_types_v010::encoding::Binary; +use cw_types_v010::types::CanonicalAddr; +use cw_types_v1::addresses::Addr; +use cw_types_v1::results::{DecryptedReply, Event, Reply, SubMsgResponse, SubMsgResult}; +use cw_types_v1::timestamp::Timestamp; use enclave_cosmos_types::types::{ContractCode, HandleType, SigInfo}; -use enclave_cosmwasm_v010_types as cosmwasm_v010_types; -use enclave_cosmwasm_v010_types::encoding::Binary; -use enclave_cosmwasm_v1_types::addresses::Addr; -use enclave_cosmwasm_v1_types::results::{ - DecryptedReply, Event, Reply, SubMsgResponse, SubMsgResult, -}; -use enclave_cosmwasm_v1_types::timestamp::Timestamp; use enclave_crypto::{Ed25519PublicKey, HASH_SIZE}; use enclave_utils::coalesce; @@ -56,40 +55,42 @@ pub fn init( sig_info: &[u8], // info about signature verification ) -> Result { let contract_code = ContractCode::new(contract); + let contract_hash = contract_code.hash(); - let mut env_v010: cosmwasm_v010_types::types::Env = - serde_json::from_slice(env).map_err(|err| { - warn!( - "init got an error while trying to deserialize env input bytes into json {:?}: {}", - String::from_utf8_lossy(&env), - err - ); - EnclaveError::FailedToDeserialize - })?; - env_v010.contract_code_hash = hex::encode(contract_code.hash()); - - let canonical_contract_address = CanonicalAddr::from_human(&env_v010.contract.address).map_err(|err| { + let base_env: BaseEnv = serde_json::from_slice(env).map_err(|err| { warn!( - "init got an error while trying to deserialize env_v010.contract.address from bech32 string to bytes {:?}: {}", - env_v010.contract.address, err + "init got an error while trying to deserialize env input bytes into json {:?}: {}", + String::from_utf8_lossy(&env), + err ); EnclaveError::FailedToDeserialize })?; - trace!("init env_v010: {:?}", env_v010); + let (sender, contract_address, block_height, sent_funds) = base_env.get_verification_params(); - let canonical_sender_address = CanonicalAddr::from_human(&env_v010.message.sender).map_err(|err| { + let canonical_contract_address = CanonicalAddr::from_human(&contract_address).map_err(|err| { + warn!( + "init got an error while trying to deserialize env_v010.contract.address from bech32 string to bytes {:?}: {}", + contract_address, err + ); + EnclaveError::FailedToDeserialize + })?; + // + // trace!("init env_v010: {:?}", env_v010); + // + let canonical_sender_address = CanonicalAddr::from_human(&sender).map_err(|err| { warn!( "init got an error while trying to deserialize env_v010.message.sender from bech32 string to bytes {:?}: {}", - env_v010.message.sender, err + sender, err ); EnclaveError::FailedToDeserialize })?; let contract_key = generate_encryption_key( - &env_v010, - contract_code.hash(), - &(canonical_contract_address.0).0, + &canonical_sender_address, + &block_height, + &contract_hash, + &canonical_contract_address, )?; trace!("init contract key: {:?}", hex::encode(contract_key)); @@ -105,7 +106,13 @@ pub fn init( trace!("init input before decryption: {:?}", base64::encode(&msg)); let secret_msg = SecretMessage::from_slice(msg)?; - verify_params(&parsed_sig_info, &env_v010, &secret_msg)?; + verify_params( + &parsed_sig_info, + &sent_funds, + &canonical_sender_address, + &contract_address, + &secret_msg, + )?; let decrypted_msg = secret_msg.decrypt()?; @@ -129,11 +136,15 @@ pub fn init( secret_msg.user_public_key, )?; - let (contract_env_bytes, contract_msg_info_bytes) = - env_to_env_msg_info_bytes(&engine, &mut env_v010)?; + let mut versioned_env = + base_env.into_versioned_env(&engine.contract_instance.cosmwasm_api_version); - let env_ptr = engine.write_to_memory(&contract_env_bytes)?; - let msg_info_ptr = engine.write_to_memory(&contract_msg_info_bytes)?; + versioned_env.set_contract_hash(&contract_hash); + + let (env_bytes, msg_info_bytes) = versioned_env.get_wasm_ptrs()?; + + let env_ptr = engine.write_to_memory(&env_bytes)?; + let msg_info_ptr = engine.write_to_memory(&msg_info_bytes)?; let msg_ptr = engine.write_to_memory(&validated_msg)?; // This wrapper is used to coalesce all errors in this block to one object @@ -148,7 +159,7 @@ pub fn init( output, &secret_msg, &canonical_contract_address, - &env_v010.contract_code_hash, + versioned_env.get_contract_hash(), reply_params, &canonical_sender_address, false, @@ -523,14 +534,13 @@ pub fn handle( ) -> Result { let contract_code = ContractCode::new(contract); - let mut env_v010: cosmwasm_v010_types::types::Env = - serde_json::from_slice(env).map_err(|err| { - warn!( + let mut env_v010: cw_types_v010::types::Env = serde_json::from_slice(env).map_err(|err| { + warn!( "handle got an error while trying to deserialize env input bytes into json {:?}: {}", env, err ); - EnclaveError::FailedToDeserialize - })?; + EnclaveError::FailedToDeserialize + })?; env_v010.contract_code_hash = hex::encode(contract_code.hash()); trace!("handle env_v010: {:?}", env_v010); @@ -585,7 +595,13 @@ pub fn handle( // Reply (that is not WASM reply) if should_validate_sig_info { // Verify env parameters against the signed tx - verify_params(&parsed_sig_info, &env_v010, &secret_msg)?; + verify_params( + &parsed_sig_info, + &env_v010.message.sent_funds, + &canonical_sender_address, + &env_v010.contract.address, + &secret_msg, + )?; } let mut validated_msg = decrypted_msg.clone(); @@ -671,14 +687,13 @@ pub fn query( ) -> Result { let contract_code = ContractCode::new(contract); - let mut env_v010: cosmwasm_v010_types::types::Env = - serde_json::from_slice(env).map_err(|err| { - warn!( - "query got an error while trying to deserialize env input bytes into json {:?}: {}", - env, err - ); - EnclaveError::FailedToDeserialize - })?; + let mut env_v010: cw_types_v010::types::Env = serde_json::from_slice(env).map_err(|err| { + warn!( + "query got an error while trying to deserialize env input bytes into json {:?}: {}", + env, err + ); + EnclaveError::FailedToDeserialize + })?; env_v010.contract_code_hash = hex::encode(contract_code.hash()); trace!("query env_v010: {:?}", env_v010); @@ -784,7 +799,7 @@ fn start_engine( fn env_to_env_msg_info_bytes( engine: &Engine, - env_v010: &mut cosmwasm_v010_types::types::Env, + env_v010: &mut cw_types_v010::types::Env, ) -> Result<(Vec, Vec), EnclaveError> { match engine.contract_instance.cosmwasm_api_version { CosmWasmApiVersion::V010 => { @@ -812,13 +827,13 @@ fn env_to_env_msg_info_bytes( Ok((env_v010_bytes, msg_info_v010_bytes)) } CosmWasmApiVersion::V1 => { - let env_v1 = enclave_cosmwasm_v1_types::types::Env { - block: enclave_cosmwasm_v1_types::types::BlockInfo { + let env_v1 = cw_types_v1::types::Env { + block: cw_types_v1::types::BlockInfo { height: env_v010.block.height, time: Timestamp::from_nanos(env_v010.block.time), chain_id: env_v010.block.chain_id.clone(), }, - contract: enclave_cosmwasm_v1_types::types::ContractInfo { + contract: cw_types_v1::types::ContractInfo { address: Addr(env_v010.contract.address.0.clone()), code_hash: env_v010.contract_code_hash.clone(), }, @@ -832,19 +847,16 @@ fn env_to_env_msg_info_bytes( EnclaveError::FailedToSerialize })?; - let msg_info_v1 = enclave_cosmwasm_v1_types::types::MessageInfo { + let msg_info_v1 = cw_types_v1::types::MessageInfo { sender: Addr(env_v010.message.sender.0.clone()), funds: env_v010 .message .sent_funds .iter() .map(|coin| { - enclave_cosmwasm_v1_types::coins::Coin::new( - coin.amount.u128(), - coin.denom.clone(), - ) + cw_types_v1::coins::Coin::new(coin.amount.u128(), coin.denom.clone()) }) - .collect::>(), + .collect::>(), }; let msg_info_v1_bytes = serde_json::to_vec(&msg_info_v1).map_err(|err| { diff --git a/cosmwasm/enclaves/shared/contract-engine/src/contract_validation.rs b/cosmwasm/enclaves/shared/contract-engine/src/contract_validation.rs index 4faf8d350..1b2a26cc5 100644 --- a/cosmwasm/enclaves/shared/contract-engine/src/contract_validation.rs +++ b/cosmwasm/enclaves/shared/contract-engine/src/contract_validation.rs @@ -1,13 +1,13 @@ -use enclave_cosmwasm_v1_types::results::REPLY_ENCRYPTION_MAGIC_BYTES; +use cw_types_v1::results::REPLY_ENCRYPTION_MAGIC_BYTES; use log::*; use enclave_ffi_types::EnclaveError; +use cw_types_v010::types::{CanonicalAddr, Coin, Env, HumanAddr}; use enclave_cosmos_types::traits::CosmosAminoPubkey; use enclave_cosmos_types::types::{ ContractCode, CosmWasmMsg, CosmosPubKey, SigInfo, SignDoc, StdSignDoc, }; -use enclave_cosmwasm_v010_types::types::{CanonicalAddr, Coin, Env, HumanAddr}; use enclave_crypto::traits::VerifyingKey; use enclave_crypto::{sha_256, AESKey, Hmac, Kdf, HASH_SIZE, KEY_MANAGER}; @@ -22,30 +22,32 @@ const HEX_ENCODED_HASH_SIZE: usize = HASH_SIZE * 2; const SIZE_OF_U64: usize = 8; pub fn generate_encryption_key( - env: &Env, - contract_hash: [u8; HASH_SIZE], - contract_address: &[u8], + sender: &CanonicalAddr, + block_height: &u64, + contract_hash: &[u8; HASH_SIZE], + contract_address: &CanonicalAddr, ) -> Result<[u8; CONTRACT_KEY_LENGTH], EnclaveError> { let consensus_state_ikm = KEY_MANAGER.get_consensus_state_ikm().unwrap(); - let (_, sender_address_u5) = bech32::decode(env.message.sender.as_str()).map_err(|err| { - warn!( - "got an error while trying to deserialize env.message.sender from bech32 string to bytes {:?}: {}", - env.message.sender, err - ); - EnclaveError::FailedToDeserialize - })?; - let snder_address: Vec = sender_address_u5.iter().map(|x| x.to_u8()).collect(); + // todo: check that this is just getting the canonicaladdr + // let (_, sender_address_u5) = bech32::decode(sender.as_str()).map_err(|err| { + // warn!( + // "got an error while trying to deserialize env.message.sender from bech32 string to bytes {:?}: {}", + // env.message.sender, err + // ); + // EnclaveError::FailedToDeserialize + // })?; + // let snder_address: Vec = sender_address_u5.iter().map(|x| x.to_u8()).collect(); - let sender_id = generate_sender_id(&snder_address, env.block.height as u64); + let sender_id = generate_sender_id(&(sender.0).0, block_height); let mut encryption_key = [0u8; 64]; let authenticated_contract_id = generate_contract_id( &consensus_state_ikm, &sender_id, - &contract_hash, - contract_address, + contract_hash, + &(contract_address.0).0, ); encryption_key[0..32].copy_from_slice(&sender_id); @@ -81,7 +83,7 @@ pub fn extract_contract_key(env: &Env) -> Result<[u8; CONTRACT_KEY_LENGTH], Encl Ok(key_as_bytes) } -pub fn generate_sender_id(msg_sender: &[u8], block_height: u64) -> [u8; HASH_SIZE] { +pub fn generate_sender_id(msg_sender: &[u8], block_height: &u64) -> [u8; HASH_SIZE] { let mut input_data = msg_sender.to_vec(); input_data.extend_from_slice(&block_height.to_be_bytes()); sha_256(&input_data) @@ -210,19 +212,16 @@ pub fn validate_msg( /// Verify all the parameters sent to the enclave match up, and were signed by the right account. pub fn verify_params( sig_info: &SigInfo, - env: &Env, + sent_funds: &[Coin], + sender: &CanonicalAddr, + contract_address: &HumanAddr, msg: &SecretMessage, ) -> Result<(), EnclaveError> { info!("Verifying message signatures for: {:?}", sig_info); // If there's no callback signature - it's not a callback and there has to be a tx signer + signature if let Some(callback_sig) = &sig_info.callback_sig { - return verify_callback_sig( - callback_sig.as_slice(), - &env.message.sender, - msg, - &env.message.sent_funds, - ); + return verify_callback_sig(callback_sig.as_slice(), sender, msg, sent_funds); } trace!( @@ -230,7 +229,7 @@ pub fn verify_params( String::from_utf8_lossy(sig_info.sign_bytes.as_slice()) ); - let (sender_public_key, messages) = get_signer_and_messages(sig_info, env)?; + let (sender_public_key, messages) = get_signer_and_messages(sig_info, sender)?; trace!( "sender canonical address is: {:?}", @@ -249,7 +248,14 @@ pub fn verify_params( EnclaveError::FailedTxVerification })?; - if verify_message_params(&messages, env, &sender_public_key, msg) { + if verify_message_params( + &messages, + sender, + sent_funds, + contract_address, + &sender_public_key, + msg, + ) { info!("Parameters verified successfully"); return Ok(()); } @@ -261,7 +267,7 @@ pub fn verify_params( fn get_signer_and_messages( sign_info: &SigInfo, - env: &Env, + sender: &CanonicalAddr, ) -> Result<(CosmosPubKey, Vec), EnclaveError> { use cosmos_proto::tx::signing::SignMode::*; match sign_info.sign_mode { @@ -269,15 +275,6 @@ fn get_signer_and_messages( let sign_doc = SignDoc::from_bytes(sign_info.sign_bytes.as_slice())?; trace!("sign doc: {:?}", sign_doc); - let sender = CanonicalAddr::from_human(&env.message.sender).map_err(|err| { - warn!( - "failed to canonicalize message sender: {} {}", - env.message.sender, err - ); - EnclaveError::FailedTxVerification - })?; - trace!("sender canonical address is: {:?}", sender.0.0); - // This verifies that signatures and sign bytes are self consistent let sender_public_key = sign_doc @@ -327,16 +324,11 @@ fn get_signer_and_messages( ///This is used when contracts send callbacks to each other. fn verify_callback_sig( callback_signature: &[u8], - sender: &HumanAddr, + sender: &CanonicalAddr, msg: &SecretMessage, sent_funds: &[Coin], ) -> Result<(), EnclaveError> { - if verify_callback_sig_impl( - callback_signature, - &CanonicalAddr::from_human(sender).or(Err(EnclaveError::FailedToSerialize))?, - msg, - sent_funds, - ) { + if verify_callback_sig_impl(callback_signature, sender, msg, sent_funds) { info!("Message verified! msg.sender is the calling contract"); return Ok(()); } @@ -387,16 +379,16 @@ fn get_verified_msg<'sd>( } /// Check that the contract listed in the cosmwasm message matches the one in env -fn verify_contract(msg: &CosmWasmMsg, env: &Env) -> bool { +fn verify_contract(msg: &CosmWasmMsg, contract_address: &HumanAddr) -> bool { // Contract address is relevant only to execute, since during sending an instantiate message the contract address is not yet known match msg { CosmWasmMsg::Execute { contract, .. } => { info!("Verifying contract address.."); - let is_verified = env.contract.address == *contract; + let is_verified = contract_address == contract; if !is_verified { trace!( "Contract address sent to enclave {:?} is not the same as the signed one {:?}", - env.contract.address, + contract_address, *contract ); } @@ -408,36 +400,38 @@ fn verify_contract(msg: &CosmWasmMsg, env: &Env) -> bool { } /// Check that the funds listed in the cosmwasm message matches the ones in env -fn verify_funds(msg: &CosmWasmMsg, env: &Env) -> bool { +fn verify_funds(msg: &CosmWasmMsg, sent_funds_msg: &[Coin]) -> bool { match msg { CosmWasmMsg::Execute { sent_funds, .. } | CosmWasmMsg::Instantiate { init_funds: sent_funds, .. - } => &env.message.sent_funds == sent_funds, + } => &sent_funds_msg == sent_funds, CosmWasmMsg::Other => false, } } fn verify_message_params( messages: &[CosmWasmMsg], - env: &Env, + sender: &CanonicalAddr, + sent_funds: &[Coin], + contract_address: &HumanAddr, signer_public_key: &CosmosPubKey, sent_msg: &SecretMessage, ) -> bool { info!("Verifying sender.."); - let msg_sender = match CanonicalAddr::from_human(&env.message.sender) { - Ok(msg_sender) => msg_sender, - _ => return false, - }; + // let msg_sender = match CanonicalAddr::from_human(&env.message.sender) { + // Ok(msg_sender) => msg_sender, + // _ => return false, + // }; let signer_addr = signer_public_key.get_address(); - if signer_addr != msg_sender { + if &signer_addr != sender { warn!("Sender verification failed!"); trace!( "Message sender {:?} does not match with the message signer {:?}", - msg_sender, + sender, signer_addr ); return false; @@ -446,13 +440,13 @@ fn verify_message_params( info!("Verifying message.."); // If msg is not found (is None) then it means message verification failed, // since it didn't find a matching signed message - let msg = get_verified_msg(messages, &msg_sender, sent_msg); + let msg = get_verified_msg(messages, sender, sent_msg); if msg.is_none() { warn!("Message verification failed!"); trace!( "Message sent to contract {:?} by {:?} does not match any signed messages {:?}", sent_msg.to_vec(), - msg_sender, + sender, messages ); return false; @@ -467,13 +461,13 @@ fn verify_message_params( return false; } - if !verify_contract(msg, env) { + if !verify_contract(msg, contract_address) { warn!("Contract address verification failed!"); return false; } info!("Verifying funds.."); - if !verify_funds(msg, env) { + if !verify_funds(msg, sent_funds) { warn!("Funds verification failed!"); return false; } diff --git a/cosmwasm/enclaves/shared/contract-engine/src/io.rs b/cosmwasm/enclaves/shared/contract-engine/src/io.rs index 4ddcc6e8f..593a70ea8 100644 --- a/cosmwasm/enclaves/shared/contract-engine/src/io.rs +++ b/cosmwasm/enclaves/shared/contract-engine/src/io.rs @@ -5,9 +5,9 @@ use crate::contract_validation::ReplyParams; /// that is unique to the user and the enclave /// use super::types::{IoNonce, SecretMessage}; -use enclave_cosmwasm_v010_types::encoding::Binary; -use enclave_cosmwasm_v010_types::types::{CanonicalAddr, Coin}; -use enclave_cosmwasm_v1_types::results::{Event, Reply, ReplyOn, SubMsgResponse, SubMsgResult}; +use cw_types_v010::encoding::Binary; +use cw_types_v010::types::{CanonicalAddr, Coin}; +use cw_types_v1::results::{Event, Reply, ReplyOn, SubMsgResponse, SubMsgResult}; use enclave_ffi_types::EnclaveError; @@ -42,13 +42,13 @@ enum RawWasmOutput { }, OkV010 { #[serde(rename = "Ok")] - ok: enclave_cosmwasm_v010_types::types::ContractResult, + ok: cw_types_v010::types::ContractResult, internal_reply_enclave_sig: Option, internal_msg_id: Option, }, OkV1 { #[serde(rename = "Ok")] - ok: enclave_cosmwasm_v1_types::results::Response, + ok: cw_types_v1::results::Response, internal_reply_enclave_sig: Option, internal_msg_id: Option, }, @@ -57,7 +57,7 @@ enum RawWasmOutput { #[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] struct V010WasmOutput { #[serde(rename = "Ok")] - pub ok: Option, + pub ok: Option, #[serde(rename = "Err")] pub err: Option, } @@ -65,7 +65,7 @@ struct V010WasmOutput { #[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] struct V1WasmOutput { #[serde(rename = "Ok")] - pub ok: Option, + pub ok: Option, #[serde(rename = "Err")] pub err: Option, } @@ -242,7 +242,7 @@ pub fn encrypt_output( internal_msg_id, } => { for msg in &mut ok.messages { - if let enclave_cosmwasm_v010_types::types::CosmosMsg::Wasm(wasm_msg) = msg { + if let cw_types_v010::types::CosmosMsg::Wasm(wasm_msg) = msg { encrypt_v010_wasm_msg( wasm_msg, secret_msg.nonce, @@ -325,7 +325,7 @@ pub fn encrypt_output( internal_msg_id, } => { for sub_msg in &mut ok.messages { - if let enclave_cosmwasm_v1_types::results::CosmosMsg::Wasm(wasm_msg) = + if let cw_types_v1::results::CosmosMsg::Wasm(wasm_msg) = &mut sub_msg.msg { encrypt_v1_wasm_msg( @@ -515,20 +515,20 @@ pub fn encrypt_output( } fn encrypt_v010_wasm_msg( - wasm_msg: &mut enclave_cosmwasm_v010_types::types::WasmMsg, + wasm_msg: &mut cw_types_v010::types::WasmMsg, nonce: IoNonce, user_public_key: Ed25519PublicKey, contract_addr: &CanonicalAddr, ) -> Result<(), EnclaveError> { match wasm_msg { - enclave_cosmwasm_v010_types::types::WasmMsg::Execute { + cw_types_v010::types::WasmMsg::Execute { msg, callback_code_hash, callback_sig, send, .. } - | enclave_cosmwasm_v010_types::types::WasmMsg::Instantiate { + | cw_types_v010::types::WasmMsg::Instantiate { msg, callback_code_hash, callback_sig, @@ -555,7 +555,7 @@ fn encrypt_v010_wasm_msg( } fn encrypt_v1_wasm_msg( - wasm_msg: &mut enclave_cosmwasm_v1_types::results::WasmMsg, + wasm_msg: &mut cw_types_v1::results::WasmMsg, reply_on: &ReplyOn, msg_id: u64, // In every submessage there is a field called "id", currently used only by "reply". nonce: IoNonce, @@ -564,14 +564,14 @@ fn encrypt_v1_wasm_msg( reply_recipient_contract_hash: &str, ) -> Result<(), EnclaveError> { match wasm_msg { - enclave_cosmwasm_v1_types::results::WasmMsg::Execute { + cw_types_v1::results::WasmMsg::Execute { msg, code_hash, callback_sig, funds, .. } - | enclave_cosmwasm_v1_types::results::WasmMsg::Instantiate { + | cw_types_v1::results::WasmMsg::Instantiate { msg, code_hash, callback_sig, @@ -587,7 +587,7 @@ fn encrypt_v1_wasm_msg( let mut hash_appended_msg = code_hash.as_bytes().to_vec(); if *reply_on != ReplyOn::Never { hash_appended_msg.extend_from_slice( - enclave_cosmwasm_v1_types::results::REPLY_ENCRYPTION_MAGIC_BYTES, + cw_types_v1::results::REPLY_ENCRYPTION_MAGIC_BYTES, ); hash_appended_msg.extend_from_slice(&msg_id.to_be_bytes()); hash_appended_msg.extend_from_slice(reply_recipient_contract_hash.as_bytes()); @@ -609,11 +609,11 @@ fn encrypt_v1_wasm_msg( &msg_to_pass, &funds .iter() - .map(|coin| enclave_cosmwasm_v010_types::types::Coin { + .map(|coin| cw_types_v010::types::Coin { denom: coin.denom.clone(), - amount: enclave_cosmwasm_v010_types::math::Uint128(coin.amount.u128()), + amount: cw_types_v010::math::Uint128(coin.amount.u128()), }) - .collect::>()[..], + .collect::>()[..], )); } } diff --git a/cosmwasm/enclaves/shared/contract-engine/src/query_chain.rs b/cosmwasm/enclaves/shared/contract-engine/src/query_chain.rs index eec21d0bc..a99eb0bdc 100644 --- a/cosmwasm/enclaves/shared/contract-engine/src/query_chain.rs +++ b/cosmwasm/enclaves/shared/contract-engine/src/query_chain.rs @@ -11,7 +11,7 @@ use super::errors::WasmEngineError; use crate::external::{ecalls, ocalls}; use crate::types::{IoNonce, SecretMessage}; -use enclave_cosmwasm_v010_types::{ +use cw_types_v010::{ encoding::Binary, query::{QueryRequest, WasmQuery}, std_error::{StdError, StdResult}, diff --git a/cosmwasm/enclaves/shared/contract-engine/src/wasm/contract.rs b/cosmwasm/enclaves/shared/contract-engine/src/wasm/contract.rs index efcd11a53..95ecf74f8 100644 --- a/cosmwasm/enclaves/shared/contract-engine/src/wasm/contract.rs +++ b/cosmwasm/enclaves/shared/contract-engine/src/wasm/contract.rs @@ -9,7 +9,9 @@ use wasmi::{Error as InterpreterError, MemoryInstance, MemoryRef, ModuleRef, Run use enclave_ffi_types::{Ctx, EnclaveError}; -use enclave_cosmwasm_v010_types::consts::BECH32_PREFIX_ACC_ADDR; +use cw_types_generic::CosmWasmApiVersion; +use cw_types_v010::consts::BECH32_PREFIX_ACC_ADDR; + use enclave_crypto::{sha_256, Ed25519PublicKey, WasmApiCryptoError}; use crate::contract_validation::ContractKey; @@ -29,14 +31,6 @@ mod api_marker { pub const V1: &str = "interface_version_8"; } -/// CosmwasmApiVersion is used to decide how to handle contract inputs and outputs -pub enum CosmWasmApiVersion { - /// CosmWasm v0.10 API - V010, - /// CosmWasm v1 API - V1, -} - /// Right now ContractOperation is used to detect queris and prevent state changes #[derive(Clone, Copy, Debug)] pub enum ContractOperation { diff --git a/cosmwasm/enclaves/shared/contract-engine/src/wasm/engine.rs b/cosmwasm/enclaves/shared/contract-engine/src/wasm/engine.rs index 880cb9970..b9fefc626 100644 --- a/cosmwasm/enclaves/shared/contract-engine/src/wasm/engine.rs +++ b/cosmwasm/enclaves/shared/contract-engine/src/wasm/engine.rs @@ -4,7 +4,9 @@ use wasmi::{ModuleRef, RuntimeValue}; use enclave_ffi_types::EnclaveError; -use super::contract::{ContractInstance, CosmWasmApiVersion}; +use cw_types_generic::CosmWasmApiVersion; + +use super::contract::ContractInstance; use crate::errors::{wasmi_error_to_enclave_error, WasmEngineError}; use enclave_cosmos_types::types::HandleType; diff --git a/cosmwasm/enclaves/shared/contract-engine/src/wasm/mod.rs b/cosmwasm/enclaves/shared/contract-engine/src/wasm/mod.rs index a9883a7a1..43ed153d9 100644 --- a/cosmwasm/enclaves/shared/contract-engine/src/wasm/mod.rs +++ b/cosmwasm/enclaves/shared/contract-engine/src/wasm/mod.rs @@ -4,6 +4,7 @@ mod externals; mod import_resolver; pub mod traits; -pub use contract::{ContractInstance, ContractOperation, CosmWasmApiVersion}; +pub use contract::{ContractInstance, ContractOperation}; +pub use cw_types_generic::CosmWasmApiVersion; pub use engine::Engine; pub use import_resolver::{create_builder, WasmiImportResolver}; diff --git a/cosmwasm/enclaves/shared/cosmos-types/Cargo.toml b/cosmwasm/enclaves/shared/cosmos-types/Cargo.toml index fa2c3417f..c1ee9ace8 100644 --- a/cosmwasm/enclaves/shared/cosmos-types/Cargo.toml +++ b/cosmwasm/enclaves/shared/cosmos-types/Cargo.toml @@ -19,7 +19,7 @@ sgx_tstd = { rev = "a37ffb9449ba6d5b6e4a9d586bbab864ae732269", git = "https://gi cosmos_proto = { path = "../cosmos-proto" } enclave-ffi-types = { path = "../../ffi-types" } enclave_crypto = { path = "../crypto" } -enclave_cosmwasm_v010_types = { path = "../cosmwasm-v010-types" } +cw_types_v010 = { path = "../cosmwasm-types/v0.10" } log = "0.4.14" serde = { git = "https://github.com/mesalock-linux/serde-sgx", features = [ "derive" diff --git a/cosmwasm/enclaves/shared/cosmos-types/src/multisig.rs b/cosmwasm/enclaves/shared/cosmos-types/src/multisig.rs index daff4798b..3f8984fe2 100644 --- a/cosmwasm/enclaves/shared/cosmos-types/src/multisig.rs +++ b/cosmwasm/enclaves/shared/cosmos-types/src/multisig.rs @@ -10,7 +10,7 @@ use cosmos_proto::crypto::multisig::multisig::MultiSignature; use super::traits::CosmosAminoPubkey; -use enclave_cosmwasm_v010_types::types::CanonicalAddr; +use cw_types_v010::types::CanonicalAddr; use enclave_crypto::CryptoError; use protobuf::Message; diff --git a/cosmwasm/enclaves/shared/cosmos-types/src/single_address.rs b/cosmwasm/enclaves/shared/cosmos-types/src/single_address.rs index 7cdf08d6a..d739c3b23 100644 --- a/cosmwasm/enclaves/shared/cosmos-types/src/single_address.rs +++ b/cosmwasm/enclaves/shared/cosmos-types/src/single_address.rs @@ -2,7 +2,7 @@ use enclave_crypto::secp256k1::{Secp256k1PubKey, SECP256K1_PREFIX}; use log::warn; use super::traits::CosmosAminoPubkey; -use enclave_cosmwasm_v010_types::types::CanonicalAddr; +use cw_types_v010::types::CanonicalAddr; use enclave_crypto::hash::ripemd::ripemd160; use enclave_crypto::hash::sha::sha_256; diff --git a/cosmwasm/enclaves/shared/cosmos-types/src/traits.rs b/cosmwasm/enclaves/shared/cosmos-types/src/traits.rs index 97952c457..ec4dfff37 100644 --- a/cosmwasm/enclaves/shared/cosmos-types/src/traits.rs +++ b/cosmwasm/enclaves/shared/cosmos-types/src/traits.rs @@ -1,4 +1,4 @@ -use enclave_cosmwasm_v010_types::types::CanonicalAddr; +use cw_types_v010::types::CanonicalAddr; // https://github.com/tendermint/tendermint/blob/v0.33.3/crypto/crypto.go#L22 pub trait CosmosAminoPubkey: PartialEq { diff --git a/cosmwasm/enclaves/shared/cosmos-types/src/types.rs b/cosmwasm/enclaves/shared/cosmos-types/src/types.rs index 873a80733..ed42b6011 100644 --- a/cosmwasm/enclaves/shared/cosmos-types/src/types.rs +++ b/cosmwasm/enclaves/shared/cosmos-types/src/types.rs @@ -12,7 +12,7 @@ use enclave_crypto::{ use cosmos_proto as proto; -use enclave_cosmwasm_v010_types::{ +use cw_types_v010::{ coins::Coin, encoding::Binary, math::Uint128, diff --git a/cosmwasm/enclaves/shared/cosmwasm-types/generic/Cargo.toml b/cosmwasm/enclaves/shared/cosmwasm-types/generic/Cargo.toml new file mode 100644 index 000000000..75d926a53 --- /dev/null +++ b/cosmwasm/enclaves/shared/cosmwasm-types/generic/Cargo.toml @@ -0,0 +1,20 @@ +[package] +name = "cw_types_generic" +version = "0.1.0" +authors = ["bob"] +edition = "2018" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +serde = { git = "https://github.com/mesalock-linux/serde-sgx", features = [ + "derive" +] } +serde_json = { git = "https://github.com/mesalock-linux/serde-json-sgx" } +enclave-ffi-types = { path = "../../../ffi-types" } + +cw_types_v010 = { path = "../v0.10" } +cw_types_v1 = { path = "../v1.0" } + +log = "0.4.14" +hex = "0.4.2" diff --git a/cosmwasm/enclaves/shared/cosmwasm-types/generic/src/lib.rs b/cosmwasm/enclaves/shared/cosmwasm-types/generic/src/lib.rs new file mode 100644 index 000000000..22b4a017a --- /dev/null +++ b/cosmwasm/enclaves/shared/cosmwasm-types/generic/src/lib.rs @@ -0,0 +1,143 @@ +use log::warn; +use serde::{Deserialize, Serialize}; + +use cw_types_v010::types::{Env as V010Env, HumanAddr}; +use cw_types_v1::types::Env as V1Env; +use cw_types_v1::types::MessageInfo as V1MessageInfo; + +use cw_types_v010::types as v010types; +use cw_types_v1::types as v1types; + +use enclave_ffi_types::EnclaveError; +use hex; + +/// CosmwasmApiVersion is used to decide how to handle contract inputs and outputs +pub enum CosmWasmApiVersion { + /// CosmWasm v0.10 API + V010, + /// CosmWasm v1 API + V1, +} + +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] +#[serde(rename_all = "snake_case")] +pub struct BaseEnv(pub V010Env); + +impl BaseEnv { + pub fn get_verification_params(&self) -> (&HumanAddr, &HumanAddr, u64, &Vec) { + ( + &self.0.message.sender, + &self.0.contract.address, + self.0.block.height, + &self.0.message.sent_funds, + ) + } + + pub fn into_versioned_env(self, api_version: &CosmWasmApiVersion) -> CwEnv { + match api_version { + CosmWasmApiVersion::V010 => self.into_v010(), + CosmWasmApiVersion::V1 => self.into_v1(), + } + } + + fn into_v010(self) -> CwEnv { + CwEnv::V010Env { env: self.0 } + } + + /// This is the conversion function from the base to the new env. We assume that if there are + /// any API changes that are necessary on the base level we will have to update this as well + fn into_v1(self) -> CwEnv { + CwEnv::V1Env { + env: V1Env { + block: v1types::BlockInfo { + height: self.0.block.height, + time: v1types::Timestamp::from_nanos(self.0.block.time), + chain_id: self.0.block.chain_id.clone(), + }, + contract: v1types::ContractInfo { + address: v1types::Addr::unchecked(self.0.contract.address.0), + code_hash: self.0.contract_code_hash, + }, + }, + msg_info: v1types::MessageInfo { + sender: v1types::Addr::unchecked(self.0.message.sender.0), + funds: self + .0 + .message + .sent_funds + .into_iter() + .map(|x| x.into()) + .collect(), + }, + } + } +} + +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] +#[serde(rename_all = "snake_case")] +pub enum CwEnv { + V010Env { env: V010Env }, + V1Env { env: V1Env, msg_info: V1MessageInfo }, +} + +impl CwEnv { + pub fn get_contract_hash(&self) -> &String { + match self { + CwEnv::V010Env { env } => &env.contract_code_hash, + CwEnv::V1Env { env, .. } => &env.contract.code_hash, + } + } + + pub fn set_contract_hash(&mut self, contract_hash: &[u8; 32]) { + match self { + CwEnv::V010Env { env } => { + env.contract_code_hash = hex::encode(contract_hash); + } + CwEnv::V1Env { env, .. } => { + env.contract.code_hash = hex::encode(contract_hash); + } + } + } + + pub fn get_wasm_ptrs(&self) -> Result<(Vec, Vec), EnclaveError> { + match self { + CwEnv::V010Env { env } => { + let env_bytes = serde_json::to_vec(env).map_err(|err| { + warn!( + "got an error while trying to serialize env_v010 (cosmwasm v0.10) into bytes {:?}: {}", + env, err + ); + EnclaveError::FailedToSerialize + })?; + + Ok((env_bytes, vec![])) + } + CwEnv::V1Env { env, msg_info } => { + let env_bytes = serde_json::to_vec(env).map_err(|err| { + warn!( + "got an error while trying to serialize env_v010 (cosmwasm v0.10) into bytes {:?}: {}", + env, err + ); + EnclaveError::FailedToSerialize + })?; + let msg_bytes = serde_json::to_vec(msg_info).map_err(|err| { + warn!( + "got an error while trying to serialize env_v010 (cosmwasm v0.10) into bytes {:?}: {}", + msg_info, err + ); + EnclaveError::FailedToSerialize + })?; + + Ok((env_bytes, msg_bytes)) + } + } + } +} + +#[cfg(test)] +mod tests { + #[test] + fn it_works() { + assert_eq!(2 + 2, 4); + } +} diff --git a/cosmwasm/enclaves/shared/cosmwasm-v010-types/Cargo.toml b/cosmwasm/enclaves/shared/cosmwasm-types/v0.10/Cargo.toml similarity index 91% rename from cosmwasm/enclaves/shared/cosmwasm-v010-types/Cargo.toml rename to cosmwasm/enclaves/shared/cosmwasm-types/v0.10/Cargo.toml index 75c2e4b16..246aae17a 100644 --- a/cosmwasm/enclaves/shared/cosmwasm-v010-types/Cargo.toml +++ b/cosmwasm/enclaves/shared/cosmwasm-types/v0.10/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "enclave_cosmwasm_v010_types" +name = "cw_types_v010" version = "1.2.4" authors = ["Cashmaney "] edition = "2018" @@ -13,7 +13,7 @@ sgx_tstd = { rev = "a37ffb9449ba6d5b6e4a9d586bbab864ae732269", git = "https://gi ] } [dependencies] -enclave-ffi-types = { path = "../../ffi-types" } +enclave-ffi-types = { path = "../../../ffi-types" } log = "0.4.8" serde = { git = "https://github.com/mesalock-linux/serde-sgx", features = [ "derive" diff --git a/cosmwasm/enclaves/shared/cosmwasm-v010-types/Makefile b/cosmwasm/enclaves/shared/cosmwasm-types/v0.10/Makefile similarity index 89% rename from cosmwasm/enclaves/shared/cosmwasm-v010-types/Makefile rename to cosmwasm/enclaves/shared/cosmwasm-types/v0.10/Makefile index ad94f0548..165f1ac7a 100644 --- a/cosmwasm/enclaves/shared/cosmwasm-v010-types/Makefile +++ b/cosmwasm/enclaves/shared/cosmwasm-types/v0.10/Makefile @@ -6,7 +6,7 @@ else Rust_Flags := "-Z force-unstable-if-unmarked -C target-cpu=skylake" endif -Rust_Target_Path = "$(CURDIR)/../../xargo" +Rust_Target_Path = "$(CURDIR)/../../../xargo" .PHONY: check check: diff --git a/cosmwasm/enclaves/shared/cosmwasm-v010-types/src/coins.rs b/cosmwasm/enclaves/shared/cosmwasm-types/v0.10/src/coins.rs similarity index 100% rename from cosmwasm/enclaves/shared/cosmwasm-v010-types/src/coins.rs rename to cosmwasm/enclaves/shared/cosmwasm-types/v0.10/src/coins.rs diff --git a/cosmwasm/enclaves/shared/cosmwasm-v010-types/src/consts.rs b/cosmwasm/enclaves/shared/cosmwasm-types/v0.10/src/consts.rs similarity index 100% rename from cosmwasm/enclaves/shared/cosmwasm-v010-types/src/consts.rs rename to cosmwasm/enclaves/shared/cosmwasm-types/v0.10/src/consts.rs diff --git a/cosmwasm/enclaves/shared/cosmwasm-v010-types/src/encoding.rs b/cosmwasm/enclaves/shared/cosmwasm-types/v0.10/src/encoding.rs similarity index 100% rename from cosmwasm/enclaves/shared/cosmwasm-v010-types/src/encoding.rs rename to cosmwasm/enclaves/shared/cosmwasm-types/v0.10/src/encoding.rs diff --git a/cosmwasm/enclaves/shared/cosmwasm-v010-types/src/lib.rs b/cosmwasm/enclaves/shared/cosmwasm-types/v0.10/src/lib.rs similarity index 100% rename from cosmwasm/enclaves/shared/cosmwasm-v010-types/src/lib.rs rename to cosmwasm/enclaves/shared/cosmwasm-types/v0.10/src/lib.rs diff --git a/cosmwasm/enclaves/shared/cosmwasm-v010-types/src/math.rs b/cosmwasm/enclaves/shared/cosmwasm-types/v0.10/src/math.rs similarity index 100% rename from cosmwasm/enclaves/shared/cosmwasm-v010-types/src/math.rs rename to cosmwasm/enclaves/shared/cosmwasm-types/v0.10/src/math.rs diff --git a/cosmwasm/enclaves/shared/cosmwasm-v010-types/src/query.rs b/cosmwasm/enclaves/shared/cosmwasm-types/v0.10/src/query.rs similarity index 100% rename from cosmwasm/enclaves/shared/cosmwasm-v010-types/src/query.rs rename to cosmwasm/enclaves/shared/cosmwasm-types/v0.10/src/query.rs diff --git a/cosmwasm/enclaves/shared/cosmwasm-v010-types/src/std_error.rs b/cosmwasm/enclaves/shared/cosmwasm-types/v0.10/src/std_error.rs similarity index 100% rename from cosmwasm/enclaves/shared/cosmwasm-v010-types/src/std_error.rs rename to cosmwasm/enclaves/shared/cosmwasm-types/v0.10/src/std_error.rs diff --git a/cosmwasm/enclaves/shared/cosmwasm-v010-types/src/system_error.rs b/cosmwasm/enclaves/shared/cosmwasm-types/v0.10/src/system_error.rs similarity index 100% rename from cosmwasm/enclaves/shared/cosmwasm-v010-types/src/system_error.rs rename to cosmwasm/enclaves/shared/cosmwasm-types/v0.10/src/system_error.rs diff --git a/cosmwasm/enclaves/shared/cosmwasm-v010-types/src/types.rs b/cosmwasm/enclaves/shared/cosmwasm-types/v0.10/src/types.rs similarity index 100% rename from cosmwasm/enclaves/shared/cosmwasm-v010-types/src/types.rs rename to cosmwasm/enclaves/shared/cosmwasm-types/v0.10/src/types.rs diff --git a/cosmwasm/enclaves/shared/cosmwasm-v1-types/Cargo.toml b/cosmwasm/enclaves/shared/cosmwasm-types/v1.0/Cargo.toml similarity index 86% rename from cosmwasm/enclaves/shared/cosmwasm-v1-types/Cargo.toml rename to cosmwasm/enclaves/shared/cosmwasm-types/v1.0/Cargo.toml index 2fcbdc5a6..03afdf208 100644 --- a/cosmwasm/enclaves/shared/cosmwasm-v1-types/Cargo.toml +++ b/cosmwasm/enclaves/shared/cosmwasm-types/v1.0/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "enclave_cosmwasm_v1_types" +name = "cw_types_v1" version = "1.2.4" authors = ["Cashmaney "] edition = "2018" @@ -13,8 +13,8 @@ sgx_tstd = { rev = "a37ffb9449ba6d5b6e4a9d586bbab864ae732269", git = "https://gi ] } [dependencies] -enclave-ffi-types = { path = "../../ffi-types" } -enclave_cosmwasm_v010_types = { path = "../cosmwasm-v010-types" } +enclave-ffi-types = { path = "../../../ffi-types" } +cw_types_v010 = { path = "../v0.10" } log = "0.4.8" serde = { git = "https://github.com/mesalock-linux/serde-sgx", features = [ "derive" diff --git a/cosmwasm/enclaves/shared/cosmwasm-v1-types/Makefile b/cosmwasm/enclaves/shared/cosmwasm-types/v1.0/Makefile similarity index 89% rename from cosmwasm/enclaves/shared/cosmwasm-v1-types/Makefile rename to cosmwasm/enclaves/shared/cosmwasm-types/v1.0/Makefile index ad94f0548..165f1ac7a 100644 --- a/cosmwasm/enclaves/shared/cosmwasm-v1-types/Makefile +++ b/cosmwasm/enclaves/shared/cosmwasm-types/v1.0/Makefile @@ -6,7 +6,7 @@ else Rust_Flags := "-Z force-unstable-if-unmarked -C target-cpu=skylake" endif -Rust_Target_Path = "$(CURDIR)/../../xargo" +Rust_Target_Path = "$(CURDIR)/../../../xargo" .PHONY: check check: diff --git a/cosmwasm/enclaves/shared/cosmwasm-v1-types/src/addresses.rs b/cosmwasm/enclaves/shared/cosmwasm-types/v1.0/src/addresses.rs similarity index 100% rename from cosmwasm/enclaves/shared/cosmwasm-v1-types/src/addresses.rs rename to cosmwasm/enclaves/shared/cosmwasm-types/v1.0/src/addresses.rs diff --git a/cosmwasm/enclaves/shared/cosmwasm-v1-types/src/coins.rs b/cosmwasm/enclaves/shared/cosmwasm-types/v1.0/src/coins.rs similarity index 79% rename from cosmwasm/enclaves/shared/cosmwasm-v1-types/src/coins.rs rename to cosmwasm/enclaves/shared/cosmwasm-types/v1.0/src/coins.rs index 0a54f1959..e923772a0 100644 --- a/cosmwasm/enclaves/shared/cosmwasm-v1-types/src/coins.rs +++ b/cosmwasm/enclaves/shared/cosmwasm-types/v1.0/src/coins.rs @@ -1,6 +1,8 @@ use serde::{Deserialize, Serialize}; use std::fmt; +use cw_types_v010::coins::Coin as V010Coin; + use super::math::Uint128; #[derive(Serialize, Deserialize, Clone, Default, Debug, PartialEq)] @@ -27,3 +29,12 @@ impl fmt::Display for Coin { write!(f, "{}{}", self.amount, self.denom) } } + +impl From for Coin { + fn from(other: V010Coin) -> Self { + Coin { + amount: other.amount.into(), + denom: other.denom, + } + } +} diff --git a/cosmwasm/enclaves/shared/cosmwasm-v1-types/src/errors/crypto_error.rs b/cosmwasm/enclaves/shared/cosmwasm-types/v1.0/src/errors/crypto_error.rs similarity index 100% rename from cosmwasm/enclaves/shared/cosmwasm-v1-types/src/errors/crypto_error.rs rename to cosmwasm/enclaves/shared/cosmwasm-types/v1.0/src/errors/crypto_error.rs diff --git a/cosmwasm/enclaves/shared/cosmwasm-v1-types/src/errors/mod.rs b/cosmwasm/enclaves/shared/cosmwasm-types/v1.0/src/errors/mod.rs similarity index 100% rename from cosmwasm/enclaves/shared/cosmwasm-v1-types/src/errors/mod.rs rename to cosmwasm/enclaves/shared/cosmwasm-types/v1.0/src/errors/mod.rs diff --git a/cosmwasm/enclaves/shared/cosmwasm-v1-types/src/errors/recover_pubkey_error.rs b/cosmwasm/enclaves/shared/cosmwasm-types/v1.0/src/errors/recover_pubkey_error.rs similarity index 100% rename from cosmwasm/enclaves/shared/cosmwasm-v1-types/src/errors/recover_pubkey_error.rs rename to cosmwasm/enclaves/shared/cosmwasm-types/v1.0/src/errors/recover_pubkey_error.rs diff --git a/cosmwasm/enclaves/shared/cosmwasm-v1-types/src/errors/std_error.rs b/cosmwasm/enclaves/shared/cosmwasm-types/v1.0/src/errors/std_error.rs similarity index 100% rename from cosmwasm/enclaves/shared/cosmwasm-v1-types/src/errors/std_error.rs rename to cosmwasm/enclaves/shared/cosmwasm-types/v1.0/src/errors/std_error.rs diff --git a/cosmwasm/enclaves/shared/cosmwasm-v1-types/src/errors/verification_error.rs b/cosmwasm/enclaves/shared/cosmwasm-types/v1.0/src/errors/verification_error.rs similarity index 100% rename from cosmwasm/enclaves/shared/cosmwasm-v1-types/src/errors/verification_error.rs rename to cosmwasm/enclaves/shared/cosmwasm-types/v1.0/src/errors/verification_error.rs diff --git a/cosmwasm/enclaves/shared/cosmwasm-v1-types/src/lib.rs b/cosmwasm/enclaves/shared/cosmwasm-types/v1.0/src/lib.rs similarity index 100% rename from cosmwasm/enclaves/shared/cosmwasm-v1-types/src/lib.rs rename to cosmwasm/enclaves/shared/cosmwasm-types/v1.0/src/lib.rs diff --git a/cosmwasm/enclaves/shared/cosmwasm-v1-types/src/math/mod.rs b/cosmwasm/enclaves/shared/cosmwasm-types/v1.0/src/math/mod.rs similarity index 100% rename from cosmwasm/enclaves/shared/cosmwasm-v1-types/src/math/mod.rs rename to cosmwasm/enclaves/shared/cosmwasm-types/v1.0/src/math/mod.rs diff --git a/cosmwasm/enclaves/shared/cosmwasm-v1-types/src/math/uint128.rs b/cosmwasm/enclaves/shared/cosmwasm-types/v1.0/src/math/uint128.rs similarity index 98% rename from cosmwasm/enclaves/shared/cosmwasm-v1-types/src/math/uint128.rs rename to cosmwasm/enclaves/shared/cosmwasm-types/v1.0/src/math/uint128.rs index 919804442..46c1df620 100644 --- a/cosmwasm/enclaves/shared/cosmwasm-v1-types/src/math/uint128.rs +++ b/cosmwasm/enclaves/shared/cosmwasm-types/v1.0/src/math/uint128.rs @@ -6,6 +6,8 @@ use std::ops; use crate::errors::{DivideByZeroError, OverflowError, OverflowOperation, StdError}; +use cw_types_v010::math::Uint128 as V010Uint128; + /// A thin wrapper around u128 that is using strings for JSON encoding/decoding, /// such that the full u128 range can be used for clients that convert JSON numbers to floats, /// like JavaScript and jq. @@ -321,6 +323,12 @@ impl<'a> Sum<&'a Uint128> for Uint128 { } } +impl From for Uint128 { + fn from(other: V010Uint128) -> Self { + Uint128(other.0) + } +} + /// This module is purely a workaround that lets us ignore lints for all the code /// the `construct_uint!` macro generates. #[allow(clippy::all)] diff --git a/cosmwasm/enclaves/shared/cosmwasm-v1-types/src/math/uint64.rs b/cosmwasm/enclaves/shared/cosmwasm-types/v1.0/src/math/uint64.rs similarity index 100% rename from cosmwasm/enclaves/shared/cosmwasm-v1-types/src/math/uint64.rs rename to cosmwasm/enclaves/shared/cosmwasm-types/v1.0/src/math/uint64.rs diff --git a/cosmwasm/enclaves/shared/cosmwasm-v1-types/src/results/contract_result.rs b/cosmwasm/enclaves/shared/cosmwasm-types/v1.0/src/results/contract_result.rs similarity index 100% rename from cosmwasm/enclaves/shared/cosmwasm-v1-types/src/results/contract_result.rs rename to cosmwasm/enclaves/shared/cosmwasm-types/v1.0/src/results/contract_result.rs diff --git a/cosmwasm/enclaves/shared/cosmwasm-v1-types/src/results/cosmos_msg.rs b/cosmwasm/enclaves/shared/cosmwasm-types/v1.0/src/results/cosmos_msg.rs similarity index 99% rename from cosmwasm/enclaves/shared/cosmwasm-v1-types/src/results/cosmos_msg.rs rename to cosmwasm/enclaves/shared/cosmwasm-types/v1.0/src/results/cosmos_msg.rs index f141bff5f..9c43a1dd9 100644 --- a/cosmwasm/enclaves/shared/cosmwasm-v1-types/src/results/cosmos_msg.rs +++ b/cosmwasm/enclaves/shared/cosmwasm-types/v1.0/src/results/cosmos_msg.rs @@ -4,7 +4,7 @@ use std::fmt; use crate::coins::Coin; #[cfg(feature = "stargate")] use crate::ibc::IbcMsg; -use enclave_cosmwasm_v010_types::encoding::Binary; +use cw_types_v010::encoding::Binary; use super::Empty; diff --git a/cosmwasm/enclaves/shared/cosmwasm-v1-types/src/results/empty.rs b/cosmwasm/enclaves/shared/cosmwasm-types/v1.0/src/results/empty.rs similarity index 100% rename from cosmwasm/enclaves/shared/cosmwasm-v1-types/src/results/empty.rs rename to cosmwasm/enclaves/shared/cosmwasm-types/v1.0/src/results/empty.rs diff --git a/cosmwasm/enclaves/shared/cosmwasm-v1-types/src/results/events.rs b/cosmwasm/enclaves/shared/cosmwasm-types/v1.0/src/results/events.rs similarity index 94% rename from cosmwasm/enclaves/shared/cosmwasm-v1-types/src/results/events.rs rename to cosmwasm/enclaves/shared/cosmwasm-types/v1.0/src/results/events.rs index 34e5e8450..caa8bb305 100644 --- a/cosmwasm/enclaves/shared/cosmwasm-v1-types/src/results/events.rs +++ b/cosmwasm/enclaves/shared/cosmwasm-types/v1.0/src/results/events.rs @@ -1,4 +1,4 @@ -use enclave_cosmwasm_v010_types::types::LogAttribute; +use cw_types_v010::types::LogAttribute; use serde::{Deserialize, Serialize}; /// A full [*Cosmos SDK* event]. /// diff --git a/cosmwasm/enclaves/shared/cosmwasm-v1-types/src/results/mod.rs b/cosmwasm/enclaves/shared/cosmwasm-types/v1.0/src/results/mod.rs similarity index 100% rename from cosmwasm/enclaves/shared/cosmwasm-v1-types/src/results/mod.rs rename to cosmwasm/enclaves/shared/cosmwasm-types/v1.0/src/results/mod.rs diff --git a/cosmwasm/enclaves/shared/cosmwasm-v1-types/src/results/response.rs b/cosmwasm/enclaves/shared/cosmwasm-types/v1.0/src/results/response.rs similarity index 97% rename from cosmwasm/enclaves/shared/cosmwasm-v1-types/src/results/response.rs rename to cosmwasm/enclaves/shared/cosmwasm-types/v1.0/src/results/response.rs index 1a6054a0c..956636af7 100644 --- a/cosmwasm/enclaves/shared/cosmwasm-v1-types/src/results/response.rs +++ b/cosmwasm/enclaves/shared/cosmwasm-types/v1.0/src/results/response.rs @@ -1,7 +1,7 @@ use serde::{Deserialize, Serialize}; use std::fmt; -use enclave_cosmwasm_v010_types::{encoding::Binary, types::LogAttribute}; +use cw_types_v010::{encoding::Binary, types::LogAttribute}; use super::{Empty, Event, SubMsg}; diff --git a/cosmwasm/enclaves/shared/cosmwasm-v1-types/src/results/submessages.rs b/cosmwasm/enclaves/shared/cosmwasm-types/v1.0/src/results/submessages.rs similarity index 98% rename from cosmwasm/enclaves/shared/cosmwasm-v1-types/src/results/submessages.rs rename to cosmwasm/enclaves/shared/cosmwasm-types/v1.0/src/results/submessages.rs index b408467ff..78e0c00bf 100644 --- a/cosmwasm/enclaves/shared/cosmwasm-v1-types/src/results/submessages.rs +++ b/cosmwasm/enclaves/shared/cosmwasm-types/v1.0/src/results/submessages.rs @@ -1,7 +1,7 @@ use serde::{Deserialize, Serialize}; use std::fmt; -use enclave_cosmwasm_v010_types::encoding::Binary; +use cw_types_v010::encoding::Binary; use super::{CosmosMsg, Empty, Event}; diff --git a/cosmwasm/enclaves/shared/cosmwasm-v1-types/src/timestamp.rs b/cosmwasm/enclaves/shared/cosmwasm-types/v1.0/src/timestamp.rs similarity index 100% rename from cosmwasm/enclaves/shared/cosmwasm-v1-types/src/timestamp.rs rename to cosmwasm/enclaves/shared/cosmwasm-types/v1.0/src/timestamp.rs diff --git a/cosmwasm/enclaves/shared/cosmwasm-v1-types/src/types.rs b/cosmwasm/enclaves/shared/cosmwasm-types/v1.0/src/types.rs similarity index 97% rename from cosmwasm/enclaves/shared/cosmwasm-v1-types/src/types.rs rename to cosmwasm/enclaves/shared/cosmwasm-types/v1.0/src/types.rs index e78d3e21b..537a05af8 100644 --- a/cosmwasm/enclaves/shared/cosmwasm-v1-types/src/types.rs +++ b/cosmwasm/enclaves/shared/cosmwasm-types/v1.0/src/types.rs @@ -1,8 +1,8 @@ use serde::{Deserialize, Serialize}; -use super::addresses::Addr; -use super::coins::Coin; -use super::timestamp::Timestamp; +pub use super::addresses::Addr; +pub use super::coins::Coin; +pub use super::timestamp::Timestamp; #[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] pub struct Env { From 0725def6f09e80b9d75a3a1af34d6f6650faa8ed Mon Sep 17 00:00:00 2001 From: Assaf Morami Date: Tue, 23 Aug 2022 20:57:06 +0300 Subject: [PATCH 49/93] Integration tests: finish implementing v1 contract query --- integration-tests/contract-v1/src/contract.rs | 22 ++++++++++++------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/integration-tests/contract-v1/src/contract.rs b/integration-tests/contract-v1/src/contract.rs index 09949c2f5..f98b32cdc 100644 --- a/integration-tests/contract-v1/src/contract.rs +++ b/integration-tests/contract-v1/src/contract.rs @@ -1,10 +1,10 @@ use cosmwasm_std::{ entry_point, to_binary, to_vec, AllBalanceResponse, AllDelegationsResponse, AllValidatorsResponse, BalanceResponse, BankMsg, BankQuery, Binary, BondedDenomResponse, - ChannelResponse, ContractInfoResponse, CosmosMsg, DelegationResponse, Deps, DepsMut, - DistributionMsg, Empty, Env, GovMsg, IbcMsg, IbcQuery, ListChannelsResponse, MessageInfo, - PortIdResponse, QueryRequest, Response, StakingMsg, StakingQuery, StdResult, ValidatorResponse, - WasmMsg, WasmQuery, + ChannelResponse, ContractInfoResponse, ContractResult, CosmosMsg, DelegationResponse, Deps, + DepsMut, DistributionMsg, Empty, Env, GovMsg, IbcMsg, IbcQuery, ListChannelsResponse, + MessageInfo, PortIdResponse, QueryRequest, Response, StakingMsg, StakingQuery, StdError, + StdResult, ValidatorResponse, WasmMsg, WasmQuery, }; use crate::msg::{Msg, QueryMsg}; @@ -223,13 +223,19 @@ pub fn query(deps: Deps, _env: Env, msg: QueryMsg) -> StdResult { code_hash, msg, } => { - return Ok(to_binary(&deps.querier.query::( - &QueryRequest::Wasm(WasmQuery::Smart { + let result = &deps + .querier + .raw_query(&to_vec(&QueryRequest::Wasm::(WasmQuery::Smart { contract_addr, code_hash, msg, - }), - )?)?); + }))?) + .unwrap(); + + match result { + ContractResult::Ok(ok) => Ok(Binary(ok.0.to_vec())), + ContractResult::Err(err) => Err(StdError::generic_err(err)), + } } QueryMsg::WasmContractInfo { contract_addr } => { return Ok(to_binary(&deps.querier.query::( From 3849efb15345f82a7e5d61eec3aaedf832949a68 Mon Sep 17 00:00:00 2001 From: Assaf Morami Date: Tue, 23 Aug 2022 22:52:22 +0300 Subject: [PATCH 50/93] Verify EIP191 inside the enclave --- cosmwasm/enclaves/Cargo.lock | 21 +++++++++++++++++++ .../src/contract_validation.rs | 3 ++- .../shared/cosmos-proto/src/tx/signing.rs | 3 +++ .../shared/cosmos-types/src/multisig.rs | 11 +++++++--- .../enclaves/shared/cosmos-types/src/types.rs | 13 +++++++++--- cosmwasm/enclaves/shared/crypto/Cargo.toml | 5 ++--- .../enclaves/shared/crypto/src/secp256k1.rs | 15 +++++++++++-- cosmwasm/enclaves/shared/crypto/src/traits.rs | 8 ++++++- 8 files changed, 66 insertions(+), 13 deletions(-) diff --git a/cosmwasm/enclaves/Cargo.lock b/cosmwasm/enclaves/Cargo.lock index 26a972389..b5825d278 100644 --- a/cosmwasm/enclaves/Cargo.lock +++ b/cosmwasm/enclaves/Cargo.lock @@ -496,6 +496,7 @@ name = "enclave_crypto" version = "1.2.4" dependencies = [ "aes-siv", + "cosmos_proto", "derive_more", "enclave-ffi-types", "hex", @@ -508,6 +509,7 @@ dependencies = [ "sgx_tstd 1.1.3 (git+https://github.com/apache/teaclave-sgx-sdk.git?rev=a37ffb9449ba6d5b6e4a9d586bbab864ae732269)", "sgx_types 1.1.3 (git+https://github.com/apache/teaclave-sgx-sdk.git?rev=a37ffb9449ba6d5b6e4a9d586bbab864ae732269)", "sha2 0.8.2", + "sha3", "x25519-dalek", ] @@ -642,6 +644,12 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "112c678d4050afce233f4f2852bb2eb519230b3cf12f33585275537d7e41578d" +[[package]] +name = "keccak" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9b7d56ba4a8344d6be9729995e6b06f928af29998cdf79fe390cbf6b1fee838" + [[package]] name = "lazy_static" version = "1.4.0" @@ -1342,6 +1350,19 @@ dependencies = [ "opaque-debug 0.3.0", ] +[[package]] +name = "sha3" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd26bc0e7a2e3a7c959bc494caf58b72ee0c71d67704e9520f736ca7e4853ecf" +dependencies = [ + "block-buffer 0.7.3", + "byte-tools", + "digest 0.8.1", + "keccak", + "opaque-debug 0.2.3", +] + [[package]] name = "spin" version = "0.5.2" diff --git a/cosmwasm/enclaves/shared/contract-engine/src/contract_validation.rs b/cosmwasm/enclaves/shared/contract-engine/src/contract_validation.rs index 31671051c..e07031ff3 100644 --- a/cosmwasm/enclaves/shared/contract-engine/src/contract_validation.rs +++ b/cosmwasm/enclaves/shared/contract-engine/src/contract_validation.rs @@ -243,6 +243,7 @@ pub fn verify_params( .verify_bytes( sig_info.sign_bytes.as_slice(), sig_info.signature.as_slice(), + sig_info.sign_mode, ) .map_err(|err| { warn!("Signature verification failed: {:?}", err); @@ -290,7 +291,7 @@ fn get_signer_and_messages( Ok((sender_public_key.clone(), sign_doc.body.messages)) } - SIGN_MODE_LEGACY_AMINO_JSON => { + SIGN_MODE_LEGACY_AMINO_JSON | SIGN_MODE_EIP_191 => { use protobuf::well_known_types::Any as AnyProto; use protobuf::Message; diff --git a/cosmwasm/enclaves/shared/cosmos-proto/src/tx/signing.rs b/cosmwasm/enclaves/shared/cosmos-proto/src/tx/signing.rs index d73a38f55..35ace061c 100644 --- a/cosmwasm/enclaves/shared/cosmos-proto/src/tx/signing.rs +++ b/cosmwasm/enclaves/shared/cosmos-proto/src/tx/signing.rs @@ -1156,6 +1156,7 @@ pub enum SignMode { SIGN_MODE_DIRECT = 1, SIGN_MODE_TEXTUAL = 2, SIGN_MODE_LEGACY_AMINO_JSON = 127, + SIGN_MODE_EIP_191 = 191 } impl ::protobuf::ProtobufEnum for SignMode { @@ -1169,6 +1170,7 @@ impl ::protobuf::ProtobufEnum for SignMode { 1 => ::std::option::Option::Some(SignMode::SIGN_MODE_DIRECT), 2 => ::std::option::Option::Some(SignMode::SIGN_MODE_TEXTUAL), 127 => ::std::option::Option::Some(SignMode::SIGN_MODE_LEGACY_AMINO_JSON), + 191 => ::std::option::Option::Some(SignMode::SIGN_MODE_EIP_191), _ => ::std::option::Option::None } } @@ -1179,6 +1181,7 @@ impl ::protobuf::ProtobufEnum for SignMode { SignMode::SIGN_MODE_DIRECT, SignMode::SIGN_MODE_TEXTUAL, SignMode::SIGN_MODE_LEGACY_AMINO_JSON, + SignMode::SIGN_MODE_EIP_191, ]; values } diff --git a/cosmwasm/enclaves/shared/cosmos-types/src/multisig.rs b/cosmwasm/enclaves/shared/cosmos-types/src/multisig.rs index daff4798b..03ead3866 100644 --- a/cosmwasm/enclaves/shared/cosmos-types/src/multisig.rs +++ b/cosmwasm/enclaves/shared/cosmos-types/src/multisig.rs @@ -6,7 +6,7 @@ use crate::types::CosmosPubKey; use enclave_crypto::traits::VerifyingKey; -use cosmos_proto::crypto::multisig::multisig::MultiSignature; +use cosmos_proto::{crypto::multisig::multisig::MultiSignature, tx::signing::SignMode}; use super::traits::CosmosAminoPubkey; @@ -94,7 +94,12 @@ impl CosmosAminoPubkey for MultisigThresholdPubKey { } impl VerifyingKey for MultisigThresholdPubKey { - fn verify_bytes(&self, bytes: &[u8], sig: &[u8]) -> Result<(), CryptoError> { + fn verify_bytes( + &self, + bytes: &[u8], + sig: &[u8], + sign_mode: SignMode, + ) -> Result<(), CryptoError> { debug!("verifying multisig"); trace!("Sign bytes are: {:?}", bytes); let signatures = decode_multisig_signature(sig)?; @@ -122,7 +127,7 @@ impl VerifyingKey for MultisigThresholdPubKey { for (i, current_signer) in signers.iter().enumerate() { trace!("Checking pubkey: {:?}", current_signer); // This technically support that one of the multisig signers is a multisig itself - let result = current_signer.verify_bytes(bytes, current_sig); + let result = current_signer.verify_bytes(bytes, current_sig, sign_mode); if result.is_ok() { signer_pos = Some(i); diff --git a/cosmwasm/enclaves/shared/cosmos-types/src/types.rs b/cosmwasm/enclaves/shared/cosmos-types/src/types.rs index 873a80733..77aee26cb 100644 --- a/cosmwasm/enclaves/shared/cosmos-types/src/types.rs +++ b/cosmwasm/enclaves/shared/cosmos-types/src/types.rs @@ -1,6 +1,7 @@ use log::*; use enclave_ffi_types::EnclaveError; +use proto::tx::signing::SignMode; use protobuf::Message; use serde::{Deserialize, Serialize}; @@ -120,10 +121,15 @@ impl CosmosAminoPubkey for CosmosPubKey { } impl VerifyingKey for CosmosPubKey { - fn verify_bytes(&self, bytes: &[u8], sig: &[u8]) -> Result<(), CryptoError> { + fn verify_bytes( + &self, + bytes: &[u8], + sig: &[u8], + sign_mode: SignMode, + ) -> Result<(), CryptoError> { match self { - CosmosPubKey::Secp256k1(pubkey) => pubkey.verify_bytes(bytes, sig), - CosmosPubKey::Multisig(pubkey) => pubkey.verify_bytes(bytes, sig), + CosmosPubKey::Secp256k1(pubkey) => pubkey.verify_bytes(bytes, sig, sign_mode), + CosmosPubKey::Multisig(pubkey) => pubkey.verify_bytes(bytes, sig, sign_mode), } } } @@ -139,6 +145,7 @@ pub enum SignModeDef { SIGN_MODE_DIRECT = 1, SIGN_MODE_TEXTUAL = 2, SIGN_MODE_LEGACY_AMINO_JSON = 127, + SIGN_MODE_EIP_191 = 191, } #[allow(non_camel_case_types)] diff --git a/cosmwasm/enclaves/shared/crypto/Cargo.toml b/cosmwasm/enclaves/shared/crypto/Cargo.toml index 1760b23ff..cac9051a0 100644 --- a/cosmwasm/enclaves/shared/crypto/Cargo.toml +++ b/cosmwasm/enclaves/shared/crypto/Cargo.toml @@ -19,19 +19,18 @@ sgx_types = { rev = "a37ffb9449ba6d5b6e4a9d586bbab864ae732269", git = "https://g [dependencies] sgx_trts = { rev = "a37ffb9449ba6d5b6e4a9d586bbab864ae732269", git = "https://github.com/apache/teaclave-sgx-sdk.git" } - enclave-ffi-types = { path = "../../ffi-types" } - log = "0.4.8" derive_more = "0.99" lazy_static = "1.4" hex = "0.4.2" - ring = { git = "https://github.com/mesalock-linux/ring-sgx", tag = "v0.16.5" } sha2 = "0.8.1" +sha3 = "0.8.1" ripemd160 = "0.9.1" secp256k1 = "0.21.3" aes-siv = "=0.6.2" x25519-dalek = { version = "=1.2.0", default-features = false, features = [ "u64_backend" ] } +cosmos_proto = { path = "../cosmos-proto" } diff --git a/cosmwasm/enclaves/shared/crypto/src/secp256k1.rs b/cosmwasm/enclaves/shared/crypto/src/secp256k1.rs index aab3e37cf..074e26b85 100644 --- a/cosmwasm/enclaves/shared/crypto/src/secp256k1.rs +++ b/cosmwasm/enclaves/shared/crypto/src/secp256k1.rs @@ -2,8 +2,10 @@ use log::*; use crate::traits::VerifyingKey; use crate::CryptoError; +use cosmos_proto::tx::signing::SignMode; use secp256k1::Secp256k1; use sha2::{Digest as Sha2Digest, Sha256}; +use sha3::Keccak256; pub const SECP256K1_PREFIX: [u8; 4] = [235, 90, 233, 135]; @@ -17,9 +19,18 @@ impl Secp256k1PubKey { } impl VerifyingKey for Secp256k1PubKey { - fn verify_bytes(&self, bytes: &[u8], sig: &[u8]) -> Result<(), CryptoError> { + fn verify_bytes( + &self, + bytes: &[u8], + sig: &[u8], + sign_mode: SignMode, + ) -> Result<(), CryptoError> { // Signing ref: https://docs.cosmos.network/master/spec/_ics/ics-030-signed-messages.html#preliminary - let sign_bytes_hash = Sha256::digest(bytes); + let sign_bytes_hash = if sign_mode == SignMode::SIGN_MODE_EIP_191 { + Keccak256::digest(bytes) + } else { + Sha256::digest(bytes) + }; let msg = secp256k1::Message::from_slice(sign_bytes_hash.as_slice()).map_err(|err| { warn!("Failed to create a secp256k1 message from tx: {:?}", err); CryptoError::VerificationError diff --git a/cosmwasm/enclaves/shared/crypto/src/traits.rs b/cosmwasm/enclaves/shared/crypto/src/traits.rs index fe058203a..3e0651857 100644 --- a/cosmwasm/enclaves/shared/crypto/src/traits.rs +++ b/cosmwasm/enclaves/shared/crypto/src/traits.rs @@ -1,3 +1,4 @@ +use cosmos_proto::tx::signing::SignMode; use enclave_ffi_types::EnclaveError; use crate::errors::CryptoError; @@ -44,5 +45,10 @@ pub trait ExportECKey { // https://github.com/tendermint/tendermint/blob/v0.33.3/crypto/crypto.go#L22 pub trait VerifyingKey: PartialEq { /// Verify that `sig` was generated by this public key, for the content in `bytes` - fn verify_bytes(&self, bytes: &[u8], sig: &[u8]) -> Result<(), CryptoError>; + fn verify_bytes( + &self, + bytes: &[u8], + sig: &[u8], + sign_mode: SignMode, + ) -> Result<(), CryptoError>; } From 9f333d3d0df5e3a06c0e3758b8df4e42cd53b2b3 Mon Sep 17 00:00:00 2001 From: Assaf Morami Date: Tue, 23 Aug 2022 22:25:57 +0300 Subject: [PATCH 51/93] Increase `make go-tests` timeout 20m->40m --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 4b9793536..364e9b530 100644 --- a/Makefile +++ b/Makefile @@ -361,7 +361,7 @@ go-tests: build-test-contract cp ./cosmwasm/enclaves/execute/librust_cosmwasm_enclave.signed.so ./x/compute/internal/keeper rm -rf ./x/compute/internal/keeper/.sgx_secrets mkdir -p ./x/compute/internal/keeper/.sgx_secrets - GOMAXPROCS=8 SGX_MODE=SW SCRT_SGX_STORAGE='./' go test -failfast -timeout 1200s -v ./x/compute/internal/... $(GO_TEST_ARGS) + GOMAXPROCS=8 SGX_MODE=SW SCRT_SGX_STORAGE='./' go test -failfast -timeout 2400s -v ./x/compute/internal/... $(GO_TEST_ARGS) go-tests-hw: build-test-contract # empty BUILD_PROFILE means debug mode which compiles faster From 38c225a820953226ad4f868aa56d7b3fdfcfbec5 Mon Sep 17 00:00:00 2001 From: Assaf Morami Date: Tue, 23 Aug 2022 22:56:41 +0300 Subject: [PATCH 52/93] Fix go tests for StargateMsg (Add compute MsgServer) --- proto/secret/compute/v1beta1/msg.proto | 98 +- x/compute/alias.go | 2 +- x/compute/internal/keeper/msg_server.go | 77 ++ .../keeper/param_verification_test.go | 1031 ----------------- x/compute/internal/keeper/querier.go | 78 +- x/compute/internal/keeper/test_common.go | 10 + x/compute/internal/types/msg.pb.go | 1027 +++++++++++++--- x/compute/module.go | 2 + 8 files changed, 996 insertions(+), 1329 deletions(-) create mode 100644 x/compute/internal/keeper/msg_server.go delete mode 100644 x/compute/internal/keeper/param_verification_test.go diff --git a/proto/secret/compute/v1beta1/msg.proto b/proto/secret/compute/v1beta1/msg.proto index 417f7c2b1..c0f1f62f9 100644 --- a/proto/secret/compute/v1beta1/msg.proto +++ b/proto/secret/compute/v1beta1/msg.proto @@ -6,8 +6,16 @@ option go_package = "github.com/enigmampc/SecretNetwork/x/compute/internal/types import "gogoproto/gogo.proto"; import "cosmos/base/v1beta1/coin.proto"; -//import "x/compute/internal/types/types.proto"; +// Msg defines the wasm Msg service. +service Msg { + // StoreCode to submit Wasm code to the system + rpc StoreCode(MsgStoreCode) returns (MsgStoreCodeResponse); + // Instantiate creates a new smart contract instance for the given code id. + rpc InstantiateContract(MsgInstantiateContract) returns (MsgInstantiateContractResponse); + // Execute submits the given message data to a smart contract + rpc ExecuteContract(MsgExecuteContract) returns (MsgExecuteContractResponse); +} message MsgStoreCode { option (gogoproto.goproto_getters) = false; @@ -19,8 +27,12 @@ message MsgStoreCode { string source = 3; // Builder is a valid docker image name with tag, optional string builder = 4; - // InstantiatePermission to apply on contract creation, optional -// AccessConfig InstantiatePermission = 5; +} + +// MsgStoreCodeResponse returns store result data. +message MsgStoreCodeResponse { + // CodeID is the reference to the stored WASM code + uint64 code_id = 1 [ (gogoproto.customname) = "CodeID" ]; } message MsgInstantiateContract { @@ -37,6 +49,14 @@ message MsgInstantiateContract { bytes callback_sig = 7 [(gogoproto.customname) = "CallbackSig"]; } +// MsgInstantiateContractResponse return instantiation result data +message MsgInstantiateContractResponse { + // Address is the bech32 address of the new contract instance. + string address = 1; + // Data contains base64-encoded bytes to returned from the contract + bytes data = 2; +} + message MsgExecuteContract { option (gogoproto.goproto_getters) = false; @@ -48,70 +68,8 @@ message MsgExecuteContract { bytes callback_sig = 6 [(gogoproto.customname) = "CallbackSig"]; } -// Todo: keeping this here for future replacing of bytes -> string -//syntax = "proto3"; -//package secret.compute.v1beta1; -// -//option go_package = "github.com/enigmampc/SecretNetwork/x/compute/internal/types"; -// -//import "gogoproto/gogo.proto"; -//import "cosmos/base/v1beta1/coin.proto"; -// -////import "x/compute/internal/types/types.proto"; -// -// -//message MsgStoreCode { -// option (gogoproto.goproto_getters) = false; -// -// // -// string sender = 1 [(gogoproto.moretags) = "yaml:\"sender\""]; -// // WASMByteCode can be raw or gzip compressed -// bytes wasm_byte_code = 2 [(gogoproto.customname) = "WASMByteCode"]; -// // Source is a valid absolute HTTPS URI to the contract's source code, optional -// string source = 3 [(gogoproto.moretags) = "yaml:\"source\""]; -// // Builder is a valid docker image name with tag, optional -// string builder = 4 [(gogoproto.moretags) = "yaml:\"builder\""]; -//} -// -//message MsgInstantiateContract { -// option (gogoproto.goproto_getters) = false; -// -// // -// string sender = 1 [(gogoproto.moretags) = "yaml:\"sender\""]; -// // -// string callback_code_hash = 2 [(gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"callback_code_hash\"" ]; -// // -// uint64 code_id = 3 [(gogoproto.customname) = "CodeID", (gogoproto.moretags) = "yaml:\"code_id\""]; -// // -// string label = 4 [(gogoproto.moretags) = "yaml:\"label\""]; -// // -// bytes init_msg = 5 [(gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"init_msg\"" ]; -// // -// repeated cosmos.base.v1beta1.Coin init_funds = 6 [ -// (gogoproto.nullable) = false, -// (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins", -// (gogoproto.moretags) = "yaml:\"init_funds\"" -// ]; -// // -// bytes callback_sig = 7 [(gogoproto.customname) = "CallbackSig", (gogoproto.moretags) = "yaml:\"callback_sig\""]; -//} -// -//message MsgExecuteContract { -// option (gogoproto.goproto_getters) = false; -// // -// string sender = 1 [(gogoproto.moretags) = "yaml:\"sender\""]; -// // -// string contract = 2 [(gogoproto.moretags) = "yaml:\"contract\""]; -// // -// bytes msg = 3 [(gogoproto.moretags) = "yaml:\"msg\""]; -// // -// string callback_code_hash = 4 [(gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"callback_code_hash\"" ]; -// // -// repeated cosmos.base.v1beta1.Coin sent_funds = 5 [ -// (gogoproto.nullable) = false, -// (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins", -// (gogoproto.moretags) = "yaml:\"sent_funds\"" -// ]; -// // -// bytes callback_sig = 6 [(gogoproto.customname) = "CallbackSig", (gogoproto.moretags) = "yaml:\"callback_sig\""]; -//} \ No newline at end of file +// MsgExecuteContractResponse returns execution result data. +message MsgExecuteContractResponse { + // Data contains base64-encoded bytes to returned from the contract + bytes data = 1; +} \ No newline at end of file diff --git a/x/compute/alias.go b/x/compute/alias.go index ea3beec23..462e953db 100644 --- a/x/compute/alias.go +++ b/x/compute/alias.go @@ -67,7 +67,7 @@ var ( EncodeStakingMsg = keeper.EncodeStakingMsg EncodeWasmMsg = keeper.EncodeWasmMsg NewKeeper = keeper.NewKeeper - NewQuerier = keeper.NewQuerier + NewQuerier = keeper.NewGrpcQuerier NewLegacyQuerier = keeper.NewLegacyQuerier DefaultQueryPlugins = keeper.DefaultQueryPlugins BankQuerier = keeper.BankQuerier diff --git a/x/compute/internal/keeper/msg_server.go b/x/compute/internal/keeper/msg_server.go new file mode 100644 index 000000000..cb1d94f00 --- /dev/null +++ b/x/compute/internal/keeper/msg_server.go @@ -0,0 +1,77 @@ +package keeper + +import ( + "context" + + sdk "github.com/cosmos/cosmos-sdk/types" + + "github.com/enigmampc/SecretNetwork/x/compute/internal/types" +) + +var _ types.MsgServer = msgServer{} + +type msgServer struct { + keeper Keeper +} + +func NewMsgServerImpl(k Keeper) types.MsgServer { + return &msgServer{keeper: k} +} + +func (m msgServer) StoreCode(goCtx context.Context, msg *types.MsgStoreCode) (*types.MsgStoreCodeResponse, error) { + ctx := sdk.UnwrapSDKContext(goCtx) + + ctx.EventManager().EmitEvent(sdk.NewEvent( + sdk.EventTypeMessage, + sdk.NewAttribute(sdk.AttributeKeyModule, types.ModuleName), + sdk.NewAttribute(sdk.AttributeKeySender, msg.Sender.String()), + )) + + codeID, err := m.keeper.Create(ctx, msg.Sender, msg.WASMByteCode, msg.Source, msg.Builder) + if err != nil { + return nil, err + } + + return &types.MsgStoreCodeResponse{ + CodeID: codeID, + }, nil +} + +func (m msgServer) InstantiateContract(goCtx context.Context, msg *types.MsgInstantiateContract) (*types.MsgInstantiateContractResponse, error) { + ctx := sdk.UnwrapSDKContext(goCtx) + + ctx.EventManager().EmitEvent(sdk.NewEvent( + sdk.EventTypeMessage, + sdk.NewAttribute(sdk.AttributeKeyModule, types.ModuleName), + sdk.NewAttribute(sdk.AttributeKeySender, msg.Sender.String()), + )) + + contractAddr, data, err := m.keeper.Instantiate(ctx, msg.CodeID, msg.Sender, msg.InitMsg, msg.Label, msg.InitFunds, msg.CallbackSig) + if err != nil { + return nil, err + } + + return &types.MsgInstantiateContractResponse{ + Address: contractAddr.String(), + Data: data, + }, nil +} + +func (m msgServer) ExecuteContract(goCtx context.Context, msg *types.MsgExecuteContract) (*types.MsgExecuteContractResponse, error) { + ctx := sdk.UnwrapSDKContext(goCtx) + + ctx.EventManager().EmitEvent(sdk.NewEvent( + sdk.EventTypeMessage, + sdk.NewAttribute(sdk.AttributeKeyModule, types.ModuleName), + sdk.NewAttribute(sdk.AttributeKeySender, msg.Sender.String()), + )) + + data, err := m.keeper.Execute(ctx, msg.Contract, msg.Sender, msg.Msg, msg.SentFunds, msg.CallbackSig) + if err != nil { + return nil, err + } + + return &types.MsgExecuteContractResponse{ + Data: data.Data, + }, nil +} diff --git a/x/compute/internal/keeper/param_verification_test.go b/x/compute/internal/keeper/param_verification_test.go deleted file mode 100644 index 266f2d58d..000000000 --- a/x/compute/internal/keeper/param_verification_test.go +++ /dev/null @@ -1,1031 +0,0 @@ -package keeper - -import ( - "fmt" - "testing" - - "github.com/stretchr/testify/require" - - "github.com/cosmos/cosmos-sdk/client" - "github.com/cosmos/cosmos-sdk/crypto/keys/ed25519" - multisigkeys "github.com/cosmos/cosmos-sdk/crypto/keys/multisig" - crypto "github.com/cosmos/cosmos-sdk/crypto/types" - "github.com/cosmos/cosmos-sdk/crypto/types/multisig" - sdk "github.com/cosmos/cosmos-sdk/types" - sdksigning "github.com/cosmos/cosmos-sdk/types/tx/signing" - authante "github.com/cosmos/cosmos-sdk/x/auth/ante" - authsigning "github.com/cosmos/cosmos-sdk/x/auth/signing" - authtx "github.com/cosmos/cosmos-sdk/x/auth/tx" - authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" - - "github.com/enigmampc/SecretNetwork/x/compute/internal/types" -) - -func getSignBytes( - t *testing.T, signModeHandler authsigning.SignModeHandler, builder client.TxBuilder, multisigAccount Account, signer Account, -) []byte { - sig := sdksigning.SignatureV2{ - PubKey: signer.public, - Sequence: multisigAccount.acct.GetSequence(), - Data: &sdksigning.SingleSignatureData{ - SignMode: sdksigning.SignMode_SIGN_MODE_LEGACY_AMINO_JSON, - Signature: nil, - }, - } - err := builder.SetSignatures(sig) - require.NoError(t, err) - signerData := authsigning.SignerData{ - ChainID: "", - AccountNumber: signer.acct.GetAccountNumber(), - Sequence: signer.acct.GetSequence(), - } - bytesToSign, err := signModeHandler.GetSignBytes(sdksigning.SignMode_SIGN_MODE_LEGACY_AMINO_JSON, signerData, builder.GetTx()) - require.NoError(t, err) - - return bytesToSign -} - -func generateSignatures( - t *testing.T, signModeHandler authsigning.SignModeHandler, - builder client.TxBuilder, multisigAccount Account, signers []Account, actualSigners int, -) *sdksigning.MultiSignatureData { - multiSig := multisig.NewMultisig(len(signers)) - - for i := 0; i < len(signers); i++ { - signBytes := getSignBytes(t, signModeHandler, builder, multisigAccount, signers[i]) - var signature []byte - if i < actualSigners { - signature, _ = signers[i].private.Sign(signBytes) - } - signatureData := sdksigning.SingleSignatureData{ - SignMode: sdksigning.SignMode_SIGN_MODE_LEGACY_AMINO_JSON, - Signature: signature, - } - - err := multisig.AddSignatureFromPubKey(multiSig, &signatureData, signers[i].public, Accounts(signers).pubKeys()) - require.NoError(t, err) - } - - fmt.Printf("Multisig is %+v\n", multiSig) - - return multiSig -} - -func multisigTxCreator( - t *testing.T, ctx *sdk.Context, keeper Keeper, n int, threshold int, actualSigners int, sdkMsg sdk.Msg, -) (authsigning.SignModeHandler, []Account, Account) { - signers, multisigAccount := generateMultisigAccount(*ctx, keeper, n, threshold) - signModeHandler := multisigTxCreatorForExisting(t, ctx, multisigAccount, signers, actualSigners, sdkMsg) - return signModeHandler, signers, multisigAccount -} - -func multisigTxCreatorForExisting( - t *testing.T, ctx *sdk.Context, multisigAccount Account, signers []Account, actualSigners int, sdkMsg sdk.Msg, -) authsigning.SignModeHandler { - switch msg := sdkMsg.(type) { - case *types.MsgInstantiateContract: - msg.Sender = multisigAccount.address - case *types.MsgExecuteContract: - msg.Sender = multisigAccount.address - } - - txConfig := authtx.NewTxConfig(nil, authtx.DefaultSignModes) - signmodeHandler := txConfig.SignModeHandler() - builder := txConfig.NewTxBuilder() - builder.SetFeeAmount(nil) - builder.SetGasLimit(0) - builder.SetTimeoutHeight(0) - - _ = builder.SetMsgs(sdkMsg) - - multiSignature := generateSignatures(t, signmodeHandler, builder, multisigAccount, signers, actualSigners) - signature := sdksigning.SignatureV2{ - PubKey: multisigAccount.public, - Sequence: multisigAccount.acct.GetSequence(), - Data: multiSignature, - } - err := builder.SetSignatures(signature) - require.NoError(t, err) - - tx := builder.(protoTxProvider) - txbytes, err := tx.GetProtoTx().Marshal() - require.NoError(t, err) - *ctx = ctx.WithTxBytes(txbytes) - - return signmodeHandler -} - -type Account struct { - acct authtypes.AccountI - address sdk.AccAddress - public crypto.PubKey - private crypto.PrivKey -} - -func newAccount(ctx sdk.Context, keeper Keeper, private crypto.PrivKey) Account { - public := private.PubKey() - address := sdk.AccAddress(public.Address()) - acct, err := authante.GetSignerAcc(ctx, keeper.accountKeeper, address) - if err != nil { - panic(fmt.Sprintf("failed to get signer account %v", address)) - } - return Account{ - acct, - address, - public, - private, - } -} - -type Accounts []Account - -func (accts Accounts) pubKeys() []crypto.PubKey { - var pubKeys []crypto.PubKey - for _, acct := range accts { - pubKeys = append(pubKeys, acct.public) - } - return pubKeys -} - -func generateMultisigAccount(ctx sdk.Context, keeper Keeper, n int, threshold int) ([]Account, Account) { - accounts := make([]Account, n) - - for i := 0; i < n; i++ { - deposit := sdk.NewCoins(sdk.NewInt64Coin("denom", 100000)) - _, privKey := CreateFakeFundedAccount(ctx, keeper.accountKeeper, keeper.bankKeeper, deposit.Add(deposit...)) - accounts[i] = newAccount(ctx, keeper, privKey) - } - - multisigAccount := generateMultisigAccountFromPublicKeys(ctx, keeper, Accounts(accounts).pubKeys(), threshold) - - return accounts, multisigAccount -} - -func generateMultisigAccountFromPublicKeys(ctx sdk.Context, keeper Keeper, pubKeys []crypto.PubKey, threshold int) Account { - multisigPubkey := multisigkeys.NewLegacyAminoPubKey(threshold, pubKeys) - - // Register to keeper - addr := multisigPubkey.Address().Bytes() - baseAcct := authtypes.NewBaseAccountWithAddress(addr) - coins := sdk.NewCoins(sdk.NewInt64Coin("denom", 100000)) - _ = baseAcct.SetPubKey(multisigPubkey) - keeper.accountKeeper.SetAccount(ctx, baseAcct) - - if err := keeper.bankKeeper.MintCoins(ctx, faucetAccountName, coins); err != nil { - panic(err) - } - - _ = keeper.bankKeeper.SendCoinsFromModuleToAccount(ctx, faucetAccountName, addr, coins) - - return Account{ - acct: baseAcct, - address: addr, - public: multisigPubkey, - private: nil, - } -} - -func prepareInitSignedTxMultipleMsgs( - t *testing.T, keeper Keeper, ctx sdk.Context, - creators []sdk.AccAddress, privKeys []crypto.PrivKey, initMsgs []sdk.Msg, codeID uint64, -) sdk.Context { - t.SkipNow() // skipping till multisig is fixed - accounts := make([]authtypes.AccountI, len(creators)) - for i, acc := range creators { - account, err := authante.GetSignerAcc(ctx, keeper.accountKeeper, acc) - require.NoError(t, err) - accounts[i] = account - } - - tx := NewTestTxMultiple(initMsgs, accounts, privKeys) - txBytes, err := tx.Marshal() - require.NoError(t, err) - - return ctx.WithTxBytes(txBytes) -} - -func TestMultipleSigners(t *testing.T) { - // - t.SkipNow() // skipping till multisig is fixed - ctx, keeper, codeID, codeHash, walletA, privKeyA, walletB, privKeyB := setupTest(t, "./testdata/test-contract/contract.wasm", sdk.NewCoins()) - - initMsg := `{"nop":{}}` - - msg := types.SecretMsg{ - CodeHash: []byte(codeHash), - Msg: []byte(initMsg), - } - - initMsgBz, err := wasmCtx.Encrypt(msg.Serialize()) - require.NoError(t, err) - nonce := initMsgBz[0:32] - - sdkMsgA := types.MsgInstantiateContract{ - Sender: walletA, - // Admin: nil, - CodeID: codeID, - Label: "demo contract 1", - InitMsg: initMsgBz, - InitFunds: nil, - } - sdkMsgB := types.MsgInstantiateContract{ - Sender: walletB, - // Admin: nil, - CodeID: codeID, - Label: "demo contract 2", - InitMsg: initMsgBz, - InitFunds: nil, - } - - ctx = prepareInitSignedTxMultipleMsgs( - t, keeper, ctx, - []sdk.AccAddress{walletA, walletB}, []crypto.PrivKey{privKeyA, privKeyB}, []sdk.Msg{&sdkMsgA, &sdkMsgB}, codeID, - ) - - contractAddressA, _, err := keeper.Instantiate(ctx, codeID, walletA /* nil,*/, initMsgBz, "demo contract 1", sdk.NewCoins(sdk.NewInt64Coin("denom", 0)), nil) - if err != nil { - err = extractInnerError(t, err, nonce, true, false) - } - require.NoError(t, err) - - wasmEvents := getDecryptedWasmEvents(t, ctx, nonce) - - require.Equal(t, - []ContractEvent{ - { - {Key: "contract_address", Value: contractAddressA.String()}, - {Key: "init", Value: "🌈"}, - }, - }, - wasmEvents, - ) - - contractAddressB, _, err := keeper.Instantiate(ctx, codeID, walletB /* nil,*/, initMsgBz, "demo contract 2", sdk.NewCoins(sdk.NewInt64Coin("denom", 0)), nil) - if err != nil { - err = extractInnerError(t, err, nonce, false, false) - } - require.NoError(t, err) - - wasmEvents = getDecryptedWasmEvents(t, ctx, nonce) - - require.Equal(t, - []ContractEvent{ - { - {Key: "contract_address", Value: contractAddressA.String()}, - {Key: "init", Value: "🌈"}, - }, - { - {Key: "contract_address", Value: contractAddressB.String()}, - {Key: "init", Value: "🌈"}, - }, - }, - wasmEvents, - ) -} - -func TestWrongSigner(t *testing.T) { - t.SkipNow() // skipping till multisig is fixed - ctx, keeper, codeID, _, walletA, _, walletB, privKeyB := setupTest(t, "./testdata/test-contract/contract.wasm", sdk.NewCoins()) - - initMsg := `{"nop":{}}` - - initMsgBz, err := wasmCtx.Encrypt([]byte(initMsg)) - require.NoError(t, err) - nonce := initMsgBz[0:32] - - sdkMsgA := types.MsgInstantiateContract{ - Sender: walletB, - // Admin: nil, - CodeID: codeID, - Label: "demo contract 1", - InitMsg: initMsgBz, - InitFunds: nil, - } - - ctx = prepareInitSignedTxMultipleMsgs(t, keeper, ctx, []sdk.AccAddress{walletB}, []crypto.PrivKey{privKeyB}, []sdk.Msg{&sdkMsgA}, codeID) - - _, _, err = keeper.Instantiate(ctx, codeID, walletA /* nil,*/, initMsgBz, "some label", sdk.NewCoins(sdk.NewInt64Coin("denom", 0)), nil) - if err != nil { - err = extractInnerError(t, err, nonce, false, false) - } - require.Contains(t, err.Error(), "is not found in the tx signer set") -} - -func TestMultiSig(t *testing.T) { - t.SkipNow() // skipping till multisig is fixed - ctx, keeper, codeID, codeHash, _, _, _, _ := setupTest(t, "./testdata/test-contract/contract.wasm", sdk.NewCoins()) - - initMsg := `{"nop":{}}` - msg := types.NewSecretMsg([]byte(codeHash), []byte(initMsg)) - - initMsgBz, err := wasmCtx.Encrypt(msg.Serialize()) - require.NoError(t, err) - nonce := initMsgBz[0:32] - - for i := 0; i < 5; i++ { - for j := 0; j <= i; j++ { - label := fmt.Sprintf("demo contract %d %d", i, j) - sdkMsg := types.MsgInstantiateContract{ - // Admin: nil, - CodeID: codeID, - Label: label, - InitMsg: initMsgBz, - InitFunds: sdk.NewCoins(sdk.NewInt64Coin("denom", 0)), - } - - _, _, multisigAddr := multisigTxCreator(t, &ctx, keeper, i+1, j+1, i+1, &sdkMsg) - - contractAddressA, _, err := keeper.Instantiate(ctx, codeID, multisigAddr.address /* nil, */, initMsgBz, label, sdk.NewCoins(sdk.NewInt64Coin("denom", 0)), nil) - if err != nil { - err = extractInnerError(t, err, nonce, true, false) - } - require.NoError(t, err) - - wasmEvents := getDecryptedWasmEvents(t, ctx, nonce) - - require.Equal(t, - []ContractEvent{ - { - {Key: "contract_address", Value: contractAddressA.String()}, - {Key: "init", Value: "🌈"}, - }, - }, - wasmEvents, - ) - - // Reset wasm events - ctx, keeper, codeID, codeHash, _, _, _, _ = setupTest(t, "./testdata/test-contract/contract.wasm", sdk.NewCoins()) - } - } -} - -func TestMultiSigThreshold(t *testing.T) { - t.SkipNow() // skipping till multisig is fixed - ctx, keeper, codeID, codeHash, _, _, _, _ := setupTest(t, "./testdata/test-contract/contract.wasm", sdk.NewCoins()) - - initMsg := `{"nop":{}}` - - msg := types.SecretMsg{ - CodeHash: []byte(codeHash), - Msg: []byte(initMsg), - } - - initMsgBz, err := wasmCtx.Encrypt(msg.Serialize()) - require.NoError(t, err) - nonce := initMsgBz[0:32] - - for i := 0; i < 5; i++ { - for j := 0; j <= i; j++ { - label := fmt.Sprintf("demo contract %d %d", i+1, j+1) - sdkMsg := types.MsgInstantiateContract{ - // Admin: nil, - CodeID: codeID, - Label: label, - InitMsg: initMsgBz, - InitFunds: sdk.NewCoins(sdk.NewInt64Coin("denom", 0)), - } - - _, _, multisigAddr := multisigTxCreator(t, &ctx, keeper, i+1, j+1, j+1, &sdkMsg) - - contractAddressA, _, err := keeper.Instantiate(ctx, codeID, multisigAddr.address /* nil,*/, initMsgBz, label, sdk.NewCoins(sdk.NewInt64Coin("denom", 0)), nil) - if err != nil { - err = extractInnerError(t, err, nonce, true, false) - } - require.NoError(t, err) - - wasmEvents := getDecryptedWasmEvents(t, ctx, nonce) - - require.Equal(t, - []ContractEvent{ - { - {Key: "contract_address", Value: contractAddressA.String()}, - {Key: "init", Value: "🌈"}, - }, - }, - wasmEvents, - ) - - // Reset wasm events - ctx, keeper, codeID, _, _, _, _, _ = setupTest(t, "./testdata/test-contract/contract.wasm", sdk.NewCoins()) - } - } -} - -func TestMultiSigThresholdNotMet(t *testing.T) { - t.SkipNow() // skipping till multisig is fixed - ctx, keeper, codeID, codeHash, _, _, _, _ := setupTest(t, "./testdata/test-contract/contract.wasm", sdk.NewCoins()) - - initMsg := `{"nop":{}}` - - msg := types.SecretMsg{ - CodeHash: []byte(codeHash), - Msg: []byte(initMsg), - } - - initMsgBz, err := wasmCtx.Encrypt(msg.Serialize()) - require.NoError(t, err) - nonce := initMsgBz[0:32] - - sdkMsg := types.MsgInstantiateContract{ - // Admin: nil, - CodeID: codeID, - Label: "demo contract 1", - InitMsg: initMsgBz, - InitFunds: sdk.NewCoins(sdk.NewInt64Coin("denom", 0)), - } - - _, _, multisigAddr := multisigTxCreator(t, &ctx, keeper, 3, 2, 1, &sdkMsg) - - _, _, err = keeper.Instantiate(ctx, codeID, multisigAddr.address /* nil,*/, initMsgBz, "demo contract 1", sdk.NewCoins(sdk.NewInt64Coin("denom", 0)), nil) - if err != nil { - err = extractInnerError(t, err, nonce, false, false) - } - require.Contains(t, err.Error(), "failed to verify transaction signature") -} - -func TestMultiSigExecute(t *testing.T) { - t.SkipNow() // skipping till multisig is fixed - ctx, keeper, codeID, codeHash, _, _, walletB, privKeyB := setupTest(t, "./testdata/erc20.wasm", sdk.NewCoins()) - - accounts, multisigAccount := generateMultisigAccount(ctx, keeper, 5, 4) - - initMsg := fmt.Sprintf( - `{"decimals":10,"initial_balances":[{"address":"%s","amount":"108"},{"address":"%s","amount":"53"}],"name":"ReuvenPersonalRustCoin","symbol":"RPRC"}`, - multisigAccount.address, walletB.String(), - ) - - _, _, contractAddress, _, error := initHelper(t, keeper, ctx, codeID, walletB, privKeyB, initMsg, true, false, defaultGasForTests) - require.Empty(t, error) - - execMsg := fmt.Sprintf(`{"transfer":{"amount":"10","recipient":"%s"}}`, walletB.String()) - - msg := types.SecretMsg{ - CodeHash: []byte(codeHash), - Msg: []byte(execMsg), - } - - execMsgBz, err := wasmCtx.Encrypt(msg.Serialize()) - require.NoError(t, err) - nonce := execMsgBz[0:32] - - funds := sdk.NewCoins(sdk.NewInt64Coin("denom", 0)) - sdkMsg := types.MsgExecuteContract{ - Contract: contractAddress, - Msg: execMsgBz, - SentFunds: funds, - CallbackSig: nil, - } - - _ = multisigTxCreatorForExisting(t, &ctx, multisigAccount, accounts, 4, &sdkMsg) - - execRes, err := keeper.Execute(ctx, contractAddress, multisigAccount.address, execMsgBz, funds, nil) - if err != nil { - err = extractInnerError(t, err, nonce, true, false) - } - require.NoError(t, err) - - data := getDecryptedData(t, execRes.Data, nonce) - wasmEvents := getDecryptedWasmEvents(t, ctx, nonce) - require.Empty(t, data) - require.Equal(t, - []ContractEvent{ - { - {Key: "contract_address", Value: contractAddress.String()}, - {Key: "action", Value: "transfer"}, - {Key: "sender", Value: multisigAccount.address.String()}, - {Key: "recipient", Value: walletB.String()}, - }, - }, - wasmEvents, - ) -} - -func TestMultiSigCallbacks(t *testing.T) { - t.SkipNow() // skipping till multisig is fixed - ctx, keeper, codeID, codeHash, walletA, privKeyA, _, _ := setupTest(t, "./testdata/test-contract/contract.wasm", sdk.NewCoins()) - - // init - _, _, contractAddress, initEvents, error := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, false, defaultGasForTests) - require.Empty(t, error) - - require.Equal(t, - []ContractEvent{ - { - {Key: "contract_address", Value: contractAddress.String()}, - {Key: "init", Value: "🌈"}, - }, - }, - initEvents, - ) - - execMsg := fmt.Sprintf(`{"a":{"contract_addr":"%s","code_hash":"%s","x":2,"y":3}}`, contractAddress.String(), codeHash) - - msg := types.SecretMsg{ - CodeHash: []byte(codeHash), - Msg: []byte(execMsg), - } - - execMsgBz, err := wasmCtx.Encrypt(msg.Serialize()) - require.NoError(t, err) - nonce := execMsgBz[0:32] - - sdkMsg := types.MsgExecuteContract{ - Contract: contractAddress, - Msg: execMsgBz, - SentFunds: sdk.NewCoins(sdk.NewInt64Coin("denom", 0)), - CallbackSig: nil, - } - - _, _, multisigAddr := multisigTxCreator(t, &ctx, keeper, 3, 2, 2, &sdkMsg) - - execRes, err := keeper.Execute(ctx, contractAddress, multisigAddr.address, execMsgBz, sdk.NewCoins(sdk.NewInt64Coin("denom", 0)), nil) - if err != nil { - err = extractInnerError(t, err, nonce, true, false) - } - data := getDecryptedData(t, execRes.Data, nonce) - execEvents := getDecryptedWasmEvents(t, ctx, nonce) - - require.Empty(t, err) - require.Equal(t, - []ContractEvent{ - { - {Key: "contract_address", Value: contractAddress.String()}, - {Key: "banana", Value: "🍌"}, - }, - { - {Key: "contract_address", Value: contractAddress.String()}, - {Key: "kiwi", Value: "🥝"}, - }, - { - {Key: "contract_address", Value: contractAddress.String()}, - {Key: "watermelon", Value: "🍉"}, - }, - }, - execEvents, - ) - require.Equal(t, []byte{2, 3}, data) -} - -func TestMultiSigInMultiSig(t *testing.T) { - t.SkipNow() // skipping till multisig is fixed - ctx, keeper, codeID, codeHash, _, privKeyA, _, privKeyB := setupTest(t, "./testdata/test-contract/contract.wasm", sdk.NewCoins()) - - accounts, multisigAccount := generateMultisigAccount(ctx, keeper, 5, 3) - multiSigPubKeys := []crypto.PubKey{multisigAccount.public, privKeyA.PubKey(), privKeyB.PubKey()} - multimultisigAccount := generateMultisigAccountFromPublicKeys(ctx, keeper, multiSigPubKeys, 2) - - initMsg := `{"nop":{}}` - - msg := types.SecretMsg{ - CodeHash: []byte(codeHash), - Msg: []byte(initMsg), - } - - initMsgBz, err := wasmCtx.Encrypt(msg.Serialize()) - require.NoError(t, err) - nonce := initMsgBz[0:32] - - sdkMsg := types.MsgInstantiateContract{ - Sender: multimultisigAccount.address, - // Admin: nil, - CodeID: codeID, - Label: "demo contract 1", - InitMsg: initMsgBz, - InitFunds: sdk.NewCoins(sdk.NewInt64Coin("denom", 0)), - } - - txConfig := authtx.NewTxConfig(nil, authtx.DefaultSignModes) - signModeHandler := txConfig.SignModeHandler() - builder := txConfig.NewTxBuilder() - builder.SetFeeAmount(nil) - builder.SetGasLimit(0) - builder.SetTimeoutHeight(0) - - _ = builder.SetMsgs(&sdkMsg) - multimultiSignBytes := getSignBytes(t, signModeHandler, builder, multimultisigAccount, multisigAccount) - multimultiSig := multisig.NewMultisig(3) - - // Sign by multisig - multiSignature := generateSignatures(t, signModeHandler, builder, multisigAccount, accounts, 3) - fmt.Printf("multisig sig: %+v\n", multiSignature) - - // Sign by wallet A - walletASignature, _ := privKeyA.Sign(multimultiSignBytes) - walletASignatureData := sdksigning.SingleSignatureData{ - SignMode: sdksigning.SignMode_SIGN_MODE_LEGACY_AMINO_JSON, - Signature: walletASignature, - } - walletBSignatureData := sdksigning.SingleSignatureData{ - SignMode: sdksigning.SignMode_SIGN_MODE_LEGACY_AMINO_JSON, - Signature: nil, // No signature provided - } - - fmt.Printf("wallet A sig: %v\n", walletASignature) - - _ = multisig.AddSignatureFromPubKey(multimultiSig, multiSignature, multisigAccount.public, multiSigPubKeys) - _ = multisig.AddSignatureFromPubKey(multimultiSig, &walletASignatureData, privKeyA.PubKey(), multiSigPubKeys) - _ = multisig.AddSignatureFromPubKey(multimultiSig, &walletBSignatureData, privKeyB.PubKey(), multiSigPubKeys) - - fmt.Printf("multimultisig sig: %+v\n", multimultiSig) - - multimultisigAcc := keeper.accountKeeper.GetAccount(ctx, multimultisigAccount.address.Bytes()) - signature := sdksigning.SignatureV2{ - PubKey: multimultisigAccount.public, - Sequence: multimultisigAcc.GetSequence(), - Data: multimultiSig, - } - err = builder.SetSignatures(signature) - require.NoError(t, err) - - tx := builder.(protoTxProvider) - txBytes, err := tx.GetProtoTx().Marshal() - require.NoError(t, err) - - ctx = ctx.WithTxBytes(txBytes) - - contractAddressA, _, err := keeper.Instantiate( - ctx, - codeID, - multimultisigAccount.address, - /* nil, */ - initMsgBz, - "demo contract 1", - sdk.NewCoins(sdk.NewInt64Coin("denom", 0)), - nil, - ) - if err != nil { - err = extractInnerError(t, err, nonce, true, false) - } - require.NoError(t, err) - - wasmEvents := getDecryptedWasmEvents(t, ctx, nonce) - - require.Equal(t, - []ContractEvent{ - { - {Key: "contract_address", Value: contractAddressA.String()}, - {Key: "init", Value: "🌈"}, - }, - }, - wasmEvents, - ) -} - -func TestMultiSigInMultiSigDifferentOrder(t *testing.T) { - t.SkipNow() // skipping till multisig is fixed - ctx, keeper, codeID, codeHash, _, privKeyA, _, privKeyB := setupTest(t, "./testdata/test-contract/contract.wasm", sdk.NewCoins()) - - accounts, multisigAccount := generateMultisigAccount(ctx, keeper, 5, 3) - multiSigPubKeys := []crypto.PubKey{multisigAccount.public, privKeyA.PubKey(), privKeyB.PubKey()} - multimultisigAccount := generateMultisigAccountFromPublicKeys(ctx, keeper, multiSigPubKeys, 2) - - initMsg := `{"nop":{}}` - - msg := types.SecretMsg{ - CodeHash: []byte(codeHash), - Msg: []byte(initMsg), - } - - initMsgBz, err := wasmCtx.Encrypt(msg.Serialize()) - require.NoError(t, err) - nonce := initMsgBz[0:32] - - sdkMsg := types.MsgInstantiateContract{ - Sender: multimultisigAccount.address, - // Admin: nil, - CodeID: codeID, - Label: "demo contract 1", - InitMsg: initMsgBz, - InitFunds: sdk.NewCoins(sdk.NewInt64Coin("denom", 0)), - } - - txConfig := authtx.NewTxConfig(nil, authtx.DefaultSignModes) - signModeHandler := txConfig.SignModeHandler() - builder := txConfig.NewTxBuilder() - builder.SetFeeAmount(nil) - builder.SetGasLimit(0) - builder.SetTimeoutHeight(0) - - _ = builder.SetMsgs(&sdkMsg) - multimultiSignBytes := getSignBytes(t, signModeHandler, builder, multimultisigAccount, multisigAccount) - multimultiSig := multisig.NewMultisig(3) - - // Sign by multisig - multiSignature := generateSignatures(t, signModeHandler, builder, multisigAccount, accounts, 3) - fmt.Printf("multisig sig: %+v\n", multiSignature) - - // Sign by wallet A - walletASignature, _ := privKeyA.Sign(multimultiSignBytes) - walletASignatureData := sdksigning.SingleSignatureData{ - SignMode: sdksigning.SignMode_SIGN_MODE_LEGACY_AMINO_JSON, - Signature: walletASignature, - } - walletBSignatureData := sdksigning.SingleSignatureData{ - SignMode: sdksigning.SignMode_SIGN_MODE_LEGACY_AMINO_JSON, - Signature: nil, // No signature provided - } - - fmt.Printf("wallet A sig: %v\n", walletASignature) - - err = multisig.AddSignatureFromPubKey(multimultiSig, &walletBSignatureData, privKeyB.PubKey(), multiSigPubKeys) - err = multisig.AddSignatureFromPubKey(multimultiSig, multiSignature, multisigAccount.public, multiSigPubKeys) - err = multisig.AddSignatureFromPubKey(multimultiSig, &walletASignatureData, privKeyA.PubKey(), multiSigPubKeys) - - fmt.Printf("multimultisig sig: %+v\n", multimultiSig) - - multimultisigAcc := keeper.accountKeeper.GetAccount(ctx, multimultisigAccount.address.Bytes()) - signature := sdksigning.SignatureV2{ - PubKey: multimultisigAccount.public, - Sequence: multimultisigAcc.GetSequence(), - Data: multimultiSig, - } - err = builder.SetSignatures(signature) - require.NoError(t, err) - - tx := builder.(protoTxProvider) - txBytes, err := tx.GetProtoTx().Marshal() - require.NoError(t, err) - - ctx = ctx.WithTxBytes(txBytes) - - contractAddressA, _, err := keeper.Instantiate( - ctx, - codeID, - multimultisigAccount.address, - /* nil, */ - initMsgBz, - "demo contract 1", - sdk.NewCoins(sdk.NewInt64Coin("denom", 0)), - nil, - ) - if err != nil { - err = extractInnerError(t, err, nonce, true, false) - } - require.NoError(t, err) - - wasmEvents := getDecryptedWasmEvents(t, ctx, nonce) - - require.Equal(t, - []ContractEvent{ - { - {Key: "contract_address", Value: contractAddressA.String()}, - {Key: "init", Value: "🌈"}, - }, - }, - wasmEvents, - ) -} - -func TestInvalidKeyType(t *testing.T) { - t.SkipNow() // skipping till multisig is fixed - ctx, keeper, codeID, codeHash, _, _, _, _ := setupTest(t, "./testdata/test-contract/contract.wasm", sdk.NewCoins()) - - edKey := ed25519.GenPrivKey() - edPub := edKey.PubKey() - edAddr := sdk.AccAddress(edPub.Address()) - baseAcct := authtypes.NewBaseAccountWithAddress(edAddr) - coins := sdk.NewCoins(sdk.NewInt64Coin("denom", 100000)) - _ = baseAcct.SetPubKey(edPub) - - if err := keeper.bankKeeper.MintCoins(ctx, faucetAccountName, sdk.NewCoins(sdk.NewInt64Coin("denom", 100000))); err != nil { - panic(err) - } - - _ = keeper.bankKeeper.SendCoinsFromModuleToAccount(ctx, faucetAccountName, edAddr, coins) - - keeper.accountKeeper.SetAccount(ctx, baseAcct) - - initMsg := `{"nop":{}}` - - msg := types.SecretMsg{ - CodeHash: []byte(codeHash), - Msg: []byte(initMsg), - } - - initMsgBz, err := wasmCtx.Encrypt(msg.Serialize()) - require.NoError(t, err) - // nonce := initMsgBz[0:32] - - sdkMsg := types.MsgInstantiateContract{ - Sender: edAddr, - // Admin: nil, - CodeID: codeID, - Label: "demo contract 1", - InitMsg: initMsgBz, - InitFunds: sdk.NewCoins(sdk.NewInt64Coin("denom", 0)), - } - - ctx = prepareInitSignedTxMultipleMsgs(t, keeper, ctx, []sdk.AccAddress{edAddr}, []crypto.PrivKey{edKey}, []sdk.Msg{&sdkMsg}, codeID) - - _, _, err = keeper.Instantiate(ctx, codeID, edAddr /* nil,*/, initMsgBz, "demo contract 1", sdk.NewCoins(sdk.NewInt64Coin("denom", 0)), nil) - require.Contains(t, err.Error(), "failed to verify transaction signature") -} - -func TestInvalidKeyTypeInMultisig(t *testing.T) { - t.SkipNow() // skipping till multisig is fixed - ctx, keeper, codeID, codeHash, _, privKeyA, _, privKeyB := setupTest(t, "./testdata/test-contract/contract.wasm", sdk.NewCoins()) - - edKey := ed25519.GenPrivKey() - edPub := edKey.PubKey() - edAddr := sdk.AccAddress(edPub.Address()) - baseAcct := authtypes.NewBaseAccountWithAddress(edAddr) - coins := sdk.NewCoins(sdk.NewInt64Coin("denom", 100000)) - _ = baseAcct.SetPubKey(edPub) - - if err := keeper.bankKeeper.MintCoins(ctx, faucetAccountName, coins); err != nil { - panic(err) - } - - _ = keeper.bankKeeper.SendCoinsFromModuleToAccount(ctx, faucetAccountName, edAddr, coins) - - keeper.accountKeeper.SetAccount(ctx, baseAcct) - - edPubAccount := Account{ - private: edKey, - public: edPub, - address: edAddr, - acct: baseAcct, - } - AccountA := newAccount(ctx, keeper, privKeyA) - AccountB := newAccount(ctx, keeper, privKeyB) - - pubKeys := []crypto.PubKey{edPub, privKeyA.PubKey(), privKeyB.PubKey()} - accounts := []Account{edPubAccount, AccountA, AccountB} - multisigPubkey := generateMultisigAccountFromPublicKeys(ctx, keeper, pubKeys, 2) - - initMsg := `{"nop":{}}` - - msg := types.SecretMsg{ - CodeHash: []byte(codeHash), - Msg: []byte(initMsg), - } - - initMsgBz, err := wasmCtx.Encrypt(msg.Serialize()) - require.NoError(t, err) - - sdkMsg := types.MsgInstantiateContract{ - Sender: multisigPubkey.address.Bytes(), - // Admin: nil, - CodeID: codeID, - Label: "demo contract 1", - InitMsg: initMsgBz, - InitFunds: sdk.NewCoins(sdk.NewInt64Coin("denom", 0)), - } - - txConfig := authtx.NewTxConfig(nil, authtx.DefaultSignModes) - signModeHanler := txConfig.SignModeHandler() - builder := txConfig.NewTxBuilder() - builder.SetFeeAmount(nil) - builder.SetGasLimit(0) - builder.SetTimeoutHeight(0) - - _ = builder.SetMsgs(&sdkMsg) - - multiSignature := generateSignatures(t, signModeHanler, builder, multisigPubkey, accounts, 3) - - multisigAcc := keeper.accountKeeper.GetAccount(ctx, multisigPubkey.address.Bytes()) - signature := sdksigning.SignatureV2{ - PubKey: multisigPubkey.public, - Sequence: multisigAcc.GetSequence(), - Data: multiSignature, - } - err = builder.SetSignatures(signature) - require.NoError(t, err) - - tx := builder.(protoTxProvider) - txBytes, err := tx.GetProtoTx().Marshal() - require.NoError(t, err) - ctx = ctx.WithTxBytes(txBytes) - - _, _, err = keeper.Instantiate( - ctx, - codeID, - sdk.AccAddress(multisigPubkey.address), - /* nil, */ - initMsgBz, - "demo contract 1", - sdk.NewCoins(sdk.NewInt64Coin("denom", 0)), - nil, - ) - require.Error(t, err) - require.Contains(t, err.Error(), "failed to verify transaction signature") -} - -func TestWrongFundsNoFunds(t *testing.T) { - t.SkipNow() - ctx, keeper, codeID, codeHash, walletA, privKeyA, _, _ := setupTest(t, "./testdata/test-contract/contract.wasm", sdk.NewCoins()) - - initMsg := `{"nop":{}}` - - msg := types.SecretMsg{ - CodeHash: []byte(codeHash), - Msg: []byte(initMsg), - } - - initMsgBz, err := wasmCtx.Encrypt(msg.Serialize()) - require.NoError(t, err) - nonce := initMsgBz[0:32] - - ctx = PrepareInitSignedTx(t, keeper, ctx, walletA, privKeyA, initMsgBz, codeID, nil) - - _, _, err = keeper.Instantiate(ctx, codeID, walletA /* nil,*/, initMsgBz, "demo contract 1", sdk.NewCoins(sdk.NewInt64Coin("denom", 1000)), nil) - if err != nil { - err = extractInnerError(t, err, nonce, false, false) - } - require.Error(t, err) - require.Contains(t, err.Error(), "failed to verify transaction signature") -} - -func TestWrongFundsSomeFunds(t *testing.T) { - t.SkipNow() - ctx, keeper, codeID, codeHash, walletA, privKeyA, _, _ := setupTest(t, "./testdata/test-contract/contract.wasm", sdk.NewCoins()) - - initMsg := `{"nop":{}}` - - msg := types.SecretMsg{ - CodeHash: []byte(codeHash), - Msg: []byte(initMsg), - } - - initMsgBz, err := wasmCtx.Encrypt(msg.Serialize()) - require.NoError(t, err) - nonce := initMsgBz[0:32] - - ctx = PrepareInitSignedTx(t, keeper, ctx, walletA, privKeyA, initMsgBz, codeID, sdk.NewCoins(sdk.NewInt64Coin("denom", 200))) - - _, _, err = keeper.Instantiate(ctx, codeID, walletA /* nil,*/, initMsgBz, "demo contract 1", sdk.NewCoins(sdk.NewInt64Coin("denom", 1000)), nil) - if err != nil { - err = extractInnerError(t, err, nonce, false, false) - } - require.Error(t, err) - require.Contains(t, err.Error(), "failed to verify transaction signature") -} - -func TestWrongMessage(t *testing.T) { - t.SkipNow() - ctx, keeper, codeID, codeHash, walletA, privKeyA, _, _ := setupTest(t, "./testdata/test-contract/contract.wasm", sdk.NewCoins()) - - initMsg := `{"nop":{}}` - - msg := types.SecretMsg{ - CodeHash: []byte(codeHash), - Msg: []byte(initMsg), - } - - initMsgBz, err := wasmCtx.Encrypt(msg.Serialize()) - require.NoError(t, err) - nonce := initMsgBz[0:32] - - notTheRealMsg := `{"no_logs":{}}` - - notReallyTheMsg := types.SecretMsg{ - CodeHash: []byte(codeHash), - Msg: []byte(notTheRealMsg), - } - - notTheRealMsgBz, err := wasmCtx.Encrypt(notReallyTheMsg.Serialize()) - require.NoError(t, err) - - ctx = PrepareInitSignedTx(t, keeper, ctx, walletA, privKeyA, initMsgBz, codeID, nil) - - _, _, err = keeper.Instantiate(ctx, codeID, walletA /* nil, */, notTheRealMsgBz, "demo contract 1", sdk.NewCoins(sdk.NewInt64Coin("denom", 1000)), nil) - if err != nil { - err = extractInnerError(t, err, nonce, false, false) - } - require.Error(t, err) - require.Contains(t, err.Error(), "failed to verify transaction signature") -} - -func TestWrongContractAddress(t *testing.T) { - t.SkipNow() - ctx, keeper, codeID, codeHash, walletA, privKeyA, walletB, privKeyB := setupTest(t, "./testdata/erc20.wasm", sdk.NewCoins()) - - initMsg := fmt.Sprintf(`{"decimals":10,"initial_balances":[{"address":"%s","amount":"108"},{"address":"%s","amount":"53"}],"name":"ReuvenPersonalRustCoin","symbol":"RPRC"}`, walletA.String(), walletB.String()) - - _, _, contractAddress, _, stderr := initHelper(t, keeper, ctx, codeID, walletB, privKeyB, initMsg, true, false, defaultGasForTests) - require.Empty(t, stderr) - _, _, differentContractAddress, _, stderr := initHelper(t, keeper, ctx, codeID, walletB, privKeyB, initMsg, true, false, defaultGasForTests) - require.Empty(t, stderr) - - require.NotEqual(t, contractAddress, differentContractAddress) - - execMsg := fmt.Sprintf(`{"transfer":{"amount":"10","recipient":"%s"}}`, walletB.String()) - - msg := types.SecretMsg{ - CodeHash: []byte(codeHash), - Msg: []byte(execMsg), - } - - execMsgBz, err := wasmCtx.Encrypt(msg.Serialize()) - require.NoError(t, err) - nonce := execMsgBz[0:32] - - ctx = PrepareExecSignedTx(t, keeper, ctx, walletA, privKeyA, execMsgBz, contractAddress, sdk.NewCoins(sdk.NewInt64Coin("denom", 0))) - - _, err = keeper.Execute(ctx, differentContractAddress, walletA, execMsgBz, sdk.NewCoins(sdk.NewInt64Coin("denom", 0)), nil) - if err != nil { - err = extractInnerError(t, err, nonce, false, false) - } - require.Error(t, err) - require.Contains(t, err.Error(), "failed to verify transaction signature") -} diff --git a/x/compute/internal/keeper/querier.go b/x/compute/internal/keeper/querier.go index 5a30da3cf..1fb69171f 100644 --- a/x/compute/internal/keeper/querier.go +++ b/x/compute/internal/keeper/querier.go @@ -16,7 +16,7 @@ type GrpcQuerier struct { } // todo: this needs proper tests and doc -func NewQuerier(keeper Keeper) GrpcQuerier { +func NewGrpcQuerier(keeper Keeper) GrpcQuerier { return GrpcQuerier{keeper: keeper} } @@ -37,24 +37,6 @@ func (q GrpcQuerier) ContractInfo(c context.Context, req *types.QueryContractInf }, nil } -/* -func (q GrpcQuerier) ContractHistory(c context.Context, req *types.QueryContractHistoryRequest) (*types.QueryContractHistoryResponse, error) { - if err := sdk.VerifyAddressFormat(req.Address); err != nil { - return nil, err - } - rsp, err := queryContractHistory(sdk.UnwrapSDKContext(c), req.Address, q.keeper) - switch { - case err != nil: - return nil, err - case rsp == nil: - return nil, types.ErrNotFound - } - return &types.QueryContractHistoryResponse{ - Entries: rsp, - }, nil -} -*/ - func (q GrpcQuerier) ContractsByCode(c context.Context, req *types.QueryContractsByCodeRequest) (*types.QueryContractsByCodeResponse, error) { if req.CodeId == 0 { return nil, sdkerrors.Wrap(types.ErrInvalid, "code id") @@ -71,40 +53,6 @@ func (q GrpcQuerier) ContractsByCode(c context.Context, req *types.QueryContract }, nil } -/* -func (q GrpcQuerier) AllContractState(c context.Context, req *types.QueryAllContractStateRequest) (*types.QueryAllContractStateResponse, error) { - if err := sdk.VerifyAddressFormat(req.Address); err != nil { - return nil, err - } - ctx := sdk.UnwrapSDKContext(c) - if !q.keeper.containsContractInfo(ctx, req.Address) { - return nil, types.ErrNotFound - } - var resultData []types.Model - for iter := q.keeper.GetContractState(ctx, req.Address); iter.Valid(); iter.Next() { - resultData = append(resultData, types.Model{ - Key: iter.Key(), - Value: iter.Value(), - }) - } - return &types.QueryAllContractStateResponse{Models: resultData}, nil -} - -func (q GrpcQuerier) RawContractState(c context.Context, req *types.QueryRawContractStateRequest) (*types.QueryRawContractStateResponse, error) { - ctx := sdk.UnwrapSDKContext(c) - - if err := sdk.VerifyAddressFormat(req.Address); err != nil { - return nil, err - } - - if !q.keeper.containsContractInfo(ctx, req.Address) { - return nil, types.ErrNotFound - } - rsp := q.keeper.QueryRaw(ctx, req.Address, req.QueryData) - return &types.QueryRawContractStateResponse{Data: rsp}, nil -} -*/ - func (q GrpcQuerier) SmartContractState(c context.Context, req *types.QuerySmartContractStateRequest) (*types.QuerySmartContractStateResponse, error) { if err := sdk.VerifyAddressFormat(req.Address); err != nil { return nil, err @@ -269,30 +217,6 @@ func queryCodeList(ctx sdk.Context, keeper Keeper) ([]types.CodeInfoResponse, er return info, nil } -/* -func queryContractHistory(ctx sdk.Context, bech string, keeper Keeper) ([]byte, error) { - contractAddr, err := sdk.AccAddressFromBech32(bech) - if err != nil { - return nil, sdkerrors.Wrap(sdkerrors.ErrInvalidAddress, err.Error()) - } - entries := keeper.GetContractHistory(ctx, contractAddr) - if entries == nil { - // nil, nil leads to 404 in rest handler - return nil, nil - } - // redact response - for i := range entries { - entries[i].Updated = nil - } - - bz, err := json.MarshalIndent(entries, "", " ") - if err != nil { - return nil, sdkerrors.Wrap(sdkerrors.ErrJSONMarshal, err.Error()) - } - return bz, nil -} -*/ - func queryContractAddress(ctx sdk.Context, label string, keeper Keeper) (sdk.AccAddress, error) { res := keeper.GetContractAddress(ctx, label) if res == nil { diff --git a/x/compute/internal/keeper/test_common.go b/x/compute/internal/keeper/test_common.go index d5812e124..65bc66403 100644 --- a/x/compute/internal/keeper/test_common.go +++ b/x/compute/internal/keeper/test_common.go @@ -437,6 +437,16 @@ func CreateTestInput(t *testing.T, isCheckTx bool, supportedFeatures string, enc // add wasm handler so we can loop-back (contracts calling contracts) router.AddRoute(sdk.NewRoute(wasmtypes.RouterKey, TestHandler(keeper))) + am := module.NewManager( // minimal module set that we use for message/ query tests + bank.NewAppModule(encodingConfig.Marshaler, bankKeeper, authKeeper), + staking.NewAppModule(encodingConfig.Marshaler, stakingKeeper, authKeeper, bankKeeper), + distribution.NewAppModule(encodingConfig.Marshaler, distKeeper, authKeeper, bankKeeper, stakingKeeper), + gov.NewAppModule(encodingConfig.Marshaler, govKeeper, authKeeper, bankKeeper), + ) + am.RegisterServices(module.NewConfigurator(encodingConfig.Marshaler, msgRouter, queryRouter)) + wasmtypes.RegisterMsgServer(msgRouter, NewMsgServerImpl(keeper)) + wasmtypes.RegisterQueryServer(queryRouter, NewGrpcQuerier(keeper)) + keepers := TestKeepers{ AccountKeeper: authKeeper, StakingKeeper: stakingKeeper, diff --git a/x/compute/internal/types/msg.pb.go b/x/compute/internal/types/msg.pb.go index 7b2dda060..148c9c588 100644 --- a/x/compute/internal/types/msg.pb.go +++ b/x/compute/internal/types/msg.pb.go @@ -4,11 +4,16 @@ 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" + 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" @@ -39,7 +44,7 @@ func (m *MsgStoreCode) Reset() { *m = MsgStoreCode{} } func (m *MsgStoreCode) String() string { return proto.CompactTextString(m) } func (*MsgStoreCode) ProtoMessage() {} func (*MsgStoreCode) Descriptor() ([]byte, []int) { - return fileDescriptor_6815433faf72a133, []int{0} + return fileDescriptor_ba393690c2c2062e, []int{0} } func (m *MsgStoreCode) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -68,6 +73,52 @@ func (m *MsgStoreCode) XXX_DiscardUnknown() { var xxx_messageInfo_MsgStoreCode proto.InternalMessageInfo +// MsgStoreCodeResponse returns store result data. +type MsgStoreCodeResponse struct { + // CodeID is the reference to the stored WASM code + CodeID uint64 `protobuf:"varint,1,opt,name=code_id,json=codeId,proto3" json:"code_id,omitempty"` +} + +func (m *MsgStoreCodeResponse) Reset() { *m = MsgStoreCodeResponse{} } +func (m *MsgStoreCodeResponse) String() string { return proto.CompactTextString(m) } +func (*MsgStoreCodeResponse) ProtoMessage() {} +func (*MsgStoreCodeResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_ba393690c2c2062e, []int{1} +} +func (m *MsgStoreCodeResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MsgStoreCodeResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgStoreCodeResponse.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 *MsgStoreCodeResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgStoreCodeResponse.Merge(m, src) +} +func (m *MsgStoreCodeResponse) XXX_Size() int { + return m.Size() +} +func (m *MsgStoreCodeResponse) XXX_DiscardUnknown() { + xxx_messageInfo_MsgStoreCodeResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_MsgStoreCodeResponse proto.InternalMessageInfo + +func (m *MsgStoreCodeResponse) GetCodeID() uint64 { + if m != nil { + return m.CodeID + } + return 0 +} + type MsgInstantiateContract struct { Sender github_com_cosmos_cosmos_sdk_types.AccAddress `protobuf:"bytes,1,opt,name=sender,proto3,casttype=github.com/cosmos/cosmos-sdk/types.AccAddress" json:"sender,omitempty"` // Admin is an optional address that can execute migrations @@ -84,7 +135,7 @@ func (m *MsgInstantiateContract) Reset() { *m = MsgInstantiateContract{} func (m *MsgInstantiateContract) String() string { return proto.CompactTextString(m) } func (*MsgInstantiateContract) ProtoMessage() {} func (*MsgInstantiateContract) Descriptor() ([]byte, []int) { - return fileDescriptor_6815433faf72a133, []int{1} + return fileDescriptor_ba393690c2c2062e, []int{2} } func (m *MsgInstantiateContract) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -113,6 +164,61 @@ func (m *MsgInstantiateContract) XXX_DiscardUnknown() { var xxx_messageInfo_MsgInstantiateContract proto.InternalMessageInfo +// MsgInstantiateContractResponse return instantiation result data +type MsgInstantiateContractResponse struct { + // Address is the bech32 address of the new contract instance. + Address string `protobuf:"bytes,1,opt,name=address,proto3" json:"address,omitempty"` + // Data contains base64-encoded bytes to returned from the contract + Data []byte `protobuf:"bytes,2,opt,name=data,proto3" json:"data,omitempty"` +} + +func (m *MsgInstantiateContractResponse) Reset() { *m = MsgInstantiateContractResponse{} } +func (m *MsgInstantiateContractResponse) String() string { return proto.CompactTextString(m) } +func (*MsgInstantiateContractResponse) ProtoMessage() {} +func (*MsgInstantiateContractResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_ba393690c2c2062e, []int{3} +} +func (m *MsgInstantiateContractResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MsgInstantiateContractResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgInstantiateContractResponse.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 *MsgInstantiateContractResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgInstantiateContractResponse.Merge(m, src) +} +func (m *MsgInstantiateContractResponse) XXX_Size() int { + return m.Size() +} +func (m *MsgInstantiateContractResponse) XXX_DiscardUnknown() { + xxx_messageInfo_MsgInstantiateContractResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_MsgInstantiateContractResponse proto.InternalMessageInfo + +func (m *MsgInstantiateContractResponse) GetAddress() string { + if m != nil { + return m.Address + } + return "" +} + +func (m *MsgInstantiateContractResponse) GetData() []byte { + if m != nil { + return m.Data + } + return nil +} + type MsgExecuteContract struct { Sender github_com_cosmos_cosmos_sdk_types.AccAddress `protobuf:"bytes,1,opt,name=sender,proto3,casttype=github.com/cosmos/cosmos-sdk/types.AccAddress" json:"sender,omitempty"` Contract github_com_cosmos_cosmos_sdk_types.AccAddress `protobuf:"bytes,2,opt,name=contract,proto3,casttype=github.com/cosmos/cosmos-sdk/types.AccAddress" json:"contract,omitempty"` @@ -126,7 +232,7 @@ func (m *MsgExecuteContract) Reset() { *m = MsgExecuteContract{} } func (m *MsgExecuteContract) String() string { return proto.CompactTextString(m) } func (*MsgExecuteContract) ProtoMessage() {} func (*MsgExecuteContract) Descriptor() ([]byte, []int) { - return fileDescriptor_6815433faf72a133, []int{2} + return fileDescriptor_ba393690c2c2062e, []int{4} } func (m *MsgExecuteContract) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -155,52 +261,267 @@ func (m *MsgExecuteContract) XXX_DiscardUnknown() { var xxx_messageInfo_MsgExecuteContract proto.InternalMessageInfo +// MsgExecuteContractResponse returns execution result data. +type MsgExecuteContractResponse struct { + // Data contains base64-encoded bytes to returned from the contract + Data []byte `protobuf:"bytes,1,opt,name=data,proto3" json:"data,omitempty"` +} + +func (m *MsgExecuteContractResponse) Reset() { *m = MsgExecuteContractResponse{} } +func (m *MsgExecuteContractResponse) String() string { return proto.CompactTextString(m) } +func (*MsgExecuteContractResponse) ProtoMessage() {} +func (*MsgExecuteContractResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_ba393690c2c2062e, []int{5} +} +func (m *MsgExecuteContractResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MsgExecuteContractResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgExecuteContractResponse.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 *MsgExecuteContractResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgExecuteContractResponse.Merge(m, src) +} +func (m *MsgExecuteContractResponse) XXX_Size() int { + return m.Size() +} +func (m *MsgExecuteContractResponse) XXX_DiscardUnknown() { + xxx_messageInfo_MsgExecuteContractResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_MsgExecuteContractResponse proto.InternalMessageInfo + +func (m *MsgExecuteContractResponse) GetData() []byte { + if m != nil { + return m.Data + } + return nil +} + func init() { proto.RegisterType((*MsgStoreCode)(nil), "secret.compute.v1beta1.MsgStoreCode") + proto.RegisterType((*MsgStoreCodeResponse)(nil), "secret.compute.v1beta1.MsgStoreCodeResponse") proto.RegisterType((*MsgInstantiateContract)(nil), "secret.compute.v1beta1.MsgInstantiateContract") + proto.RegisterType((*MsgInstantiateContractResponse)(nil), "secret.compute.v1beta1.MsgInstantiateContractResponse") proto.RegisterType((*MsgExecuteContract)(nil), "secret.compute.v1beta1.MsgExecuteContract") + proto.RegisterType((*MsgExecuteContractResponse)(nil), "secret.compute.v1beta1.MsgExecuteContractResponse") +} + +func init() { proto.RegisterFile("secret/compute/v1beta1/tx.proto", fileDescriptor_ba393690c2c2062e) } + +var fileDescriptor_ba393690c2c2062e = []byte{ + // 696 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x55, 0x3f, 0x4f, 0xdb, 0x4e, + 0x18, 0x8e, 0x71, 0x48, 0xc8, 0x4b, 0xf4, 0x03, 0xdd, 0x0f, 0x21, 0x93, 0xc1, 0x46, 0x69, 0x87, + 0xa8, 0x02, 0x1b, 0x52, 0x89, 0xa1, 0x4c, 0x84, 0xb6, 0x6a, 0x86, 0x30, 0x38, 0xaa, 0x2a, 0x75, + 0x89, 0xce, 0xe7, 0xab, 0x63, 0x48, 0x7c, 0xa9, 0xef, 0x52, 0x60, 0xe8, 0xde, 0xa5, 0x52, 0x87, + 0x7e, 0x80, 0xce, 0xfd, 0x24, 0x74, 0x63, 0x64, 0x4a, 0xab, 0xf0, 0x2d, 0x3a, 0x55, 0xe7, 0x7f, + 0x89, 0x68, 0x40, 0x69, 0x55, 0xa6, 0xdc, 0x9b, 0xf7, 0xf1, 0xf3, 0xfe, 0x79, 0x1e, 0xdd, 0x81, + 0xc1, 0x29, 0x09, 0xa9, 0xb0, 0x08, 0xeb, 0x0f, 0x86, 0x82, 0x5a, 0xef, 0x76, 0x1d, 0x2a, 0xf0, + 0xae, 0x25, 0xce, 0xcc, 0x41, 0xc8, 0x04, 0x43, 0xeb, 0x31, 0xc0, 0x4c, 0x00, 0x66, 0x02, 0xa8, + 0xac, 0x79, 0xcc, 0x63, 0x11, 0xc4, 0x92, 0xa7, 0x18, 0x5d, 0xd1, 0x09, 0xe3, 0x7d, 0xc6, 0x2d, + 0x07, 0xf3, 0x09, 0x17, 0x61, 0x7e, 0x10, 0xe7, 0xab, 0xdf, 0x14, 0x28, 0xb7, 0xb8, 0xd7, 0x16, + 0x2c, 0xa4, 0x87, 0xcc, 0xa5, 0xa8, 0x09, 0x05, 0x4e, 0x03, 0x97, 0x86, 0x9a, 0xb2, 0xa9, 0xd4, + 0xca, 0x8d, 0xdd, 0x9f, 0x23, 0x63, 0xdb, 0xf3, 0x45, 0x77, 0xe8, 0xc8, 0x92, 0x56, 0xc2, 0x17, + 0xff, 0x6c, 0x73, 0xf7, 0xc4, 0x12, 0xe7, 0x03, 0xca, 0xcd, 0x03, 0x42, 0x0e, 0x5c, 0x37, 0xa4, + 0x9c, 0xdb, 0x09, 0x01, 0xda, 0x83, 0xff, 0x4e, 0x31, 0xef, 0x77, 0x9c, 0x73, 0x41, 0x3b, 0x84, + 0xb9, 0x54, 0x5b, 0x88, 0x28, 0x57, 0xc7, 0x23, 0xa3, 0xfc, 0xea, 0xa0, 0xdd, 0x6a, 0x9c, 0x8b, + 0xa8, 0xa8, 0x5d, 0x96, 0xb8, 0x34, 0x42, 0xeb, 0x50, 0xe0, 0x6c, 0x18, 0x12, 0xaa, 0xa9, 0x9b, + 0x4a, 0xad, 0x64, 0x27, 0x11, 0xd2, 0xa0, 0xe8, 0x0c, 0xfd, 0x9e, 0xec, 0x2d, 0x1f, 0x25, 0xd2, + 0xf0, 0x49, 0xfe, 0xc3, 0x17, 0x23, 0x57, 0xdd, 0x87, 0xb5, 0xe9, 0x51, 0x6c, 0xca, 0x07, 0x2c, + 0xe0, 0x14, 0x3d, 0x80, 0xa2, 0xac, 0xde, 0xf1, 0xdd, 0x68, 0xa6, 0x7c, 0x03, 0xc6, 0x23, 0xa3, + 0x20, 0x21, 0xcd, 0xa7, 0x76, 0x41, 0xa6, 0x9a, 0x6e, 0xf5, 0xa3, 0x0a, 0xeb, 0x2d, 0xee, 0x35, + 0x03, 0x2e, 0x70, 0x20, 0x7c, 0x2c, 0x7b, 0x09, 0x44, 0x88, 0x89, 0xf8, 0x97, 0x2b, 0xd9, 0x02, + 0x44, 0x70, 0xaf, 0xe7, 0x60, 0x72, 0x12, 0x6d, 0xa4, 0xd3, 0xc5, 0xbc, 0x1b, 0xad, 0xa5, 0x64, + 0xaf, 0xa6, 0x19, 0xd9, 0xd9, 0x0b, 0xcc, 0xbb, 0xd3, 0x8d, 0xab, 0xb7, 0x35, 0x8e, 0xd6, 0x60, + 0xb1, 0x87, 0x1d, 0xda, 0x4b, 0x76, 0x12, 0x07, 0x68, 0x03, 0x96, 0xfc, 0xc0, 0x17, 0x9d, 0x3e, + 0xf7, 0xb4, 0x45, 0xd9, 0xb5, 0x5d, 0x94, 0x71, 0x8b, 0x7b, 0xe8, 0x18, 0x20, 0x4a, 0xbd, 0x19, + 0x06, 0x2e, 0xd7, 0x0a, 0x9b, 0x6a, 0x6d, 0xb9, 0xbe, 0x61, 0xc6, 0xdd, 0x9b, 0xd2, 0x27, 0xa9, + 0xa5, 0xcc, 0x43, 0xe6, 0x07, 0x8d, 0x9d, 0x8b, 0x91, 0x91, 0xfb, 0xfa, 0xdd, 0xa8, 0xcd, 0x31, + 0xb1, 0xfc, 0x80, 0xdb, 0x25, 0x49, 0xff, 0x5c, 0xb2, 0xa3, 0x3a, 0x94, 0xb3, 0x79, 0xb9, 0xef, + 0x69, 0xc5, 0x68, 0x81, 0x2b, 0xe3, 0x91, 0xb1, 0x7c, 0x98, 0xfc, 0xdf, 0xf6, 0x3d, 0x7b, 0x99, + 0x4c, 0x82, 0x44, 0xcc, 0x23, 0xd0, 0x67, 0xcb, 0x91, 0xc9, 0xaa, 0x41, 0x11, 0xc7, 0xeb, 0x8d, + 0x74, 0x29, 0xd9, 0x69, 0x88, 0x10, 0xe4, 0x5d, 0x2c, 0x70, 0x6c, 0x37, 0x3b, 0x3a, 0x57, 0x3f, + 0xab, 0x80, 0x5a, 0xdc, 0x7b, 0x76, 0x46, 0xc9, 0xf0, 0x7e, 0xb4, 0x6d, 0xc1, 0x12, 0x49, 0x68, + 0x13, 0xa3, 0xff, 0x05, 0x59, 0x46, 0x81, 0x56, 0x41, 0x95, 0xe2, 0xa9, 0xd1, 0x0c, 0xf2, 0x78, + 0x8b, 0x79, 0xf2, 0xb7, 0x98, 0xe7, 0x18, 0x80, 0xd3, 0x20, 0x95, 0x79, 0xf1, 0x1e, 0x64, 0x96, + 0xf4, 0xb3, 0x65, 0x2e, 0xcc, 0x2d, 0xf3, 0x0e, 0x54, 0x7e, 0x57, 0x25, 0x93, 0x38, 0x15, 0x52, + 0x99, 0x08, 0x59, 0xbf, 0x5a, 0x00, 0x55, 0xda, 0xb8, 0x03, 0xa5, 0xc9, 0xad, 0xf5, 0xd0, 0x9c, + 0x7d, 0x2b, 0x9a, 0xd3, 0x17, 0x42, 0x65, 0x6b, 0x1e, 0x54, 0x56, 0xfc, 0x3d, 0xfc, 0x3f, 0xeb, + 0x36, 0x30, 0xef, 0x20, 0x99, 0x81, 0xaf, 0xec, 0xfd, 0x19, 0x3e, 0x2b, 0xff, 0x16, 0x56, 0x6e, + 0x9a, 0xf5, 0xd1, 0x1d, 0x54, 0x37, 0xb0, 0x95, 0xfa, 0xfc, 0xd8, 0xb4, 0x64, 0xe3, 0xe5, 0xc5, + 0x58, 0x57, 0x2e, 0xc7, 0xba, 0xf2, 0x63, 0xac, 0x2b, 0x9f, 0xae, 0xf5, 0xdc, 0xe5, 0xb5, 0x9e, + 0xbb, 0xba, 0xd6, 0x73, 0xaf, 0xf7, 0xa7, 0x5c, 0x41, 0x03, 0xdf, 0xeb, 0xe3, 0xfe, 0x80, 0x58, + 0xed, 0xa8, 0xc2, 0x11, 0x15, 0xa7, 0x2c, 0x3c, 0xb1, 0xce, 0xb2, 0x37, 0xcb, 0x0f, 0x04, 0x0d, + 0x03, 0xdc, 0x8b, 0xed, 0xe2, 0x14, 0xa2, 0xa7, 0xe6, 0xf1, 0xaf, 0x00, 0x00, 0x00, 0xff, 0xff, + 0x2d, 0x4f, 0xbc, 0x89, 0xdb, 0x06, 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 { + // StoreCode to submit Wasm code to the system + StoreCode(ctx context.Context, in *MsgStoreCode, opts ...grpc.CallOption) (*MsgStoreCodeResponse, error) + // Instantiate creates a new smart contract instance for the given code id. + InstantiateContract(ctx context.Context, in *MsgInstantiateContract, opts ...grpc.CallOption) (*MsgInstantiateContractResponse, error) + // Execute submits the given message data to a smart contract + ExecuteContract(ctx context.Context, in *MsgExecuteContract, opts ...grpc.CallOption) (*MsgExecuteContractResponse, error) +} + +type msgClient struct { + cc grpc1.ClientConn +} + +func NewMsgClient(cc grpc1.ClientConn) MsgClient { + return &msgClient{cc} +} + +func (c *msgClient) StoreCode(ctx context.Context, in *MsgStoreCode, opts ...grpc.CallOption) (*MsgStoreCodeResponse, error) { + out := new(MsgStoreCodeResponse) + err := c.cc.Invoke(ctx, "/secret.compute.v1beta1.Msg/StoreCode", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *msgClient) InstantiateContract(ctx context.Context, in *MsgInstantiateContract, opts ...grpc.CallOption) (*MsgInstantiateContractResponse, error) { + out := new(MsgInstantiateContractResponse) + err := c.cc.Invoke(ctx, "/secret.compute.v1beta1.Msg/InstantiateContract", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *msgClient) ExecuteContract(ctx context.Context, in *MsgExecuteContract, opts ...grpc.CallOption) (*MsgExecuteContractResponse, error) { + out := new(MsgExecuteContractResponse) + err := c.cc.Invoke(ctx, "/secret.compute.v1beta1.Msg/ExecuteContract", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// MsgServer is the server API for Msg service. +type MsgServer interface { + // StoreCode to submit Wasm code to the system + StoreCode(context.Context, *MsgStoreCode) (*MsgStoreCodeResponse, error) + // Instantiate creates a new smart contract instance for the given code id. + InstantiateContract(context.Context, *MsgInstantiateContract) (*MsgInstantiateContractResponse, error) + // Execute submits the given message data to a smart contract + ExecuteContract(context.Context, *MsgExecuteContract) (*MsgExecuteContractResponse, error) +} + +// UnimplementedMsgServer can be embedded to have forward compatible implementations. +type UnimplementedMsgServer struct { +} + +func (*UnimplementedMsgServer) StoreCode(ctx context.Context, req *MsgStoreCode) (*MsgStoreCodeResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method StoreCode not implemented") +} +func (*UnimplementedMsgServer) InstantiateContract(ctx context.Context, req *MsgInstantiateContract) (*MsgInstantiateContractResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method InstantiateContract not implemented") +} +func (*UnimplementedMsgServer) ExecuteContract(ctx context.Context, req *MsgExecuteContract) (*MsgExecuteContractResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method ExecuteContract not implemented") +} + +func RegisterMsgServer(s grpc1.Server, srv MsgServer) { + s.RegisterService(&_Msg_serviceDesc, srv) +} + +func _Msg_StoreCode_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(MsgStoreCode) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(MsgServer).StoreCode(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/secret.compute.v1beta1.Msg/StoreCode", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MsgServer).StoreCode(ctx, req.(*MsgStoreCode)) + } + return interceptor(ctx, in, info, handler) +} + +func _Msg_InstantiateContract_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(MsgInstantiateContract) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(MsgServer).InstantiateContract(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/secret.compute.v1beta1.Msg/InstantiateContract", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MsgServer).InstantiateContract(ctx, req.(*MsgInstantiateContract)) + } + return interceptor(ctx, in, info, handler) +} + +func _Msg_ExecuteContract_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(MsgExecuteContract) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(MsgServer).ExecuteContract(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/secret.compute.v1beta1.Msg/ExecuteContract", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MsgServer).ExecuteContract(ctx, req.(*MsgExecuteContract)) + } + return interceptor(ctx, in, info, handler) } -func init() { proto.RegisterFile("secret/compute/v1beta1/msg.proto", fileDescriptor_6815433faf72a133) } - -var fileDescriptor_6815433faf72a133 = []byte{ - // 572 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x54, 0x31, 0x6f, 0xd3, 0x40, - 0x18, 0x8d, 0x49, 0xea, 0xb4, 0xd7, 0x08, 0xaa, 0x53, 0x55, 0xb9, 0x1d, 0xec, 0xa8, 0x2c, 0x19, - 0xa8, 0x4d, 0x8b, 0xc4, 0x00, 0x53, 0x53, 0x40, 0x64, 0x08, 0x83, 0x23, 0x84, 0xc4, 0x12, 0x9d, - 0xcf, 0xc7, 0xe5, 0xda, 0xf8, 0x2e, 0xf2, 0x77, 0xa6, 0xed, 0x3f, 0x60, 0x41, 0x62, 0xe0, 0x07, - 0x30, 0xf3, 0x4b, 0xca, 0xd6, 0x91, 0x29, 0x20, 0xf7, 0x5f, 0x30, 0xa1, 0x3b, 0x3b, 0x2d, 0x03, - 0x95, 0x2a, 0x44, 0xa7, 0xdc, 0xcb, 0x7b, 0x7e, 0xf7, 0xbd, 0x7b, 0xa7, 0x43, 0x5d, 0x60, 0x34, - 0x67, 0x3a, 0xa2, 0x2a, 0x9b, 0x15, 0x9a, 0x45, 0xef, 0x77, 0x13, 0xa6, 0xc9, 0x6e, 0x94, 0x01, - 0x0f, 0x67, 0xb9, 0xd2, 0x0a, 0x6f, 0x54, 0x8a, 0xb0, 0x56, 0x84, 0xb5, 0x62, 0x6b, 0x9d, 0x2b, - 0xae, 0xac, 0x24, 0x32, 0xab, 0x4a, 0xbd, 0xe5, 0x53, 0x05, 0x99, 0x82, 0x28, 0x21, 0x70, 0x65, - 0x46, 0x95, 0x90, 0x15, 0xbf, 0xfd, 0xcd, 0x41, 0x9d, 0x21, 0xf0, 0x91, 0x56, 0x39, 0x3b, 0x50, - 0x29, 0xc3, 0x03, 0xe4, 0x02, 0x93, 0x29, 0xcb, 0x3d, 0xa7, 0xeb, 0xf4, 0x3a, 0xfd, 0xdd, 0x5f, - 0xf3, 0x60, 0x87, 0x0b, 0x3d, 0x29, 0x12, 0xb3, 0x65, 0x54, 0xfb, 0x55, 0x3f, 0x3b, 0x90, 0x1e, - 0x45, 0xfa, 0x74, 0xc6, 0x20, 0xdc, 0xa7, 0x74, 0x3f, 0x4d, 0x73, 0x06, 0x10, 0xd7, 0x06, 0xf8, - 0x31, 0xba, 0x7b, 0x4c, 0x20, 0x1b, 0x27, 0xa7, 0x9a, 0x8d, 0xa9, 0x4a, 0x99, 0x77, 0xc7, 0x5a, - 0xae, 0x95, 0xf3, 0xa0, 0xf3, 0x66, 0x7f, 0x34, 0xec, 0x9f, 0x6a, 0xbb, 0x69, 0xdc, 0x31, 0xba, - 0x05, 0xc2, 0x1b, 0xc8, 0x05, 0x55, 0xe4, 0x94, 0x79, 0xcd, 0xae, 0xd3, 0x5b, 0x89, 0x6b, 0x84, - 0x3d, 0xd4, 0x4e, 0x0a, 0x31, 0x35, 0xb3, 0xb5, 0x2c, 0xb1, 0x80, 0x4f, 0x5a, 0x1f, 0xbe, 0x04, - 0x8d, 0xed, 0x8f, 0x4d, 0xb4, 0x31, 0x04, 0x3e, 0x90, 0xa0, 0x89, 0xd4, 0x82, 0x18, 0x3b, 0xa9, - 0x73, 0x42, 0xf5, 0xff, 0x4c, 0xf5, 0x00, 0x61, 0x4a, 0xa6, 0xd3, 0x84, 0xd0, 0x23, 0x1b, 0x6a, - 0x3c, 0x21, 0x30, 0xb1, 0xc9, 0x56, 0xe2, 0xb5, 0x05, 0x63, 0x72, 0xbc, 0x24, 0x30, 0xc1, 0xf7, - 0x51, 0xdb, 0x8a, 0x44, 0x6a, 0xc3, 0xb4, 0xfa, 0xa8, 0x9c, 0x07, 0xae, 0xa1, 0x07, 0xcf, 0x62, - 0xd7, 0x50, 0x83, 0x14, 0xaf, 0xa3, 0xa5, 0x29, 0x49, 0xd8, 0xb4, 0x8e, 0x55, 0x01, 0xbc, 0x89, - 0x96, 0x85, 0x14, 0x7a, 0x9c, 0x01, 0xf7, 0x96, 0xcc, 0xd4, 0x71, 0xdb, 0xe0, 0x21, 0x70, 0x7c, - 0x88, 0x90, 0xa5, 0xde, 0x15, 0x32, 0x05, 0xcf, 0xed, 0x36, 0x7b, 0xab, 0x7b, 0x9b, 0x61, 0x35, - 0x7d, 0x68, 0xaa, 0x5e, 0xdc, 0x8a, 0xf0, 0x40, 0x09, 0xd9, 0x7f, 0x78, 0x36, 0x0f, 0x1a, 0x5f, - 0x7f, 0x04, 0xbd, 0x1b, 0x24, 0x36, 0x1f, 0x40, 0xbc, 0x62, 0xec, 0x5f, 0x18, 0x77, 0xbc, 0x87, - 0x3a, 0x97, 0x79, 0x41, 0x70, 0xaf, 0x6d, 0x0f, 0xf0, 0x5e, 0x39, 0x0f, 0x56, 0x0f, 0xea, 0xff, - 0x47, 0x82, 0xc7, 0xab, 0xf4, 0x0a, 0xd4, 0x7d, 0x7c, 0x6e, 0x22, 0x3c, 0x04, 0xfe, 0xfc, 0x84, - 0xd1, 0xe2, 0x76, 0xba, 0x18, 0xa2, 0x65, 0x5a, 0xdb, 0xd6, 0x77, 0xeb, 0x1f, 0xcc, 0x2e, 0x2d, - 0xf0, 0x1a, 0x6a, 0x9a, 0xc3, 0x6e, 0xda, 0xc3, 0x36, 0xcb, 0x6b, 0xca, 0x6e, 0x5d, 0x53, 0xf6, - 0x21, 0x42, 0xc0, 0xe4, 0xa2, 0x96, 0xa5, 0x5b, 0xa8, 0xc5, 0xd8, 0xff, 0xbd, 0x16, 0xf7, 0xa6, - 0xb5, 0xf4, 0x5f, 0x9f, 0x95, 0xbe, 0x73, 0x5e, 0xfa, 0xce, 0xcf, 0xd2, 0x77, 0x3e, 0x5d, 0xf8, - 0x8d, 0xf3, 0x0b, 0xbf, 0xf1, 0xfd, 0xc2, 0x6f, 0xbc, 0x7d, 0xfa, 0xc7, 0x20, 0x4c, 0x0a, 0x9e, - 0x91, 0x6c, 0x46, 0xa3, 0x91, 0x7d, 0x6f, 0x5e, 0x31, 0x7d, 0xac, 0xf2, 0xa3, 0xe8, 0xe4, 0xf2, - 0x69, 0x12, 0x52, 0xb3, 0x5c, 0x92, 0x69, 0x35, 0x61, 0xe2, 0xda, 0x07, 0xe5, 0xd1, 0xef, 0x00, - 0x00, 0x00, 0xff, 0xff, 0xea, 0x28, 0x0f, 0x71, 0xc2, 0x04, 0x00, 0x00, +var _Msg_serviceDesc = grpc.ServiceDesc{ + ServiceName: "secret.compute.v1beta1.Msg", + HandlerType: (*MsgServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "StoreCode", + Handler: _Msg_StoreCode_Handler, + }, + { + MethodName: "InstantiateContract", + Handler: _Msg_InstantiateContract_Handler, + }, + { + MethodName: "ExecuteContract", + Handler: _Msg_ExecuteContract_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "secret/compute/v1beta1/tx.proto", } func (m *MsgStoreCode) Marshal() (dAtA []byte, err error) { @@ -226,34 +547,62 @@ func (m *MsgStoreCode) MarshalToSizedBuffer(dAtA []byte) (int, error) { if len(m.Builder) > 0 { i -= len(m.Builder) copy(dAtA[i:], m.Builder) - i = encodeVarintMsg(dAtA, i, uint64(len(m.Builder))) + i = encodeVarintTx(dAtA, i, uint64(len(m.Builder))) i-- dAtA[i] = 0x22 } if len(m.Source) > 0 { i -= len(m.Source) copy(dAtA[i:], m.Source) - i = encodeVarintMsg(dAtA, i, uint64(len(m.Source))) + i = encodeVarintTx(dAtA, i, uint64(len(m.Source))) i-- dAtA[i] = 0x1a } if len(m.WASMByteCode) > 0 { i -= len(m.WASMByteCode) copy(dAtA[i:], m.WASMByteCode) - i = encodeVarintMsg(dAtA, i, uint64(len(m.WASMByteCode))) + i = encodeVarintTx(dAtA, i, uint64(len(m.WASMByteCode))) i-- dAtA[i] = 0x12 } if len(m.Sender) > 0 { i -= len(m.Sender) copy(dAtA[i:], m.Sender) - i = encodeVarintMsg(dAtA, i, uint64(len(m.Sender))) + i = encodeVarintTx(dAtA, i, uint64(len(m.Sender))) i-- dAtA[i] = 0xa } return len(dAtA) - i, nil } +func (m *MsgStoreCodeResponse) 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 *MsgStoreCodeResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgStoreCodeResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.CodeID != 0 { + i = encodeVarintTx(dAtA, i, uint64(m.CodeID)) + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + func (m *MsgInstantiateContract) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -277,7 +626,7 @@ func (m *MsgInstantiateContract) MarshalToSizedBuffer(dAtA []byte) (int, error) if len(m.CallbackSig) > 0 { i -= len(m.CallbackSig) copy(dAtA[i:], m.CallbackSig) - i = encodeVarintMsg(dAtA, i, uint64(len(m.CallbackSig))) + i = encodeVarintTx(dAtA, i, uint64(len(m.CallbackSig))) i-- dAtA[i] = 0x3a } @@ -289,7 +638,7 @@ func (m *MsgInstantiateContract) MarshalToSizedBuffer(dAtA []byte) (int, error) return 0, err } i -= size - i = encodeVarintMsg(dAtA, i, uint64(size)) + i = encodeVarintTx(dAtA, i, uint64(size)) } i-- dAtA[i] = 0x32 @@ -298,33 +647,70 @@ func (m *MsgInstantiateContract) MarshalToSizedBuffer(dAtA []byte) (int, error) if len(m.InitMsg) > 0 { i -= len(m.InitMsg) copy(dAtA[i:], m.InitMsg) - i = encodeVarintMsg(dAtA, i, uint64(len(m.InitMsg))) + i = encodeVarintTx(dAtA, i, uint64(len(m.InitMsg))) i-- dAtA[i] = 0x2a } if len(m.Label) > 0 { i -= len(m.Label) copy(dAtA[i:], m.Label) - i = encodeVarintMsg(dAtA, i, uint64(len(m.Label))) + i = encodeVarintTx(dAtA, i, uint64(len(m.Label))) i-- dAtA[i] = 0x22 } if m.CodeID != 0 { - i = encodeVarintMsg(dAtA, i, uint64(m.CodeID)) + i = encodeVarintTx(dAtA, i, uint64(m.CodeID)) i-- dAtA[i] = 0x18 } if len(m.CallbackCodeHash) > 0 { i -= len(m.CallbackCodeHash) copy(dAtA[i:], m.CallbackCodeHash) - i = encodeVarintMsg(dAtA, i, uint64(len(m.CallbackCodeHash))) + i = encodeVarintTx(dAtA, i, uint64(len(m.CallbackCodeHash))) i-- dAtA[i] = 0x12 } if len(m.Sender) > 0 { i -= len(m.Sender) copy(dAtA[i:], m.Sender) - i = encodeVarintMsg(dAtA, i, uint64(len(m.Sender))) + i = encodeVarintTx(dAtA, i, uint64(len(m.Sender))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *MsgInstantiateContractResponse) 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 *MsgInstantiateContractResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgInstantiateContractResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Data) > 0 { + i -= len(m.Data) + copy(dAtA[i:], m.Data) + i = encodeVarintTx(dAtA, i, uint64(len(m.Data))) + i-- + dAtA[i] = 0x12 + } + if len(m.Address) > 0 { + i -= len(m.Address) + copy(dAtA[i:], m.Address) + i = encodeVarintTx(dAtA, i, uint64(len(m.Address))) i-- dAtA[i] = 0xa } @@ -354,7 +740,7 @@ func (m *MsgExecuteContract) MarshalToSizedBuffer(dAtA []byte) (int, error) { if len(m.CallbackSig) > 0 { i -= len(m.CallbackSig) copy(dAtA[i:], m.CallbackSig) - i = encodeVarintMsg(dAtA, i, uint64(len(m.CallbackSig))) + i = encodeVarintTx(dAtA, i, uint64(len(m.CallbackSig))) i-- dAtA[i] = 0x32 } @@ -366,7 +752,7 @@ func (m *MsgExecuteContract) MarshalToSizedBuffer(dAtA []byte) (int, error) { return 0, err } i -= size - i = encodeVarintMsg(dAtA, i, uint64(size)) + i = encodeVarintTx(dAtA, i, uint64(size)) } i-- dAtA[i] = 0x2a @@ -375,36 +761,66 @@ func (m *MsgExecuteContract) MarshalToSizedBuffer(dAtA []byte) (int, error) { if len(m.CallbackCodeHash) > 0 { i -= len(m.CallbackCodeHash) copy(dAtA[i:], m.CallbackCodeHash) - i = encodeVarintMsg(dAtA, i, uint64(len(m.CallbackCodeHash))) + i = encodeVarintTx(dAtA, i, uint64(len(m.CallbackCodeHash))) i-- dAtA[i] = 0x22 } if len(m.Msg) > 0 { i -= len(m.Msg) copy(dAtA[i:], m.Msg) - i = encodeVarintMsg(dAtA, i, uint64(len(m.Msg))) + i = encodeVarintTx(dAtA, i, uint64(len(m.Msg))) i-- dAtA[i] = 0x1a } if len(m.Contract) > 0 { i -= len(m.Contract) copy(dAtA[i:], m.Contract) - i = encodeVarintMsg(dAtA, i, uint64(len(m.Contract))) + i = encodeVarintTx(dAtA, i, uint64(len(m.Contract))) i-- dAtA[i] = 0x12 } if len(m.Sender) > 0 { i -= len(m.Sender) copy(dAtA[i:], m.Sender) - i = encodeVarintMsg(dAtA, i, uint64(len(m.Sender))) + i = encodeVarintTx(dAtA, i, uint64(len(m.Sender))) i-- dAtA[i] = 0xa } return len(dAtA) - i, nil } -func encodeVarintMsg(dAtA []byte, offset int, v uint64) int { - offset -= sovMsg(v) +func (m *MsgExecuteContractResponse) 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 *MsgExecuteContractResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgExecuteContractResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Data) > 0 { + i -= len(m.Data) + copy(dAtA[i:], m.Data) + i = encodeVarintTx(dAtA, i, uint64(len(m.Data))) + i-- + dAtA[i] = 0xa + } + 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) @@ -422,19 +838,31 @@ func (m *MsgStoreCode) Size() (n int) { _ = l l = len(m.Sender) if l > 0 { - n += 1 + l + sovMsg(uint64(l)) + n += 1 + l + sovTx(uint64(l)) } l = len(m.WASMByteCode) if l > 0 { - n += 1 + l + sovMsg(uint64(l)) + n += 1 + l + sovTx(uint64(l)) } l = len(m.Source) if l > 0 { - n += 1 + l + sovMsg(uint64(l)) + n += 1 + l + sovTx(uint64(l)) } l = len(m.Builder) if l > 0 { - n += 1 + l + sovMsg(uint64(l)) + n += 1 + l + sovTx(uint64(l)) + } + return n +} + +func (m *MsgStoreCodeResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.CodeID != 0 { + n += 1 + sovTx(uint64(m.CodeID)) } return n } @@ -447,32 +875,49 @@ func (m *MsgInstantiateContract) Size() (n int) { _ = l l = len(m.Sender) if l > 0 { - n += 1 + l + sovMsg(uint64(l)) + n += 1 + l + sovTx(uint64(l)) } l = len(m.CallbackCodeHash) if l > 0 { - n += 1 + l + sovMsg(uint64(l)) + n += 1 + l + sovTx(uint64(l)) } if m.CodeID != 0 { - n += 1 + sovMsg(uint64(m.CodeID)) + n += 1 + sovTx(uint64(m.CodeID)) } l = len(m.Label) if l > 0 { - n += 1 + l + sovMsg(uint64(l)) + n += 1 + l + sovTx(uint64(l)) } l = len(m.InitMsg) if l > 0 { - n += 1 + l + sovMsg(uint64(l)) + n += 1 + l + sovTx(uint64(l)) } if len(m.InitFunds) > 0 { for _, e := range m.InitFunds { l = e.Size() - n += 1 + l + sovMsg(uint64(l)) + n += 1 + l + sovTx(uint64(l)) } } l = len(m.CallbackSig) if l > 0 { - n += 1 + l + sovMsg(uint64(l)) + n += 1 + l + sovTx(uint64(l)) + } + return n +} + +func (m *MsgInstantiateContractResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Address) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + l = len(m.Data) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) } return n } @@ -485,38 +930,51 @@ func (m *MsgExecuteContract) Size() (n int) { _ = l l = len(m.Sender) if l > 0 { - n += 1 + l + sovMsg(uint64(l)) + n += 1 + l + sovTx(uint64(l)) } l = len(m.Contract) if l > 0 { - n += 1 + l + sovMsg(uint64(l)) + n += 1 + l + sovTx(uint64(l)) } l = len(m.Msg) if l > 0 { - n += 1 + l + sovMsg(uint64(l)) + n += 1 + l + sovTx(uint64(l)) } l = len(m.CallbackCodeHash) if l > 0 { - n += 1 + l + sovMsg(uint64(l)) + n += 1 + l + sovTx(uint64(l)) } if len(m.SentFunds) > 0 { for _, e := range m.SentFunds { l = e.Size() - n += 1 + l + sovMsg(uint64(l)) + n += 1 + l + sovTx(uint64(l)) } } l = len(m.CallbackSig) if l > 0 { - n += 1 + l + sovMsg(uint64(l)) + n += 1 + l + sovTx(uint64(l)) } return n } -func sovMsg(x uint64) (n int) { +func (m *MsgExecuteContractResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Data) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + return n +} + +func sovTx(x uint64) (n int) { return (math_bits.Len64(x|1) + 6) / 7 } -func sozMsg(x uint64) (n int) { - return sovMsg(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +func sozTx(x uint64) (n int) { + return sovTx(uint64((x << 1) ^ uint64((int64(x) >> 63)))) } func (m *MsgStoreCode) Unmarshal(dAtA []byte) error { l := len(dAtA) @@ -526,7 +984,7 @@ func (m *MsgStoreCode) Unmarshal(dAtA []byte) error { var wire uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflowMsg + return ErrIntOverflowTx } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -554,7 +1012,7 @@ func (m *MsgStoreCode) Unmarshal(dAtA []byte) error { var byteLen int for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflowMsg + return ErrIntOverflowTx } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -567,11 +1025,11 @@ func (m *MsgStoreCode) Unmarshal(dAtA []byte) error { } } if byteLen < 0 { - return ErrInvalidLengthMsg + return ErrInvalidLengthTx } postIndex := iNdEx + byteLen if postIndex < 0 { - return ErrInvalidLengthMsg + return ErrInvalidLengthTx } if postIndex > l { return io.ErrUnexpectedEOF @@ -588,7 +1046,7 @@ func (m *MsgStoreCode) Unmarshal(dAtA []byte) error { var byteLen int for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflowMsg + return ErrIntOverflowTx } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -601,11 +1059,11 @@ func (m *MsgStoreCode) Unmarshal(dAtA []byte) error { } } if byteLen < 0 { - return ErrInvalidLengthMsg + return ErrInvalidLengthTx } postIndex := iNdEx + byteLen if postIndex < 0 { - return ErrInvalidLengthMsg + return ErrInvalidLengthTx } if postIndex > l { return io.ErrUnexpectedEOF @@ -622,7 +1080,7 @@ func (m *MsgStoreCode) Unmarshal(dAtA []byte) error { var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflowMsg + return ErrIntOverflowTx } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -636,11 +1094,11 @@ func (m *MsgStoreCode) Unmarshal(dAtA []byte) error { } intStringLen := int(stringLen) if intStringLen < 0 { - return ErrInvalidLengthMsg + return ErrInvalidLengthTx } postIndex := iNdEx + intStringLen if postIndex < 0 { - return ErrInvalidLengthMsg + return ErrInvalidLengthTx } if postIndex > l { return io.ErrUnexpectedEOF @@ -654,7 +1112,7 @@ func (m *MsgStoreCode) Unmarshal(dAtA []byte) error { var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflowMsg + return ErrIntOverflowTx } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -668,11 +1126,11 @@ func (m *MsgStoreCode) Unmarshal(dAtA []byte) error { } intStringLen := int(stringLen) if intStringLen < 0 { - return ErrInvalidLengthMsg + return ErrInvalidLengthTx } postIndex := iNdEx + intStringLen if postIndex < 0 { - return ErrInvalidLengthMsg + return ErrInvalidLengthTx } if postIndex > l { return io.ErrUnexpectedEOF @@ -681,12 +1139,81 @@ func (m *MsgStoreCode) Unmarshal(dAtA []byte) error { iNdEx = postIndex default: iNdEx = preIndex - skippy, err := skipMsg(dAtA[iNdEx:]) + 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 *MsgStoreCodeResponse) 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: MsgStoreCodeResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgStoreCodeResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field CodeID", wireType) + } + m.CodeID = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.CodeID |= uint64(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 ErrInvalidLengthMsg + return ErrInvalidLengthTx } if (iNdEx + skippy) > l { return io.ErrUnexpectedEOF @@ -708,7 +1235,7 @@ func (m *MsgInstantiateContract) Unmarshal(dAtA []byte) error { var wire uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflowMsg + return ErrIntOverflowTx } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -736,7 +1263,7 @@ func (m *MsgInstantiateContract) Unmarshal(dAtA []byte) error { var byteLen int for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflowMsg + return ErrIntOverflowTx } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -749,11 +1276,11 @@ func (m *MsgInstantiateContract) Unmarshal(dAtA []byte) error { } } if byteLen < 0 { - return ErrInvalidLengthMsg + return ErrInvalidLengthTx } postIndex := iNdEx + byteLen if postIndex < 0 { - return ErrInvalidLengthMsg + return ErrInvalidLengthTx } if postIndex > l { return io.ErrUnexpectedEOF @@ -770,7 +1297,7 @@ func (m *MsgInstantiateContract) Unmarshal(dAtA []byte) error { var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflowMsg + return ErrIntOverflowTx } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -784,11 +1311,11 @@ func (m *MsgInstantiateContract) Unmarshal(dAtA []byte) error { } intStringLen := int(stringLen) if intStringLen < 0 { - return ErrInvalidLengthMsg + return ErrInvalidLengthTx } postIndex := iNdEx + intStringLen if postIndex < 0 { - return ErrInvalidLengthMsg + return ErrInvalidLengthTx } if postIndex > l { return io.ErrUnexpectedEOF @@ -802,7 +1329,7 @@ func (m *MsgInstantiateContract) Unmarshal(dAtA []byte) error { m.CodeID = 0 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflowMsg + return ErrIntOverflowTx } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -821,7 +1348,7 @@ func (m *MsgInstantiateContract) Unmarshal(dAtA []byte) error { var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflowMsg + return ErrIntOverflowTx } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -835,11 +1362,11 @@ func (m *MsgInstantiateContract) Unmarshal(dAtA []byte) error { } intStringLen := int(stringLen) if intStringLen < 0 { - return ErrInvalidLengthMsg + return ErrInvalidLengthTx } postIndex := iNdEx + intStringLen if postIndex < 0 { - return ErrInvalidLengthMsg + return ErrInvalidLengthTx } if postIndex > l { return io.ErrUnexpectedEOF @@ -853,7 +1380,7 @@ func (m *MsgInstantiateContract) Unmarshal(dAtA []byte) error { var byteLen int for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflowMsg + return ErrIntOverflowTx } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -866,11 +1393,11 @@ func (m *MsgInstantiateContract) Unmarshal(dAtA []byte) error { } } if byteLen < 0 { - return ErrInvalidLengthMsg + return ErrInvalidLengthTx } postIndex := iNdEx + byteLen if postIndex < 0 { - return ErrInvalidLengthMsg + return ErrInvalidLengthTx } if postIndex > l { return io.ErrUnexpectedEOF @@ -887,7 +1414,7 @@ func (m *MsgInstantiateContract) Unmarshal(dAtA []byte) error { var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflowMsg + return ErrIntOverflowTx } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -900,11 +1427,11 @@ func (m *MsgInstantiateContract) Unmarshal(dAtA []byte) error { } } if msglen < 0 { - return ErrInvalidLengthMsg + return ErrInvalidLengthTx } postIndex := iNdEx + msglen if postIndex < 0 { - return ErrInvalidLengthMsg + return ErrInvalidLengthTx } if postIndex > l { return io.ErrUnexpectedEOF @@ -921,7 +1448,7 @@ func (m *MsgInstantiateContract) Unmarshal(dAtA []byte) error { var byteLen int for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflowMsg + return ErrIntOverflowTx } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -934,11 +1461,11 @@ func (m *MsgInstantiateContract) Unmarshal(dAtA []byte) error { } } if byteLen < 0 { - return ErrInvalidLengthMsg + return ErrInvalidLengthTx } postIndex := iNdEx + byteLen if postIndex < 0 { - return ErrInvalidLengthMsg + return ErrInvalidLengthTx } if postIndex > l { return io.ErrUnexpectedEOF @@ -950,12 +1477,128 @@ func (m *MsgInstantiateContract) Unmarshal(dAtA []byte) error { iNdEx = postIndex default: iNdEx = preIndex - skippy, err := skipMsg(dAtA[iNdEx:]) + skippy, err := skipTx(dAtA[iNdEx:]) if err != nil { return err } if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthMsg + return ErrInvalidLengthTx + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *MsgInstantiateContractResponse) 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: MsgInstantiateContractResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgInstantiateContractResponse: 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 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.Address = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Data", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Data = append(m.Data[:0], dAtA[iNdEx:postIndex]...) + if m.Data == nil { + m.Data = []byte{} + } + 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 @@ -977,7 +1620,7 @@ func (m *MsgExecuteContract) Unmarshal(dAtA []byte) error { var wire uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflowMsg + return ErrIntOverflowTx } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -1005,7 +1648,7 @@ func (m *MsgExecuteContract) Unmarshal(dAtA []byte) error { var byteLen int for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflowMsg + return ErrIntOverflowTx } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -1018,11 +1661,11 @@ func (m *MsgExecuteContract) Unmarshal(dAtA []byte) error { } } if byteLen < 0 { - return ErrInvalidLengthMsg + return ErrInvalidLengthTx } postIndex := iNdEx + byteLen if postIndex < 0 { - return ErrInvalidLengthMsg + return ErrInvalidLengthTx } if postIndex > l { return io.ErrUnexpectedEOF @@ -1039,7 +1682,7 @@ func (m *MsgExecuteContract) Unmarshal(dAtA []byte) error { var byteLen int for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflowMsg + return ErrIntOverflowTx } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -1052,11 +1695,11 @@ func (m *MsgExecuteContract) Unmarshal(dAtA []byte) error { } } if byteLen < 0 { - return ErrInvalidLengthMsg + return ErrInvalidLengthTx } postIndex := iNdEx + byteLen if postIndex < 0 { - return ErrInvalidLengthMsg + return ErrInvalidLengthTx } if postIndex > l { return io.ErrUnexpectedEOF @@ -1073,7 +1716,7 @@ func (m *MsgExecuteContract) Unmarshal(dAtA []byte) error { var byteLen int for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflowMsg + return ErrIntOverflowTx } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -1086,11 +1729,11 @@ func (m *MsgExecuteContract) Unmarshal(dAtA []byte) error { } } if byteLen < 0 { - return ErrInvalidLengthMsg + return ErrInvalidLengthTx } postIndex := iNdEx + byteLen if postIndex < 0 { - return ErrInvalidLengthMsg + return ErrInvalidLengthTx } if postIndex > l { return io.ErrUnexpectedEOF @@ -1107,7 +1750,7 @@ func (m *MsgExecuteContract) Unmarshal(dAtA []byte) error { var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflowMsg + return ErrIntOverflowTx } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -1121,11 +1764,11 @@ func (m *MsgExecuteContract) Unmarshal(dAtA []byte) error { } intStringLen := int(stringLen) if intStringLen < 0 { - return ErrInvalidLengthMsg + return ErrInvalidLengthTx } postIndex := iNdEx + intStringLen if postIndex < 0 { - return ErrInvalidLengthMsg + return ErrInvalidLengthTx } if postIndex > l { return io.ErrUnexpectedEOF @@ -1139,7 +1782,7 @@ func (m *MsgExecuteContract) Unmarshal(dAtA []byte) error { var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflowMsg + return ErrIntOverflowTx } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -1152,11 +1795,11 @@ func (m *MsgExecuteContract) Unmarshal(dAtA []byte) error { } } if msglen < 0 { - return ErrInvalidLengthMsg + return ErrInvalidLengthTx } postIndex := iNdEx + msglen if postIndex < 0 { - return ErrInvalidLengthMsg + return ErrInvalidLengthTx } if postIndex > l { return io.ErrUnexpectedEOF @@ -1173,7 +1816,7 @@ func (m *MsgExecuteContract) Unmarshal(dAtA []byte) error { var byteLen int for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflowMsg + return ErrIntOverflowTx } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -1186,11 +1829,11 @@ func (m *MsgExecuteContract) Unmarshal(dAtA []byte) error { } } if byteLen < 0 { - return ErrInvalidLengthMsg + return ErrInvalidLengthTx } postIndex := iNdEx + byteLen if postIndex < 0 { - return ErrInvalidLengthMsg + return ErrInvalidLengthTx } if postIndex > l { return io.ErrUnexpectedEOF @@ -1202,12 +1845,96 @@ func (m *MsgExecuteContract) Unmarshal(dAtA []byte) error { iNdEx = postIndex default: iNdEx = preIndex - skippy, err := skipMsg(dAtA[iNdEx:]) + 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 *MsgExecuteContractResponse) 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: MsgExecuteContractResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgExecuteContractResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Data", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Data = append(m.Data[:0], dAtA[iNdEx:postIndex]...) + if m.Data == nil { + m.Data = []byte{} + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipTx(dAtA[iNdEx:]) if err != nil { return err } if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthMsg + return ErrInvalidLengthTx } if (iNdEx + skippy) > l { return io.ErrUnexpectedEOF @@ -1221,7 +1948,7 @@ func (m *MsgExecuteContract) Unmarshal(dAtA []byte) error { } return nil } -func skipMsg(dAtA []byte) (n int, err error) { +func skipTx(dAtA []byte) (n int, err error) { l := len(dAtA) iNdEx := 0 depth := 0 @@ -1229,7 +1956,7 @@ func skipMsg(dAtA []byte) (n int, err error) { var wire uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return 0, ErrIntOverflowMsg + return 0, ErrIntOverflowTx } if iNdEx >= l { return 0, io.ErrUnexpectedEOF @@ -1246,7 +1973,7 @@ func skipMsg(dAtA []byte) (n int, err error) { case 0: for shift := uint(0); ; shift += 7 { if shift >= 64 { - return 0, ErrIntOverflowMsg + return 0, ErrIntOverflowTx } if iNdEx >= l { return 0, io.ErrUnexpectedEOF @@ -1262,7 +1989,7 @@ func skipMsg(dAtA []byte) (n int, err error) { var length int for shift := uint(0); ; shift += 7 { if shift >= 64 { - return 0, ErrIntOverflowMsg + return 0, ErrIntOverflowTx } if iNdEx >= l { return 0, io.ErrUnexpectedEOF @@ -1275,14 +2002,14 @@ func skipMsg(dAtA []byte) (n int, err error) { } } if length < 0 { - return 0, ErrInvalidLengthMsg + return 0, ErrInvalidLengthTx } iNdEx += length case 3: depth++ case 4: if depth == 0 { - return 0, ErrUnexpectedEndOfGroupMsg + return 0, ErrUnexpectedEndOfGroupTx } depth-- case 5: @@ -1291,7 +2018,7 @@ func skipMsg(dAtA []byte) (n int, err error) { return 0, fmt.Errorf("proto: illegal wireType %d", wireType) } if iNdEx < 0 { - return 0, ErrInvalidLengthMsg + return 0, ErrInvalidLengthTx } if depth == 0 { return iNdEx, nil @@ -1301,7 +2028,7 @@ func skipMsg(dAtA []byte) (n int, err error) { } var ( - ErrInvalidLengthMsg = fmt.Errorf("proto: negative length found during unmarshaling") - ErrIntOverflowMsg = fmt.Errorf("proto: integer overflow") - ErrUnexpectedEndOfGroupMsg = fmt.Errorf("proto: unexpected end of group") + 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/compute/module.go b/x/compute/module.go index a593250dc..a8cb27355 100644 --- a/x/compute/module.go +++ b/x/compute/module.go @@ -103,7 +103,9 @@ func NewAppModule(keeper Keeper) AppModule { func (AppModule) ConsensusVersion() uint64 { return 1 } func (am AppModule) RegisterServices(configurator module.Configurator) { + types.RegisterMsgServer(configurator.MsgServer(), keeper.NewMsgServerImpl(am.keeper)) types.RegisterQueryServer(configurator.QueryServer(), NewQuerier(am.keeper)) + // TODO register migrations here if needed } func (am AppModule) LegacyQuerierHandler(amino *codec.LegacyAmino) sdk.Querier { From 6585e96c11d20849a6be93b44fe2a0af5cbed7cf Mon Sep 17 00:00:00 2001 From: Assaf Morami Date: Tue, 23 Aug 2022 23:07:37 +0300 Subject: [PATCH 53/93] Fix Integration-Tests CI --- .github/workflows/ci.yaml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 90e6d89be..e6849050f 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -308,7 +308,6 @@ jobs: run: | git clone --depth 1 https://github.com/scrtlabs/secret.js # Copy v1 contract to tests directory - cp ./target/wasm32-unknown-unknown/release/v1_sanity_contract.wasm ./secret.js/test/test_contract_v1.wasm cd secret.js # Use the docker images that we built just a few steps above perl -i -pe 's/localsecret:.+?"/localsecret:v0.0.0"/' ./test/* From bd1f3962f362ac9cecc6c33d3b2bed5c92f403d7 Mon Sep 17 00:00:00 2001 From: Assaf Morami Date: Tue, 23 Aug 2022 23:29:38 +0300 Subject: [PATCH 54/93] Clippy --- cosmwasm/enclaves/shared/cosmwasm-v1-types/src/ibc.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cosmwasm/enclaves/shared/cosmwasm-v1-types/src/ibc.rs b/cosmwasm/enclaves/shared/cosmwasm-v1-types/src/ibc.rs index cbb02ec70..c8772ea7d 100644 --- a/cosmwasm/enclaves/shared/cosmwasm-v1-types/src/ibc.rs +++ b/cosmwasm/enclaves/shared/cosmwasm-v1-types/src/ibc.rs @@ -194,7 +194,7 @@ impl IbcPacketTrait for IbcPacketAckMsg { self.original_packet.data = data; } fn get_ack(&self) -> Option { - return Some(self.acknowledgement.data.clone()); + Some(self.acknowledgement.data.clone()) } fn set_ack(&mut self, data: Self::Data) { self.acknowledgement.data = data; From a58ecae5e37395fb66d8f2fbe4ad406acaaa7929 Mon Sep 17 00:00:00 2001 From: Assaf Morami Date: Tue, 23 Aug 2022 23:57:11 +0300 Subject: [PATCH 55/93] Clippy --- .../enclaves/shared/contract-engine/src/contract_operations.rs | 2 +- cosmwasm/enclaves/shared/contract-engine/src/io.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/cosmwasm/enclaves/shared/contract-engine/src/contract_operations.rs b/cosmwasm/enclaves/shared/contract-engine/src/contract_operations.rs index 7e0381f44..d40ddce0c 100644 --- a/cosmwasm/enclaves/shared/contract-engine/src/contract_operations.rs +++ b/cosmwasm/enclaves/shared/contract-engine/src/contract_operations.rs @@ -200,7 +200,7 @@ pub fn redact_custom_events(reply: &mut Reply) { } } - if new_ev.attributes.len() > 0 { + if !new_ev.attributes.is_empty() { events.push(new_ev); } } diff --git a/cosmwasm/enclaves/shared/contract-engine/src/io.rs b/cosmwasm/enclaves/shared/contract-engine/src/io.rs index 4ddcc6e8f..73ba75a74 100644 --- a/cosmwasm/enclaves/shared/contract-engine/src/io.rs +++ b/cosmwasm/enclaves/shared/contract-engine/src/io.rs @@ -385,7 +385,7 @@ pub fn encrypt_output( Some(_) => { let mut events: Vec = vec![]; - if ok.attributes.len() > 0 { + if !ok.attributes.is_empty() { events.push(Event { ty: "wasm".to_string(), attributes: ok.attributes.clone(), From aa542b27d7f63f19f8a2dbf07d8f958cbc5cf1d7 Mon Sep 17 00:00:00 2001 From: Assaf Morami Date: Wed, 24 Aug 2022 00:47:13 +0300 Subject: [PATCH 56/93] Fix CI Integration-Tests? --- .github/workflows/ci.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index e6849050f..0d3c54e02 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -302,7 +302,7 @@ jobs: run: | cd integration-tests yarn - TAG=v0.0.0 make run-localsecret & + docker run -d -p 9091:9091 --name localsecret ghcr.io/scrtlabs/localsecret:v0.0.0 yarn test - name: Run secret.js tests run: | From 0ec34976ebf39a0399b405dd3c2db7dadd54f2fd Mon Sep 17 00:00:00 2001 From: Assaf Morami Date: Wed, 24 Aug 2022 16:20:33 +0300 Subject: [PATCH 57/93] Parse protos on reply to extract reply params --- go-cosmwasm/lib.go | 4 +-- x/compute/internal/keeper/msg_dispatcher.go | 30 ++++++++++++++++++--- 2 files changed, 28 insertions(+), 6 deletions(-) diff --git a/go-cosmwasm/lib.go b/go-cosmwasm/lib.go index a6f14b5fd..43336d2d7 100644 --- a/go-cosmwasm/lib.go +++ b/go-cosmwasm/lib.go @@ -205,7 +205,7 @@ func (w *Wasmer) Instantiate( if isOutputAddressedToReply { respV010orV1.V1.Ok.Data, err = AppendReplyInternalDataToData(respV010orV1.V1.Ok.Data, respV010orV1.InternaReplyEnclaveSig, respV010orV1.InternalMsgId) if err != nil { - return nil, nil, gasUsed, fmt.Errorf("cannot serialize v1 DataWithInternalReplyInfo into binary : %w", err) + return nil, nil, gasUsed, fmt.Errorf("cannot serialize v1 DataWithInternalReplyInfo into binary: %w", err) } } else { respV010orV1.V1.Ok.Data = nil @@ -305,7 +305,7 @@ func (w *Wasmer) Execute( if isOutputAddressedToReply { respV010orV1.V1.Ok.Data, err = AppendReplyInternalDataToData(respV010orV1.V1.Ok.Data, respV010orV1.InternaReplyEnclaveSig, respV010orV1.InternalMsgId) if err != nil { - return nil, gasUsed, fmt.Errorf("cannot serialize v1 DataWithInternalReplyInfo into binary : %w", err) + return nil, gasUsed, fmt.Errorf("cannot serialize v1 DataWithInternalReplyInfo into binary: %w", err) } } return respV010orV1.V1.Ok, gasUsed, nil diff --git a/x/compute/internal/keeper/msg_dispatcher.go b/x/compute/internal/keeper/msg_dispatcher.go index 80486471f..a68907845 100644 --- a/x/compute/internal/keeper/msg_dispatcher.go +++ b/x/compute/internal/keeper/msg_dispatcher.go @@ -11,6 +11,7 @@ import ( v010wasmTypes "github.com/enigmampc/SecretNetwork/go-cosmwasm/types/v010" v1wasmTypes "github.com/enigmampc/SecretNetwork/go-cosmwasm/types/v1" "github.com/enigmampc/SecretNetwork/x/compute/internal/types" + "github.com/gogo/protobuf/proto" abci "github.com/tendermint/tendermint/abci/types" ) @@ -277,16 +278,37 @@ func (d MessageDispatcher) DispatchSubmessages(ctx sdk.Context, contractAddr sdk var dataWithInternalReplyInfo v1wasmTypes.DataWithInternalReplyInfo if reply.Result.Ok != nil { - err = json.Unmarshal(reply.Result.Ok.Data, &dataWithInternalReplyInfo) - if err != nil { - return nil, fmt.Errorf("cannot serialize v1 DataWithInternalReplyInfo into json : %w", err) + if msg.Msg.Wasm != nil && msg.Msg.Wasm.Execute != nil { + var execResponse types.MsgExecuteContractResponse + err = proto.Unmarshal(reply.Result.Ok.Data, &execResponse) + if err != nil { + return nil, fmt.Errorf("exec: cannot decode v1 DataWithInternalReplyInfo from protobuf: %w", err) + } + + err = json.Unmarshal(execResponse.Data, &dataWithInternalReplyInfo) + if err != nil { + return nil, fmt.Errorf("exec: cannot serialize v1 DataWithInternalReplyInfo into json: %w", err) + } + } else if msg.Msg.Wasm != nil && msg.Msg.Wasm.Instantiate != nil { + var initResponse types.MsgInstantiateContractResponse + err = proto.Unmarshal(reply.Result.Ok.Data, &initResponse) + if err != nil { + return nil, fmt.Errorf("init: cannot decode v1 DataWithInternalReplyInfo from protobuf: %w", err) + } + + err = json.Unmarshal(initResponse.Data, &dataWithInternalReplyInfo) + if err != nil { + return nil, fmt.Errorf("init: cannot serialize v1 DataWithInternalReplyInfo into json: %w", err) + } + } else { + return nil, fmt.Errorf("cannot detect wasm msg type: %+v", msg.Msg) } reply.Result.Ok.Data = dataWithInternalReplyInfo.Data } else { err = json.Unmarshal(data[0], &dataWithInternalReplyInfo) if err != nil { - return nil, fmt.Errorf("cannot serialize v1 DataWithInternalReplyInfo into json : %w", err) + return nil, fmt.Errorf("cannot serialize v1 DataWithInternalReplyInfo into json: %w", err) } } From 10dd4e857d960d4351533d4366472708270437f1 Mon Sep 17 00:00:00 2001 From: Itzik Date: Wed, 24 Aug 2022 17:06:31 +0300 Subject: [PATCH 58/93] More refactoring --- cosmwasm/enclaves/Cargo.lock | 25 +- cosmwasm/enclaves/execute/Cargo.toml | 2 +- cosmwasm/enclaves/query/Cargo.toml | 2 +- .../shared/contract-engine/Cargo.toml | 2 +- .../src/contract_operations.rs | 653 +++--------------- .../src/contract_validation.rs | 44 +- .../enclaves/shared/contract-engine/src/db.rs | 6 +- .../shared/contract-engine/src/errors.rs | 6 + .../enclaves/shared/contract-engine/src/io.rs | 2 +- .../shared/contract-engine/src/lib.rs | 1 + .../shared/contract-engine/src/message.rs | 347 ++++++++++ .../shared/contract-engine/src/types.rs | 6 + .../enclaves/shared/cosmos-proto/Cargo.toml | 2 +- .../enclaves/shared/cosmos-types/Cargo.toml | 2 +- .../shared/cosmwasm-types/generic/Cargo.toml | 1 + .../shared/cosmwasm-types/generic/src/lib.rs | 36 +- .../shared/cosmwasm-types/v0.10/Cargo.toml | 2 +- .../shared/cosmwasm-types/v1.0/Cargo.toml | 2 +- cosmwasm/enclaves/shared/crypto/Cargo.toml | 2 +- cosmwasm/enclaves/shared/utils/Cargo.toml | 2 +- go-cosmwasm/types/env.go | 4 + .../internal/keeper/secret_contracts_test.go | 4 +- x/compute/internal/types/types.go | 3 +- 23 files changed, 537 insertions(+), 619 deletions(-) create mode 100644 cosmwasm/enclaves/shared/contract-engine/src/message.rs diff --git a/cosmwasm/enclaves/Cargo.lock b/cosmwasm/enclaves/Cargo.lock index 8fe1057c5..96c12b424 100644 --- a/cosmwasm/enclaves/Cargo.lock +++ b/cosmwasm/enclaves/Cargo.lock @@ -79,6 +79,12 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +[[package]] +name = "base64" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd" + [[package]] name = "base64" version = "0.13.0" @@ -250,7 +256,7 @@ checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" [[package]] name = "cosmos_proto" -version = "1.2.4" +version = "1.4.0" dependencies = [ "dirs", "protobuf", @@ -319,6 +325,7 @@ dependencies = [ name = "cw_types_generic" version = "0.1.0" dependencies = [ + "base64 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)", "cw_types_v010", "cw_types_v1", "enclave-ffi-types", @@ -330,7 +337,7 @@ dependencies = [ [[package]] name = "cw_types_v010" -version = "1.2.4" +version = "1.4.0" dependencies = [ "base64 0.13.0 (git+https://github.com/mesalock-linux/rust-base64-sgx?rev=dc7389e10817b078f289386b3b6a852ab6c4c021)", "bech32", @@ -344,7 +351,7 @@ dependencies = [ [[package]] name = "cw_types_v1" -version = "1.2.4" +version = "1.4.0" dependencies = [ "base64 0.13.0 (git+https://github.com/mesalock-linux/rust-base64-sgx?rev=dc7389e10817b078f289386b3b6a852ab6c4c021)", "bech32", @@ -455,7 +462,7 @@ dependencies = [ [[package]] name = "enclave_contract_engine" -version = "1.2.4" +version = "1.4.0" dependencies = [ "base64 0.13.0 (git+https://github.com/mesalock-linux/rust-base64-sgx?rev=dc7389e10817b078f289386b3b6a852ab6c4c021)", "bech32", @@ -489,7 +496,7 @@ dependencies = [ [[package]] name = "enclave_cosmos_types" -version = "1.2.4" +version = "1.4.0" dependencies = [ "cosmos_proto", "cw_types_v010", @@ -507,7 +514,7 @@ dependencies = [ [[package]] name = "enclave_crypto" -version = "1.2.4" +version = "1.4.0" dependencies = [ "aes-siv", "derive_more", @@ -527,7 +534,7 @@ dependencies = [ [[package]] name = "enclave_utils" -version = "1.2.4" +version = "1.4.0" dependencies = [ "enclave-ffi-types", "lazy_static", @@ -1024,7 +1031,7 @@ dependencies = [ [[package]] name = "secret-enclave" -version = "1.2.4" +version = "1.4.0" dependencies = [ "base64 0.13.0 (git+https://github.com/mesalock-linux/rust-base64-sgx?rev=dc7389e10817b078f289386b3b6a852ab6c4c021)", "bit-vec", @@ -1061,7 +1068,7 @@ dependencies = [ [[package]] name = "secret-query-enclave" -version = "1.2.4" +version = "1.4.0" dependencies = [ "ctor", "enclave_contract_engine", diff --git a/cosmwasm/enclaves/execute/Cargo.toml b/cosmwasm/enclaves/execute/Cargo.toml index 9c551b242..da0c296d6 100644 --- a/cosmwasm/enclaves/execute/Cargo.toml +++ b/cosmwasm/enclaves/execute/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "secret-enclave" -version = "1.2.4" +version = "1.4.0" authors = ["SCRT Labs "] edition = "2018" description = "An enclave running wasmi, to be used by cosmwasm-sgx-vm" diff --git a/cosmwasm/enclaves/query/Cargo.toml b/cosmwasm/enclaves/query/Cargo.toml index fb897856c..861f82881 100644 --- a/cosmwasm/enclaves/query/Cargo.toml +++ b/cosmwasm/enclaves/query/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "secret-query-enclave" -version = "1.2.4" +version = "1.4.0" authors = ["SCRT Labs "] edition = "2018" description = "An enclave running wasmi, to be used by cosmwasm-sgx-vm" diff --git a/cosmwasm/enclaves/shared/contract-engine/Cargo.toml b/cosmwasm/enclaves/shared/contract-engine/Cargo.toml index 7c567c99f..04fcec99e 100644 --- a/cosmwasm/enclaves/shared/contract-engine/Cargo.toml +++ b/cosmwasm/enclaves/shared/contract-engine/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "enclave_contract_engine" -version = "1.2.4" +version = "1.4.0" authors = ["Cashmaney "] edition = "2018" diff --git a/cosmwasm/enclaves/shared/contract-engine/src/contract_operations.rs b/cosmwasm/enclaves/shared/contract-engine/src/contract_operations.rs index 95a96a81b..f1edabaac 100644 --- a/cosmwasm/enclaves/shared/contract-engine/src/contract_operations.rs +++ b/cosmwasm/enclaves/shared/contract-engine/src/contract_operations.rs @@ -1,26 +1,24 @@ -use log::*; +use cosmos_proto::tx::signing::SignMode; -use enclave_ffi_types::{Ctx, EnclaveError}; +use cw_types_generic::{BaseAddr, BaseEnv}; -use crate::contract_validation::{ReplyParams, ValidatedMessage}; -use crate::external::results::{HandleSuccess, InitSuccess, QuerySuccess}; -use crate::wasm::CosmWasmApiVersion; -use cosmos_proto::tx::signing::SignMode; -use cw_types_generic::{BaseEnv, CwEnv}; -use cw_types_v010; use cw_types_v010::encoding::Binary; use cw_types_v010::types::CanonicalAddr; -use cw_types_v1::addresses::Addr; -use cw_types_v1::results::{DecryptedReply, Event, Reply, SubMsgResponse, SubMsgResult}; -use cw_types_v1::timestamp::Timestamp; -use enclave_cosmos_types::types::{ContractCode, HandleType, SigInfo}; +use cw_types_v1::types::{Addr, Timestamp}; + +use enclave_cosmos_types::types::{ContractCode, HandleType, SigInfo}; use enclave_crypto::{Ed25519PublicKey, HASH_SIZE}; +use enclave_ffi_types::{Ctx, EnclaveError}; use enclave_utils::coalesce; +use log::*; + +use crate::contract_validation::{ReplyParams, ValidatedMessage}; +use crate::external::results::{HandleSuccess, InitSuccess, QuerySuccess}; +use crate::message::{parse_message, ParsedMessage}; use super::contract_validation::{ - extract_contract_key, generate_encryption_key, validate_contract_key, validate_msg, - verify_params, ContractKey, + generate_encryption_key, validate_contract_key, validate_msg, verify_params, ContractKey, }; use super::gas::WasmCosts; use super::io::encrypt_output; @@ -28,8 +26,6 @@ use super::module_cache::create_module_instance; use super::types::{IoNonce, SecretMessage}; use super::wasm::{ContractInstance, ContractOperation, Engine}; -const HEX_ENCODED_HASH_SIZE: usize = HASH_SIZE * 2; - /* Each contract is compiled with these functions already implemented in wasm: fn cosmwasm_api_0_6() -> i32; // Seems unused, but we should support it anyways @@ -54,37 +50,18 @@ pub fn init( msg: &[u8], // probably function call and args sig_info: &[u8], // info about signature verification ) -> Result { + trace!("Starting init"); + let contract_code = ContractCode::new(contract); let contract_hash = contract_code.hash(); - let base_env: BaseEnv = serde_json::from_slice(env).map_err(|err| { - warn!( - "init got an error while trying to deserialize env input bytes into json {:?}: {}", - String::from_utf8_lossy(&env), - err - ); - EnclaveError::FailedToDeserialize - })?; + let base_env: BaseEnv = extract_base_env(env)?; let (sender, contract_address, block_height, sent_funds) = base_env.get_verification_params(); - let canonical_contract_address = CanonicalAddr::from_human(&contract_address).map_err(|err| { - warn!( - "init got an error while trying to deserialize env_v010.contract.address from bech32 string to bytes {:?}: {}", - contract_address, err - ); - EnclaveError::FailedToDeserialize - })?; - // - // trace!("init env_v010: {:?}", env_v010); - // - let canonical_sender_address = CanonicalAddr::from_human(&sender).map_err(|err| { - warn!( - "init got an error while trying to deserialize env_v010.message.sender from bech32 string to bytes {:?}: {}", - sender, err - ); - EnclaveError::FailedToDeserialize - })?; + let canonical_contract_address = to_canonical(contract_address)?; + + let canonical_sender_address = to_canonical(sender)?; let contract_key = generate_encryption_key( &canonical_sender_address, @@ -92,18 +69,9 @@ pub fn init( &contract_hash, &canonical_contract_address, )?; - trace!("init contract key: {:?}", hex::encode(contract_key)); - let parsed_sig_info: SigInfo = serde_json::from_slice(sig_info).map_err(|err| { - warn!( - "init got an error while trying to deserialize env input bytes into json {:?}: {}", - String::from_utf8_lossy(&sig_info), - err - ); - EnclaveError::FailedToDeserialize - })?; + let parsed_sig_info: SigInfo = extract_sig_info(sig_info)?; - trace!("init input before decryption: {:?}", base64::encode(&msg)); let secret_msg = SecretMessage::from_slice(msg)?; verify_params( @@ -119,12 +87,7 @@ pub fn init( let ValidatedMessage { validated_msg, reply_params, - } = validate_msg(&decrypted_msg, contract_code.hash(), None)?; - - trace!( - "init input after decryption: {:?}", - String::from_utf8_lossy(&validated_msg) - ); + } = validate_msg(&decrypted_msg, &contract_hash, None)?; let mut engine = start_engine( context, @@ -152,9 +115,6 @@ pub fn init( let output = coalesce!(EnclaveError, { let vec_ptr = engine.init(env_ptr, msg_info_ptr, msg_ptr)?; let output = engine.extract_vector(vec_ptr)?; - // TODO: copy cosmwasm's structures to enclave - // TODO: ref: https://github.com/CosmWasm/cosmwasm/blob/b971c037a773bf6a5f5d08a88485113d9b9e8e7b/packages/std/src/init_handle.rs#L129 - // TODO: ref: https://github.com/CosmWasm/cosmwasm/blob/b971c037a773bf6a5f5d08a88485113d9b9e8e7b/packages/std/src/query.rs#L13 let output = encrypt_output( output, &secret_msg, @@ -181,344 +141,14 @@ pub fn init( }) } -pub struct ParsedMessage { - pub should_validate_sig_info: bool, - pub was_msg_encrypted: bool, - pub secret_msg: SecretMessage, - pub decrypted_msg: Vec, - pub contract_hash_for_validation: Option>, -} - -pub fn redact_custom_events(reply: &mut Reply) { - reply.result = match &reply.result { - SubMsgResult::Ok(r) => { - let mut events: Vec = Default::default(); - - let filtered_attributes = vec!["contract_address".to_string(), "code_id".to_string()]; - for ev in r.events.iter() { - if !ev.ty.starts_with("wasm") { - continue; - } - - let mut new_ev = Event { - ty: ev.ty.clone(), - attributes: vec![], - }; - - for attr in &ev.attributes { - if !filtered_attributes.contains(&attr.key) { - new_ev.attributes.push(attr.clone()); - } - } - - if new_ev.attributes.len() > 0 { - events.push(new_ev); - } - } - - SubMsgResult::Ok(SubMsgResponse { - events, - data: r.data.clone(), - }) - } - SubMsgResult::Err(_) => reply.result.clone(), - }; -} - -// Parse the message that was passed to handle (Based on the assumption that it might be a reply or IBC as well) -pub fn parse_message( - message: &[u8], - sig_info: &SigInfo, - handle_type: &HandleType, -) -> Result { - let orig_secret_msg = SecretMessage::from_slice(message)?; - - return match handle_type { - HandleType::HANDLE_TYPE_EXECUTE => { - trace!( - "handle input before decryption: {:?}", - base64::encode(&message) - ); - let decrypted_msg = orig_secret_msg.decrypt()?; - Ok(ParsedMessage { - should_validate_sig_info: true, - was_msg_encrypted: true, - secret_msg: orig_secret_msg, - decrypted_msg, - contract_hash_for_validation: None, - }) - } - - HandleType::HANDLE_TYPE_REPLY => { - if sig_info.sign_mode == SignMode::SIGN_MODE_UNSPECIFIED { - trace!("reply input is not encrypted"); - let decrypted_msg = orig_secret_msg.msg.clone(); - let mut reply: Reply = serde_json::from_slice(&decrypted_msg) - .map_err(|err| { - warn!( - "reply got an error while trying to deserialize decrypted reply bytes into json {:?}: {}", - String::from_utf8_lossy(&decrypted_msg), - err - ); - EnclaveError::FailedToDeserialize - })?; - - let msg_id = String::from_utf8(reply.id.as_slice().to_vec()).map_err(|err| { - warn!( - "Failed to parse message id as string {:?}: {}", - reply.id.as_slice().to_vec(), - err - ); - EnclaveError::FailedToDeserialize - })?; - - let msg_id_as_num = match msg_id.parse::() { - Ok(m) => m, - Err(err) => { - warn!("Failed to parse message id as number {}: {}", msg_id, err); - return Err(EnclaveError::FailedToDeserialize); - } - }; - - let decrypted_reply = DecryptedReply { - id: msg_id_as_num, - result: reply.result.clone(), - }; - - redact_custom_events(&mut reply); - let serialized_encrypted_reply : Vec = serde_json::to_vec(&reply).map_err(|err| { - warn!( - "got an error while trying to serialize encrypted reply into bytes {:?}: {}", - reply, err - ); - EnclaveError::FailedToSerialize - })?; - - let reply_secret_msg = SecretMessage { - nonce: orig_secret_msg.nonce, - user_public_key: orig_secret_msg.user_public_key, - msg: serialized_encrypted_reply, - }; - - let serialized_reply: Vec = serde_json::to_vec(&decrypted_reply).map_err(|err| { - warn!( - "got an error while trying to serialize decrypted reply into bytes {:?}: {}", - decrypted_reply, err - ); - EnclaveError::FailedToSerialize - })?; - - return Ok(ParsedMessage { - should_validate_sig_info: false, - was_msg_encrypted: false, - secret_msg: reply_secret_msg, - decrypted_msg: serialized_reply, - contract_hash_for_validation: None, - }); - } - - // Here we are sure the reply is OK because only OK is encrypted - trace!( - "reply input before decryption: {:?}", - base64::encode(&message) - ); - let mut parsed_encrypted_reply: Reply = serde_json::from_slice( - &orig_secret_msg.msg.as_slice().to_vec(), - ) - .map_err(|err| { - warn!( - "reply got an error while trying to deserialize msg input bytes into json {:?}: {}", - String::from_utf8_lossy(&orig_secret_msg.msg), - err - ); - EnclaveError::FailedToDeserialize - })?; - - match parsed_encrypted_reply.result.clone() { - SubMsgResult::Ok(response) => { - let decrypted_msg_data = match response.data { - Some(data) => { - let tmp_secret_msg_data = SecretMessage { - nonce: orig_secret_msg.nonce, - user_public_key: orig_secret_msg.user_public_key, - msg: data.as_slice().to_vec(), - }; - - Some(Binary( - tmp_secret_msg_data.decrypt()?[HEX_ENCODED_HASH_SIZE..].to_vec(), - )) - } - None => None, - }; - - let tmp_secret_msg_id = SecretMessage { - nonce: orig_secret_msg.nonce, - user_public_key: orig_secret_msg.user_public_key, - msg: parsed_encrypted_reply.id.as_slice().to_vec(), - }; - - let tmp_decrypted_msg_id = tmp_secret_msg_id.decrypt()?; - - // Now we need to create synthetic SecretMessage to fit the API in "handle" - let result = SubMsgResult::Ok(SubMsgResponse { - events: response.events, - data: decrypted_msg_data, - }); - - let msg_id = - String::from_utf8(tmp_decrypted_msg_id[HEX_ENCODED_HASH_SIZE..].to_vec()) - .map_err(|err| { - warn!( - "Failed to parse message id as string {:?}: {}", - tmp_decrypted_msg_id[HEX_ENCODED_HASH_SIZE..].to_vec(), - err - ); - EnclaveError::FailedToDeserialize - })?; - - let msg_id_as_num = match msg_id.parse::() { - Ok(m) => m, - Err(err) => { - warn!("Failed to parse message id as number {}: {}", msg_id, err); - return Err(EnclaveError::FailedToDeserialize); - } - }; - - let decrypted_reply = DecryptedReply { - id: msg_id_as_num, - result, - }; - - let decrypted_reply_as_vec = - serde_json::to_vec(&decrypted_reply).map_err(|err| { - warn!( - "got an error while trying to serialize reply into bytes {:?}: {}", - decrypted_reply, err - ); - EnclaveError::FailedToSerialize - })?; - - redact_custom_events(&mut parsed_encrypted_reply); - let serialized_encrypted_reply : Vec = serde_json::to_vec(&parsed_encrypted_reply).map_err(|err| { - warn!( - "got an error while trying to serialize encrypted reply into bytes {:?}: {}", - parsed_encrypted_reply, err - ); - EnclaveError::FailedToSerialize - })?; - - let reply_secret_msg = SecretMessage { - nonce: orig_secret_msg.nonce, - user_public_key: orig_secret_msg.user_public_key, - msg: serialized_encrypted_reply, - }; - - Ok(ParsedMessage { - should_validate_sig_info: true, - was_msg_encrypted: true, - secret_msg: reply_secret_msg, - decrypted_msg: decrypted_reply_as_vec, - contract_hash_for_validation: Some( - tmp_decrypted_msg_id[..HEX_ENCODED_HASH_SIZE].to_vec(), - ), - }) - } - SubMsgResult::Err(response) => { - let secret_msg = SecretMessage { - nonce: orig_secret_msg.nonce, - user_public_key: orig_secret_msg.user_public_key, - msg: base64::decode(response.clone()).map_err(|err| { - warn!( - "got an error while trying to serialize err reply from base64 {:?}: {}", - response, err - ); - EnclaveError::FailedToSerialize - })? - }; - - let decrypted_error = secret_msg.decrypt()?; - - let tmp_secret_msg_id = SecretMessage { - nonce: orig_secret_msg.nonce, - user_public_key: orig_secret_msg.user_public_key, - msg: parsed_encrypted_reply.id.as_slice().to_vec(), - }; - - let tmp_decrypted_msg_id = tmp_secret_msg_id.decrypt()?; - - // Now we need to create synthetic SecretMessage to fit the API in "handle" - let result = SubMsgResult::Err( - String::from_utf8(decrypted_error[HEX_ENCODED_HASH_SIZE..].to_vec()) - .map_err(|err| { - warn!( - "Failed to parse error as string {:?}: {}", - decrypted_error[HEX_ENCODED_HASH_SIZE..].to_vec(), - err - ); - EnclaveError::FailedToDeserialize - })?, - ); - - let msg_id = - String::from_utf8(tmp_decrypted_msg_id[HEX_ENCODED_HASH_SIZE..].to_vec()) - .map_err(|err| { - warn!( - "Failed to parse message id as string {:?}: {}", - tmp_decrypted_msg_id[HEX_ENCODED_HASH_SIZE..].to_vec(), - err - ); - EnclaveError::FailedToDeserialize - })?; - - let msg_id_as_num = match msg_id.parse::() { - Ok(m) => m, - Err(err) => { - warn!("Failed to parse message id as number {}: {}", msg_id, err); - return Err(EnclaveError::FailedToDeserialize); - } - }; - - let decrypted_reply = DecryptedReply { - id: msg_id_as_num, - result, - }; - - let decrypted_reply_as_vec = - serde_json::to_vec(&decrypted_reply).map_err(|err| { - warn!( - "got an error while trying to serialize reply into bytes {:?}: {}", - decrypted_reply, err - ); - EnclaveError::FailedToSerialize - })?; - - let serialized_encrypted_reply : Vec = serde_json::to_vec(&parsed_encrypted_reply).map_err(|err| { - warn!( - "got an error while trying to serialize encrypted reply into bytes {:?}: {}", - parsed_encrypted_reply, err - ); - EnclaveError::FailedToSerialize - })?; - - let reply_secret_msg = SecretMessage { - nonce: orig_secret_msg.nonce, - user_public_key: orig_secret_msg.user_public_key, - msg: serialized_encrypted_reply, - }; - - Ok(ParsedMessage { - should_validate_sig_info: true, - was_msg_encrypted: true, - secret_msg: reply_secret_msg, - decrypted_msg: decrypted_reply_as_vec, - contract_hash_for_validation: Some( - tmp_decrypted_msg_id[..HEX_ENCODED_HASH_SIZE].to_vec(), - ), - }) - } - } - } - }; +fn to_canonical(contract_address: &BaseAddr) -> Result { + CanonicalAddr::from_human(contract_address).map_err(|err| { + warn!( + "error while trying to deserialize address from bech32 string to bytes {:?}: {}", + contract_address, err + ); + EnclaveError::FailedToDeserialize + }) } #[cfg_attr(feature = "cargo-clippy", allow(clippy::too_many_arguments))] @@ -532,50 +162,24 @@ pub fn handle( sig_info: &[u8], handle_type: u8, ) -> Result { + trace!("Starting handle"); + let contract_code = ContractCode::new(contract); + let contract_hash = contract_code.hash(); - let mut env_v010: cw_types_v010::types::Env = serde_json::from_slice(env).map_err(|err| { - warn!( - "handle got an error while trying to deserialize env input bytes into json {:?}: {}", - env, err - ); - EnclaveError::FailedToDeserialize - })?; - env_v010.contract_code_hash = hex::encode(contract_code.hash()); + let base_env: BaseEnv = extract_base_env(env)?; - trace!("handle env_v010: {:?}", env_v010); + let (sender, contract_address, _, sent_funds) = base_env.get_verification_params(); - let canonical_contract_address = CanonicalAddr::from_human(&env_v010.contract.address).map_err(|err| { - warn!( - "got an error while trying to deserialize env_v010.contract.address from bech32 string to bytes {:?}: {}", - env_v010.contract.address, err - ); - EnclaveError::FailedToDeserialize - })?; + let canonical_contract_address = to_canonical(contract_address)?; - let canonical_sender_address = CanonicalAddr::from_human(&env_v010.message.sender).map_err(|err| { - warn!( - "init got an error while trying to deserialize env_v010.message.sender from bech32 string to bytes {:?}: {}", - env_v010.message.sender, err - ); - EnclaveError::FailedToDeserialize - })?; + let canonical_sender_address = to_canonical(sender)?; - let contract_key = extract_contract_key(&env_v010)?; + let contract_key = base_env.get_contract_key()?; - if !validate_contract_key(&contract_key, &canonical_contract_address, &contract_code) { - warn!("got an error while trying to deserialize output bytes"); - return Err(EnclaveError::FailedContractAuthentication); - } + validate_contract_key(&contract_key, &canonical_contract_address, &contract_code)?; - let parsed_sig_info: SigInfo = serde_json::from_slice(sig_info).map_err(|err| { - warn!( - "handle got an error while trying to deserialize sig info input bytes into json {:?}: {}", - String::from_utf8_lossy(&sig_info), - err - ); - EnclaveError::FailedToDeserialize - })?; + let parsed_sig_info: SigInfo = extract_sig_info(sig_info)?; // The flow of handle is now used for multiple messages (such ash Handle, Reply) // When the message is handle, we expect it always to be encrypted while in Reply for example it might be plaintext @@ -597,9 +201,9 @@ pub fn handle( // Verify env parameters against the signed tx verify_params( &parsed_sig_info, - &env_v010.message.sent_funds, + sent_funds, &canonical_sender_address, - &env_v010.contract.address, + contract_address, &secret_msg, )?; } @@ -607,24 +211,11 @@ pub fn handle( let mut validated_msg = decrypted_msg.clone(); let mut reply_params: Option = None; if was_msg_encrypted { - let x = validate_msg( - &decrypted_msg, - contract_code.hash(), - contract_hash_for_validation, - )?; + let x = validate_msg(&decrypted_msg, &contract_hash, contract_hash_for_validation)?; validated_msg = x.validated_msg; reply_params = x.reply_params; } - trace!( - "handle input afer decryption: {:?}", - String::from_utf8_lossy(&validated_msg) - ); - - trace!("Successfully authenticated the contract!"); - - trace!("Handle: Contract Key: {:?}", hex::encode(contract_key)); - // Although the operation here is not always handle it is irrelevant in this case // because it only helps to decide whether to check floating points or not // In this case we want to do the same as in Handle both for Reply and for others so we can always pass "Handle". @@ -638,11 +229,15 @@ pub fn handle( secret_msg.user_public_key, )?; - let (contract_env_bytes, contract_msg_info_bytes) = - env_to_env_msg_info_bytes(&engine, &mut env_v010)?; + let mut versioned_env = + base_env.into_versioned_env(&engine.contract_instance.cosmwasm_api_version); + + versioned_env.set_contract_hash(&contract_hash); - let env_ptr = engine.write_to_memory(&contract_env_bytes)?; - let msg_info_ptr = engine.write_to_memory(&contract_msg_info_bytes)?; + let (env_bytes, msg_info_bytes) = versioned_env.get_wasm_ptrs()?; + + let env_ptr = engine.write_to_memory(&env_bytes)?; + let msg_info_ptr = engine.write_to_memory(&msg_info_bytes)?; let msg_ptr = engine.write_to_memory(&validated_msg)?; // This wrapper is used to coalesce all errors in this block to one object @@ -661,7 +256,7 @@ pub fn handle( output, &secret_msg, &canonical_contract_address, - &env_v010.contract_code_hash, + versioned_env.get_contract_hash(), reply_params, &canonical_sender_address, false, @@ -677,6 +272,17 @@ pub fn handle( Ok(HandleSuccess { output }) } +fn extract_sig_info(sig_info: &[u8]) -> Result { + serde_json::from_slice(sig_info).map_err(|err| { + warn!( + "handle got an error while trying to deserialize sig info input bytes into json {:?}: {}", + String::from_utf8_lossy(&sig_info), + err + ); + EnclaveError::FailedToDeserialize + }) +} + pub fn query( context: Ctx, gas_limit: u64, @@ -685,46 +291,26 @@ pub fn query( env: &[u8], msg: &[u8], ) -> Result { + trace!("Entered query"); + let contract_code = ContractCode::new(contract); + let contract_hash = contract_code.hash(); - let mut env_v010: cw_types_v010::types::Env = serde_json::from_slice(env).map_err(|err| { - warn!( - "query got an error while trying to deserialize env input bytes into json {:?}: {}", - env, err - ); - EnclaveError::FailedToDeserialize - })?; - env_v010.contract_code_hash = hex::encode(contract_code.hash()); + let base_env: BaseEnv = extract_base_env(env)?; - trace!("query env_v010: {:?}", env_v010); + let (_, contract_address, _, _) = base_env.get_verification_params(); - let canonical_contract_address = CanonicalAddr::from_human(&env_v010.contract.address).map_err(|err| { - warn!( - "got an error while trying to deserialize env_v010.contract.address from bech32 string to bytes {:?}: {}", - env_v010.contract.address, err - ); - EnclaveError::FailedToDeserialize - })?; + let canonical_contract_address = to_canonical(contract_address)?; - let contract_key = extract_contract_key(&env_v010)?; - - if !validate_contract_key(&contract_key, &canonical_contract_address, &contract_code) { - warn!("query got an error while trying to validate contract key"); - return Err(EnclaveError::FailedContractAuthentication); - } + let contract_key = base_env.get_contract_key()?; - trace!("successfully authenticated the contract!"); - trace!("query contract key: {:?}", hex::encode(contract_key)); + validate_contract_key(&contract_key, &canonical_contract_address, &contract_code)?; - trace!("query input before decryption: {:?}", base64::encode(&msg)); let secret_msg = SecretMessage::from_slice(msg)?; let decrypted_msg = secret_msg.decrypt()?; - trace!( - "query input afer decryption: {:?}", - String::from_utf8_lossy(&decrypted_msg) - ); + let ValidatedMessage { validated_msg, .. } = - validate_msg(&decrypted_msg, contract_code.hash(), None)?; + validate_msg(&decrypted_msg, &contract_hash, None)?; let mut engine = start_engine( context, @@ -736,10 +322,14 @@ pub fn query( secret_msg.user_public_key, )?; - let (contract_env_bytes, _ /* no msg_info in query */) = - env_to_env_msg_info_bytes(&engine, &mut env_v010)?; + let mut versioned_env = + base_env.into_versioned_env(&engine.contract_instance.cosmwasm_api_version); + + versioned_env.set_contract_hash(&contract_hash); + + let (env_bytes, _) = versioned_env.get_wasm_ptrs()?; - let env_ptr = engine.write_to_memory(&contract_env_bytes)?; + let env_ptr = engine.write_to_memory(&env_bytes)?; let msg_ptr = engine.write_to_memory(&validated_msg)?; // This wrapper is used to coalesce all errors in this block to one object @@ -797,77 +387,18 @@ fn start_engine( Ok(Engine::new(contract_instance, module)) } -fn env_to_env_msg_info_bytes( - engine: &Engine, - env_v010: &mut cw_types_v010::types::Env, -) -> Result<(Vec, Vec), EnclaveError> { - match engine.contract_instance.cosmwasm_api_version { - CosmWasmApiVersion::V010 => { - // Assaf: contract_key is irrelevant inside the contract, - // but existing v0.10 contracts might expect it to be populated :facepalm:, - // therefore we are going to leave it populated :shrug:. - // env_v010.contract_key = None; - - // in v0.10 the timestamp passed from Go was unix time in seconds - // 10.16 time is unix time in nanoseconds, so now Go passes here unix time in nanoseconds - // but v0.10 contracts still expect time to be in unix seconds, - // so we need to convert it from nanoseconds to seconds - env_v010.block.time = Timestamp::from_nanos(env_v010.block.time).seconds(); - - let env_v010_bytes = serde_json::to_vec(env_v010).map_err(|err| { - warn!( - "got an error while trying to serialize env_v010 (cosmwasm v0.10) into bytes {:?}: {}", - env_v010, err - ); - EnclaveError::FailedToSerialize - })?; - - let msg_info_v010_bytes: Vec = vec![]; // in v0.10 msg_info is inside env - - Ok((env_v010_bytes, msg_info_v010_bytes)) - } - CosmWasmApiVersion::V1 => { - let env_v1 = cw_types_v1::types::Env { - block: cw_types_v1::types::BlockInfo { - height: env_v010.block.height, - time: Timestamp::from_nanos(env_v010.block.time), - chain_id: env_v010.block.chain_id.clone(), - }, - contract: cw_types_v1::types::ContractInfo { - address: Addr(env_v010.contract.address.0.clone()), - code_hash: env_v010.contract_code_hash.clone(), - }, - }; - - let env_v1_bytes = serde_json::to_vec(&env_v1).map_err(|err| { - warn!( - "got an error while trying to serialize env_v1 (CosmWasm v1) into bytes {:?}: {}", - env_v1, err - ); - EnclaveError::FailedToSerialize - })?; - - let msg_info_v1 = cw_types_v1::types::MessageInfo { - sender: Addr(env_v010.message.sender.0.clone()), - funds: env_v010 - .message - .sent_funds - .iter() - .map(|coin| { - cw_types_v1::coins::Coin::new(coin.amount.u128(), coin.denom.clone()) - }) - .collect::>(), - }; - - let msg_info_v1_bytes = serde_json::to_vec(&msg_info_v1).map_err(|err| { - warn!( - "got an error while trying to serialize msg_info_v1 (CosmWasm v1) into bytes {:?}: {}", - msg_info_v1, err - ); - EnclaveError::FailedToSerialize - })?; - - Ok((env_v1_bytes, msg_info_v1_bytes)) - } - } +fn extract_base_env(env: &[u8]) -> Result { + serde_json::from_slice(env) + .map_err(|err| { + warn!( + "error while deserializing env into json {:?}: {}", + String::from_utf8_lossy(&env), + err + ); + EnclaveError::FailedToDeserialize + }) + .map(|base_env| { + trace!("base env: {:?}", base_env); + base_env + }) } diff --git a/cosmwasm/enclaves/shared/contract-engine/src/contract_validation.rs b/cosmwasm/enclaves/shared/contract-engine/src/contract_validation.rs index 1b2a26cc5..549c4d449 100644 --- a/cosmwasm/enclaves/shared/contract-engine/src/contract_validation.rs +++ b/cosmwasm/enclaves/shared/contract-engine/src/contract_validation.rs @@ -1,3 +1,4 @@ +use cw_types_generic::BaseEnv; use cw_types_v1::results::REPLY_ENCRYPTION_MAGIC_BYTES; use log::*; @@ -53,34 +54,9 @@ pub fn generate_encryption_key( encryption_key[0..32].copy_from_slice(&sender_id); encryption_key[32..].copy_from_slice(&authenticated_contract_id); - Ok(encryption_key) -} - -pub fn extract_contract_key(env: &Env) -> Result<[u8; CONTRACT_KEY_LENGTH], EnclaveError> { - if env.contract_key.is_none() { - warn!("Contract execute with empty contract key"); - return Err(EnclaveError::FailedContractAuthentication); - } - - let contract_key = - base64::decode(env.contract_key.as_ref().unwrap().as_bytes()).map_err(|err| { - warn!( - "got an error while trying to deserialize output bytes into json {:?}: {}", - env, err - ); - EnclaveError::FailedContractAuthentication - })?; - - if contract_key.len() != CONTRACT_KEY_LENGTH { - warn!("Contract execute with empty contract key"); - return Err(EnclaveError::FailedContractAuthentication); - } - - let mut key_as_bytes = [0u8; CONTRACT_KEY_LENGTH]; + trace!("contract key: {:?}", hex::encode(encryption_key)); - key_as_bytes.copy_from_slice(&contract_key); - - Ok(key_as_bytes) + Ok(encryption_key) } pub fn generate_sender_id(msg_sender: &[u8], block_height: &u64) -> [u8; HASH_SIZE] { @@ -107,7 +83,7 @@ pub fn validate_contract_key( contract_key: &[u8; CONTRACT_KEY_LENGTH], contract_address: &CanonicalAddr, contract_code: &ContractCode, -) -> bool { +) -> Result<(), EnclaveError> { // parse contract key -> < signer_id || authentication_code > let mut signer_id: [u8; HASH_SIZE] = [0u8; HASH_SIZE]; signer_id.copy_from_slice(&contract_key[0..HASH_SIZE]); @@ -132,7 +108,13 @@ pub fn validate_contract_key( contract_address.as_slice(), ); - calculated_authentication_id == expected_authentication_id + return if calculated_authentication_id == expected_authentication_id { + trace!("Successfully authenticated the contract!"); + Ok(()) + } else { + warn!("got an error while trying to deserialize output bytes"); + Err(EnclaveError::FailedContractAuthentication) + }; } pub struct ValidatedMessage { @@ -148,7 +130,7 @@ pub struct ReplyParams { /// Validate that the message sent to the enclave (after decryption) was actually addressed to this contract. pub fn validate_msg( msg: &[u8], - contract_hash: [u8; HASH_SIZE], + contract_hash: &[u8; HASH_SIZE], contract_hash_for_validation: Option>, ) -> Result { if contract_hash_for_validation.is_none() && msg.len() < HEX_ENCODED_HASH_SIZE { @@ -406,7 +388,7 @@ fn verify_funds(msg: &CosmWasmMsg, sent_funds_msg: &[Coin]) -> bool { | CosmWasmMsg::Instantiate { init_funds: sent_funds, .. - } => &sent_funds_msg == sent_funds, + } => sent_funds_msg == sent_funds, CosmWasmMsg::Other => false, } } diff --git a/cosmwasm/enclaves/shared/contract-engine/src/db.rs b/cosmwasm/enclaves/shared/contract-engine/src/db.rs index fad8a47b6..e5764ba2c 100644 --- a/cosmwasm/enclaves/shared/contract-engine/src/db.rs +++ b/cosmwasm/enclaves/shared/contract-engine/src/db.rs @@ -22,7 +22,7 @@ pub fn write_encrypted_key( let scrambled_field_name = field_name_digest(key, contract_key); - info!( + trace!( "Writing to scrambled field name: {:?}", scrambled_field_name ); @@ -53,7 +53,7 @@ pub fn read_encrypted_key( ) -> Result<(Option>, u64), WasmEngineError> { let scrambled_field_name = field_name_digest(key, contract_key); - info!( + trace!( "Reading from scrambled field name: {:?}", scrambled_field_name ); @@ -82,7 +82,7 @@ pub fn remove_encrypted_key( ) -> Result { let scrambled_field_name = field_name_digest(key, contract_key); - info!("Removing scrambled field name: {:?}", scrambled_field_name); + trace!("Removing scrambled field name: {:?}", scrambled_field_name); // Call remove_db (this bubbles up to Tendermint via ocalls and FFI to Go code) // fn remove_db(context: Ctx, key: &[u8]) { diff --git a/cosmwasm/enclaves/shared/contract-engine/src/errors.rs b/cosmwasm/enclaves/shared/contract-engine/src/errors.rs index 0f649127a..4c5b18982 100644 --- a/cosmwasm/enclaves/shared/contract-engine/src/errors.rs +++ b/cosmwasm/enclaves/shared/contract-engine/src/errors.rs @@ -7,6 +7,12 @@ use enclave_ffi_types::{EnclaveError, UntrustedVmError}; use crate::external::ecalls::BufferRecoveryError; +#[derive(Debug, Display)] +#[non_exhaustive] +pub enum ContractError { + DeserializingEnvErr +} + #[derive(Debug, Display)] #[non_exhaustive] pub enum WasmEngineError { diff --git a/cosmwasm/enclaves/shared/contract-engine/src/io.rs b/cosmwasm/enclaves/shared/contract-engine/src/io.rs index 593a70ea8..e930f5117 100644 --- a/cosmwasm/enclaves/shared/contract-engine/src/io.rs +++ b/cosmwasm/enclaves/shared/contract-engine/src/io.rs @@ -385,7 +385,7 @@ pub fn encrypt_output( Some(_) => { let mut events: Vec = vec![]; - if ok.attributes.len() > 0 { + if !ok.attributes.is_empty() { events.push(Event { ty: "wasm".to_string(), attributes: ok.attributes.clone(), diff --git a/cosmwasm/enclaves/shared/contract-engine/src/lib.rs b/cosmwasm/enclaves/shared/contract-engine/src/lib.rs index 5fab47759..c70c99a0f 100644 --- a/cosmwasm/enclaves/shared/contract-engine/src/lib.rs +++ b/cosmwasm/enclaves/shared/contract-engine/src/lib.rs @@ -12,6 +12,7 @@ pub mod external; mod gas; mod io; mod memory; +mod message; pub(crate) mod module_cache; mod query_chain; pub(crate) mod types; diff --git a/cosmwasm/enclaves/shared/contract-engine/src/message.rs b/cosmwasm/enclaves/shared/contract-engine/src/message.rs new file mode 100644 index 000000000..f5b83e8e6 --- /dev/null +++ b/cosmwasm/enclaves/shared/contract-engine/src/message.rs @@ -0,0 +1,347 @@ +use cosmos_proto::tx::signing::SignMode; +use cw_types_v010::encoding::Binary; + +use log::{trace, warn}; + +use crate::types::SecretMessage; +use cw_types_v1::results::{DecryptedReply, Event, Reply, SubMsgResponse, SubMsgResult}; +use enclave_cosmos_types::types::{HandleType, SigInfo}; +use enclave_ffi_types::EnclaveError; + +const HEX_ENCODED_HASH_SIZE: usize = 64; + +pub struct ParsedMessage { + pub should_validate_sig_info: bool, + pub was_msg_encrypted: bool, + pub secret_msg: SecretMessage, + pub decrypted_msg: Vec, + pub contract_hash_for_validation: Option>, +} + +fn redact_custom_events(reply: &mut Reply) { + reply.result = match &reply.result { + SubMsgResult::Ok(r) => { + let mut events: Vec = Default::default(); + + let filtered_attributes = vec!["contract_address".to_string(), "code_id".to_string()]; + for ev in r.events.iter() { + if !ev.ty.starts_with("wasm") { + continue; + } + + let mut new_ev = Event { + ty: ev.ty.clone(), + attributes: vec![], + }; + + for attr in &ev.attributes { + if !filtered_attributes.contains(&attr.key) { + new_ev.attributes.push(attr.clone()); + } + } + + if !new_ev.attributes.is_empty() { + events.push(new_ev); + } + } + + SubMsgResult::Ok(SubMsgResponse { + events, + data: r.data.clone(), + }) + } + SubMsgResult::Err(_) => reply.result.clone(), + }; +} + +// Parse the message that was passed to handle (Based on the assumption that it might be a reply or IBC as well) +pub fn parse_message( + message: &[u8], + sig_info: &SigInfo, + handle_type: &HandleType, +) -> Result { + let orig_secret_msg = SecretMessage::from_slice(message)?; + + return match handle_type { + HandleType::HANDLE_TYPE_EXECUTE => { + let decrypted_msg = orig_secret_msg.decrypt()?; + Ok(ParsedMessage { + should_validate_sig_info: true, + was_msg_encrypted: true, + secret_msg: orig_secret_msg, + decrypted_msg, + contract_hash_for_validation: None, + }) + } + + HandleType::HANDLE_TYPE_REPLY => { + if sig_info.sign_mode == SignMode::SIGN_MODE_UNSPECIFIED { + trace!("reply input is not encrypted"); + let decrypted_msg = orig_secret_msg.msg.clone(); + let mut reply: Reply = serde_json::from_slice(&decrypted_msg) + .map_err(|err| { + warn!( + "reply got an error while trying to deserialize decrypted reply bytes into json {:?}: {}", + String::from_utf8_lossy(&decrypted_msg), + err + ); + EnclaveError::FailedToDeserialize + })?; + + let msg_id = String::from_utf8(reply.id.as_slice().to_vec()).map_err(|err| { + warn!( + "Failed to parse message id as string {:?}: {}", + reply.id.as_slice().to_vec(), + err + ); + EnclaveError::FailedToDeserialize + })?; + + let msg_id_as_num = match msg_id.parse::() { + Ok(m) => m, + Err(err) => { + warn!("Failed to parse message id as number {}: {}", msg_id, err); + return Err(EnclaveError::FailedToDeserialize); + } + }; + + let decrypted_reply = DecryptedReply { + id: msg_id_as_num, + result: reply.result.clone(), + }; + + redact_custom_events(&mut reply); + let serialized_encrypted_reply : Vec = serde_json::to_vec(&reply).map_err(|err| { + warn!( + "got an error while trying to serialize encrypted reply into bytes {:?}: {}", + reply, err + ); + EnclaveError::FailedToSerialize + })?; + + let reply_secret_msg = SecretMessage { + nonce: orig_secret_msg.nonce, + user_public_key: orig_secret_msg.user_public_key, + msg: serialized_encrypted_reply, + }; + + let serialized_reply: Vec = serde_json::to_vec(&decrypted_reply).map_err(|err| { + warn!( + "got an error while trying to serialize decrypted reply into bytes {:?}: {}", + decrypted_reply, err + ); + EnclaveError::FailedToSerialize + })?; + + return Ok(ParsedMessage { + should_validate_sig_info: false, + was_msg_encrypted: false, + secret_msg: reply_secret_msg, + decrypted_msg: serialized_reply, + contract_hash_for_validation: None, + }); + } + + // Here we are sure the reply is OK because only OK is encrypted + trace!( + "reply input before decryption: {:?}", + base64::encode(&message) + ); + let mut parsed_encrypted_reply: Reply = serde_json::from_slice( + &orig_secret_msg.msg.as_slice().to_vec(), + ) + .map_err(|err| { + warn!( + "reply got an error while trying to deserialize msg input bytes into json {:?}: {}", + String::from_utf8_lossy(&orig_secret_msg.msg), + err + ); + EnclaveError::FailedToDeserialize + })?; + + match parsed_encrypted_reply.result.clone() { + SubMsgResult::Ok(response) => { + let decrypted_msg_data = match response.data { + Some(data) => { + let tmp_secret_msg_data = SecretMessage { + nonce: orig_secret_msg.nonce, + user_public_key: orig_secret_msg.user_public_key, + msg: data.as_slice().to_vec(), + }; + + Some(Binary( + tmp_secret_msg_data.decrypt()?[HEX_ENCODED_HASH_SIZE..].to_vec(), + )) + } + None => None, + }; + + let tmp_secret_msg_id = SecretMessage { + nonce: orig_secret_msg.nonce, + user_public_key: orig_secret_msg.user_public_key, + msg: parsed_encrypted_reply.id.as_slice().to_vec(), + }; + + let tmp_decrypted_msg_id = tmp_secret_msg_id.decrypt()?; + + // Now we need to create synthetic SecretMessage to fit the API in "handle" + let result = SubMsgResult::Ok(SubMsgResponse { + events: response.events, + data: decrypted_msg_data, + }); + + let msg_id = + String::from_utf8(tmp_decrypted_msg_id[HEX_ENCODED_HASH_SIZE..].to_vec()) + .map_err(|err| { + warn!( + "Failed to parse message id as string {:?}: {}", + tmp_decrypted_msg_id[HEX_ENCODED_HASH_SIZE..].to_vec(), + err + ); + EnclaveError::FailedToDeserialize + })?; + + let msg_id_as_num = match msg_id.parse::() { + Ok(m) => m, + Err(err) => { + warn!("Failed to parse message id as number {}: {}", msg_id, err); + return Err(EnclaveError::FailedToDeserialize); + } + }; + + let decrypted_reply = DecryptedReply { + id: msg_id_as_num, + result, + }; + + let decrypted_reply_as_vec = + serde_json::to_vec(&decrypted_reply).map_err(|err| { + warn!( + "got an error while trying to serialize reply into bytes {:?}: {}", + decrypted_reply, err + ); + EnclaveError::FailedToSerialize + })?; + + redact_custom_events(&mut parsed_encrypted_reply); + let serialized_encrypted_reply : Vec = serde_json::to_vec(&parsed_encrypted_reply).map_err(|err| { + warn!( + "got an error while trying to serialize encrypted reply into bytes {:?}: {}", + parsed_encrypted_reply, err + ); + EnclaveError::FailedToSerialize + })?; + + let reply_secret_msg = SecretMessage { + nonce: orig_secret_msg.nonce, + user_public_key: orig_secret_msg.user_public_key, + msg: serialized_encrypted_reply, + }; + + Ok(ParsedMessage { + should_validate_sig_info: true, + was_msg_encrypted: true, + secret_msg: reply_secret_msg, + decrypted_msg: decrypted_reply_as_vec, + contract_hash_for_validation: Some( + tmp_decrypted_msg_id[..HEX_ENCODED_HASH_SIZE].to_vec(), + ), + }) + } + SubMsgResult::Err(response) => { + let secret_msg = SecretMessage { + nonce: orig_secret_msg.nonce, + user_public_key: orig_secret_msg.user_public_key, + msg: base64::decode(response.clone()).map_err(|err| { + warn!( + "got an error while trying to serialize err reply from base64 {:?}: {}", + response, err + ); + EnclaveError::FailedToSerialize + })? + }; + + let decrypted_error = secret_msg.decrypt()?; + + let tmp_secret_msg_id = SecretMessage { + nonce: orig_secret_msg.nonce, + user_public_key: orig_secret_msg.user_public_key, + msg: parsed_encrypted_reply.id.as_slice().to_vec(), + }; + + let tmp_decrypted_msg_id = tmp_secret_msg_id.decrypt()?; + + // Now we need to create synthetic SecretMessage to fit the API in "handle" + let result = SubMsgResult::Err( + String::from_utf8(decrypted_error[HEX_ENCODED_HASH_SIZE..].to_vec()) + .map_err(|err| { + warn!( + "Failed to parse error as string {:?}: {}", + decrypted_error[HEX_ENCODED_HASH_SIZE..].to_vec(), + err + ); + EnclaveError::FailedToDeserialize + })?, + ); + + let msg_id = + String::from_utf8(tmp_decrypted_msg_id[HEX_ENCODED_HASH_SIZE..].to_vec()) + .map_err(|err| { + warn!( + "Failed to parse message id as string {:?}: {}", + tmp_decrypted_msg_id[HEX_ENCODED_HASH_SIZE..].to_vec(), + err + ); + EnclaveError::FailedToDeserialize + })?; + + let msg_id_as_num = match msg_id.parse::() { + Ok(m) => m, + Err(err) => { + warn!("Failed to parse message id as number {}: {}", msg_id, err); + return Err(EnclaveError::FailedToDeserialize); + } + }; + + let decrypted_reply = DecryptedReply { + id: msg_id_as_num, + result, + }; + + let decrypted_reply_as_vec = + serde_json::to_vec(&decrypted_reply).map_err(|err| { + warn!( + "got an error while trying to serialize reply into bytes {:?}: {}", + decrypted_reply, err + ); + EnclaveError::FailedToSerialize + })?; + + let serialized_encrypted_reply : Vec = serde_json::to_vec(&parsed_encrypted_reply).map_err(|err| { + warn!( + "got an error while trying to serialize encrypted reply into bytes {:?}: {}", + parsed_encrypted_reply, err + ); + EnclaveError::FailedToSerialize + })?; + + let reply_secret_msg = SecretMessage { + nonce: orig_secret_msg.nonce, + user_public_key: orig_secret_msg.user_public_key, + msg: serialized_encrypted_reply, + }; + + Ok(ParsedMessage { + should_validate_sig_info: true, + was_msg_encrypted: true, + secret_msg: reply_secret_msg, + decrypted_msg: decrypted_reply_as_vec, + contract_hash_for_validation: Some( + tmp_decrypted_msg_id[..HEX_ENCODED_HASH_SIZE].to_vec(), + ), + }) + } + } + } + }; +} diff --git a/cosmwasm/enclaves/shared/contract-engine/src/types.rs b/cosmwasm/enclaves/shared/contract-engine/src/types.rs index 07e2ff7c9..0fe611b12 100644 --- a/cosmwasm/enclaves/shared/contract-engine/src/types.rs +++ b/cosmwasm/enclaves/shared/contract-engine/src/types.rs @@ -28,6 +28,7 @@ impl SecretMessage { } pub fn decrypt(&self) -> Result, EnclaveError> { + trace!("input before decryption: {:?}", base64::encode(&self.msg)); let key = self.encryption_key(); // pass @@ -36,6 +37,11 @@ impl SecretMessage { EnclaveError::DecryptionError })?; + trace!( + "input after decryption: {:?}", + String::from_utf8_lossy(&msg) + ); + Ok(msg) } diff --git a/cosmwasm/enclaves/shared/cosmos-proto/Cargo.toml b/cosmwasm/enclaves/shared/cosmos-proto/Cargo.toml index 30b15d02f..b12275afc 100644 --- a/cosmwasm/enclaves/shared/cosmos-proto/Cargo.toml +++ b/cosmwasm/enclaves/shared/cosmos-proto/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cosmos_proto" -version = "1.2.4" +version = "1.4.0" authors = ["bob"] edition = "2018" diff --git a/cosmwasm/enclaves/shared/cosmos-types/Cargo.toml b/cosmwasm/enclaves/shared/cosmos-types/Cargo.toml index c1ee9ace8..e9c5ece00 100644 --- a/cosmwasm/enclaves/shared/cosmos-types/Cargo.toml +++ b/cosmwasm/enclaves/shared/cosmos-types/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "enclave_cosmos_types" -version = "1.2.4" +version = "1.4.0" authors = ["Cashmaney "] edition = "2018" diff --git a/cosmwasm/enclaves/shared/cosmwasm-types/generic/Cargo.toml b/cosmwasm/enclaves/shared/cosmwasm-types/generic/Cargo.toml index 75d926a53..dd13cedf3 100644 --- a/cosmwasm/enclaves/shared/cosmwasm-types/generic/Cargo.toml +++ b/cosmwasm/enclaves/shared/cosmwasm-types/generic/Cargo.toml @@ -18,3 +18,4 @@ cw_types_v1 = { path = "../v1.0" } log = "0.4.14" hex = "0.4.2" +base64 = "0.13.0" diff --git a/cosmwasm/enclaves/shared/cosmwasm-types/generic/src/lib.rs b/cosmwasm/enclaves/shared/cosmwasm-types/generic/src/lib.rs index 22b4a017a..a34bb7897 100644 --- a/cosmwasm/enclaves/shared/cosmwasm-types/generic/src/lib.rs +++ b/cosmwasm/enclaves/shared/cosmwasm-types/generic/src/lib.rs @@ -9,7 +9,8 @@ use cw_types_v010::types as v010types; use cw_types_v1::types as v1types; use enclave_ffi_types::EnclaveError; -use hex; + +pub const CONTRACT_KEY_LENGTH: usize = 64; /// CosmwasmApiVersion is used to decide how to handle contract inputs and outputs pub enum CosmWasmApiVersion { @@ -19,12 +20,43 @@ pub enum CosmWasmApiVersion { V1, } +pub type BaseAddr = HumanAddr; +pub type BaseCoin = v010types::Coin; +pub type BaseCanoncalAddr = v010types::CanonicalAddr; + #[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] #[serde(rename_all = "snake_case")] pub struct BaseEnv(pub V010Env); impl BaseEnv { - pub fn get_verification_params(&self) -> (&HumanAddr, &HumanAddr, u64, &Vec) { + + pub fn get_contract_key(&self) -> Result<[u8; CONTRACT_KEY_LENGTH], EnclaveError> { + + let contract_key = if let Some(b64_key) = &self.0.contract_key { + base64::decode(b64_key).map_err(|err| { + warn!( + "got an error while trying to decode contract key {:?}: {}", + b64_key, err + ); + EnclaveError::FailedContractAuthentication + })? + } else { + warn!("Contract execute with empty contract key"); + return Err(EnclaveError::FailedContractAuthentication); + }; + + if contract_key.len() != CONTRACT_KEY_LENGTH { + warn!("Contract execute with empty contract key"); + return Err(EnclaveError::FailedContractAuthentication); + } + + let mut key_as_bytes = [0u8; CONTRACT_KEY_LENGTH]; + key_as_bytes.copy_from_slice(&contract_key); + + Ok(key_as_bytes) + } + + pub fn get_verification_params(&self) -> (&BaseAddr, &BaseAddr, u64, &Vec) { ( &self.0.message.sender, &self.0.contract.address, diff --git a/cosmwasm/enclaves/shared/cosmwasm-types/v0.10/Cargo.toml b/cosmwasm/enclaves/shared/cosmwasm-types/v0.10/Cargo.toml index 246aae17a..ecbde79fe 100644 --- a/cosmwasm/enclaves/shared/cosmwasm-types/v0.10/Cargo.toml +++ b/cosmwasm/enclaves/shared/cosmwasm-types/v0.10/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw_types_v010" -version = "1.2.4" +version = "1.4.0" authors = ["Cashmaney "] edition = "2018" diff --git a/cosmwasm/enclaves/shared/cosmwasm-types/v1.0/Cargo.toml b/cosmwasm/enclaves/shared/cosmwasm-types/v1.0/Cargo.toml index 03afdf208..10794b5b2 100644 --- a/cosmwasm/enclaves/shared/cosmwasm-types/v1.0/Cargo.toml +++ b/cosmwasm/enclaves/shared/cosmwasm-types/v1.0/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw_types_v1" -version = "1.2.4" +version = "1.4.0" authors = ["Cashmaney "] edition = "2018" diff --git a/cosmwasm/enclaves/shared/crypto/Cargo.toml b/cosmwasm/enclaves/shared/crypto/Cargo.toml index 1760b23ff..65a7ff848 100644 --- a/cosmwasm/enclaves/shared/crypto/Cargo.toml +++ b/cosmwasm/enclaves/shared/crypto/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "enclave_crypto" -version = "1.2.4" +version = "1.4.0" authors = ["Cashmaney "] edition = "2018" diff --git a/cosmwasm/enclaves/shared/utils/Cargo.toml b/cosmwasm/enclaves/shared/utils/Cargo.toml index 78d74d86a..cb451b52b 100644 --- a/cosmwasm/enclaves/shared/utils/Cargo.toml +++ b/cosmwasm/enclaves/shared/utils/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "enclave_utils" -version = "1.2.4" +version = "1.4.0" authors = ["Cashmaney "] edition = "2018" diff --git a/go-cosmwasm/types/env.go b/go-cosmwasm/types/env.go index 6afd3d27d..ac93d8067 100644 --- a/go-cosmwasm/types/env.go +++ b/go-cosmwasm/types/env.go @@ -15,6 +15,10 @@ type Env struct { Recursive bool `json:"recursive"` } +type BaseEnv[T Env] struct { + First T +} + type ContractKey string type BlockInfo struct { diff --git a/x/compute/internal/keeper/secret_contracts_test.go b/x/compute/internal/keeper/secret_contracts_test.go index bb3a70a7a..7f36b84a9 100644 --- a/x/compute/internal/keeper/secret_contracts_test.go +++ b/x/compute/internal/keeper/secret_contracts_test.go @@ -610,12 +610,12 @@ func TestCallbackSanity(t *testing.T) { {Key: "banana", Value: "🍌"}, }, { - {Key: "contract_address", Value: contractAddress.String()}, {Key: "kiwi", Value: "🥝"}, + {Key: "contract_address", Value: contractAddress.String()}, }, { - {Key: "contract_address", Value: contractAddress.String()}, {Key: "watermelon", Value: "🍉"}, + {Key: "contract_address", Value: contractAddress.String()}, }, }, execEvents, diff --git a/x/compute/internal/types/types.go b/x/compute/internal/types/types.go index b36c03854..e7fa33014 100644 --- a/x/compute/internal/types/types.go +++ b/x/compute/internal/types/types.go @@ -172,7 +172,8 @@ func ContractLogsToSdkEvents(logs []wasmTypesV010.LogAttribute, contractAddr sdk attrs = append(attrs, attr) } } - // each wasm invokation always returns one sdk.Event + + // each wasm invocation always returns one sdk.Event return sdk.Events{sdk.NewEvent(CustomEventType, attrs...)} } From 38d7c517b53033125c830352df71b51349e1cb29 Mon Sep 17 00:00:00 2001 From: Assaf Morami Date: Wed, 24 Aug 2022 17:10:41 +0300 Subject: [PATCH 59/93] Compute MsgServer refactor --- x/compute/internal/keeper/msg_server.go | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/x/compute/internal/keeper/msg_server.go b/x/compute/internal/keeper/msg_server.go index cb1d94f00..a74c07025 100644 --- a/x/compute/internal/keeper/msg_server.go +++ b/x/compute/internal/keeper/msg_server.go @@ -28,13 +28,10 @@ func (m msgServer) StoreCode(goCtx context.Context, msg *types.MsgStoreCode) (*t )) codeID, err := m.keeper.Create(ctx, msg.Sender, msg.WASMByteCode, msg.Source, msg.Builder) - if err != nil { - return nil, err - } return &types.MsgStoreCodeResponse{ CodeID: codeID, - }, nil + }, err } func (m msgServer) InstantiateContract(goCtx context.Context, msg *types.MsgInstantiateContract) (*types.MsgInstantiateContractResponse, error) { @@ -47,14 +44,14 @@ func (m msgServer) InstantiateContract(goCtx context.Context, msg *types.MsgInst )) contractAddr, data, err := m.keeper.Instantiate(ctx, msg.CodeID, msg.Sender, msg.InitMsg, msg.Label, msg.InitFunds, msg.CallbackSig) - if err != nil { - return nil, err - } + // we always return data (internally used in reply) + // note: even if contractAddr == nil then contractAddr.String() is ok + // \o/🤷🤷‍♂️🤷‍♀️🤦🤦‍♂️🤦‍♀️ return &types.MsgInstantiateContractResponse{ Address: contractAddr.String(), Data: data, - }, nil + }, err } func (m msgServer) ExecuteContract(goCtx context.Context, msg *types.MsgExecuteContract) (*types.MsgExecuteContractResponse, error) { @@ -67,11 +64,9 @@ func (m msgServer) ExecuteContract(goCtx context.Context, msg *types.MsgExecuteC )) data, err := m.keeper.Execute(ctx, msg.Contract, msg.Sender, msg.Msg, msg.SentFunds, msg.CallbackSig) - if err != nil { - return nil, err - } + // we always return data (internally used in reply) return &types.MsgExecuteContractResponse{ Data: data.Data, - }, nil + }, err } From c87d153aebdca3d7e3db38960a278ba12cd5e320 Mon Sep 17 00:00:00 2001 From: Lior Bondarevski Date: Wed, 24 Aug 2022 17:14:05 +0300 Subject: [PATCH 60/93] Fix the majority of linting problems --- cmd/secretd/attestation.go | 20 ++++++++++--------- cmd/secretd/genaccounts.go | 6 ++---- go-cosmwasm/cmd/main.go | 6 +++++- go-cosmwasm/types/queries.go | 2 +- x/registration/client/cli/query.go | 2 +- x/registration/internal/keeper/keeper.go | 5 +++-- .../internal/keeper/querier_test.go | 1 + 7 files changed, 24 insertions(+), 18 deletions(-) diff --git a/cmd/secretd/attestation.go b/cmd/secretd/attestation.go index a9bc95ce9..5e3cd9175 100644 --- a/cmd/secretd/attestation.go +++ b/cmd/secretd/attestation.go @@ -17,7 +17,6 @@ import ( "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/flags" - "github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/server" "github.com/cosmos/cosmos-sdk/x/genutil" genutiltypes "github.com/cosmos/cosmos-sdk/x/genutil/types" @@ -124,8 +123,7 @@ blockchain. Writes the certificate in DER format to ~/attestation_cert Args: cobra.MaximumNArgs(2), RunE: func(cmd *cobra.Command, args []string) error { clientCtx := client.GetClientContextFromCmd(cmd) - depCdc := clientCtx.Codec - cdc := depCdc.(codec.Codec) + cdc := clientCtx.Codec serverCtx := server.GetServerContextFromCmd(cmd) config := serverCtx.Config @@ -175,8 +173,8 @@ blockchain. Writes the certificate in DER format to ~/attestation_cert return err } - fmt.Println(fmt.Sprintf("%s", hex.EncodeToString(pubkey))) - fmt.Println(fmt.Sprintf("%s", hex.EncodeToString(masterKey))) + fmt.Printf("%s\n", hex.EncodeToString(pubkey)) + fmt.Printf("%s\n", hex.EncodeToString(masterKey)) // sanity check - make sure the certificate we're using matches the generated key if hex.EncodeToString(pubkey) != hex.EncodeToString(masterKey) { @@ -239,7 +237,7 @@ func ParseCert() *cobra.Command { return err } - fmt.Println(fmt.Sprintf("0x%s", hex.EncodeToString(pubkey))) + fmt.Printf("0x%s\n", hex.EncodeToString(pubkey)) return nil }, } @@ -313,7 +311,7 @@ func HealthCheck() *cobra.Command { return fmt.Errorf("failed to start enclave. Enclave returned: %s", err) } - fmt.Println(fmt.Sprintf("SGX enclave health status: %s", res)) + fmt.Printf("SGX enclave health status: %s\n", res) return nil }, } @@ -491,7 +489,11 @@ Please report any issues with this command "certificate": "%s" }`, base64.StdEncoding.EncodeToString(cert))) - resp, err := http.Post(fmt.Sprintf(`%s`, regUrl), "application/json", bytes.NewBuffer(data)) + resp, err := http.Post(regUrl, "application/json", bytes.NewBuffer(data)) + if err != nil { + log.Fatalln(err) + } + defer resp.Body.Close() body, err := ioutil.ReadAll(resp.Body) @@ -515,7 +517,7 @@ Please report any issues with this command } seed := details.Details.Value - log.Printf(fmt.Sprintf(`seed: %s`, seed)) + log.Printf(`seed: %s\n`, seed) if len(seed) > 2 { seed = seed[2:] diff --git a/cmd/secretd/genaccounts.go b/cmd/secretd/genaccounts.go index e4bf9b8c7..3ed771043 100644 --- a/cmd/secretd/genaccounts.go +++ b/cmd/secretd/genaccounts.go @@ -14,7 +14,6 @@ import ( "github.com/spf13/cobra" "github.com/cosmos/cosmos-sdk/client/flags" - "github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/server" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/x/genutil" @@ -42,8 +41,7 @@ contain valid denominations. Accounts may optionally be supplied with vesting pa Args: cobra.ExactArgs(2), RunE: func(cmd *cobra.Command, args []string) error { clientCtx := client.GetClientContextFromCmd(cmd) - depCdc := clientCtx.Codec - cdc := depCdc.(codec.Codec) + cdc := clientCtx.Codec serverCtx := server.GetServerContextFromCmd(cmd) config := serverCtx.Config @@ -161,7 +159,7 @@ contain valid denominations. Accounts may optionally be supplied with vesting pa appState[authtypes.ModuleName] = authGenStateBz - bankGenState := banktypes.GetGenesisStateFromAppState(depCdc, appState) + bankGenState := banktypes.GetGenesisStateFromAppState(cdc, appState) bankGenState.Balances = append(bankGenState.Balances, balances) bankGenState.Balances = banktypes.SanitizeGenesisBalances(bankGenState.Balances) diff --git a/go-cosmwasm/cmd/main.go b/go-cosmwasm/cmd/main.go index 149d3ccf4..c088ecbaf 100644 --- a/go-cosmwasm/cmd/main.go +++ b/go-cosmwasm/cmd/main.go @@ -18,7 +18,11 @@ func main() { } fmt.Println("Loaded!") - os.MkdirAll("tmp", 0o755) + err = os.MkdirAll("tmp", 0o755) + if err != nil { + panic(err) + } + wasmer, err := wasm.NewWasmer("tmp", "staking", 0, 15) if err != nil { panic(err) diff --git a/go-cosmwasm/types/queries.go b/go-cosmwasm/types/queries.go index 90519e2a4..ffc7bb4c7 100644 --- a/go-cosmwasm/types/queries.go +++ b/go-cosmwasm/types/queries.go @@ -101,7 +101,7 @@ type StakingQuery struct { Validators *ValidatorsQuery `json:"validators,omitempty"` AllDelegations *AllDelegationsQuery `json:"all_delegations,omitempty"` Delegation *DelegationQuery `json:"delegation,omitempty"` - UnBondingDelegations *UnbondingDeletionsQuery `json:"unbonding_delegations, omitempty"` + UnBondingDelegations *UnbondingDeletionsQuery `json:"unbonding_delegations,omitempty"` BondedDenom *struct{} `json:"bonded_denom,omitempty"` } diff --git a/x/registration/client/cli/query.go b/x/registration/client/cli/query.go index e879ddc49..a9bcfb0a3 100644 --- a/x/registration/client/cli/query.go +++ b/x/registration/client/cli/query.go @@ -56,7 +56,7 @@ func GetCmdEncryptedSeed() *cobra.Command { if err != nil { return err } - fmt.Println(fmt.Sprintf("0x%s", hex.EncodeToString(res))) + fmt.Printf("0x%s\n", hex.EncodeToString(res)) return nil }, } diff --git a/x/registration/internal/keeper/keeper.go b/x/registration/internal/keeper/keeper.go index 3c49c55b1..f83c24b19 100644 --- a/x/registration/internal/keeper/keeper.go +++ b/x/registration/internal/keeper/keeper.go @@ -47,6 +47,9 @@ func InitializeNode(homeDir string, enclave EnclaveInterface) { // get PK from CLI // get encrypted master key byteValue, err := getFile(seedPath) + if err != nil { + panic(sdkerrors.Wrap(types.ErrSeedInitFailed, err.Error())) + } var seedCfg types.SeedConfig @@ -69,8 +72,6 @@ func InitializeNode(homeDir string, enclave EnclaveInterface) { if err != nil { panic(sdkerrors.Wrap(types.ErrSeedInitFailed, err.Error())) } - - return } func (k Keeper) RegisterNode(ctx sdk.Context, certificate ra.Certificate) ([]byte, error) { diff --git a/x/registration/internal/keeper/querier_test.go b/x/registration/internal/keeper/querier_test.go index 13034f152..51cac4e25 100644 --- a/x/registration/internal/keeper/querier_test.go +++ b/x/registration/internal/keeper/querier_test.go @@ -100,5 +100,6 @@ func TestNewQuerier(t *testing.T) { keeper.setMasterCertificate(ctx, types.MasterCertificate{Bytes: regInfo.Certificate}, types.MasterIoKeyId) binResult, err := querier(ctx, []string{QueryMasterCertificate}, abci.RequestQuery{Data: []byte("")}) + require.NoError(t, err) require.Equal(t, string(binResult), string(expectedSecretParams)) } From c23c6dc76ae94dd3b7ec3de12539217cbc8c7ccc Mon Sep 17 00:00:00 2001 From: Itzik Date: Wed, 24 Aug 2022 17:20:00 +0300 Subject: [PATCH 61/93] Clippy must be made happy --- .../src/contract_operations.rs | 6 +-- .../src/contract_validation.rs | 17 ++------ .../shared/contract-engine/src/errors.rs | 6 --- .../packages/sgx-vm/src/errors/vm_error.rs | 42 +++++++++++++++---- 4 files changed, 37 insertions(+), 34 deletions(-) diff --git a/cosmwasm/enclaves/shared/contract-engine/src/contract_operations.rs b/cosmwasm/enclaves/shared/contract-engine/src/contract_operations.rs index f1edabaac..46810114b 100644 --- a/cosmwasm/enclaves/shared/contract-engine/src/contract_operations.rs +++ b/cosmwasm/enclaves/shared/contract-engine/src/contract_operations.rs @@ -1,14 +1,10 @@ -use cosmos_proto::tx::signing::SignMode; - use cw_types_generic::{BaseAddr, BaseEnv}; use cw_types_v010::encoding::Binary; use cw_types_v010::types::CanonicalAddr; -use cw_types_v1::types::{Addr, Timestamp}; - use enclave_cosmos_types::types::{ContractCode, HandleType, SigInfo}; -use enclave_crypto::{Ed25519PublicKey, HASH_SIZE}; +use enclave_crypto::Ed25519PublicKey; use enclave_ffi_types::{Ctx, EnclaveError}; use enclave_utils::coalesce; use log::*; diff --git a/cosmwasm/enclaves/shared/contract-engine/src/contract_validation.rs b/cosmwasm/enclaves/shared/contract-engine/src/contract_validation.rs index 549c4d449..7e28228a4 100644 --- a/cosmwasm/enclaves/shared/contract-engine/src/contract_validation.rs +++ b/cosmwasm/enclaves/shared/contract-engine/src/contract_validation.rs @@ -1,10 +1,9 @@ -use cw_types_generic::BaseEnv; use cw_types_v1::results::REPLY_ENCRYPTION_MAGIC_BYTES; use log::*; use enclave_ffi_types::EnclaveError; -use cw_types_v010::types::{CanonicalAddr, Coin, Env, HumanAddr}; +use cw_types_v010::types::{CanonicalAddr, Coin, HumanAddr}; use enclave_cosmos_types::traits::CosmosAminoPubkey; use enclave_cosmos_types::types::{ ContractCode, CosmWasmMsg, CosmosPubKey, SigInfo, SignDoc, StdSignDoc, @@ -30,16 +29,6 @@ pub fn generate_encryption_key( ) -> Result<[u8; CONTRACT_KEY_LENGTH], EnclaveError> { let consensus_state_ikm = KEY_MANAGER.get_consensus_state_ikm().unwrap(); - // todo: check that this is just getting the canonicaladdr - // let (_, sender_address_u5) = bech32::decode(sender.as_str()).map_err(|err| { - // warn!( - // "got an error while trying to deserialize env.message.sender from bech32 string to bytes {:?}: {}", - // env.message.sender, err - // ); - // EnclaveError::FailedToDeserialize - // })?; - // let snder_address: Vec = sender_address_u5.iter().map(|x| x.to_u8()).collect(); - let sender_id = generate_sender_id(&(sender.0).0, block_height); let mut encryption_key = [0u8; 64]; @@ -108,13 +97,13 @@ pub fn validate_contract_key( contract_address.as_slice(), ); - return if calculated_authentication_id == expected_authentication_id { + if calculated_authentication_id == expected_authentication_id { trace!("Successfully authenticated the contract!"); Ok(()) } else { warn!("got an error while trying to deserialize output bytes"); Err(EnclaveError::FailedContractAuthentication) - }; + } } pub struct ValidatedMessage { diff --git a/cosmwasm/enclaves/shared/contract-engine/src/errors.rs b/cosmwasm/enclaves/shared/contract-engine/src/errors.rs index 4c5b18982..0f649127a 100644 --- a/cosmwasm/enclaves/shared/contract-engine/src/errors.rs +++ b/cosmwasm/enclaves/shared/contract-engine/src/errors.rs @@ -7,12 +7,6 @@ use enclave_ffi_types::{EnclaveError, UntrustedVmError}; use crate::external::ecalls::BufferRecoveryError; -#[derive(Debug, Display)] -#[non_exhaustive] -pub enum ContractError { - DeserializingEnvErr -} - #[derive(Debug, Display)] #[non_exhaustive] pub enum WasmEngineError { diff --git a/cosmwasm/packages/sgx-vm/src/errors/vm_error.rs b/cosmwasm/packages/sgx-vm/src/errors/vm_error.rs index 83410389d..e72b445dc 100644 --- a/cosmwasm/packages/sgx-vm/src/errors/vm_error.rs +++ b/cosmwasm/packages/sgx-vm/src/errors/vm_error.rs @@ -1,5 +1,5 @@ use snafu::Snafu; -use std::fmt::{Debug, Display}; +use std::fmt::Debug; use super::communication_error::CommunicationError; // use crate::backends::InsufficientGasLeft; @@ -107,11 +107,17 @@ pub enum VmError { #[allow(unused)] impl VmError { pub(crate) fn cache_err>(msg: S) -> Self { - CacheErr { msg: &Self::truncate_input(msg) }.build() + CacheErr { + msg: &Self::truncate_input(msg), + } + .build() } pub(crate) fn compile_err>(msg: S) -> Self { - CompileErr { msg: &Self::truncate_input(msg) }.build() + CompileErr { + msg: &Self::truncate_input(msg), + } + .build() } pub(crate) fn conversion_err, T: Into, U: Into>( @@ -128,11 +134,17 @@ impl VmError { } pub(crate) fn generic_err>(msg: S) -> Self { - GenericErr { msg: &Self::truncate_input(msg) }.build() + GenericErr { + msg: &Self::truncate_input(msg), + } + .build() } pub(crate) fn instantiation_err>(msg: S) -> Self { - InstantiationErr { msg: &Self::truncate_input(msg) }.build() + InstantiationErr { + msg: &Self::truncate_input(msg), + } + .build() } pub(crate) fn integrity_err() -> Self { @@ -161,19 +173,31 @@ impl VmError { } pub(crate) fn resolve_err>(msg: S) -> Self { - ResolveErr { msg: &Self::truncate_input(msg) }.build() + ResolveErr { + msg: &Self::truncate_input(msg), + } + .build() } pub(crate) fn runtime_err>(msg: S) -> Self { - RuntimeErr { msg: &Self::truncate_input(msg) }.build() + RuntimeErr { + msg: &Self::truncate_input(msg), + } + .build() } pub(crate) fn static_validation_err>(msg: S) -> Self { - StaticValidationErr { msg: &Self::truncate_input(msg) }.build() + StaticValidationErr { + msg: &Self::truncate_input(msg), + } + .build() } pub(crate) fn uninitialized_context_data>(kind: S) -> Self { - UninitializedContextData { kind: &Self::truncate_input(kind) }.build() + UninitializedContextData { + kind: &Self::truncate_input(kind), + } + .build() } // this is not super ideal, as we don't want super long strings to be copied and moved around From c397862f9a9473e9c655f65afdaa61102a441238 Mon Sep 17 00:00:00 2001 From: Assaf Morami Date: Wed, 24 Aug 2022 22:19:05 +0300 Subject: [PATCH 62/93] Use v0.10 MsgRouter for MsgExec & MsgInit To support passing reply internal data in the `data` field. --- app/app.go | 1 + x/compute/internal/keeper/handler_plugin.go | 54 ++++++++++++++++----- x/compute/internal/keeper/keeper.go | 3 +- x/compute/internal/keeper/msg_dispatcher.go | 28 ++--------- x/compute/internal/keeper/test_common.go | 1 + 5 files changed, 50 insertions(+), 37 deletions(-) diff --git a/app/app.go b/app/app.go index df08d75bd..eee43cdfb 100644 --- a/app/app.go +++ b/app/app.go @@ -434,6 +434,7 @@ func NewSecretNetworkApp( app.ibcKeeper.PortKeeper, app.transferKeeper, app.ibcKeeper.ChannelKeeper, + app.Router(), app.MsgServiceRouter(), app.GRPCQueryRouter(), computeDir, diff --git a/x/compute/internal/keeper/handler_plugin.go b/x/compute/internal/keeper/handler_plugin.go index a6357b0bb..38ab54568 100644 --- a/x/compute/internal/keeper/handler_plugin.go +++ b/x/compute/internal/keeper/handler_plugin.go @@ -6,6 +6,7 @@ import ( "fmt" codectypes "github.com/cosmos/cosmos-sdk/codec/types" + "github.com/cosmos/cosmos-sdk/x/auth/legacy/legacytx" capabilitykeeper "github.com/cosmos/cosmos-sdk/x/capability/keeper" ibctransfertypes "github.com/cosmos/ibc-go/v3/modules/apps/transfer/types" ibcclienttypes "github.com/cosmos/ibc-go/v3/modules/core/02-client/types" @@ -35,14 +36,20 @@ type MessageHandlerChain struct { // SDKMessageHandler can handles messages that can be encoded into sdk.Message types and routed. type SDKMessageHandler struct { - router MessageRouter - encoders MessageEncoders + // router is used to route StargateMsg and any other msg except for MsgExecuteContract & MsgInstantiateContrat. + router MessageRouter + // legacyRouter is used to route MsgExecuteContract & MsgInstantiateContrat. + // the reason is those msgs use the data field internally for reply, which is + // truncated if the msg erred + legacyRouter sdk.Router + encoders MessageEncoders } -func NewSDKMessageHandler(router MessageRouter, encoders MessageEncoders) SDKMessageHandler { +func NewSDKMessageHandler(router MessageRouter, legacyRouter sdk.Router, encoders MessageEncoders) SDKMessageHandler { return SDKMessageHandler{ - router: router, - encoders: encoders, + router: router, + legacyRouter: legacyRouter, + encoders: encoders, } } @@ -68,6 +75,7 @@ func NewMessageHandlerChain(first Messenger, others ...Messenger) *MessageHandle func NewMessageHandler( msgRouter MessageRouter, + legacyMsgRouter sdk.Router, customEncoders *MessageEncoders, channelKeeper channelkeeper.Keeper, capabilityKeeper capabilitykeeper.ScopedKeeper, @@ -76,7 +84,7 @@ func NewMessageHandler( ) Messenger { encoders := DefaultEncoders(portSource, unpacker).Merge(customEncoders) return NewMessageHandlerChain( - NewSDKMessageHandler(msgRouter, encoders), + NewSDKMessageHandler(msgRouter, legacyMsgRouter, encoders), NewIBCRawPacketHandler(channelKeeper, capabilityKeeper), ) } @@ -528,10 +536,14 @@ func (h SDKMessageHandler) DispatchMsg(ctx sdk.Context, contractAddr sdk.AccAddr for _, sdkMsg := range sdkMsgs { res, err := h.handleSdkMessage(ctx, contractAddr, sdkMsg) if err != nil { - return nil, nil, err + if res != nil { + data = append(data, res.Data) + } + return nil, data, err } // append data data = append(data, res.Data) + // append events sdkEvents := make([]sdk.Event, len(res.Events)) for i := range res.Events { @@ -547,20 +559,40 @@ func (h SDKMessageHandler) handleSdkMessage(ctx sdk.Context, contractAddr sdk.Ad if err := msg.ValidateBasic(); err != nil { return nil, err } - // make sure this account can send it + + // make sure the contract account is also the "signer" on the message for _, acct := range msg.GetSigners() { if !acct.Equals(contractAddr) { return nil, sdkerrors.Wrap(sdkerrors.ErrUnauthorized, "contract doesn't have permission") } } + _, isMsgInitContract := msg.(*types.MsgInstantiateContract) + _, isMsgExecContract := msg.(*types.MsgExecuteContract) + + if isMsgInitContract || isMsgExecContract { + // legacyMsgRouter logic (CosmWasm v0.10) + if legacyMsg, ok := msg.(legacytx.LegacyMsg); ok { + msgRoute := legacyMsg.Route() + handler := h.legacyRouter.Route(ctx, msgRoute) + if handler == nil { + return nil, sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "can't route message %+v", msg) + } + + return handler(ctx, msg) + } else { + return nil, sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "unrecognized legacy message route: %s", sdk.MsgTypeURL(msg)) + } + } + + // msgRouter logic (CosmWasm v1) + // find the handler and execute it if handler := h.router.Handler(msg); handler != nil { // ADR 031 request type routing - msgResult, err := handler(ctx, msg) - return msgResult, err + return handler(ctx, msg) } - // legacy sdk.Msg routing + // Assuming that the app developer has migrated all their Msgs to // proto messages and has registered all `Msg services`, then this // path should never be called, because all those Msgs should be diff --git a/x/compute/internal/keeper/keeper.go b/x/compute/internal/keeper/keeper.go index ad03c3c10..4a091cada 100644 --- a/x/compute/internal/keeper/keeper.go +++ b/x/compute/internal/keeper/keeper.go @@ -99,6 +99,7 @@ func NewKeeper( portKeeper portkeeper.Keeper, portSource types.ICS20TransferPortSource, channelKeeper channelkeeper.Keeper, + legacyMsgRouter sdk.Router, msgRouter MessageRouter, queryRouter GRPCQueryRouter, homeDir string, @@ -121,7 +122,7 @@ func NewKeeper( bankKeeper: bankKeeper, portKeeper: portKeeper, capabilityKeeper: capabilityKeeper, - messenger: NewMessageHandler(msgRouter, customEncoders, channelKeeper, capabilityKeeper, portSource, cdc), + messenger: NewMessageHandler(msgRouter, legacyMsgRouter, customEncoders, channelKeeper, capabilityKeeper, portSource, cdc), queryGasLimit: wasmConfig.SmartQueryGasLimit, } keeper.queryPlugins = DefaultQueryPlugins(govKeeper, distKeeper, mintKeeper, bankKeeper, stakingKeeper, queryRouter, &keeper, channelKeeper).Merge(customPlugins) diff --git a/x/compute/internal/keeper/msg_dispatcher.go b/x/compute/internal/keeper/msg_dispatcher.go index a68907845..51ed0022f 100644 --- a/x/compute/internal/keeper/msg_dispatcher.go +++ b/x/compute/internal/keeper/msg_dispatcher.go @@ -11,7 +11,6 @@ import ( v010wasmTypes "github.com/enigmampc/SecretNetwork/go-cosmwasm/types/v010" v1wasmTypes "github.com/enigmampc/SecretNetwork/go-cosmwasm/types/v1" "github.com/enigmampc/SecretNetwork/x/compute/internal/types" - "github.com/gogo/protobuf/proto" abci "github.com/tendermint/tendermint/abci/types" ) @@ -278,30 +277,9 @@ func (d MessageDispatcher) DispatchSubmessages(ctx sdk.Context, contractAddr sdk var dataWithInternalReplyInfo v1wasmTypes.DataWithInternalReplyInfo if reply.Result.Ok != nil { - if msg.Msg.Wasm != nil && msg.Msg.Wasm.Execute != nil { - var execResponse types.MsgExecuteContractResponse - err = proto.Unmarshal(reply.Result.Ok.Data, &execResponse) - if err != nil { - return nil, fmt.Errorf("exec: cannot decode v1 DataWithInternalReplyInfo from protobuf: %w", err) - } - - err = json.Unmarshal(execResponse.Data, &dataWithInternalReplyInfo) - if err != nil { - return nil, fmt.Errorf("exec: cannot serialize v1 DataWithInternalReplyInfo into json: %w", err) - } - } else if msg.Msg.Wasm != nil && msg.Msg.Wasm.Instantiate != nil { - var initResponse types.MsgInstantiateContractResponse - err = proto.Unmarshal(reply.Result.Ok.Data, &initResponse) - if err != nil { - return nil, fmt.Errorf("init: cannot decode v1 DataWithInternalReplyInfo from protobuf: %w", err) - } - - err = json.Unmarshal(initResponse.Data, &dataWithInternalReplyInfo) - if err != nil { - return nil, fmt.Errorf("init: cannot serialize v1 DataWithInternalReplyInfo into json: %w", err) - } - } else { - return nil, fmt.Errorf("cannot detect wasm msg type: %+v", msg.Msg) + err = json.Unmarshal(reply.Result.Ok.Data, &dataWithInternalReplyInfo) + if err != nil { + return nil, fmt.Errorf("cannot serialize v1 DataWithInternalReplyInfo into json: %w", err) } reply.Result.Ok.Data = dataWithInternalReplyInfo.Data diff --git a/x/compute/internal/keeper/test_common.go b/x/compute/internal/keeper/test_common.go index 65bc66403..8ac6d2038 100644 --- a/x/compute/internal/keeper/test_common.go +++ b/x/compute/internal/keeper/test_common.go @@ -425,6 +425,7 @@ func CreateTestInput(t *testing.T, isCheckTx bool, supportedFeatures string, enc ibcKeeper.PortKeeper, MockIBCTransferKeeper{}, ibcKeeper.ChannelKeeper, + router, msgRouter, queryRouter, tempDir, From eae764e96c49223e123e84e879e479d792a876fc Mon Sep 17 00:00:00 2001 From: Assaf Morami Date: Wed, 24 Aug 2022 22:50:21 +0300 Subject: [PATCH 63/93] Try debugging Integration-Tests CI --- .github/workflows/ci.yaml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 0d3c54e02..81b1fed7d 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -303,11 +303,12 @@ jobs: cd integration-tests yarn docker run -d -p 9091:9091 --name localsecret ghcr.io/scrtlabs/localsecret:v0.0.0 + sleep 30 + docker logs localsecret yarn test - name: Run secret.js tests run: | git clone --depth 1 https://github.com/scrtlabs/secret.js - # Copy v1 contract to tests directory cd secret.js # Use the docker images that we built just a few steps above perl -i -pe 's/localsecret:.+?"/localsecret:v0.0.0"/' ./test/* From 2dbedca61002d904713ea0f9ce6f5310a3a97542 Mon Sep 17 00:00:00 2001 From: Assaf Morami Date: Wed, 24 Aug 2022 23:16:41 +0300 Subject: [PATCH 64/93] Try debugging Integration-Tests CI --- integration-tests/test.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/integration-tests/test.ts b/integration-tests/test.ts index ff3217054..b9a40053d 100644 --- a/integration-tests/test.ts +++ b/integration-tests/test.ts @@ -150,12 +150,13 @@ async function waitForBlocks() { try { const { block } = await secretjs.query.tendermint.getLatestBlock({}); + console.log("block:", JSON.stringify(block)); if (Number(block?.header?.height) >= 1) { break; } } catch (e) { - // console.error(e); + console.error("block error:", e); } await sleep(100); } From 9157ddf0304f3fb04114452f4bc20b42dd024095 Mon Sep 17 00:00:00 2001 From: Assaf Morami Date: Wed, 24 Aug 2022 23:33:33 +0300 Subject: [PATCH 65/93] CI Go-Tests increase timeout 20m->40m --- .github/workflows/ci.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 81b1fed7d..65a0ab5ed 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -221,7 +221,7 @@ jobs: echo "not_a_key" > ias_keys/develop/spid.txt echo "not_a_key" > ias_keys/develop/api_key.txt LOG_LEVEL=ERROR go test -v ./x/compute/client/... - LOG_LEVEL=ERROR go test -p 1 -timeout 20m -v ./x/compute/internal/... + LOG_LEVEL=ERROR go test -p 1 -timeout 40m -v ./x/compute/internal/... Clippy: runs-on: ubuntu-20.04 From 898e3752e4ad995659990abfce57d7b50289891f Mon Sep 17 00:00:00 2001 From: Assaf Morami Date: Thu, 25 Aug 2022 00:52:02 +0300 Subject: [PATCH 66/93] Fix bug from previous merge --- x/compute/internal/keeper/test_common.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x/compute/internal/keeper/test_common.go b/x/compute/internal/keeper/test_common.go index 8ce7cb255..836533697 100644 --- a/x/compute/internal/keeper/test_common.go +++ b/x/compute/internal/keeper/test_common.go @@ -301,7 +301,7 @@ func CreateTestInput(t *testing.T, isCheckTx bool, supportedFeatures string, enc distrAcc := authtypes.NewEmptyModuleAccount(distrtypes.ModuleName) totalSupply := sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(2000000))) - err := bankKeeper.MintCoins(ctx, faucetAccountName, totalSupply) + err = bankKeeper.MintCoins(ctx, faucetAccountName, totalSupply) require.NoError(t, err) // err = bankKeeper.SendCoinsFromModuleToAccount(ctx, faucetAccountName, distrAcc.GetAddress(), totalSupply) From 229bc8132255a292b8fb47fbd08065cad467adc5 Mon Sep 17 00:00:00 2001 From: Assaf Morami Date: Thu, 25 Aug 2022 01:16:46 +0300 Subject: [PATCH 67/93] v1 sanity contract: make ExecuteMsg::GasMeter more efficient because it's timing out in the CI --- .../keeper/testdata/v1-sanity-contract/src/contract.rs | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/x/compute/internal/keeper/testdata/v1-sanity-contract/src/contract.rs b/x/compute/internal/keeper/testdata/v1-sanity-contract/src/contract.rs index 1210a4b53..6551b76ef 100644 --- a/x/compute/internal/keeper/testdata/v1-sanity-contract/src/contract.rs +++ b/x/compute/internal/keeper/testdata/v1-sanity-contract/src/contract.rs @@ -531,7 +531,15 @@ pub fn execute(deps: DepsMut, env: Env, info: MessageInfo, msg: ExecuteMsg) -> S ) .add_attribute("attr3", "🐙") .add_attribute_plaintext("attr4", "🦄")), - ExecuteMsg::GasMeter {} => loop {}, + ExecuteMsg::GasMeter {} => { + // busy work + let mut v = vec![0; 65536]; + let mut x = 0; + loop { + x += (x + 1) % 65536; + v[x] = 65536 - x; + } + } ExecuteMsg::GasMeterProxy {} => Ok(Response::default()), ExecuteMsg::TransferMoney { amount } => transfer_money(deps, amount), ExecuteMsg::RecursiveReply {} => recursive_reply(env, deps), From 76b2562e3dad3a22f6e02f275f84e25ba208ece5 Mon Sep 17 00:00:00 2001 From: Assaf Morami Date: Thu, 25 Aug 2022 01:17:02 +0300 Subject: [PATCH 68/93] rustfmt v1 sanity contract --- .../v1-sanity-contract/src/contract.rs | 38 +++++++++++++------ 1 file changed, 27 insertions(+), 11 deletions(-) diff --git a/x/compute/internal/keeper/testdata/v1-sanity-contract/src/contract.rs b/x/compute/internal/keeper/testdata/v1-sanity-contract/src/contract.rs index 6551b76ef..4dfa3fcdf 100644 --- a/x/compute/internal/keeper/testdata/v1-sanity-contract/src/contract.rs +++ b/x/compute/internal/keeper/testdata/v1-sanity-contract/src/contract.rs @@ -296,23 +296,31 @@ pub fn instantiate( InstantiateMsg::CosmosMsgCustom {} => { Ok(Response::new().add_message(CosmosMsg::Custom(Empty {}))) } - InstantiateMsg::SendMultipleFundsToInitCallback { coins, code_id, code_hash } => Ok( + InstantiateMsg::SendMultipleFundsToInitCallback { + coins, + code_id, + code_hash, + } => Ok( Response::new().add_message(CosmosMsg::Wasm(WasmMsg::Instantiate { code_id, code_hash, msg: Binary("{\"nop\":{}}".as_bytes().to_vec()), funds: coins, - label: "init test".to_string() - })) + label: "init test".to_string(), + })), ), - InstantiateMsg::SendMultipleFundsToExecCallback { coins, to, code_hash } => Ok( + InstantiateMsg::SendMultipleFundsToExecCallback { + coins, + to, + code_hash, + } => Ok( Response::new().add_message(CosmosMsg::Wasm(WasmMsg::Execute { contract_addr: to, code_hash, msg: Binary("{\"no_data\":{}}".as_bytes().to_vec()), funds: coins, - })) - ) + })), + ), } } @@ -1131,22 +1139,30 @@ pub fn execute(deps: DepsMut, env: Env, info: MessageInfo, msg: ExecuteMsg) -> S ExecuteMsg::CosmosMsgCustom {} => { Ok(Response::new().add_message(CosmosMsg::Custom(Empty {}))) } - ExecuteMsg::SendMultipleFundsToInitCallback { coins, code_id, code_hash } => Ok( + ExecuteMsg::SendMultipleFundsToInitCallback { + coins, + code_id, + code_hash, + } => Ok( Response::new().add_message(CosmosMsg::Wasm(WasmMsg::Instantiate { code_id, code_hash, msg: Binary("{\"nop\":{}}".as_bytes().to_vec()), funds: coins, - label: "test".to_string() - })) + label: "test".to_string(), + })), ), - ExecuteMsg::SendMultipleFundsToExecCallback { coins, to, code_hash } => Ok( + ExecuteMsg::SendMultipleFundsToExecCallback { + coins, + to, + code_hash, + } => Ok( Response::new().add_message(CosmosMsg::Wasm(WasmMsg::Execute { contract_addr: to, code_hash, msg: Binary("{\"no_data\":{}}".as_bytes().to_vec()), funds: coins, - })) + })), ), } } From bb335e0b5c4d775e9e1769d06f8650b016ecf861 Mon Sep 17 00:00:00 2001 From: Assaf Morami Date: Thu, 25 Aug 2022 01:18:28 +0300 Subject: [PATCH 69/93] Fix TestCallbackSanity for wasmd v0.28 Events are now sorted (wasmd v0.28), but for us they're sorted while encrypted so when testing with random encryption keys this is non-deterministic --- .../internal/keeper/secret_contracts_test.go | 30 ++++++++----------- 1 file changed, 13 insertions(+), 17 deletions(-) diff --git a/x/compute/internal/keeper/secret_contracts_test.go b/x/compute/internal/keeper/secret_contracts_test.go index d96b25c6c..16286099f 100644 --- a/x/compute/internal/keeper/secret_contracts_test.go +++ b/x/compute/internal/keeper/secret_contracts_test.go @@ -603,23 +603,19 @@ func TestCallbackSanity(t *testing.T) { _, _, data, execEvents, _, err := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, fmt.Sprintf(`{"a":{"contract_addr":"%s","code_hash":"%s","x":2,"y":3}}`, contractAddress.String(), codeHash), true, testContract.IsCosmWasmV1, defaultGasForTests, 0) require.Empty(t, err) - require.Equal(t, - []ContractEvent{ - { - {Key: "contract_address", Value: contractAddress.String()}, - {Key: "banana", Value: "🍌"}, - }, - { - {Key: "contract_address", Value: contractAddress.String()}, - {Key: "kiwi", Value: "🥝"}, - }, - { - {Key: "contract_address", Value: contractAddress.String()}, - {Key: "watermelon", Value: "🍉"}, - }, - }, - execEvents, - ) + require.Equal(t, len(execEvents), 3) + require.Equal(t, len(execEvents[0]), 2) + require.Equal(t, len(execEvents[1]), 2) + require.Equal(t, len(execEvents[2]), 2) + + require.Contains(t, execEvents[0], v010cosmwasm.LogAttribute{Key: "contract_address", Value: contractAddress.String()}) + require.Contains(t, execEvents[1], v010cosmwasm.LogAttribute{Key: "contract_address", Value: contractAddress.String()}) + require.Contains(t, execEvents[2], v010cosmwasm.LogAttribute{Key: "contract_address", Value: contractAddress.String()}) + + require.Contains(t, execEvents[0], v010cosmwasm.LogAttribute{Key: "banana", Value: "🍌"}) + require.Contains(t, execEvents[1], v010cosmwasm.LogAttribute{Key: "kiwi", Value: "🥝"}) + require.Contains(t, execEvents[2], v010cosmwasm.LogAttribute{Key: "watermelon", Value: "🍉"}) + require.Equal(t, []byte{2, 3}, data) }) } From 5185c9a2d90a4fd9bacece5ddc4c1452827db33f Mon Sep 17 00:00:00 2001 From: Assaf Morami Date: Thu, 25 Aug 2022 02:11:09 +0300 Subject: [PATCH 70/93] Fix all go-test that relied on events being ordered --- Makefile | 2 +- .../internal/keeper/secret_contracts_test.go | 402 ++++++++++++------ 2 files changed, 266 insertions(+), 138 deletions(-) diff --git a/Makefile b/Makefile index 364e9b530..249c3c278 100644 --- a/Makefile +++ b/Makefile @@ -361,7 +361,7 @@ go-tests: build-test-contract cp ./cosmwasm/enclaves/execute/librust_cosmwasm_enclave.signed.so ./x/compute/internal/keeper rm -rf ./x/compute/internal/keeper/.sgx_secrets mkdir -p ./x/compute/internal/keeper/.sgx_secrets - GOMAXPROCS=8 SGX_MODE=SW SCRT_SGX_STORAGE='./' go test -failfast -timeout 2400s -v ./x/compute/internal/... $(GO_TEST_ARGS) + GOMAXPROCS=8 SGX_MODE=SW SCRT_SGX_STORAGE='./' go test -failfast -timeout 40m -v ./x/compute/internal/... $(GO_TEST_ARGS) go-tests-hw: build-test-contract # empty BUILD_PROFILE means debug mode which compiles faster diff --git a/x/compute/internal/keeper/secret_contracts_test.go b/x/compute/internal/keeper/secret_contracts_test.go index 16286099f..38f2bb66f 100644 --- a/x/compute/internal/keeper/secret_contracts_test.go +++ b/x/compute/internal/keeper/secret_contracts_test.go @@ -582,6 +582,33 @@ func initHelperImpl( return nonce, ctx, contractAddress, wasmEvents, cosmwasm.StdError{} } +// requireEvents checks events output +// Events are now sorted (since wasmd v0.28), +// but for us they're sorted while encrypted so when testing with random encryption keys +// this is non-deterministic +func requireEvents(t *testing.T, a, b []ContractEvent) { + require.Equal(t, len(a), len(b)) + + for i := range b { + require.Equal(t, len(a[i]), len(b[i])) + for j := range b[i] { + require.Contains(t, a[i], b[i][j]) + } + } +} + +// requireLogAttributes checks events output +// Events are now sorted (since wasmd v0.28), +// but for us they're sorted while encrypted so when testing with random encryption keys +// this is non-deterministic +func requireLogAttributes(t *testing.T, a, b []v010cosmwasm.LogAttribute) { + require.Equal(t, len(a), len(b)) + + for i := range b { + require.Contains(t, a, b[i]) + } +} + func TestCallbackSanity(t *testing.T) { for _, testContract := range testContracts { t.Run(testContract.CosmWasmVersion, func(t *testing.T) { @@ -591,30 +618,36 @@ func TestCallbackSanity(t *testing.T) { _, _, contractAddress, initEvents, err := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, testContract.IsCosmWasmV1, defaultGasForTests) require.Empty(t, err) - require.Equal(t, + requireEvents(t, + initEvents, []ContractEvent{ { {Key: "contract_address", Value: contractAddress.String()}, {Key: "init", Value: "🌈"}, }, }, - initEvents, ) _, _, data, execEvents, _, err := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, fmt.Sprintf(`{"a":{"contract_addr":"%s","code_hash":"%s","x":2,"y":3}}`, contractAddress.String(), codeHash), true, testContract.IsCosmWasmV1, defaultGasForTests, 0) require.Empty(t, err) - require.Equal(t, len(execEvents), 3) - require.Equal(t, len(execEvents[0]), 2) - require.Equal(t, len(execEvents[1]), 2) - require.Equal(t, len(execEvents[2]), 2) - require.Contains(t, execEvents[0], v010cosmwasm.LogAttribute{Key: "contract_address", Value: contractAddress.String()}) - require.Contains(t, execEvents[1], v010cosmwasm.LogAttribute{Key: "contract_address", Value: contractAddress.String()}) - require.Contains(t, execEvents[2], v010cosmwasm.LogAttribute{Key: "contract_address", Value: contractAddress.String()}) - - require.Contains(t, execEvents[0], v010cosmwasm.LogAttribute{Key: "banana", Value: "🍌"}) - require.Contains(t, execEvents[1], v010cosmwasm.LogAttribute{Key: "kiwi", Value: "🥝"}) - require.Contains(t, execEvents[2], v010cosmwasm.LogAttribute{Key: "watermelon", Value: "🍉"}) + requireEvents(t, + []ContractEvent{ + { + {Key: "contract_address", Value: contractAddress.String()}, + {Key: "banana", Value: "🍌"}, + }, + { + {Key: "contract_address", Value: contractAddress.String()}, + {Key: "kiwi", Value: "🥝"}, + }, + { + {Key: "contract_address", Value: contractAddress.String()}, + {Key: "watermelon", Value: "🍉"}, + }, + }, + execEvents, + ) require.Equal(t, []byte{2, 3}, data) }) @@ -646,7 +679,7 @@ func TestSanity(t *testing.T) { require.Empty(t, err) require.Empty(t, data) - require.Equal(t, + requireEvents(t, []ContractEvent{ { {Key: "contract_address", Value: contractAddress.String()}, @@ -676,7 +709,7 @@ func TestInitLogs(t *testing.T) { _, _, contractAddress, initEvents, initErr := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, testContract.IsCosmWasmV1, defaultGasForTests) require.Empty(t, initErr) require.Equal(t, 1, len(initEvents)) - require.Equal(t, + requireEvents(t, []ContractEvent{ { {Key: "contract_address", Value: contractAddress.String()}, @@ -700,7 +733,7 @@ func TestEmptyLogKeyValue(t *testing.T) { _, _, _, execEvents, _, execErr := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"empty_log_key_value":{}}`, true, testContract.IsCosmWasmV1, defaultGasForTests, 0) require.Empty(t, execErr) - require.Equal(t, + requireEvents(t, []ContractEvent{ { {Key: "contract_address", Value: contractAddress.String()}, @@ -792,7 +825,7 @@ func TestCallbackFromInitAndCallbackEvents(t *testing.T) { _, _, firstContractAddress, initEvents, initErr := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, testContract.IsCosmWasmV1, defaultGasForTests) require.Empty(t, initErr) - require.Equal(t, + requireEvents(t, []ContractEvent{ { {Key: "contract_address", Value: firstContractAddress.String()}, @@ -806,7 +839,7 @@ func TestCallbackFromInitAndCallbackEvents(t *testing.T) { _, _, contractAddress, initEvents, initErr := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, fmt.Sprintf(`{"callback":{"contract_addr":"%s", "code_hash": "%s"}}`, firstContractAddress.String(), codeHash), true, testContract.IsCosmWasmV1, defaultGasForTests) require.Empty(t, initErr) - require.Equal(t, + requireEvents(t, []ContractEvent{ { {Key: "contract_address", Value: contractAddress.String()}, @@ -1317,20 +1350,25 @@ func TestExecCallbackToInit(t *testing.T) { require.Empty(t, execData) require.Equal(t, 2, len(execEvents)) - require.Equal(t, + requireLogAttributes(t, ContractEvent{ {Key: "contract_address", Value: contractAddress.String()}, {Key: "instantiating a new contract", Value: "🪂"}, }, execEvents[0], ) - require.Equal(t, + require.Contains(t, + execEvents[1], v010cosmwasm.LogAttribute{Key: "init", Value: "🌈"}, - execEvents[1][1], ) - require.Equal(t, "contract_address", execEvents[1][0].Key) - - secondContractAddressBech32 := execEvents[1][0].Value + var secondContractAddressBech32 string + for _, v := range execEvents[1] { + if v.Key == "contract_address" { + secondContractAddressBech32 = v.Value + break + } + } + require.NotEmpty(t, secondContractAddressBech32) secondContractAddress, err := sdk.AccAddressFromBech32(secondContractAddressBech32) require.NoError(t, err) @@ -1352,20 +1390,26 @@ func TestInitCallbackToInit(t *testing.T) { require.Empty(t, initErr) require.Equal(t, 2, len(initEvents)) - require.Equal(t, + requireLogAttributes(t, ContractEvent{ {Key: "contract_address", Value: contractAddress.String()}, {Key: "instantiating a new contract from init!", Value: "🐙"}, }, initEvents[0], ) - require.Equal(t, + + require.Contains(t, + initEvents[1], v010cosmwasm.LogAttribute{Key: "init", Value: "🌈"}, - initEvents[1][1], ) - require.Equal(t, "contract_address", initEvents[1][0].Key) - - secondContractAddressBech32 := initEvents[1][0].Value + var secondContractAddressBech32 string + for _, v := range initEvents[1] { + if v.Key == "contract_address" { + secondContractAddressBech32 = v.Value + break + } + } + require.NotEmpty(t, secondContractAddressBech32) secondContractAddress, err := sdk.AccAddressFromBech32(secondContractAddressBech32) require.NoError(t, err) @@ -1789,7 +1833,7 @@ func TestMsgSenderInCallback(t *testing.T) { _, _, _, events, _, err := execHelper(t, keeper, ctx, addr, walletA, privKeyA, fmt.Sprintf(`{"callback_to_log_msg_sender":{"to":"%s","code_hash":"%s"}}`, addr.String(), codeHash), true, testContract.IsCosmWasmV1, defaultGasForTests, 0) require.Empty(t, err) - require.Equal(t, []ContractEvent{ + requireEvents(t, []ContractEvent{ { {Key: "contract_address", Value: addr.String()}, {Key: "hi", Value: "hey"}, @@ -1872,7 +1916,7 @@ func TestQueryRecursionLimitEnforcedInInits(t *testing.T) { require.Nil(t, err.GenericErr) - require.Equal(t, []ContractEvent{ + requireEvents(t, []ContractEvent{ { {Key: "contract_address", Value: addr.String()}, {Key: "message", Value: "Recursion limit was correctly enforced"}, @@ -2017,7 +2061,16 @@ func TestContractSendFundsToInitCallback(t *testing.T) { contractCoinsAfter := keeper.bankKeeper.GetAllBalances(ctx, addr) walletCoinsAfter := keeper.bankKeeper.GetAllBalances(ctx, walletA) - newContract, err := sdk.AccAddressFromBech32(execEvents[1][0].Value) + var newContractBech32 string + for _, v := range execEvents[1] { + if v.Key == "contract_address" { + newContractBech32 = v.Value + break + } + } + require.NotEmpty(t, newContractBech32) + + newContract, err := sdk.AccAddressFromBech32(newContractBech32) require.NoError(t, err) newContractCoins := keeper.bankKeeper.GetAllBalances(ctx, newContract) @@ -2402,14 +2455,24 @@ func TestCodeHashInitCallInit(t *testing.T) { _, _, addr, events, err := initHelperImpl(t, keeper, ctx, codeID, walletA, privKeyA, fmt.Sprintf(`{"call_to_init":{"code_id":%d,"code_hash":"%s","msg":"%s","label":"1"}}`, codeID, codeHash, `{\"nop\":{}}`), true, testContract.IsCosmWasmV1, defaultGasForTests, 2, sdk.NewCoins()) require.Empty(t, err) - require.Equal(t, + + var newContractBech32 string + for _, v := range events[1] { + if v.Key == "contract_address" { + newContractBech32 = v.Value + break + } + } + require.NotEmpty(t, newContractBech32) + + requireEvents(t, []ContractEvent{ { {Key: "contract_address", Value: addr.String()}, {Key: "a", Value: "a"}, }, { - {Key: "contract_address", Value: events[1][0].Value}, + {Key: "contract_address", Value: newContractBech32}, {Key: "init", Value: "🌈"}, }, }, @@ -2468,7 +2531,7 @@ func TestCodeHashInitCallExec(t *testing.T) { _, _, addr2, events, err := initHelperImpl(t, keeper, ctx, codeID, walletA, privKeyA, fmt.Sprintf(`{"call_to_exec":{"addr":"%s","code_hash":"%s","msg":"%s"}}`, addr.String(), codeHash, `{\"c\":{\"x\":1,\"y\":1}}`), true, testContract.IsCosmWasmV1, defaultGasForTests, 2, sdk.NewCoins()) require.Empty(t, err) - require.Equal(t, + requireEvents(t, []ContractEvent{ { {Key: "contract_address", Value: addr2.String()}, @@ -2534,7 +2597,7 @@ func TestCodeHashInitCallQuery(t *testing.T) { _, _, addr2, events, err := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, fmt.Sprintf(`{"call_to_query":{"addr":"%s","code_hash":"%s","msg":"%s"}}`, addr.String(), codeHash, `{\"receive_external_query\":{\"num\":1}}`), true, testContract.IsCosmWasmV1, defaultGasForTests) require.Empty(t, err) - require.Equal(t, + requireEvents(t, []ContractEvent{ { {Key: "contract_address", Value: addr2.String()}, @@ -2596,14 +2659,24 @@ func TestCodeHashExecCallInit(t *testing.T) { _, _, _, events, _, err := execHelperImpl(t, keeper, ctx, addr, walletA, privKeyA, fmt.Sprintf(`{"call_to_init":{"code_id":%d,"code_hash":"%s","msg":"%s","label":"1"}}`, codeID, codeHash, `{\"nop\":{}}`), true, testContract.IsCosmWasmV1, defaultGasForTests, 0, 2) require.Empty(t, err) - require.Equal(t, + + var newContractBech32 string + for _, v := range events[1] { + if v.Key == "contract_address" { + newContractBech32 = v.Value + break + } + } + require.NotEmpty(t, newContractBech32) + + requireEvents(t, []ContractEvent{ { {Key: "contract_address", Value: addr.String()}, {Key: "a", Value: "a"}, }, { - {Key: "contract_address", Value: events[1][0].Value}, + {Key: "contract_address", Value: newContractBech32}, {Key: "init", Value: "🌈"}, }, }, @@ -2688,14 +2761,24 @@ func TestCodeHashExecCallExec(t *testing.T) { _, _, _, events, _, err := execHelper(t, keeper, ctx, addr, walletA, privKeyA, fmt.Sprintf(`{"call_to_exec":{"addr":"%s","code_hash":"%s","msg":"%s"}}`, addr, codeHash, `{\"c\":{\"x\":1,\"y\":1}}`), true, testContract.IsCosmWasmV1, defaultGasForTests, 0) require.Empty(t, err) - require.Equal(t, + + var newContractBech32 string + for _, v := range events[1] { + if v.Key == "contract_address" { + newContractBech32 = v.Value + break + } + } + require.NotEmpty(t, newContractBech32) + + requireEvents(t, []ContractEvent{ { {Key: "contract_address", Value: addr.String()}, {Key: "b", Value: "b"}, }, { - {Key: "contract_address", Value: events[1][0].Value}, + {Key: "contract_address", Value: newContractBech32}, {Key: "watermelon", Value: "🍉"}, }, }, @@ -2779,7 +2862,7 @@ func TestCodeHashExecCallQuery(t *testing.T) { _, _, _, events, _, err := execHelper(t, keeper, ctx, addr, walletA, privKeyA, fmt.Sprintf(`{"call_to_query":{"addr":"%s","code_hash":"%s","msg":"%s"}}`, addr.String(), codeHash, `{\"receive_external_query\":{\"num\":1}}`), true, testContract.IsCosmWasmV1, defaultGasForTests, 0) require.Empty(t, err) - require.Equal(t, + requireEvents(t, []ContractEvent{ { {Key: "contract_address", Value: addr.String()}, @@ -2906,7 +2989,7 @@ func TestEncryptedAndPlaintextLogs(t *testing.T) { _, _, _, events, _, err := execHelperImpl(t, keeper, ctx, addr, walletA, privKeyA, "{}", true, false, defaultGasForTests, 0, 1) require.Empty(t, err) - require.Equal(t, + requireEvents(t, []ContractEvent{ { {Key: "contract_address", Value: addr.String()}, @@ -2933,7 +3016,7 @@ func TestSecp256k1Verify(t *testing.T) { _, _, _, events, _, err := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"secp256k1_verify":{"iterations":1,"pubkey":"A0ZGrlBHMWtCMNAIbIrOxofwCxzZ0dxjT2yzWKwKmo//","sig":"/hZeEYHs9trj+Akeb+7p3UAtXjcDNYP9/D/hj/ALIUAG9bfrJltxkfpMz/9Jn5K3c5QjLuvaNT2jgr7P/AEW8A==","msg_hash":"ARp3VEHssUlDEwoW8AzdQYGKg90ENy8yWePKcjfjzao="}}`, true, testContract.IsCosmWasmV1, defaultGasForTests, 0) require.Empty(t, err) - require.Equal(t, + requireEvents(t, []ContractEvent{ { {Key: "contract_address", Value: contractAddress.String()}, @@ -2947,7 +3030,7 @@ func TestSecp256k1Verify(t *testing.T) { _, _, _, events, _, err := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"secp256k1_verify":{"iterations":1,"pubkey":"BEZGrlBHMWtCMNAIbIrOxofwCxzZ0dxjT2yzWKwKmo///ne03QpL+5WFHztzVceB3WD4QY/Ipl0UkHr/R8kDpVk=","sig":"/hZeEYHs9trj+Akeb+7p3UAtXjcDNYP9/D/hj/ALIUAG9bfrJltxkfpMz/9Jn5K3c5QjLuvaNT2jgr7P/AEW8A==","msg_hash":"ARp3VEHssUlDEwoW8AzdQYGKg90ENy8yWePKcjfjzao="}}`, true, testContract.IsCosmWasmV1, defaultGasForTests, 0) require.Empty(t, err) - require.Equal(t, + requireEvents(t, []ContractEvent{ { {Key: "contract_address", Value: contractAddress.String()}, @@ -2961,7 +3044,7 @@ func TestSecp256k1Verify(t *testing.T) { _, _, _, events, _, err := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"secp256k1_verify":{"iterations":1,"pubkey":"A0ZGrlBHMWtCMNAIbIrOxofwCxzZ0dxjT2yzWKwKmo//","sig":"/hZeEYHs9trj+Akeb+7p3UAtXjcDNYP9/D/hj/ALIUAG9bfrJltxkfpMz/9Jn5K3c5QjLuvaNT2jgr7P/AEW8A==","msg_hash":"ARp3VEHssUlDEwoW8AzdQYGKg90ENy8yWePKcjfjzas="}}`, true, testContract.IsCosmWasmV1, defaultGasForTests, 0) require.Empty(t, err) - require.Equal(t, + requireEvents(t, []ContractEvent{ { {Key: "contract_address", Value: contractAddress.String()}, @@ -2975,7 +3058,7 @@ func TestSecp256k1Verify(t *testing.T) { _, _, _, events, _, err := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"secp256k1_verify":{"iterations":1,"pubkey":"BEZGrlBHMWtCMNAIbIrOxofwCxzZ0dxjT2yzWKwKmo///ne03QpL+5WFHztzVceB3WD4QY/Ipl0UkHr/R8kDpVk=","sig":"/hZeEYHs9trj+Akeb+7p3UAtXjcDNYP9/D/hj/ALIUAG9bfrJltxkfpMz/9Jn5K3c5QjLuvaNT2jgr7P/AEW8A==","msg_hash":"ARp3VEHssUlDEwoW8AzdQYGKg90ENy8yWePKcjfjzas="}}`, true, testContract.IsCosmWasmV1, defaultGasForTests, 0) require.Empty(t, err) - require.Equal(t, + requireEvents(t, []ContractEvent{ { {Key: "contract_address", Value: contractAddress.String()}, @@ -2989,7 +3072,7 @@ func TestSecp256k1Verify(t *testing.T) { _, _, _, events, _, err := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"secp256k1_verify":{"iterations":1,"pubkey":"A0ZGrlBHMWtCMNAIbIrOxofwCxzZ0dxjT2yzWKwKmo//","sig":"rhZeEYHs9trj+Akeb+7p3UAtXjcDNYP9/D/hj/ALIUAG9bfrJltxkfpMz/9Jn5K3c5QjLuvaNT2jgr7P/AEW8A==","msg_hash":"ARp3VEHssUlDEwoW8AzdQYGKg90ENy8yWePKcjfjzao="}}`, true, testContract.IsCosmWasmV1, defaultGasForTests, 0) require.Empty(t, err) - require.Equal(t, + requireEvents(t, []ContractEvent{ { {Key: "contract_address", Value: contractAddress.String()}, @@ -3003,7 +3086,7 @@ func TestSecp256k1Verify(t *testing.T) { _, _, _, events, _, err := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"secp256k1_verify":{"iterations":1,"pubkey":"BEZGrlBHMWtCMNAIbIrOxofwCxzZ0dxjT2yzWKwKmo///ne03QpL+5WFHztzVceB3WD4QY/Ipl0UkHr/R8kDpVk=","sig":"rhZeEYHs9trj+Akeb+7p3UAtXjcDNYP9/D/hj/ALIUAG9bfrJltxkfpMz/9Jn5K3c5QjLuvaNT2jgr7P/AEW8A==","msg_hash":"ARp3VEHssUlDEwoW8AzdQYGKg90ENy8yWePKcjfjzao="}}`, true, testContract.IsCosmWasmV1, defaultGasForTests, 0) require.Empty(t, err) - require.Equal(t, + requireEvents(t, []ContractEvent{ { {Key: "contract_address", Value: contractAddress.String()}, @@ -3017,7 +3100,7 @@ func TestSecp256k1Verify(t *testing.T) { _, _, _, events, _, err := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"secp256k1_verify":{"iterations":1,"pubkey":"AoSdDHH9J0Bfb9pT8GFn+bW9cEVkgIh4bFsepMWmczXc","sig":"/hZeEYHs9trj+Akeb+7p3UAtXjcDNYP9/D/hj/ALIUAG9bfrJltxkfpMz/9Jn5K3c5QjLuvaNT2jgr7P/AEW8A==","msg_hash":"ARp3VEHssUlDEwoW8AzdQYGKg90ENy8yWePKcjfjzao="}}`, true, testContract.IsCosmWasmV1, defaultGasForTests, 0) require.Empty(t, err) - require.Equal(t, + requireEvents(t, []ContractEvent{ { {Key: "contract_address", Value: contractAddress.String()}, @@ -3031,7 +3114,7 @@ func TestSecp256k1Verify(t *testing.T) { _, _, _, events, _, err := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"secp256k1_verify":{"iterations":1,"pubkey":"BISdDHH9J0Bfb9pT8GFn+bW9cEVkgIh4bFsepMWmczXcFWl11YCgu65hzvNDQE2Qo1hwTMQ/42Xif8O/MrxzvxI=","sig":"/hZeEYHs9trj+Akeb+7p3UAtXjcDNYP9/D/hj/ALIUAG9bfrJltxkfpMz/9Jn5K3c5QjLuvaNT2jgr7P/AEW8A==","msg_hash":"ARp3VEHssUlDEwoW8AzdQYGKg90ENy8yWePKcjfjzao="}}`, true, testContract.IsCosmWasmV1, defaultGasForTests, 0) require.Empty(t, err) - require.Equal(t, + requireEvents(t, []ContractEvent{ { {Key: "contract_address", Value: contractAddress.String()}, @@ -3096,7 +3179,7 @@ func TestEd25519Verify(t *testing.T) { _, _, _, events, _, err := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"ed25519_verify":{"iterations":1,"pubkey":"LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","sig":"8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","msg":"YXNzYWYgd2FzIGhlcmU="}}`, true, testContract.IsCosmWasmV1, defaultGasForTests, 0) require.Empty(t, err) - require.Equal(t, + requireEvents(t, []ContractEvent{ { {Key: "contract_address", Value: contractAddress.String()}, @@ -3110,7 +3193,7 @@ func TestEd25519Verify(t *testing.T) { _, _, _, events, _, err := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"ed25519_verify":{"iterations":1,"pubkey":"LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","sig":"8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","msg":"YXNzYWYgd2FzIGhlcmUK"}}`, true, testContract.IsCosmWasmV1, defaultGasForTests, 0) require.Empty(t, err) - require.Equal(t, + requireEvents(t, []ContractEvent{ { {Key: "contract_address", Value: contractAddress.String()}, @@ -3124,7 +3207,7 @@ func TestEd25519Verify(t *testing.T) { _, _, _, events, _, err := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"ed25519_verify":{"iterations":1,"pubkey":"LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","sig":"8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDw==","msg":"YXNzYWYgd2FzIGhlcmU="}}`, true, testContract.IsCosmWasmV1, defaultGasForTests, 0) require.Empty(t, err) - require.Equal(t, + requireEvents(t, []ContractEvent{ { {Key: "contract_address", Value: contractAddress.String()}, @@ -3138,7 +3221,7 @@ func TestEd25519Verify(t *testing.T) { _, _, _, events, _, err := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"ed25519_verify":{"iterations":1,"pubkey":"DV1lgRdKw7nt4hvl8XkGZXMzU9S3uM9NLTK0h0qMbUs=","sig":"8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","msg":"YXNzYWYgd2FzIGhlcmU="}}`, true, testContract.IsCosmWasmV1, defaultGasForTests, 0) require.Empty(t, err) - require.Equal(t, + requireEvents(t, []ContractEvent{ { {Key: "contract_address", Value: contractAddress.String()}, @@ -3165,7 +3248,7 @@ func TestEd25519BatchVerify(t *testing.T) { _, _, _, events, _, err := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"ed25519_batch_verify":{"iterations":1,"pubkeys":["LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA="],"sigs":["8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg=="],"msgs":["YXNzYWYgd2FzIGhlcmU="]}}`, true, testContract.IsCosmWasmV1, defaultGasForTests, 0) require.Empty(t, err) - require.Equal(t, + requireEvents(t, []ContractEvent{ { {Key: "contract_address", Value: contractAddress.String()}, @@ -3179,7 +3262,7 @@ func TestEd25519BatchVerify(t *testing.T) { _, _, _, events, _, err := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"ed25519_batch_verify":{"iterations":1,"pubkeys":["LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA="],"sigs":["8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg=="],"msgs":["YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU="]}}`, true, testContract.IsCosmWasmV1, defaultGasForTests, 0) require.Empty(t, err) - require.Equal(t, + requireEvents(t, []ContractEvent{ { {Key: "contract_address", Value: contractAddress.String()}, @@ -3193,7 +3276,7 @@ func TestEd25519BatchVerify(t *testing.T) { _, _, _, events, _, err := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"ed25519_batch_verify":{"iterations":1,"pubkeys":["DV1lgRdKw7nt4hvl8XkGZXMzU9S3uM9NLTK0h0qMbUs="],"sigs":["8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg=="],"msgs":["YXNzYWYgd2FzIGhlcmU="]}}`, true, testContract.IsCosmWasmV1, defaultGasForTests, 0) require.Empty(t, err) - require.Equal(t, + requireEvents(t, []ContractEvent{ { {Key: "contract_address", Value: contractAddress.String()}, @@ -3207,7 +3290,7 @@ func TestEd25519BatchVerify(t *testing.T) { _, _, _, events, _, err := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"ed25519_batch_verify":{"iterations":1,"pubkeys":["LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA="],"sigs":["8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg=="],"msgs":["YXNzYWYgd2FzIGhlcmUK"]}}`, true, testContract.IsCosmWasmV1, defaultGasForTests, 0) require.Empty(t, err) - require.Equal(t, + requireEvents(t, []ContractEvent{ { {Key: "contract_address", Value: contractAddress.String()}, @@ -3221,7 +3304,7 @@ func TestEd25519BatchVerify(t *testing.T) { _, _, _, events, _, err := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"ed25519_batch_verify":{"iterations":1,"pubkeys":["LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA="],"sigs":["8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDw=="],"msgs":["YXNzYWYgd2FzIGhlcmU="]}}`, true, testContract.IsCosmWasmV1, defaultGasForTests, 0) require.Empty(t, err) - require.Equal(t, + requireEvents(t, []ContractEvent{ { {Key: "contract_address", Value: contractAddress.String()}, @@ -3235,7 +3318,7 @@ func TestEd25519BatchVerify(t *testing.T) { _, _, _, events, _, err := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"ed25519_batch_verify":{"iterations":1,"pubkeys":["LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA="],"sigs":[],"msgs":[]}}`, true, testContract.IsCosmWasmV1, defaultGasForTests, 0) require.Empty(t, err) - require.Equal(t, + requireEvents(t, []ContractEvent{ { {Key: "contract_address", Value: contractAddress.String()}, @@ -3249,7 +3332,7 @@ func TestEd25519BatchVerify(t *testing.T) { _, _, _, events, _, err := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"ed25519_batch_verify":{"iterations":1,"pubkeys":[],"sigs":[],"msgs":[]}}`, true, testContract.IsCosmWasmV1, defaultGasForTests, 0) require.Empty(t, err) - require.Equal(t, + requireEvents(t, []ContractEvent{ { {Key: "contract_address", Value: contractAddress.String()}, @@ -3263,7 +3346,7 @@ func TestEd25519BatchVerify(t *testing.T) { _, _, _, events, _, err := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"ed25519_batch_verify":{"iterations":1,"pubkeys":[],"sigs":[],"msgs":["YXNzYWYgd2FzIGhlcmUK"]}}`, true, testContract.IsCosmWasmV1, defaultGasForTests, 0) require.Empty(t, err) - require.Equal(t, + requireEvents(t, []ContractEvent{ { {Key: "contract_address", Value: contractAddress.String()}, @@ -3277,7 +3360,7 @@ func TestEd25519BatchVerify(t *testing.T) { _, _, _, events, _, err := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"ed25519_batch_verify":{"iterations":1,"pubkeys":["LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","2ukhmWRNmcgCrB9fpLP9/HZVuJn6AhpITf455F4GsbM="],"sigs":["8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","bp/N4Ub2WFk9SE9poZVEanU1l46WMrFkTd5wQIXi6QJKjvZUi7+GTzmTe8y2yzgpBI+GWQmt0/QwYbnSVxq/Cg=="],"msgs":["YXNzYWYgd2FzIGhlcmU="]}}`, true, testContract.IsCosmWasmV1, defaultGasForTests, 0) require.Empty(t, err) - require.Equal(t, + requireEvents(t, []ContractEvent{ { {Key: "contract_address", Value: contractAddress.String()}, @@ -3291,7 +3374,7 @@ func TestEd25519BatchVerify(t *testing.T) { _, _, _, events, _, err := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"ed25519_batch_verify":{"iterations":1,"pubkeys":["2ukhmWRNmcgCrB9fpLP9/HZVuJn6AhpITf455F4GsbM="],"sigs":["bp/N4Ub2WFk9SE9poZVEanU1l46WMrFkTd5wQIXi6QJKjvZUi7+GTzmTe8y2yzgpBI+GWQmt0/QwYbnSVxq/Cg==","uuNxLEzAYDbuJ+BiYN94pTqhD7UhvCJNbxAbnWz0B9DivkPXmqIULko0DddP2/tVXPtjJ90J20faiWCEC3QkDg=="],"msgs":["YXNzYWYgd2FzIGhlcmU=","cGVhY2Ugb3V0"]}}`, true, testContract.IsCosmWasmV1, defaultGasForTests, 0) require.Empty(t, err) - require.Equal(t, + requireEvents(t, []ContractEvent{ { {Key: "contract_address", Value: contractAddress.String()}, @@ -3317,7 +3400,7 @@ func TestSecp256k1RecoverPubkey(t *testing.T) { _, _, _, events, _, err := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"secp256k1_recover_pubkey":{"iterations":1,"recovery_param":0,"sig":"/hZeEYHs9trj+Akeb+7p3UAtXjcDNYP9/D/hj/ALIUAG9bfrJltxkfpMz/9Jn5K3c5QjLuvaNT2jgr7P/AEW8A==","msg_hash":"ARp3VEHssUlDEwoW8AzdQYGKg90ENy8yWePKcjfjzao="}}`, true, testContract.IsCosmWasmV1, defaultGasForTests, 0) require.Empty(t, err) - require.Equal(t, + requireEvents(t, []ContractEvent{ { {Key: "contract_address", Value: contractAddress.String()}, @@ -3330,7 +3413,7 @@ func TestSecp256k1RecoverPubkey(t *testing.T) { _, _, _, events, _, err = execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"secp256k1_recover_pubkey":{"iterations":1,"recovery_param":1,"sig":"/hZeEYHs9trj+Akeb+7p3UAtXjcDNYP9/D/hj/ALIUAG9bfrJltxkfpMz/9Jn5K3c5QjLuvaNT2jgr7P/AEW8A==","msg_hash":"ARp3VEHssUlDEwoW8AzdQYGKg90ENy8yWePKcjfjzao="}}`, true, testContract.IsCosmWasmV1, defaultGasForTests, 0) require.Empty(t, err) - require.Equal(t, + requireEvents(t, []ContractEvent{ { {Key: "contract_address", Value: contractAddress.String()}, @@ -3365,7 +3448,7 @@ func TestSecp256k1Sign(t *testing.T) { _, _, _, events, _, err = execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, fmt.Sprintf(`{"secp256k1_verify":{"iterations":1,"pubkey":"ArQojoh5TVlSSNA1HFlH5HcQsv0jnrpeE7hgwR/N46nS","sig":"%s","msg_hash":"K9vGEuzCYCUcIXlhMZu20ke2K4mJhreguYct5MqAzhA="}}`, signature), true, testContract.IsCosmWasmV1, defaultGasForTests, 0) require.Empty(t, err) - require.Equal(t, + requireEvents(t, []ContractEvent{ { {Key: "contract_address", Value: contractAddress.String()}, @@ -3400,7 +3483,7 @@ func TestEd25519Sign(t *testing.T) { _, _, _, events, _, err = execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, fmt.Sprintf(`{"ed25519_verify":{"iterations":1,"pubkey":"jh58UkC0FDsiupZBLdaqKUqYubJbk3LDaruZiJiy0Po=","sig":"%s","msg":"d2VuIG1vb24="}}`, signature), true, testContract.IsCosmWasmV1, defaultGasForTests, 0) require.Empty(t, err) - require.Equal(t, + requireEvents(t, []ContractEvent{ { {Key: "contract_address", Value: contractAddress.String()}, @@ -3531,7 +3614,17 @@ func TestInitCreateNewContract(t *testing.T) { _, _, _, ev, _, err := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"init_new_contract":{}}`, true, testContract.IsCosmWasmV1, math.MaxUint64, 0) require.Empty(t, err) - newContractAddress, Aerr := sdk.AccAddressFromBech32(ev[1][0].Value) + + var newContractBech32 string + for _, v := range ev[1] { + if v.Key == "contract_address" { + newContractBech32 = v.Value + break + } + } + require.NotEmpty(t, newContractBech32) + + newContractAddress, Aerr := sdk.AccAddressFromBech32(newContractBech32) require.Empty(t, Aerr) queryRes, qErr := queryHelper(t, keeper, ctx, contractAddress, `{"get":{}}`, true, true, math.MaxUint64) require.Empty(t, qErr) @@ -3864,7 +3957,16 @@ func TestSendFunds(t *testing.T) { require.Equal(t, test.balancesAfter, originCoinsAfter.String()) if destinationType == "init" && originType != "user" { - destinationAddr, _ = sdk.AccAddressFromBech32(wasmEvents[1][0].Value) + var newContractBech32 string + for _, v := range wasmEvents[1] { + if v.Key == "contract_address" { + newContractBech32 = v.Value + break + } + } + require.NotEmpty(t, newContractBech32) + + destinationAddr, _ = sdk.AccAddressFromBech32(newContractBech32) } destinationCoinsAfter := keeper.bankKeeper.GetAllBalances(ctx, destinationAddr) @@ -4160,7 +4262,17 @@ func TestV1InitV010ContractNoReply(t *testing.T) { _, _, _, ev, _, err := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, msg, true, true, math.MaxUint64, 0) require.Empty(t, err) - accAddress, err := sdk.AccAddressFromBech32(ev[1][0].Value) + + var newContractBech32 string + for _, v := range ev[1] { + if v.Key == "contract_address" { + newContractBech32 = v.Value + break + } + } + require.NotEmpty(t, newContractBech32) + + accAddress, err := sdk.AccAddressFromBech32(newContractBech32) require.Empty(t, err) queryRes, qErr := queryHelper(t, keeper, ctx, accAddress, `{"get_count_from_v1":{}}`, true, false, math.MaxUint64) @@ -4351,7 +4463,15 @@ func TestV010InitV1ContractFromInitWithOkResponse(t *testing.T) { require.Equal(t, queryRes, "10") require.Empty(t, err) - accAddress, err := sdk.AccAddressFromBech32(initEvents[1][0].Value) + var newContractBech32 string + for _, v := range initEvents[1] { + if v.Key == "contract_address" { + newContractBech32 = v.Value + break + } + } + require.NotEmpty(t, newContractBech32) + accAddress, err := sdk.AccAddressFromBech32(newContractBech32) require.Empty(t, err) queryRes, qErr = queryHelper(t, keeper, ctx, accAddress, `{"get_contract_version":{}}`, true, false, math.MaxUint64) @@ -4381,7 +4501,15 @@ func TestV010InitV1ContractFromExecuteWithOkResponse(t *testing.T) { require.Empty(t, execErr) require.Empty(t, execData) - accAddress, err := sdk.AccAddressFromBech32(execEvents[1][0].Value) + var newContractBech32 string + for _, v := range execEvents[1] { + if v.Key == "contract_address" { + newContractBech32 = v.Value + break + } + } + require.NotEmpty(t, newContractBech32) + accAddress, err := sdk.AccAddressFromBech32(newContractBech32) require.Empty(t, err) queryRes, qErr = queryHelper(t, keeper, ctx, accAddress, `{"get_contract_version":{}}`, true, false, math.MaxUint64) @@ -4451,7 +4579,7 @@ func TestV010QueryV1ContractFromInitWithOkResponse(t *testing.T) { _, _, contractAddress, _, err := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, true, defaultGasForTests) _, _, v010ContractAddress, events, err := initHelper(t, keeper, ctx, v010CodeID, walletA, privKeyA, fmt.Sprintf(`{"call_to_query":{"addr":"%s","code_hash":"%s","msg":"%s"}}`, contractAddress.String(), codeHash, `{\"receive_external_query_v1\":{\"num\":1}}`), true, true, defaultGasForTests) require.Empty(t, err) - require.Equal(t, + requireEvents(t, []ContractEvent{ { {Key: "contract_address", Value: v010ContractAddress.String()}, @@ -4476,7 +4604,7 @@ func TestV010QueryV1ContractFromExecuteWithOkResponse(t *testing.T) { _, _, _, events, _, err := execHelper(t, keeper, ctx, v010ContractAddress, walletA, privKeyA, fmt.Sprintf(`{"call_to_query":{"addr":"%s","code_hash":"%s","msg":"%s"}}`, contractAddress.String(), codeHash, `{\"receive_external_query_v1\":{\"num\":1}}`), true, true, defaultGasForTests, 0) require.Empty(t, err) - require.Equal(t, + requireEvents(t, []ContractEvent{ { {Key: "contract_address", Value: v010ContractAddress.String()}, @@ -4589,7 +4717,7 @@ func TestSendEncryptedAttributesFromInitWithoutSubmessageWithoutReply(t *testing _, _, contractAddress, events, err := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"add_attributes":{}}`, true, testContract.IsCosmWasmV1, defaultGasForTests) require.Empty(t, err) - require.Equal(t, + requireEvents(t, []ContractEvent{ { {Key: "contract_address", Value: contractAddress.String()}, @@ -4611,7 +4739,7 @@ func TestSendEncryptedAttributesFromInitWithSubmessageWithoutReply(t *testing.T) _, _, contractAddress, events, err := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"add_attributes_with_submessage":{"id":0}}`, true, testContract.IsCosmWasmV1, defaultGasForTests) require.Empty(t, err) - require.Equal(t, + requireEvents(t, []ContractEvent{ { {Key: "contract_address", Value: contractAddress.String()}, @@ -4636,7 +4764,7 @@ func TestV1SendsEncryptedAttributesFromInitWithSubmessageWithReply(t *testing.T) _, _, contractAddress, events, err := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"add_attributes_with_submessage":{"id":2200}}`, true, true, defaultGasForTests) require.Empty(t, err) - require.Equal(t, + requireEvents(t, []ContractEvent{ { {Key: "contract_address", Value: contractAddress.String()}, @@ -4668,7 +4796,7 @@ func TestSendEncryptedAttributesFromExecuteWithoutSubmessageWithoutReply(t *test _, _, _, events, _, err := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"add_attributes":{}}`, true, testContract.IsCosmWasmV1, defaultGasForTests, 0) require.Empty(t, err) - require.Equal(t, + requireEvents(t, []ContractEvent{ { {Key: "contract_address", Value: contractAddress.String()}, @@ -4692,7 +4820,7 @@ func TestSendEncryptedAttributesFromExecuteWithSubmessageWithoutReply(t *testing _, _, _, events, _, err := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"add_attributes_with_submessage":{"id":0}}`, true, testContract.IsCosmWasmV1, defaultGasForTests, 0) require.Empty(t, err) - require.Equal(t, + requireEvents(t, []ContractEvent{ { {Key: "contract_address", Value: contractAddress.String()}, @@ -4719,7 +4847,7 @@ func TestV1SendsEncryptedAttributesFromExecuteWithSubmessageWithReply(t *testing _, _, _, events, _, err := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"add_attributes_with_submessage":{"id":2200}}`, true, true, defaultGasForTests, 0) require.Empty(t, err) - require.Equal(t, + requireEvents(t, []ContractEvent{ { {Key: "contract_address", Value: contractAddress.String()}, @@ -4749,7 +4877,7 @@ func TestSendPlaintextFromInitWithoutSubmessageWithoutReply(t *testing.T) { _, _, contractAddress, events, err := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"add_plaintext_attributes":{}}`, true, testContract.IsCosmWasmV1, defaultGasForTests, true) require.Empty(t, err) - require.Equal(t, + requireEvents(t, []ContractEvent{ { {Key: "contract_address", Value: contractAddress.String()}, @@ -4771,7 +4899,7 @@ func TestSendPlaintextAttributesFromInitWithSubmessageWithoutReply(t *testing.T) _, _, contractAddress, events, err := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"add_plaintext_attributes_with_submessage":{"id":0}}`, true, testContract.IsCosmWasmV1, defaultGasForTests, true) require.Empty(t, err) - require.Equal(t, + requireEvents(t, []ContractEvent{ { {Key: "contract_address", Value: contractAddress.String()}, @@ -4796,7 +4924,7 @@ func TestV1SendsPlaintextAttributesFromInitWithSubmessageWithReply(t *testing.T) _, _, contractAddress, events, err := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"add_plaintext_attributes_with_submessage":{"id":2300}}`, true, true, defaultGasForTests, true) require.Empty(t, err) - require.Equal(t, + requireEvents(t, []ContractEvent{ { {Key: "contract_address", Value: contractAddress.String()}, @@ -4828,7 +4956,7 @@ func TestSendPlaintextAttributesFromExecuteWithoutSubmessageWithoutReply(t *test _, _, _, events, _, err := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"add_plaintext_attributes":{}}`, true, testContract.IsCosmWasmV1, defaultGasForTests, 0, true) require.Empty(t, err) - require.Equal(t, + requireEvents(t, []ContractEvent{ { {Key: "contract_address", Value: contractAddress.String()}, @@ -4852,7 +4980,7 @@ func TestSendPlaintextAttributesFromExecuteWithSubmessageWithoutReply(t *testing _, _, _, events, _, err := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"add_plaintext_attributes_with_submessage":{"id":0}}`, true, testContract.IsCosmWasmV1, defaultGasForTests, 0, true) require.Empty(t, err) - require.Equal(t, + requireEvents(t, []ContractEvent{ { {Key: "contract_address", Value: contractAddress.String()}, @@ -4879,7 +5007,7 @@ func TestV1SendsPlaintextAttributesFromExecuteWithSubmessageWithReply(t *testing _, _, _, events, _, err := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"add_plaintext_attributes_with_submessage":{"id":2300}}`, true, true, defaultGasForTests, 0, true) require.Empty(t, err) - require.Equal(t, + requireEvents(t, []ContractEvent{ { {Key: "contract_address", Value: contractAddress.String()}, @@ -4918,7 +5046,7 @@ func TestV1SendsEncryptedEventsFromInitWithoutSubmessageWithoutReply(t *testing. attrs, err := parseAndDecryptAttributes(e.Attributes, nonce, true) require.Empty(t, err) - require.Equal(t, + requireLogAttributes(t, []v010cosmwasm.LogAttribute{ {Key: "contract_address", Value: contractAddress.String()}, {Key: "attr1", Value: "🦄"}, @@ -4935,7 +5063,7 @@ func TestV1SendsEncryptedEventsFromInitWithoutSubmessageWithoutReply(t *testing. attrs, err := parseAndDecryptAttributes(e.Attributes, nonce, true) require.Empty(t, err) - require.Equal(t, + requireLogAttributes(t, []v010cosmwasm.LogAttribute{ {Key: "contract_address", Value: contractAddress.String()}, {Key: "attr3", Value: "🐙"}, @@ -4971,7 +5099,7 @@ func TestV1SendsEncryptedEventsFromInitWithSubmessageWithoutReply(t *testing.T) attrs, err := parseAndDecryptAttributes(e.Attributes, nonce, true) require.Empty(t, err) - require.Equal(t, + requireLogAttributes(t, []v010cosmwasm.LogAttribute{ {Key: "contract_address", Value: contractAddress.String()}, {Key: "attr1", Value: "🦄"}, @@ -4988,7 +5116,7 @@ func TestV1SendsEncryptedEventsFromInitWithSubmessageWithoutReply(t *testing.T) attrs, err := parseAndDecryptAttributes(e.Attributes, nonce, true) require.Empty(t, err) - require.Equal(t, + requireLogAttributes(t, []v010cosmwasm.LogAttribute{ {Key: "contract_address", Value: contractAddress.String()}, {Key: "attr3", Value: "🐙"}, @@ -5005,7 +5133,7 @@ func TestV1SendsEncryptedEventsFromInitWithSubmessageWithoutReply(t *testing.T) attrs, err := parseAndDecryptAttributes(e.Attributes, nonce, true) require.Empty(t, err) - require.Equal(t, + requireLogAttributes(t, []v010cosmwasm.LogAttribute{ {Key: "contract_address", Value: contractAddress.String()}, {Key: "attr1", Value: "🤯"}, @@ -5022,7 +5150,7 @@ func TestV1SendsEncryptedEventsFromInitWithSubmessageWithoutReply(t *testing.T) attrs, err := parseAndDecryptAttributes(e.Attributes, nonce, true) require.Empty(t, err) - require.Equal(t, + requireLogAttributes(t, []v010cosmwasm.LogAttribute{ {Key: "contract_address", Value: contractAddress.String()}, {Key: "attr3", Value: "😅"}, @@ -5062,7 +5190,7 @@ func TestV1SendsEncryptedEventsFromInitWithSubmessageWithReply(t *testing.T) { attrs, err := parseAndDecryptAttributes(e.Attributes, nonce, true) require.Empty(t, err) - require.Equal(t, + requireLogAttributes(t, []v010cosmwasm.LogAttribute{ {Key: "contract_address", Value: contractAddress.String()}, {Key: "attr1", Value: "🦄"}, @@ -5079,7 +5207,7 @@ func TestV1SendsEncryptedEventsFromInitWithSubmessageWithReply(t *testing.T) { attrs, err := parseAndDecryptAttributes(e.Attributes, nonce, true) require.Empty(t, err) - require.Equal(t, + requireLogAttributes(t, []v010cosmwasm.LogAttribute{ {Key: "contract_address", Value: contractAddress.String()}, {Key: "attr3", Value: "🐙"}, @@ -5096,7 +5224,7 @@ func TestV1SendsEncryptedEventsFromInitWithSubmessageWithReply(t *testing.T) { attrs, err := parseAndDecryptAttributes(e.Attributes, nonce, true) require.Empty(t, err) - require.Equal(t, + requireLogAttributes(t, []v010cosmwasm.LogAttribute{ {Key: "contract_address", Value: contractAddress.String()}, {Key: "attr1", Value: "🤯"}, @@ -5113,7 +5241,7 @@ func TestV1SendsEncryptedEventsFromInitWithSubmessageWithReply(t *testing.T) { attrs, err := parseAndDecryptAttributes(e.Attributes, nonce, true) require.Empty(t, err) - require.Equal(t, + requireLogAttributes(t, []v010cosmwasm.LogAttribute{ {Key: "contract_address", Value: contractAddress.String()}, {Key: "attr3", Value: "😅"}, @@ -5130,7 +5258,7 @@ func TestV1SendsEncryptedEventsFromInitWithSubmessageWithReply(t *testing.T) { attrs, err := parseAndDecryptAttributes(e.Attributes, nonce, true) require.Empty(t, err) - require.Equal(t, + requireLogAttributes(t, []v010cosmwasm.LogAttribute{ {Key: "contract_address", Value: contractAddress.String()}, {Key: "attr1", Value: "😗"}, @@ -5147,7 +5275,7 @@ func TestV1SendsEncryptedEventsFromInitWithSubmessageWithReply(t *testing.T) { attrs, err := parseAndDecryptAttributes(e.Attributes, nonce, true) require.Empty(t, err) - require.Equal(t, + requireLogAttributes(t, []v010cosmwasm.LogAttribute{ {Key: "contract_address", Value: contractAddress.String()}, {Key: "attr3", Value: "😉"}, @@ -5187,7 +5315,7 @@ func TestV1SendsEncryptedEventsFromExecuteWithoutSubmessageWithoutReply(t *testi attrs, err := parseAndDecryptAttributes(e.Attributes, nonce, true) require.Empty(t, err) - require.Equal(t, + requireLogAttributes(t, []v010cosmwasm.LogAttribute{ {Key: "contract_address", Value: contractAddress.String()}, {Key: "attr1", Value: "🦄"}, @@ -5204,7 +5332,7 @@ func TestV1SendsEncryptedEventsFromExecuteWithoutSubmessageWithoutReply(t *testi attrs, err := parseAndDecryptAttributes(e.Attributes, nonce, true) require.Empty(t, err) - require.Equal(t, + requireLogAttributes(t, []v010cosmwasm.LogAttribute{ {Key: "contract_address", Value: contractAddress.String()}, {Key: "attr3", Value: "🐙"}, @@ -5242,7 +5370,7 @@ func TestV1SendsEncryptedEventsFromExecuteWithSubmessageWithoutReply(t *testing. attrs, err := parseAndDecryptAttributes(e.Attributes, nonce, true) require.Empty(t, err) - require.Equal(t, + requireLogAttributes(t, []v010cosmwasm.LogAttribute{ {Key: "contract_address", Value: contractAddress.String()}, {Key: "attr1", Value: "🦄"}, @@ -5259,7 +5387,7 @@ func TestV1SendsEncryptedEventsFromExecuteWithSubmessageWithoutReply(t *testing. attrs, err := parseAndDecryptAttributes(e.Attributes, nonce, true) require.Empty(t, err) - require.Equal(t, + requireLogAttributes(t, []v010cosmwasm.LogAttribute{ {Key: "contract_address", Value: contractAddress.String()}, {Key: "attr3", Value: "🐙"}, @@ -5276,7 +5404,7 @@ func TestV1SendsEncryptedEventsFromExecuteWithSubmessageWithoutReply(t *testing. attrs, err := parseAndDecryptAttributes(e.Attributes, nonce, true) require.Empty(t, err) - require.Equal(t, + requireLogAttributes(t, []v010cosmwasm.LogAttribute{ {Key: "contract_address", Value: contractAddress.String()}, {Key: "attr1", Value: "🤯"}, @@ -5293,7 +5421,7 @@ func TestV1SendsEncryptedEventsFromExecuteWithSubmessageWithoutReply(t *testing. attrs, err := parseAndDecryptAttributes(e.Attributes, nonce, true) require.Empty(t, err) - require.Equal(t, + requireLogAttributes(t, []v010cosmwasm.LogAttribute{ {Key: "contract_address", Value: contractAddress.String()}, {Key: "attr3", Value: "😅"}, @@ -5335,7 +5463,7 @@ func TestV1SendsEncryptedEventsFromExecuteWithSubmessageWithReply(t *testing.T) attrs, err := parseAndDecryptAttributes(e.Attributes, nonce, true) require.Empty(t, err) - require.Equal(t, + requireLogAttributes(t, []v010cosmwasm.LogAttribute{ {Key: "contract_address", Value: contractAddress.String()}, {Key: "attr1", Value: "🦄"}, @@ -5352,7 +5480,7 @@ func TestV1SendsEncryptedEventsFromExecuteWithSubmessageWithReply(t *testing.T) attrs, err := parseAndDecryptAttributes(e.Attributes, nonce, true) require.Empty(t, err) - require.Equal(t, + requireLogAttributes(t, []v010cosmwasm.LogAttribute{ {Key: "contract_address", Value: contractAddress.String()}, {Key: "attr3", Value: "🐙"}, @@ -5369,7 +5497,7 @@ func TestV1SendsEncryptedEventsFromExecuteWithSubmessageWithReply(t *testing.T) attrs, err := parseAndDecryptAttributes(e.Attributes, nonce, true) require.Empty(t, err) - require.Equal(t, + requireLogAttributes(t, []v010cosmwasm.LogAttribute{ {Key: "contract_address", Value: contractAddress.String()}, {Key: "attr1", Value: "🤯"}, @@ -5386,7 +5514,7 @@ func TestV1SendsEncryptedEventsFromExecuteWithSubmessageWithReply(t *testing.T) attrs, err := parseAndDecryptAttributes(e.Attributes, nonce, true) require.Empty(t, err) - require.Equal(t, + requireLogAttributes(t, []v010cosmwasm.LogAttribute{ {Key: "contract_address", Value: contractAddress.String()}, {Key: "attr3", Value: "😅"}, @@ -5403,7 +5531,7 @@ func TestV1SendsEncryptedEventsFromExecuteWithSubmessageWithReply(t *testing.T) attrs, err := parseAndDecryptAttributes(e.Attributes, nonce, true) require.Empty(t, err) - require.Equal(t, + requireLogAttributes(t, []v010cosmwasm.LogAttribute{ {Key: "contract_address", Value: contractAddress.String()}, {Key: "attr1", Value: "😗"}, @@ -5420,7 +5548,7 @@ func TestV1SendsEncryptedEventsFromExecuteWithSubmessageWithReply(t *testing.T) attrs, err := parseAndDecryptAttributes(e.Attributes, nonce, true) require.Empty(t, err) - require.Equal(t, + requireLogAttributes(t, []v010cosmwasm.LogAttribute{ {Key: "contract_address", Value: contractAddress.String()}, {Key: "attr3", Value: "😉"}, @@ -5457,7 +5585,7 @@ func TestV1SendsMixedLogsFromInitWithoutSubmessageWithoutReply(t *testing.T) { attrs, err := parseAndDecryptAttributes(e.Attributes, nonce, false) require.Empty(t, err) - require.Equal(t, + requireLogAttributes(t, []v010cosmwasm.LogAttribute{ {Key: "contract_address", Value: contractAddress.String()}, {Key: "attr1", Value: "🦄"}, @@ -5472,7 +5600,7 @@ func TestV1SendsMixedLogsFromInitWithoutSubmessageWithoutReply(t *testing.T) { require.True(t, hadCyber1) - require.Equal(t, + requireEvents(t, []ContractEvent{ { {Key: "contract_address", Value: contractAddress.String()}, @@ -5501,7 +5629,7 @@ func TestV1SendsMixedAttributesAndEventsFromInitWithSubmessageWithoutReply(t *te attrs, err := parseAndDecryptAttributes(e.Attributes, nonce, true) require.Empty(t, err) - require.Equal(t, + requireLogAttributes(t, []v010cosmwasm.LogAttribute{ {Key: "contract_address", Value: contractAddress.String()}, {Key: "attr1", Value: "🦄"}, @@ -5518,7 +5646,7 @@ func TestV1SendsMixedAttributesAndEventsFromInitWithSubmessageWithoutReply(t *te attrs, err := parseAndDecryptAttributes(e.Attributes, nonce, true) require.Empty(t, err) - require.Equal(t, + requireLogAttributes(t, []v010cosmwasm.LogAttribute{ {Key: "contract_address", Value: contractAddress.String()}, {Key: "attr5", Value: "🐙"}, @@ -5534,7 +5662,7 @@ func TestV1SendsMixedAttributesAndEventsFromInitWithSubmessageWithoutReply(t *te require.True(t, hadCyber1) require.True(t, hadCyber2) - require.Equal(t, + requireEvents(t, []ContractEvent{ { {Key: "contract_address", Value: contractAddress.String()}, @@ -5569,7 +5697,7 @@ func TestV1SendsMixedAttributesAndEventsFromInitWithSubmessageWithReply(t *testi attrs, err := parseAndDecryptAttributes(e.Attributes, nonce, true) require.Empty(t, err) - require.Equal(t, + requireLogAttributes(t, []v010cosmwasm.LogAttribute{ {Key: "contract_address", Value: contractAddress.String()}, {Key: "attr1", Value: "🦄"}, @@ -5586,7 +5714,7 @@ func TestV1SendsMixedAttributesAndEventsFromInitWithSubmessageWithReply(t *testi attrs, err := parseAndDecryptAttributes(e.Attributes, nonce, true) require.Empty(t, err) - require.Equal(t, + requireLogAttributes(t, []v010cosmwasm.LogAttribute{ {Key: "contract_address", Value: contractAddress.String()}, {Key: "attr5", Value: "🐙"}, @@ -5603,7 +5731,7 @@ func TestV1SendsMixedAttributesAndEventsFromInitWithSubmessageWithReply(t *testi attrs, err := parseAndDecryptAttributes(e.Attributes, nonce, true) require.Empty(t, err) - require.Equal(t, + requireLogAttributes(t, []v010cosmwasm.LogAttribute{ {Key: "contract_address", Value: contractAddress.String()}, {Key: "attr9", Value: "🤯"}, @@ -5620,7 +5748,7 @@ func TestV1SendsMixedAttributesAndEventsFromInitWithSubmessageWithReply(t *testi require.True(t, hadCyber2) require.True(t, hadCyber3) - require.Equal(t, + requireEvents(t, []ContractEvent{ { {Key: "contract_address", Value: contractAddress.String()}, @@ -5660,7 +5788,7 @@ func TestV1SendsMixedAttributesAndEventsFromExecuteWithoutSubmessageWithoutReply attrs, err := parseAndDecryptAttributes(e.Attributes, nonce, false) require.Empty(t, err) - require.Equal(t, + requireLogAttributes(t, []v010cosmwasm.LogAttribute{ {Key: "contract_address", Value: contractAddress.String()}, {Key: "attr1", Value: "🦄"}, @@ -5675,7 +5803,7 @@ func TestV1SendsMixedAttributesAndEventsFromExecuteWithoutSubmessageWithoutReply require.True(t, hadCyber1) - require.Equal(t, + requireEvents(t, []ContractEvent{ { {Key: "contract_address", Value: contractAddress.String()}, @@ -5706,7 +5834,7 @@ func TestV1SendsMixedAttributesAndEventsFromExecuteWithSubmessageWithoutReply(t attrs, err := parseAndDecryptAttributes(e.Attributes, nonce, true) require.Empty(t, err) - require.Equal(t, + requireLogAttributes(t, []v010cosmwasm.LogAttribute{ {Key: "contract_address", Value: contractAddress.String()}, {Key: "attr1", Value: "🦄"}, @@ -5723,7 +5851,7 @@ func TestV1SendsMixedAttributesAndEventsFromExecuteWithSubmessageWithoutReply(t attrs, err := parseAndDecryptAttributes(e.Attributes, nonce, true) require.Empty(t, err) - require.Equal(t, + requireLogAttributes(t, []v010cosmwasm.LogAttribute{ {Key: "contract_address", Value: contractAddress.String()}, {Key: "attr5", Value: "🐙"}, @@ -5739,7 +5867,7 @@ func TestV1SendsMixedAttributesAndEventsFromExecuteWithSubmessageWithoutReply(t require.True(t, hadCyber1) require.True(t, hadCyber2) - require.Equal(t, + requireEvents(t, []ContractEvent{ { {Key: "contract_address", Value: contractAddress.String()}, @@ -5776,7 +5904,7 @@ func TestV1SendsMixedAttributesAndEventsFromExecuteWithSubmessageWithReply(t *te attrs, err := parseAndDecryptAttributes(e.Attributes, nonce, true) require.Empty(t, err) - require.Equal(t, + requireLogAttributes(t, []v010cosmwasm.LogAttribute{ {Key: "contract_address", Value: contractAddress.String()}, {Key: "attr1", Value: "🦄"}, @@ -5793,7 +5921,7 @@ func TestV1SendsMixedAttributesAndEventsFromExecuteWithSubmessageWithReply(t *te attrs, err := parseAndDecryptAttributes(e.Attributes, nonce, true) require.Empty(t, err) - require.Equal(t, + requireLogAttributes(t, []v010cosmwasm.LogAttribute{ {Key: "contract_address", Value: contractAddress.String()}, {Key: "attr5", Value: "🐙"}, @@ -5810,7 +5938,7 @@ func TestV1SendsMixedAttributesAndEventsFromExecuteWithSubmessageWithReply(t *te attrs, err := parseAndDecryptAttributes(e.Attributes, nonce, true) require.Empty(t, err) - require.Equal(t, + requireLogAttributes(t, []v010cosmwasm.LogAttribute{ {Key: "contract_address", Value: contractAddress.String()}, {Key: "attr9", Value: "🤯"}, @@ -5827,7 +5955,7 @@ func TestV1SendsMixedAttributesAndEventsFromExecuteWithSubmessageWithReply(t *te require.True(t, hadCyber2) require.True(t, hadCyber3) - require.Equal(t, + requireEvents(t, []ContractEvent{ { {Key: "contract_address", Value: contractAddress.String()}, @@ -5877,7 +6005,7 @@ func TestV1SendsLogsMixedWithV010WithoutReply(t *testing.T) { attrs, err := parseAndDecryptAttributes(e.Attributes, nonce, true) require.Empty(t, err) - require.Equal(t, + requireLogAttributes(t, []v010cosmwasm.LogAttribute{ {Key: "contract_address", Value: v1ContractAddress.String()}, {Key: "attr1", Value: "🦄"}, @@ -5892,7 +6020,7 @@ func TestV1SendsLogsMixedWithV010WithoutReply(t *testing.T) { require.True(t, hadCyber1) - require.Equal(t, + requireEvents(t, []ContractEvent{ { {Key: "contract_address", Value: v1ContractAddress.String()}, @@ -5938,7 +6066,7 @@ func TestV1SendsLogsMixedWithV010WithReply(t *testing.T) { attrs, err := parseAndDecryptAttributes(e.Attributes, nonce, true) require.Empty(t, err) - require.Equal(t, + requireLogAttributes(t, []v010cosmwasm.LogAttribute{ {Key: "contract_address", Value: v1ContractAddress.String()}, {Key: "attr1", Value: "🦄"}, @@ -5955,7 +6083,7 @@ func TestV1SendsLogsMixedWithV010WithReply(t *testing.T) { attrs, err := parseAndDecryptAttributes(e.Attributes, nonce, true) require.Empty(t, err) - require.Equal(t, + requireLogAttributes(t, []v010cosmwasm.LogAttribute{ {Key: "contract_address", Value: v1ContractAddress.String()}, {Key: "attr9", Value: "🤯"}, @@ -5971,7 +6099,7 @@ func TestV1SendsLogsMixedWithV010WithReply(t *testing.T) { require.True(t, hadCyber1) require.True(t, hadCyber3) - require.Equal(t, + requireEvents(t, []ContractEvent{ { {Key: "contract_address", Value: v1ContractAddress.String()}, @@ -6019,7 +6147,7 @@ func TestV010SendsLogsMixedWithV1(t *testing.T) { attrs, err := parseAndDecryptAttributes(e.Attributes, nonce, true) require.Empty(t, err) - require.Equal(t, + requireLogAttributes(t, []v010cosmwasm.LogAttribute{ {Key: "contract_address", Value: v1ContractAddress.String()}, {Key: "attr5", Value: "🐙"}, @@ -6034,7 +6162,7 @@ func TestV010SendsLogsMixedWithV1(t *testing.T) { require.True(t, hadCyber2) - require.Equal(t, + requireEvents(t, []ContractEvent{ { {Key: "contract_address", Value: v010ContractAddress.String()}, From 0d91925cb0a9fbbfccb4da7aca198b3eab41fe1c Mon Sep 17 00:00:00 2001 From: Lior Bondarevski Date: Sun, 28 Aug 2022 11:23:45 +0300 Subject: [PATCH 71/93] Fix relay --- x/compute/internal/keeper/relay.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/x/compute/internal/keeper/relay.go b/x/compute/internal/keeper/relay.go index a60a928e0..7bb821966 100644 --- a/x/compute/internal/keeper/relay.go +++ b/x/compute/internal/keeper/relay.go @@ -94,7 +94,7 @@ func (k Keeper) OnOpenChannel( return "", sdkerrors.Wrap(err, "ibc-open-channel") } - res, err := k.ibcContractCall(ctx, contractAddress, msgBz, wasmTypes.HandleTypeIbcChannelConnect) + res, err := k.ibcContractCall(ctx, contractAddress, msgBz, wasmTypes.HandleTypeIbcChannelOpen) if err != nil { return "", sdkerrors.Wrap(types.ErrExecuteFailed, err.Error()) } @@ -196,7 +196,7 @@ func (k Keeper) OnRecvPacket( return nil, sdkerrors.Wrap(err, "ibc-recv-packet") } - res, err := k.ibcContractCall(ctx, contractAddress, msgBz, wasmTypes.HandleTypeIbcChannelConnect) + res, err := k.ibcContractCall(ctx, contractAddress, msgBz, wasmTypes.HandleTypeIbcPacketReceive) if err != nil { return nil, sdkerrors.Wrap(types.ErrExecuteFailed, err.Error()) } From 66e3ed259bb70eed42373157cb83d6182026113a Mon Sep 17 00:00:00 2001 From: Itzik Date: Sun, 28 Aug 2022 15:56:16 +0300 Subject: [PATCH 72/93] Merged env refactor changes to latest IBC branch --- .../src/contract_validation.rs | 27 -- .../enclaves/shared/contract-engine/src/io.rs | 25 +- .../shared/contract-engine/src/lib.rs | 1 + .../shared/contract-engine/src/message.rs | 231 ++++++++++++++++-- .../shared/cosmwasm-types/v1.0/src/ibc.rs | 2 +- 5 files changed, 217 insertions(+), 69 deletions(-) diff --git a/cosmwasm/enclaves/shared/contract-engine/src/contract_validation.rs b/cosmwasm/enclaves/shared/contract-engine/src/contract_validation.rs index f9a1ed48e..95fa9fe9c 100644 --- a/cosmwasm/enclaves/shared/contract-engine/src/contract_validation.rs +++ b/cosmwasm/enclaves/shared/contract-engine/src/contract_validation.rs @@ -48,33 +48,6 @@ pub fn generate_encryption_key( Ok(encryption_key) } -pub fn extract_contract_key(env: &Env) -> Result<[u8; CONTRACT_KEY_LENGTH], EnclaveError> { - if env.contract_key.is_none() { - warn!("Contract execute with empty contract key"); - return Err(EnclaveError::FailedContractAuthentication); - } - - let contract_key = - base64::decode(env.contract_key.as_ref().unwrap().as_bytes()).map_err(|err| { - warn!( - "got an error while trying to decode contract key {:?}: {}", - env, err - ); - EnclaveError::FailedContractAuthentication - })?; - - if contract_key.len() != CONTRACT_KEY_LENGTH { - warn!("Contract execute with empty contract key"); - return Err(EnclaveError::FailedContractAuthentication); - } - - let mut key_as_bytes = [0u8; CONTRACT_KEY_LENGTH]; - - key_as_bytes.copy_from_slice(&contract_key); - - Ok(key_as_bytes) -} - pub fn generate_sender_id(msg_sender: &[u8], block_height: &u64) -> [u8; HASH_SIZE] { let mut input_data = msg_sender.to_vec(); input_data.extend_from_slice(&block_height.to_be_bytes()); diff --git a/cosmwasm/enclaves/shared/contract-engine/src/io.rs b/cosmwasm/enclaves/shared/contract-engine/src/io.rs index ad7288457..d3a8ff586 100644 --- a/cosmwasm/enclaves/shared/contract-engine/src/io.rs +++ b/cosmwasm/enclaves/shared/contract-engine/src/io.rs @@ -54,11 +54,11 @@ pub enum RawWasmOutput { }, OkIBCBasic { #[serde(rename = "Ok")] - ok: enclave_cosmwasm_v1_types::ibc::IbcBasicResponse, + ok: cw_types_v1::ibc::IbcBasicResponse, }, OkIBCPacketReceive { #[serde(rename = "Ok")] - ok: enclave_cosmwasm_v1_types::ibc::IbcReceiveResponse, + ok: cw_types_v1::ibc::IbcReceiveResponse, }, } @@ -81,7 +81,7 @@ pub struct V1WasmOutput { #[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] pub struct IBCOutput { #[serde(rename = "Ok")] - pub ok: Option, + pub ok: Option, #[serde(rename = "Err")] pub err: Option, } @@ -89,7 +89,7 @@ pub struct IBCOutput { #[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] pub struct IBCReceiveOutput { #[serde(rename = "Ok")] - pub ok: Option, + pub ok: Option, #[serde(rename = "Err")] pub err: Option, } @@ -457,9 +457,7 @@ pub fn encrypt_output( internal_msg_id, } => { for sub_msg in &mut ok.messages { - if let cw_types_v1::results::CosmosMsg::Wasm(wasm_msg) = - &mut sub_msg.msg - { + if let cw_types_v1::results::CosmosMsg::Wasm(wasm_msg) = &mut sub_msg.msg { encrypt_v1_wasm_msg( wasm_msg, &sub_msg.reply_on, @@ -563,9 +561,7 @@ pub fn encrypt_output( } RawWasmOutput::OkIBCBasic { ok } => { for sub_msg in &mut ok.messages { - if let enclave_cosmwasm_v1_types::results::CosmosMsg::Wasm(wasm_msg) = - &mut sub_msg.msg - { + if let cw_types_v1::results::CosmosMsg::Wasm(wasm_msg) = &mut sub_msg.msg { encrypt_v1_wasm_msg( wasm_msg, &sub_msg.reply_on, @@ -598,9 +594,7 @@ pub fn encrypt_output( } RawWasmOutput::OkIBCPacketReceive { ok } => { for sub_msg in &mut ok.messages { - if let enclave_cosmwasm_v1_types::results::CosmosMsg::Wasm(wasm_msg) = - &mut sub_msg.msg - { + if let cw_types_v1::results::CosmosMsg::Wasm(wasm_msg) = &mut sub_msg.msg { encrypt_v1_wasm_msg( wasm_msg, &sub_msg.reply_on, @@ -725,9 +719,8 @@ fn encrypt_v1_wasm_msg( // it will treat the next 64 bytes as a recipient code-hash and prepend this code-hash to its output. let mut hash_appended_msg = code_hash.as_bytes().to_vec(); if *reply_on != ReplyOn::Never { - hash_appended_msg.extend_from_slice( - cw_types_v1::results::REPLY_ENCRYPTION_MAGIC_BYTES, - ); + hash_appended_msg + .extend_from_slice(cw_types_v1::results::REPLY_ENCRYPTION_MAGIC_BYTES); hash_appended_msg.extend_from_slice(&msg_id.to_be_bytes()); hash_appended_msg.extend_from_slice(reply_recipient_contract_hash.as_bytes()); } diff --git a/cosmwasm/enclaves/shared/contract-engine/src/lib.rs b/cosmwasm/enclaves/shared/contract-engine/src/lib.rs index c70c99a0f..49e83256a 100644 --- a/cosmwasm/enclaves/shared/contract-engine/src/lib.rs +++ b/cosmwasm/enclaves/shared/contract-engine/src/lib.rs @@ -2,6 +2,7 @@ #[cfg(not(target_env = "sgx"))] extern crate sgx_tstd as std; +extern crate core; extern crate sgx_types; mod contract_operations; diff --git a/cosmwasm/enclaves/shared/contract-engine/src/message.rs b/cosmwasm/enclaves/shared/contract-engine/src/message.rs index f5b83e8e6..d57fd4cec 100644 --- a/cosmwasm/enclaves/shared/contract-engine/src/message.rs +++ b/cosmwasm/enclaves/shared/contract-engine/src/message.rs @@ -1,13 +1,16 @@ -use cosmos_proto::tx::signing::SignMode; -use cw_types_v010::encoding::Binary; - use log::{trace, warn}; +use serde::de::DeserializeOwned; +use serde::Serialize; -use crate::types::SecretMessage; +use cosmos_proto::tx::signing::SignMode; +use cw_types_v010::encoding::Binary; +use cw_types_v1::ibc::{IbcPacketAckMsg, IbcPacketReceiveMsg, IbcPacketTimeoutMsg, IbcPacketTrait}; use cw_types_v1::results::{DecryptedReply, Event, Reply, SubMsgResponse, SubMsgResult}; use enclave_cosmos_types::types::{HandleType, SigInfo}; use enclave_ffi_types::EnclaveError; +use crate::types::SecretMessage; + const HEX_ENCODED_HASH_SIZE: usize = 64; pub struct ParsedMessage { @@ -18,7 +21,12 @@ pub struct ParsedMessage { pub contract_hash_for_validation: Option>, } -fn redact_custom_events(reply: &mut Reply) { +pub struct DecryptedSecretMessage { + pub secret_msg: SecretMessage, + pub decrypted_msg: Vec, +} + +pub fn redact_custom_events(reply: &mut Reply) { reply.result = match &reply.result { SubMsgResult::Ok(r) => { let mut events: Vec = Default::default(); @@ -54,29 +62,158 @@ fn redact_custom_events(reply: &mut Reply) { }; } +pub fn get_secret_msg(message: &[u8]) -> SecretMessage { + match SecretMessage::from_slice(message) { + Ok(orig_secret_msg) => orig_secret_msg, + Err(_) => { + trace!( + "Msg is not SecretMessage (probably plaintext): {:?}", + base64::encode(&message) + ); + + return SecretMessage { + nonce: [0; 32], + user_public_key: [0; 32], + msg: message.into(), + }; + } + } +} + +pub fn try_get_decrypted_secret_msg(message: &[u8]) -> Option { + let secret_msg = get_secret_msg(message); + match secret_msg.decrypt() { + Ok(decrypted_msg) => Some(DecryptedSecretMessage { + secret_msg, + decrypted_msg, + }), + Err(_) => None, + } +} + +pub fn parse_ibc_packet( + _t: T, + message: &[u8], + function_name: &str, +) -> Result +where + T: IbcPacketTrait + Serialize + DeserializeOwned + core::fmt::Debug, +{ + let mut parsed_encrypted_ibc_packet: T = + serde_json::from_slice(&message.to_vec()).map_err(|err| { + warn!( + "{} msg got an error while trying to deserialize msg input bytes into json {:?}: {}", + function_name, + String::from_utf8_lossy(&message), + err + ); + EnclaveError::FailedToDeserialize + })?; + + let tmp_secret_data = get_secret_msg(parsed_encrypted_ibc_packet.get_packet().as_slice()); + let mut was_msg_encrypted = false; + let mut orig_secret_msg = tmp_secret_data; + + match orig_secret_msg.decrypt() { + Ok(decrypted_msg) => { + // IBC packet was encrypted + + trace!( + "{} data before decryption: {:?}", + function_name, + base64::encode(&message) + ); + + parsed_encrypted_ibc_packet.set_packet(decrypted_msg.as_slice().into()); + was_msg_encrypted = true; + } + Err(_) => { + // assume data is not encrypted + + trace!( + "{} data was plaintext: {:?}", + function_name, + base64::encode(&message) + ); + } + } + + let ack = parsed_encrypted_ibc_packet.get_ack(); + let tmp_secret_ack = get_secret_msg(ack.unwrap_or(Binary::from(vec![].as_slice())).as_slice()); + + match tmp_secret_ack.decrypt() { + Ok(ack_data) => { + parsed_encrypted_ibc_packet.set_ack(ack_data.as_slice().into()); + was_msg_encrypted = true; + + orig_secret_msg = tmp_secret_ack; + } + Err(_) => {} + } + + Ok(ParsedMessage { + should_validate_sig_info: false, + was_msg_encrypted, + secret_msg: orig_secret_msg, + decrypted_msg: serde_json::to_vec(&parsed_encrypted_ibc_packet).map_err(|err| { + warn!( + "got an error while trying to serialize {} msg into bytes {:?}: {}", + function_name, parsed_encrypted_ibc_packet, err + ); + EnclaveError::FailedToSerialize + })?, + contract_hash_for_validation: None, + }) +} + // Parse the message that was passed to handle (Based on the assumption that it might be a reply or IBC as well) pub fn parse_message( message: &[u8], sig_info: &SigInfo, handle_type: &HandleType, ) -> Result { - let orig_secret_msg = SecretMessage::from_slice(message)?; - return match handle_type { - HandleType::HANDLE_TYPE_EXECUTE => { - let decrypted_msg = orig_secret_msg.decrypt()?; - Ok(ParsedMessage { - should_validate_sig_info: true, - was_msg_encrypted: true, - secret_msg: orig_secret_msg, - decrypted_msg, - contract_hash_for_validation: None, - }) - } + HandleType::HANDLE_TYPE_EXECUTE => match try_get_decrypted_secret_msg(message) { + Some(decrypted_secret_msg) => { + trace!( + "execute input before decryption: {:?}", + base64::encode(&message) + ); + + Ok(ParsedMessage { + should_validate_sig_info: true, + was_msg_encrypted: true, + secret_msg: decrypted_secret_msg.secret_msg, + decrypted_msg: decrypted_secret_msg.decrypted_msg, + contract_hash_for_validation: None, + }) + } + None => { + trace!( + "execute input was plaintext: {:?}", + base64::encode(&message) + ); + + let secret_msg = get_secret_msg(message); + let decrypted_msg = secret_msg.msg.clone(); + Ok(ParsedMessage { + should_validate_sig_info: true, + was_msg_encrypted: false, + secret_msg, + decrypted_msg, + contract_hash_for_validation: None, + }) + } + }, HandleType::HANDLE_TYPE_REPLY => { + let orig_secret_msg = SecretMessage::from_slice(message)?; + if sig_info.sign_mode == SignMode::SIGN_MODE_UNSPECIFIED { - trace!("reply input is not encrypted"); + trace!( + "reply input is not encrypted: {:?}", + base64::encode(&message) + ); let decrypted_msg = orig_secret_msg.msg.clone(); let mut reply: Reply = serde_json::from_slice(&decrypted_msg) .map_err(|err| { @@ -142,7 +279,6 @@ pub fn parse_message( }); } - // Here we are sure the reply is OK because only OK is encrypted trace!( "reply input before decryption: {:?}", base64::encode(&message) @@ -225,12 +361,12 @@ pub fn parse_message( redact_custom_events(&mut parsed_encrypted_reply); let serialized_encrypted_reply : Vec = serde_json::to_vec(&parsed_encrypted_reply).map_err(|err| { - warn!( + warn!( "got an error while trying to serialize encrypted reply into bytes {:?}: {}", parsed_encrypted_reply, err ); - EnclaveError::FailedToSerialize - })?; + EnclaveError::FailedToSerialize + })?; let reply_secret_msg = SecretMessage { nonce: orig_secret_msg.nonce, @@ -318,12 +454,12 @@ pub fn parse_message( })?; let serialized_encrypted_reply : Vec = serde_json::to_vec(&parsed_encrypted_reply).map_err(|err| { - warn!( + warn!( "got an error while trying to serialize encrypted reply into bytes {:?}: {}", parsed_encrypted_reply, err ); - EnclaveError::FailedToSerialize - })?; + EnclaveError::FailedToSerialize + })?; let reply_secret_msg = SecretMessage { nonce: orig_secret_msg.nonce, @@ -343,5 +479,50 @@ pub fn parse_message( } } } + HandleType::HANDLE_TYPE_IBC_CHANNEL_OPEN + | HandleType::HANDLE_TYPE_IBC_CHANNEL_CONNECT + | HandleType::HANDLE_TYPE_IBC_CHANNEL_CLOSE => { + trace!( + "parsing {} msg (Should always be plaintext): {:?}", + HandleType::to_export_name(&handle_type), + base64::encode(&message) + ); + + let scrt_msg = SecretMessage { + nonce: [0; 32], + user_public_key: [0; 32], + msg: message.into(), + }; + + let decrypted_msg = scrt_msg.msg.clone(); + + Ok(ParsedMessage { + should_validate_sig_info: false, + was_msg_encrypted: false, + secret_msg: scrt_msg, + decrypted_msg, + contract_hash_for_validation: None, + }) + } + HandleType::HANDLE_TYPE_IBC_PACKET_RECEIVE => { + // LIORRR TODO: Maybe mark whether the message was encrypted or not. + parse_ibc_packet( + IbcPacketReceiveMsg::default(), + message, + "ibc_packet_receive", + ) + } + HandleType::HANDLE_TYPE_IBC_PACKET_ACK => { + // LIORRR TODO: Maybe mark whether the message was encrypted or not. + parse_ibc_packet(IbcPacketAckMsg::default(), message, "ibc_packet_receive") + } + HandleType::HANDLE_TYPE_IBC_PACKET_TIMEOUT => { + // LIORRR TODO: Maybe mark whether the message was encrypted or not. + parse_ibc_packet( + IbcPacketTimeoutMsg::default(), + message, + "ibc_packet_timeout", + ) + } }; } diff --git a/cosmwasm/enclaves/shared/cosmwasm-types/v1.0/src/ibc.rs b/cosmwasm/enclaves/shared/cosmwasm-types/v1.0/src/ibc.rs index c8772ea7d..59cec1445 100644 --- a/cosmwasm/enclaves/shared/cosmwasm-types/v1.0/src/ibc.rs +++ b/cosmwasm/enclaves/shared/cosmwasm-types/v1.0/src/ibc.rs @@ -1,7 +1,7 @@ use crate::addresses::Addr; use crate::results::{Event, SubMsg}; use crate::timestamp::Timestamp; -use enclave_cosmwasm_v010_types::{encoding::Binary, types::Empty, types::LogAttribute}; +use cw_types_v010::{encoding::Binary, types::Empty, types::LogAttribute}; use serde::{Deserialize, Serialize}; use std::fmt; From 22a04de9e3fe1979cb3d216f08349b4f32a2ee3a Mon Sep 17 00:00:00 2001 From: Lior Bondarevski Date: Sun, 28 Aug 2022 16:45:01 +0300 Subject: [PATCH 73/93] New contract for ibc tests --- .vscode/settings.json | 1 + Makefile | 1 + .../internal/keeper/testdata/ibc/.gitignore | 13 + .../internal/keeper/testdata/ibc/Cargo.lock | 639 ++++++++++++++++++ .../internal/keeper/testdata/ibc/Cargo.toml | 44 ++ .../internal/keeper/testdata/ibc/Makefile | 8 + .../keeper/testdata/ibc/rust-toolchain | 1 + .../keeper/testdata/ibc/src/contract.rs | 36 + .../internal/keeper/testdata/ibc/src/lib.rs | 3 + .../internal/keeper/testdata/ibc/src/msg.rs | 16 + .../internal/keeper/testdata/ibc/src/state.rs | 16 + 11 files changed, 778 insertions(+) create mode 100644 x/compute/internal/keeper/testdata/ibc/.gitignore create mode 100644 x/compute/internal/keeper/testdata/ibc/Cargo.lock create mode 100644 x/compute/internal/keeper/testdata/ibc/Cargo.toml create mode 100644 x/compute/internal/keeper/testdata/ibc/Makefile create mode 100644 x/compute/internal/keeper/testdata/ibc/rust-toolchain create mode 100644 x/compute/internal/keeper/testdata/ibc/src/contract.rs create mode 100644 x/compute/internal/keeper/testdata/ibc/src/lib.rs create mode 100644 x/compute/internal/keeper/testdata/ibc/src/msg.rs create mode 100644 x/compute/internal/keeper/testdata/ibc/src/state.rs diff --git a/.vscode/settings.json b/.vscode/settings.json index 45d553f7d..4f88206e5 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -4,6 +4,7 @@ "./cosmwasm/enclaves/Cargo.toml", "./x/compute/internal/keeper/testdata/v1-sanity-contract/Cargo.toml", "./x/compute/internal/keeper/testdata/test-contract/Cargo.toml", + "./x/compute/internal/keeper/testdata/ibc/Cargo.toml", "./cosmwasm/enclaves/shared/cosmwasm-v1-types/Cargo.toml", "./cosmwasm/enclaves/shared/cosmwasm-v010-types/Cargo.toml" ], diff --git a/Makefile b/Makefile index 4b9793536..fdab5964d 100644 --- a/Makefile +++ b/Makefile @@ -348,6 +348,7 @@ build-test-contract: # sudo apt install -y binaryen $(MAKE) -C ./x/compute/internal/keeper/testdata/test-contract $(MAKE) -C ./x/compute/internal/keeper/testdata/v1-sanity-contract + $(MAKE) -C ./x/compute/internal/keeper/testdata/ibc-contract prep-go-tests: build-test-contract diff --git a/x/compute/internal/keeper/testdata/ibc/.gitignore b/x/compute/internal/keeper/testdata/ibc/.gitignore new file mode 100644 index 000000000..0e24e33d5 --- /dev/null +++ b/x/compute/internal/keeper/testdata/ibc/.gitignore @@ -0,0 +1,13 @@ +# Build results +/target +*.wasm + +# Text file backups +**/*.rs.bk + +# macOS +.DS_Store + +# IDEs +*.iml +.idea diff --git a/x/compute/internal/keeper/testdata/ibc/Cargo.lock b/x/compute/internal/keeper/testdata/ibc/Cargo.lock new file mode 100644 index 000000000..cd7e008a5 --- /dev/null +++ b/x/compute/internal/keeper/testdata/ibc/Cargo.lock @@ -0,0 +1,639 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "base16ct" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "349a06037c7bf932dd7e7d1f653678b2038b9ad46a74102f1fc7bd7872678cce" + +[[package]] +name = "base64" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd" + +[[package]] +name = "base64ct" +version = "1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3bdca834647821e0b13d9539a8634eb62d3501b6b6c2cec1722786ee6671b851" + +[[package]] +name = "block-buffer" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" +dependencies = [ + "generic-array", +] + +[[package]] +name = "byteorder" +version = "1.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" + +[[package]] +name = "cc" +version = "1.0.73" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2fff2a6927b3bb87f9595d67196a70493f627687a71d87a0d692242c33f58c11" + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "const-oid" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e4c78c047431fee22c1a7bb92e00ad095a02a983affe4d8a72e2a2c62c1b94f3" + +[[package]] +name = "cosmwasm-crypto" +version = "1.0.0" +source = "git+https://github.com/scrtlabs/cosmwasm?branch=secret#e69869a8565e4e2318bdbfd3711fd1ceda0db209" +dependencies = [ + "digest", + "ed25519-zebra", + "k256", + "rand_core 0.6.3", + "thiserror", +] + +[[package]] +name = "cosmwasm-derive" +version = "1.0.0" +source = "git+https://github.com/scrtlabs/cosmwasm?branch=secret#e69869a8565e4e2318bdbfd3711fd1ceda0db209" +dependencies = [ + "syn", +] + +[[package]] +name = "cosmwasm-std" +version = "1.0.0" +source = "git+https://github.com/scrtlabs/cosmwasm?branch=secret#e69869a8565e4e2318bdbfd3711fd1ceda0db209" +dependencies = [ + "base64", + "cosmwasm-crypto", + "cosmwasm-derive", + "forward_ref", + "schemars", + "serde", + "serde-json-wasm 0.4.1", + "thiserror", + "uint", +] + +[[package]] +name = "cosmwasm-storage" +version = "1.0.0" +source = "git+https://github.com/scrtlabs/cosmwasm?branch=secret#e69869a8565e4e2318bdbfd3711fd1ceda0db209" +dependencies = [ + "cosmwasm-std", + "serde", +] + +[[package]] +name = "cpufeatures" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59a6001667ab124aebae2a495118e11d30984c3a653e99d86d58971708cf5e4b" +dependencies = [ + "libc", +] + +[[package]] +name = "crunchy" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" + +[[package]] +name = "crypto-bigint" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03c6a1d5fa1de37e071642dfa44ec552ca5b299adb128fab16138e24b548fd21" +dependencies = [ + "generic-array", + "rand_core 0.6.3", + "subtle", + "zeroize", +] + +[[package]] +name = "crypto-mac" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1d1a86f49236c215f271d40892d5fc950490551400b02ef360692c29815c714" +dependencies = [ + "generic-array", + "subtle", +] + +[[package]] +name = "curve25519-dalek" +version = "3.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90f9d052967f590a76e62eb387bd0bbb1b000182c3cefe5364db6b7211651bc0" +dependencies = [ + "byteorder", + "digest", + "rand_core 0.5.1", + "subtle", + "zeroize", +] + +[[package]] +name = "der" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6919815d73839e7ad218de758883aae3a257ba6759ce7a9992501efbb53d705c" +dependencies = [ + "const-oid", +] + +[[package]] +name = "digest" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" +dependencies = [ + "generic-array", +] + +[[package]] +name = "dyn-clone" +version = "1.0.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d07a982d1fb29db01e5a59b1918e03da4df7297eaeee7686ac45542fd4e59c8" + +[[package]] +name = "ecdsa" +version = "0.13.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0d69ae62e0ce582d56380743515fefaf1a8c70cec685d9677636d7e30ae9dc9" +dependencies = [ + "der", + "elliptic-curve", + "rfc6979", + "signature", +] + +[[package]] +name = "ed25519-zebra" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "403ef3e961ab98f0ba902771d29f842058578bb1ce7e3c59dad5a6a93e784c69" +dependencies = [ + "curve25519-dalek", + "hex", + "rand_core 0.6.3", + "serde", + "sha2", + "thiserror", + "zeroize", +] + +[[package]] +name = "elliptic-curve" +version = "0.11.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25b477563c2bfed38a3b7a60964c49e058b2510ad3f12ba3483fd8f62c2306d6" +dependencies = [ + "base16ct", + "crypto-bigint", + "der", + "ff", + "generic-array", + "group", + "rand_core 0.6.3", + "sec1", + "subtle", + "zeroize", +] + +[[package]] +name = "ff" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "131655483be284720a17d74ff97592b8e76576dc25563148601df2d7c9080924" +dependencies = [ + "rand_core 0.6.3", + "subtle", +] + +[[package]] +name = "forward_ref" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8cbd1169bd7b4a0a20d92b9af7a7e0422888bd38a6f5ec29c1fd8c1558a272e" + +[[package]] +name = "generic-array" +version = "0.14.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd48d33ec7f05fbfa152300fdad764757cbded343c1aa1cff2fbaf4134851803" +dependencies = [ + "typenum", + "version_check", +] + +[[package]] +name = "getrandom" +version = "0.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce" +dependencies = [ + "cfg-if", + "libc", + "wasi 0.9.0+wasi-snapshot-preview1", +] + +[[package]] +name = "getrandom" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4eb1a864a501629691edf6c15a593b7a51eebaa1e8468e9ddc623de7c9b58ec6" +dependencies = [ + "cfg-if", + "libc", + "wasi 0.11.0+wasi-snapshot-preview1", +] + +[[package]] +name = "group" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc5ac374b108929de78460075f3dc439fa66df9d8fc77e8f12caa5165fcf0c89" +dependencies = [ + "ff", + "rand_core 0.6.3", + "subtle", +] + +[[package]] +name = "hex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" + +[[package]] +name = "hmac" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a2a2320eb7ec0ebe8da8f744d7812d9fc4cb4d09344ac01898dbcb6a20ae69b" +dependencies = [ + "crypto-mac", + "digest", +] + +[[package]] +name = "ibc" +version = "0.0.1" +dependencies = [ + "cosmwasm-std", + "cosmwasm-storage", + "schemars", + "secp256k1", + "serde", + "serde-json-wasm 0.2.3", +] + +[[package]] +name = "itoa" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "112c678d4050afce233f4f2852bb2eb519230b3cf12f33585275537d7e41578d" + +[[package]] +name = "k256" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19c3a5e0a0b8450278feda242592512e09f61c72e018b8cd5c859482802daf2d" +dependencies = [ + "cfg-if", + "ecdsa", + "elliptic-curve", + "sec1", + "sha2", +] + +[[package]] +name = "libc" +version = "0.2.126" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "349d5a591cd28b49e1d1037471617a32ddcda5731b99419008085f72d5a53836" + +[[package]] +name = "opaque-debug" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" + +[[package]] +name = "pkcs8" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7cabda3fb821068a9a4fab19a683eac3af12edf0f34b94a8be53c4972b8149d0" +dependencies = [ + "der", + "spki", + "zeroize", +] + +[[package]] +name = "proc-macro2" +version = "1.0.42" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c278e965f1d8cf32d6e0e96de3d3e79712178ae67986d9cf9151f51e95aac89b" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3bcdf212e9776fbcb2d23ab029360416bb1706b1aea2d1a5ba002727cbcab804" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rand_core" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" +dependencies = [ + "getrandom 0.1.16", +] + +[[package]] +name = "rand_core" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7" +dependencies = [ + "getrandom 0.2.7", +] + +[[package]] +name = "rfc6979" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96ef608575f6392792f9ecf7890c00086591d29a83910939d430753f7c050525" +dependencies = [ + "crypto-bigint", + "hmac", + "zeroize", +] + +[[package]] +name = "ryu" +version = "1.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3f6f92acf49d1b98f7a81226834412ada05458b7364277387724a237f062695" + +[[package]] +name = "schemars" +version = "0.8.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1847b767a3d62d95cbf3d8a9f0e421cf57a0d8aa4f411d4b16525afb0284d4ed" +dependencies = [ + "dyn-clone", + "schemars_derive", + "serde", + "serde_json", +] + +[[package]] +name = "schemars_derive" +version = "0.8.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af4d7e1b012cb3d9129567661a63755ea4b8a7386d339dc945ae187e403c6743" +dependencies = [ + "proc-macro2", + "quote", + "serde_derive_internals", + "syn", +] + +[[package]] +name = "sec1" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08da66b8b0965a5555b6bd6639e68ccba85e1e2506f5fbb089e93f8a04e1a2d1" +dependencies = [ + "der", + "generic-array", + "pkcs8", + "subtle", + "zeroize", +] + +[[package]] +name = "secp256k1" +version = "0.20.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97d03ceae636d0fed5bae6a7f4f664354c5f4fcedf6eef053fef17e49f837d0a" +dependencies = [ + "secp256k1-sys", +] + +[[package]] +name = "secp256k1-sys" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "957da2573cde917463ece3570eab4a0b3f19de6f1646cde62e6fd3868f566036" +dependencies = [ + "cc", +] + +[[package]] +name = "serde" +version = "1.0.140" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc855a42c7967b7c369eb5860f7164ef1f6f81c20c7cc1141f2a604e18723b03" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde-json-wasm" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "120bad73306616e91acd7ceed522ba96032a51cffeef3cc813de7f367df71e37" +dependencies = [ + "serde", +] + +[[package]] +name = "serde-json-wasm" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "479b4dbc401ca13ee8ce902851b834893251404c4f3c65370a49e047a6be09a5" +dependencies = [ + "serde", +] + +[[package]] +name = "serde_derive" +version = "1.0.140" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f2122636b9fe3b81f1cb25099fcf2d3f542cdb1d45940d56c713158884a05da" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_derive_internals" +version = "0.26.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85bf8229e7920a9f636479437026331ce11aa132b4dde37d121944a44d6e5f3c" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_json" +version = "1.0.82" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "82c2c1fdcd807d1098552c5b9a36e425e42e9fbd7c6a37a8425f390f781f7fa7" +dependencies = [ + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "sha2" +version = "0.9.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d58a1e1bf39749807d89cf2d98ac2dfa0ff1cb3faa38fbb64dd88ac8013d800" +dependencies = [ + "block-buffer", + "cfg-if", + "cpufeatures", + "digest", + "opaque-debug", +] + +[[package]] +name = "signature" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "02658e48d89f2bec991f9a78e69cfa4c316f8d6a6c4ec12fae1aeb263d486788" +dependencies = [ + "digest", + "rand_core 0.6.3", +] + +[[package]] +name = "spki" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44d01ac02a6ccf3e07db148d2be087da624fea0221a16152ed01f0496a6b0a27" +dependencies = [ + "base64ct", + "der", +] + +[[package]] +name = "static_assertions" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" + +[[package]] +name = "subtle" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" + +[[package]] +name = "syn" +version = "1.0.98" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c50aef8a904de4c23c788f104b7dddc7d6f79c647c7c8ce4cc8f73eb0ca773dd" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "thiserror" +version = "1.0.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd829fe32373d27f76265620b5309d0340cb8550f523c1dda251d6298069069a" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0396bc89e626244658bef819e22d0cc459e795a5ebe878e6ec336d1674a8d79a" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "typenum" +version = "1.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dcf81ac59edc17cc8697ff311e8f5ef2d99fcbd9817b34cec66f90b6c3dfd987" + +[[package]] +name = "uint" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "12f03af7ccf01dd611cc450a0d10dbc9b745770d096473e2faf0ca6e2d66d1e0" +dependencies = [ + "byteorder", + "crunchy", + "hex", + "static_assertions", +] + +[[package]] +name = "unicode-ident" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "15c61ba63f9235225a22310255a29b806b907c9b8c964bcbd0a2c70f3f2deea7" + +[[package]] +name = "version_check" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" + +[[package]] +name = "wasi" +version = "0.9.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[package]] +name = "zeroize" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4756f7db3f7b5574938c3eb1c117038b8e07f95ee6718c0efad4ac21508f1efd" diff --git a/x/compute/internal/keeper/testdata/ibc/Cargo.toml b/x/compute/internal/keeper/testdata/ibc/Cargo.toml new file mode 100644 index 000000000..f9427e903 --- /dev/null +++ b/x/compute/internal/keeper/testdata/ibc/Cargo.toml @@ -0,0 +1,44 @@ +[package] +name = "ibc" +version = "0.0.1" +authors = ["Enigma "] +edition = "2018" +description = "A Test contract intended to use in system tests for the Secret Netowrk" +license = "MIT" +exclude = [ + # Those files are cosmwasm-opt artifacts. You might want to commit them for convenience but they should not be part of the source code publication. + "ibc.wasm", +] + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html +[lib] +crate-type = ["cdylib", "rlib"] + +[profile.release] +opt-level = 3 +debug = false +rpath = false +lto = true +debug-assertions = false +codegen-units = 1 +panic = 'abort' +incremental = false +overflow-checks = true + +[features] +default = [] +backtraces = ["cosmwasm-std/backtraces"] +with_floats = [] +stargate = [] +ibc3 = ["stargate"] + +[dependencies] +cosmwasm-std = { git = "https://github.com/scrtlabs/cosmwasm", branch = "secret", features=["stargate"] } +cosmwasm-storage = { git = "https://github.com/scrtlabs/cosmwasm", branch = "secret" } +schemars = "0.8.1" +serde = { version = "1.0.114", default-features = false, features = [ + "derive", + "alloc" +] } +serde-json-wasm = "0.2.1" +secp256k1 = "0.20.3" diff --git a/x/compute/internal/keeper/testdata/ibc/Makefile b/x/compute/internal/keeper/testdata/ibc/Makefile new file mode 100644 index 000000000..b6bb9953e --- /dev/null +++ b/x/compute/internal/keeper/testdata/ibc/Makefile @@ -0,0 +1,8 @@ +all: src/contract.rs src/lib.rs src/msg.rs src/state.rs Cargo.toml Cargo.lock + rustup target add wasm32-unknown-unknown + RUSTFLAGS='-C link-arg=-s' cargo build --release --target wasm32-unknown-unknown + cp ./target/wasm32-unknown-unknown/release/ibc.wasm ./contract.wasm + +clean: + cargo clean + -rm -f ./contract.wasm \ No newline at end of file diff --git a/x/compute/internal/keeper/testdata/ibc/rust-toolchain b/x/compute/internal/keeper/testdata/ibc/rust-toolchain new file mode 100644 index 000000000..a7efc46ca --- /dev/null +++ b/x/compute/internal/keeper/testdata/ibc/rust-toolchain @@ -0,0 +1 @@ +1.61 \ No newline at end of file diff --git a/x/compute/internal/keeper/testdata/ibc/src/contract.rs b/x/compute/internal/keeper/testdata/ibc/src/contract.rs new file mode 100644 index 000000000..771e99267 --- /dev/null +++ b/x/compute/internal/keeper/testdata/ibc/src/contract.rs @@ -0,0 +1,36 @@ +use crate::msg::{ExecuteMsg, InstantiateMsg, QueryMsg}; +use crate::state::{count, count_read}; +use cosmwasm_std::{ + entry_point, Binary, Deps, DepsMut, Env, IbcChannelOpenMsg, MessageInfo, Response, StdResult, +}; + +#[entry_point] +pub fn instantiate( + _deps: DepsMut, + _env: Env, + _info: MessageInfo, + _msg: InstantiateMsg, +) -> StdResult { + Ok(Response::default()) +} + +#[entry_point] +pub fn execute( + _deps: DepsMut, + _env: Env, + _info: MessageInfo, + _msg: ExecuteMsg, +) -> StdResult { + Ok(Response::default()) +} + +#[entry_point] +pub fn query(deps: Deps, _env: Env, _msg: QueryMsg) -> StdResult { + Ok(count_read(deps.storage).load()?.to_be_bytes().into()) +} + +#[entry_point] +pub fn ibc_channel_open(deps: DepsMut, _env: Env, _msg: IbcChannelOpenMsg) -> StdResult<()> { + count(deps.storage).save(&1)?; + Ok(()) +} diff --git a/x/compute/internal/keeper/testdata/ibc/src/lib.rs b/x/compute/internal/keeper/testdata/ibc/src/lib.rs new file mode 100644 index 000000000..04ade40ed --- /dev/null +++ b/x/compute/internal/keeper/testdata/ibc/src/lib.rs @@ -0,0 +1,3 @@ +pub mod contract; +pub mod msg; +pub mod state; \ No newline at end of file diff --git a/x/compute/internal/keeper/testdata/ibc/src/msg.rs b/x/compute/internal/keeper/testdata/ibc/src/msg.rs new file mode 100644 index 000000000..0a45c67d3 --- /dev/null +++ b/x/compute/internal/keeper/testdata/ibc/src/msg.rs @@ -0,0 +1,16 @@ +use schemars::JsonSchema; +use serde::{Deserialize, Serialize}; + +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] +#[serde(rename_all = "snake_case")] +pub enum InstantiateMsg { + Init {}, +} + +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] +#[serde(rename_all = "snake_case")] +pub enum ExecuteMsg {} + +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] +#[serde(rename_all = "snake_case")] +pub enum QueryMsg {} diff --git a/x/compute/internal/keeper/testdata/ibc/src/state.rs b/x/compute/internal/keeper/testdata/ibc/src/state.rs new file mode 100644 index 000000000..58b97292f --- /dev/null +++ b/x/compute/internal/keeper/testdata/ibc/src/state.rs @@ -0,0 +1,16 @@ +use cosmwasm_std::{Storage}; +use cosmwasm_storage::{ + singleton, singleton_read, ReadonlySingleton, Singleton, +}; + +pub const COUNT_KEY: &[u8] = b"count"; + +pub fn count(storage: &mut dyn Storage) -> Singleton { + singleton(storage, COUNT_KEY) +} + +pub fn count_read(storage: &dyn Storage) -> ReadonlySingleton { + singleton_read(storage, COUNT_KEY) +} + + From 16455f03e49a48ac4df36547086930bb8f17c4fe Mon Sep 17 00:00:00 2001 From: Lior Bondarevski Date: Sun, 28 Aug 2022 16:45:34 +0300 Subject: [PATCH 74/93] New ibc test --- x/compute/internal/keeper/ibc_test.go | 37 +++++++++++++++++++++++---- 1 file changed, 32 insertions(+), 5 deletions(-) diff --git a/x/compute/internal/keeper/ibc_test.go b/x/compute/internal/keeper/ibc_test.go index c5a16e000..26fa0aad1 100644 --- a/x/compute/internal/keeper/ibc_test.go +++ b/x/compute/internal/keeper/ibc_test.go @@ -2,6 +2,8 @@ package keeper import ( "encoding/hex" + "encoding/json" + "math" "testing" crypto "github.com/cosmos/cosmos-sdk/crypto/types" @@ -60,7 +62,7 @@ func ibcChannelConnectHelper( func ibcChannelOpenHelper( t *testing.T, keeper Keeper, ctx sdk.Context, - contractAddr sdk.AccAddress, creatorPrivKey crypto.PrivKey, msg string, + contractAddr sdk.AccAddress, creatorPrivKey crypto.PrivKey, gas uint64, shouldSendOpenTry bool, channel v1types.IBCChannel, ) (string, cosmwasm.StdError) { // create new ctx with the same storage and a gas limit @@ -105,7 +107,7 @@ func ibcChannelOpenHelper( func ibcChannelCloseHelper( t *testing.T, keeper Keeper, ctx sdk.Context, - contractAddr sdk.AccAddress, creatorPrivKey crypto.PrivKey, msg string, + contractAddr sdk.AccAddress, creatorPrivKey crypto.PrivKey, gas uint64, shouldSendCloseConfirn bool, channel v1types.IBCChannel, ) cosmwasm.StdError { // create new ctx with the same storage and a gas limit @@ -173,7 +175,7 @@ func createIBCPacket(src v1types.IBCEndpoint, dest v1types.IBCEndpoint, sequence func ibcPacketReceiveHelper( t *testing.T, keeper Keeper, ctx sdk.Context, - contractAddr sdk.AccAddress, creatorPrivKey crypto.PrivKey, msg string, + contractAddr sdk.AccAddress, creatorPrivKey crypto.PrivKey, shouldEncryptMsg bool, gas uint64, packet v1types.IBCPacket, ) ([]byte, cosmwasm.StdError) { var nonce []byte @@ -228,7 +230,7 @@ func ibcPacketReceiveHelper( func ibcPacketAckHelper( t *testing.T, keeper Keeper, ctx sdk.Context, - contractAddr sdk.AccAddress, creatorPrivKey crypto.PrivKey, msg string, + contractAddr sdk.AccAddress, creatorPrivKey crypto.PrivKey, shouldEncryptMsg bool, gas uint64, originalPacket v1types.IBCPacket, ack []byte, ) cosmwasm.StdError { var nonce []byte @@ -285,7 +287,7 @@ func ibcPacketAckHelper( func ibcPacketTimeoutHelper( t *testing.T, keeper Keeper, ctx sdk.Context, - contractAddr sdk.AccAddress, creatorPrivKey crypto.PrivKey, msg string, + contractAddr sdk.AccAddress, creatorPrivKey crypto.PrivKey, shouldEncryptMsg bool, gas uint64, originalPacket v1types.IBCPacket, ) cosmwasm.StdError { var nonce []byte @@ -336,3 +338,28 @@ func ibcPacketTimeoutHelper( return cosmwasm.StdError{} } + +func TestIBCChannelOpen(t *testing.T) { + ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, "./testdata/ibc/contract.wasm", sdk.NewCoins()) + + _, _, contractAddress, _, err := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"init":{}}`, true, true, defaultGasForTests) + require.Empty(t, err) + + ibcChannel := v1types.IBCChannel{ + Endpoint: createIBCEndpoint(PortIDForContract(contractAddress), "channel.0"), + CounterpartyEndpoint: createIBCEndpoint(PortIDForContract(contractAddress), "channel.1"), + Order: v1types.Unordered, + Version: "1", + ConnectionID: "1", + } + _, err = ibcChannelOpenHelper(t, keeper, ctx, contractAddress, privKeyA, defaultGasForTests, false, ibcChannel) + require.Empty(t, err) + + queryRes, err := queryHelper(t, keeper, ctx, contractAddress, `{}`, true, true, math.MaxUint64) + require.Empty(t, err) + + var resp uint64 + e := json.Unmarshal([]byte(queryRes), &resp) + require.NoError(t, e) + require.Equal(t, uint64(1), resp) +} From 488cf00b4b6abb34700a3e1f659d0dba7ef712e5 Mon Sep 17 00:00:00 2001 From: Lior Bondarevski Date: Sun, 28 Aug 2022 16:45:43 +0300 Subject: [PATCH 75/93] Fix ibc --- app/app.go | 2 +- .../src/contract_operations.rs | 17 ++++---- .../enclaves/shared/contract-engine/src/io.rs | 41 ++++++++++++++++++- .../enclaves/shared/cosmos-types/src/types.rs | 6 +++ .../shared/cosmwasm-v1-types/src/ibc.rs | 9 ++++ go-cosmwasm/cmd/main.go | 2 +- go-cosmwasm/lib.go | 24 ++++++++--- go-cosmwasm/types/v1/ibc.go | 5 +++ x/compute/internal/keeper/keeper_test.go | 2 +- 9 files changed, 89 insertions(+), 19 deletions(-) diff --git a/app/app.go b/app/app.go index 326fddf9f..81ec0ec9e 100644 --- a/app/app.go +++ b/app/app.go @@ -419,7 +419,7 @@ func NewSecretNetworkApp( // The last arguments can contain custom message handlers, and custom query handlers, // if we want to allow any custom callbacks - supportedFeatures := "staking" + supportedFeatures := "staking,stargate,ibc3" app.computeKeeper = compute.NewKeeper( appCodec, diff --git a/cosmwasm/enclaves/shared/contract-engine/src/contract_operations.rs b/cosmwasm/enclaves/shared/contract-engine/src/contract_operations.rs index 7231f010a..2b0da1b0d 100644 --- a/cosmwasm/enclaves/shared/contract-engine/src/contract_operations.rs +++ b/cosmwasm/enclaves/shared/contract-engine/src/contract_operations.rs @@ -723,14 +723,6 @@ pub fn handle( EnclaveError::FailedToDeserialize })?; - let canonical_sender_address = CanonicalAddr::from_human(&env_v010.message.sender).map_err(|err| { - warn!( - "init got an error while trying to deserialize env_v010.message.sender from bech32 string to bytes {:?}: {}", - env_v010.message.sender, err - ); - EnclaveError::FailedToDeserialize - })?; - let contract_key = extract_contract_key(&env_v010)?; if !validate_contract_key(&contract_key, &canonical_contract_address, &contract_code) { @@ -822,6 +814,15 @@ pub fn handle( ); if was_msg_encrypted { + + let canonical_sender_address = CanonicalAddr::from_human(&env_v010.message.sender).map_err(|err| { + warn!( + "handle got an error while trying to deserialize env_v010.message.sender from bech32 string to bytes {:?}: {}", + env_v010.message.sender, err + ); + EnclaveError::FailedToDeserialize + })?; + output = encrypt_output( output, &secret_msg, diff --git a/cosmwasm/enclaves/shared/contract-engine/src/io.rs b/cosmwasm/enclaves/shared/contract-engine/src/io.rs index 3ef7b0cdb..2e6db65e4 100644 --- a/cosmwasm/enclaves/shared/contract-engine/src/io.rs +++ b/cosmwasm/enclaves/shared/contract-engine/src/io.rs @@ -60,6 +60,10 @@ pub enum RawWasmOutput { #[serde(rename = "Ok")] ok: enclave_cosmwasm_v1_types::ibc::IbcReceiveResponse, }, + OkIBCOpenChannel { + #[serde(rename = "Ok")] + ok: enclave_cosmwasm_v1_types::ibc::IbcChannelOpenResponse, + }, } #[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] @@ -80,7 +84,7 @@ pub struct V1WasmOutput { #[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] pub struct IBCOutput { - #[serde(rename = "Ok")] + #[serde(rename = "ok")] pub ok: Option, #[serde(rename = "Err")] pub err: Option, @@ -88,12 +92,20 @@ pub struct IBCOutput { #[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] pub struct IBCReceiveOutput { - #[serde(rename = "Ok")] + #[serde(rename = "ok")] pub ok: Option, #[serde(rename = "Err")] pub err: Option, } +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] +pub struct IBCOpenChannelOutput { + #[serde(rename = "ok")] + pub ok: Option, + #[serde(rename = "Err")] + pub err: Option, +} + #[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] pub struct QueryOutput { #[serde(rename = "Ok")] @@ -108,6 +120,7 @@ pub struct WasmOutput { pub v1: Option, pub ibc_basic: Option, pub ibc_packet_receive: Option, + pub ibc_open_channel: Option, pub query: Option, pub internal_reply_enclave_sig: Option, pub internal_msg_id: Option, @@ -193,6 +206,7 @@ pub fn finalize_raw_output(raw_output: RawWasmOutput, is_query_output: bool) -> v1: None, ibc_basic: None, ibc_packet_receive: None, + ibc_open_channel: None, query: Some(QueryOutput { ok: None, err: Some(err), @@ -209,6 +223,7 @@ pub fn finalize_raw_output(raw_output: RawWasmOutput, is_query_output: bool) -> v1: None, ibc_basic: None, ibc_packet_receive: None, + ibc_open_channel: None, query: None, internal_reply_enclave_sig, internal_msg_id, @@ -227,6 +242,7 @@ pub fn finalize_raw_output(raw_output: RawWasmOutput, is_query_output: bool) -> v1: None, ibc_basic: None, ibc_packet_receive: None, + ibc_open_channel: None, query: None, internal_reply_enclave_sig, internal_msg_id, @@ -243,6 +259,7 @@ pub fn finalize_raw_output(raw_output: RawWasmOutput, is_query_output: bool) -> }), ibc_basic: None, ibc_packet_receive: None, + ibc_open_channel: None, query: None, internal_reply_enclave_sig, internal_msg_id, @@ -252,6 +269,7 @@ pub fn finalize_raw_output(raw_output: RawWasmOutput, is_query_output: bool) -> v1: None, ibc_basic: None, ibc_packet_receive: None, + ibc_open_channel: None, query: Some(QueryOutput { ok: Some(ok), err: None, @@ -267,6 +285,7 @@ pub fn finalize_raw_output(raw_output: RawWasmOutput, is_query_output: bool) -> ok: Some(ok), }), ibc_packet_receive: None, + ibc_open_channel: None, query: None, internal_reply_enclave_sig: None, internal_msg_id: None, @@ -279,6 +298,23 @@ pub fn finalize_raw_output(raw_output: RawWasmOutput, is_query_output: bool) -> err: None, ok: Some(ok), }), + ibc_open_channel: None, + query: None, + internal_reply_enclave_sig: None, + internal_msg_id: None, + }, + RawWasmOutput::OkIBCOpenChannel { ok } => WasmOutput { + v010: None, + v1: None, + ibc_basic: None, + ibc_packet_receive: None, + ibc_open_channel: Some(IBCOpenChannelOutput { + err: None, + ok: match ok { + Some(o) => Some(o.version), + None => None, + }, + }), query: None, internal_reply_enclave_sig: None, internal_msg_id: None, @@ -637,6 +673,7 @@ pub fn encrypt_output( &reply_params, )?)?; } + RawWasmOutput::OkIBCOpenChannel { ok: _ } => {} }; let final_output = finalize_raw_output(output, is_query_output); diff --git a/cosmwasm/enclaves/shared/cosmos-types/src/types.rs b/cosmwasm/enclaves/shared/cosmos-types/src/types.rs index 39cf0dc5e..5a1b58bb5 100644 --- a/cosmwasm/enclaves/shared/cosmos-types/src/types.rs +++ b/cosmwasm/enclaves/shared/cosmos-types/src/types.rs @@ -159,6 +159,12 @@ impl HandleType { match value { 0 => Ok(HandleType::HANDLE_TYPE_EXECUTE), 1 => Ok(HandleType::HANDLE_TYPE_REPLY), + 2 => Ok(HandleType::HANDLE_TYPE_IBC_CHANNEL_OPEN), + 3 => Ok(HandleType::HANDLE_TYPE_IBC_CHANNEL_CONNECT), + 4 => Ok(HandleType::HANDLE_TYPE_IBC_CHANNEL_CLOSE), + 5 => Ok(HandleType::HANDLE_TYPE_IBC_PACKET_RECEIVE), + 6 => Ok(HandleType::HANDLE_TYPE_IBC_PACKET_ACK), + 7 => Ok(HandleType::HANDLE_TYPE_IBC_PACKET_TIMEOUT), _ => { error!("unrecognized handle type: {}", value); Err(EnclaveError::FailedToDeserialize) diff --git a/cosmwasm/enclaves/shared/cosmwasm-v1-types/src/ibc.rs b/cosmwasm/enclaves/shared/cosmwasm-v1-types/src/ibc.rs index cbb02ec70..751bb4caf 100644 --- a/cosmwasm/enclaves/shared/cosmwasm-v1-types/src/ibc.rs +++ b/cosmwasm/enclaves/shared/cosmwasm-v1-types/src/ibc.rs @@ -32,6 +32,15 @@ pub struct IbcChannel { pub connection_id: String, } +/// This serializes either as "null" or a JSON object. +pub type IbcChannelOpenResponse = Option; + +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq)] +pub struct Ibc3ChannelOpenResponse { + /// We can set the channel version to a different one than we were called with + pub version: String, +} + /// This is the return value for the majority of the ibc handlers. /// That are able to dispatch messages / events on their own, /// but have no meaningful return value to the calling code. diff --git a/go-cosmwasm/cmd/main.go b/go-cosmwasm/cmd/main.go index c088ecbaf..ac130b90b 100644 --- a/go-cosmwasm/cmd/main.go +++ b/go-cosmwasm/cmd/main.go @@ -23,7 +23,7 @@ func main() { panic(err) } - wasmer, err := wasm.NewWasmer("tmp", "staking", 0, 15) + wasmer, err := wasm.NewWasmer("tmp", "staking,stargate,ibc3", 0, 15) if err != nil { panic(err) } diff --git a/go-cosmwasm/lib.go b/go-cosmwasm/lib.go index 970da2127..dd28a2ddf 100644 --- a/go-cosmwasm/lib.go +++ b/go-cosmwasm/lib.go @@ -86,12 +86,13 @@ func (w *Wasmer) GetCode(code CodeID) (WasmCode, error) { // This struct helps us to distinguish between v0.10 contract response and v1 contract response type ContractExecResponse struct { - V1 *V1ContractExecResponse `json:"v1,omitempty"` - V010 *V010ContractExecResponse `json:"v010,omitempty"` - InternaReplyEnclaveSig []byte `json:"internal_reply_enclave_sig"` - InternalMsgId []byte `json:"internal_msg_id"` - IBCBasic *v1types.IBCBasicResult `json:"ibc_basic,omitempty"` - IBCPacketReceive *v1types.IBCReceiveResult `json:"ibc_packet_receive,omitempty"` + V1 *V1ContractExecResponse `json:"v1,omitempty"` + V010 *V010ContractExecResponse `json:"v010,omitempty"` + InternaReplyEnclaveSig []byte `json:"internal_reply_enclave_sig"` + InternalMsgId []byte `json:"internal_msg_id"` + IBCBasic *v1types.IBCBasicResult `json:"ibc_basic,omitempty"` + IBCPacketReceive *v1types.IBCReceiveResult `json:"ibc_packet_receive,omitempty"` + IBCChannelOpen *v1types.IBCOpenChannelResult `json:"ibc_open_channel,omitempty"` } type V010ContractExecResponse struct { @@ -334,6 +335,17 @@ func (w *Wasmer) Execute( } } + if resp.IBCChannelOpen != nil { + if resp.IBCChannelOpen.Err != nil { + return nil, gasUsed, fmt.Errorf("%+v", resp.IBCChannelOpen.Err) + } else if resp.IBCChannelOpen.Ok != nil { + // ibc_channel_open actually returns no data + return resp.IBCChannelOpen.Ok, gasUsed, nil + } else { + return nil, gasUsed, fmt.Errorf("cannot parse IBCChannelOpen response: %+v", resp) + } + } + return nil, gasUsed, fmt.Errorf("handle: cannot detect response type (v0.10 or v1)") } diff --git a/go-cosmwasm/types/v1/ibc.go b/go-cosmwasm/types/v1/ibc.go index efe2a462d..78099b298 100644 --- a/go-cosmwasm/types/v1/ibc.go +++ b/go-cosmwasm/types/v1/ibc.go @@ -252,6 +252,11 @@ type IBCReceiveResult struct { Err *types.StdError `json:"Err,omitempty"` } +type IBCOpenChannelResult struct { + Ok *string `json:"ok,omitempty"` + Err *types.StdError `json:"Err,omitempty"` +} + // IBCReceiveResponse defines the return value on packet response processing. // This "success" case should be returned even in application-level errors, // Where the Acknowledgement bytes contain an encoded error message to be returned to diff --git a/x/compute/internal/keeper/keeper_test.go b/x/compute/internal/keeper/keeper_test.go index 8b69ed572..82e9d22f7 100644 --- a/x/compute/internal/keeper/keeper_test.go +++ b/x/compute/internal/keeper/keeper_test.go @@ -22,7 +22,7 @@ import ( reg "github.com/enigmampc/SecretNetwork/x/registration" ) -const SupportedFeatures = "staking" +const SupportedFeatures = "staking,stargate,ibc3" var wasmCtx = wasmUtils.WASMContext{ TestKeyPairPath: "/tmp/id_tx_io.json", From 171e7699f1fe3ff9220133b81f3dc99e162e1f7b Mon Sep 17 00:00:00 2001 From: Lior Bondarevski Date: Sun, 28 Aug 2022 17:24:14 +0300 Subject: [PATCH 76/93] Now channel open works --- Makefile | 2 +- cosmwasm/enclaves/shared/contract-engine/src/io.rs | 2 +- x/compute/internal/keeper/ibc_test.go | 8 ++------ x/compute/internal/keeper/relay.go | 8 ++------ x/compute/internal/keeper/testdata/ibc/src/contract.rs | 6 ++++-- x/compute/internal/keeper/testdata/ibc/src/msg.rs | 4 +++- 6 files changed, 13 insertions(+), 17 deletions(-) diff --git a/Makefile b/Makefile index fdab5964d..e06ef7e31 100644 --- a/Makefile +++ b/Makefile @@ -348,7 +348,7 @@ build-test-contract: # sudo apt install -y binaryen $(MAKE) -C ./x/compute/internal/keeper/testdata/test-contract $(MAKE) -C ./x/compute/internal/keeper/testdata/v1-sanity-contract - $(MAKE) -C ./x/compute/internal/keeper/testdata/ibc-contract + $(MAKE) -C ./x/compute/internal/keeper/testdata/ibc prep-go-tests: build-test-contract diff --git a/cosmwasm/enclaves/shared/contract-engine/src/io.rs b/cosmwasm/enclaves/shared/contract-engine/src/io.rs index 2e6db65e4..6d747cddf 100644 --- a/cosmwasm/enclaves/shared/contract-engine/src/io.rs +++ b/cosmwasm/enclaves/shared/contract-engine/src/io.rs @@ -312,7 +312,7 @@ pub fn finalize_raw_output(raw_output: RawWasmOutput, is_query_output: bool) -> err: None, ok: match ok { Some(o) => Some(o.version), - None => None, + None => Some("".to_string()), }, }), query: None, diff --git a/x/compute/internal/keeper/ibc_test.go b/x/compute/internal/keeper/ibc_test.go index 26fa0aad1..8dd249175 100644 --- a/x/compute/internal/keeper/ibc_test.go +++ b/x/compute/internal/keeper/ibc_test.go @@ -2,7 +2,6 @@ package keeper import ( "encoding/hex" - "encoding/json" "math" "testing" @@ -355,11 +354,8 @@ func TestIBCChannelOpen(t *testing.T) { _, err = ibcChannelOpenHelper(t, keeper, ctx, contractAddress, privKeyA, defaultGasForTests, false, ibcChannel) require.Empty(t, err) - queryRes, err := queryHelper(t, keeper, ctx, contractAddress, `{}`, true, true, math.MaxUint64) + queryRes, err := queryHelper(t, keeper, ctx, contractAddress, `{"q":{}}`, true, true, math.MaxUint64) require.Empty(t, err) - var resp uint64 - e := json.Unmarshal([]byte(queryRes), &resp) - require.NoError(t, e) - require.Equal(t, uint64(1), resp) + require.Equal(t, "1", queryRes) } diff --git a/x/compute/internal/keeper/relay.go b/x/compute/internal/keeper/relay.go index 7bb821966..4497b95c9 100644 --- a/x/compute/internal/keeper/relay.go +++ b/x/compute/internal/keeper/relay.go @@ -100,12 +100,8 @@ func (k Keeper) OnOpenChannel( } switch resp := res.(type) { - case *v1types.IBC3ChannelOpenResponse: - if resp != nil { - return resp.Version, nil - } else { - return "", nil - } + case *string: + return *resp, nil default: return "", sdkerrors.Wrap(types.ErrExecuteFailed, fmt.Sprintf("ibc-open-channel: cannot cast res to IBC3ChannelOpenResponse: %+v", res)) } diff --git a/x/compute/internal/keeper/testdata/ibc/src/contract.rs b/x/compute/internal/keeper/testdata/ibc/src/contract.rs index 771e99267..3f892ac72 100644 --- a/x/compute/internal/keeper/testdata/ibc/src/contract.rs +++ b/x/compute/internal/keeper/testdata/ibc/src/contract.rs @@ -1,7 +1,8 @@ use crate::msg::{ExecuteMsg, InstantiateMsg, QueryMsg}; use crate::state::{count, count_read}; use cosmwasm_std::{ - entry_point, Binary, Deps, DepsMut, Env, IbcChannelOpenMsg, MessageInfo, Response, StdResult, + entry_point, to_binary, Binary, Deps, DepsMut, Env, IbcChannelOpenMsg, MessageInfo, Response, + StdResult, }; #[entry_point] @@ -26,7 +27,8 @@ pub fn execute( #[entry_point] pub fn query(deps: Deps, _env: Env, _msg: QueryMsg) -> StdResult { - Ok(count_read(deps.storage).load()?.to_be_bytes().into()) + let answer = count_read(deps.storage).load()?; + Ok(to_binary(&answer)?) } #[entry_point] diff --git a/x/compute/internal/keeper/testdata/ibc/src/msg.rs b/x/compute/internal/keeper/testdata/ibc/src/msg.rs index 0a45c67d3..3d5253b37 100644 --- a/x/compute/internal/keeper/testdata/ibc/src/msg.rs +++ b/x/compute/internal/keeper/testdata/ibc/src/msg.rs @@ -13,4 +13,6 @@ pub enum ExecuteMsg {} #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] #[serde(rename_all = "snake_case")] -pub enum QueryMsg {} +pub enum QueryMsg { + Q {}, +} From 9f7097267d00ad3530a81a7ac2ee73e1d3dc9cb2 Mon Sep 17 00:00:00 2001 From: Lior Bondarevski Date: Sun, 28 Aug 2022 18:21:26 +0300 Subject: [PATCH 77/93] IBC Channel Connect WIP --- x/compute/internal/keeper/ibc_test.go | 70 ++++++++++- .../internal/keeper/testdata/ibc/Cargo.toml | 2 +- .../keeper/testdata/ibc/src/contract.rs | 115 ++++++++++++++++-- .../internal/keeper/testdata/ibc/src/msg.rs | 4 +- 4 files changed, 179 insertions(+), 12 deletions(-) diff --git a/x/compute/internal/keeper/ibc_test.go b/x/compute/internal/keeper/ibc_test.go index 8dd249175..b67838c60 100644 --- a/x/compute/internal/keeper/ibc_test.go +++ b/x/compute/internal/keeper/ibc_test.go @@ -16,7 +16,7 @@ import ( func ibcChannelConnectHelper( t *testing.T, keeper Keeper, ctx sdk.Context, - contractAddr sdk.AccAddress, creatorPrivKey crypto.PrivKey, msg string, + contractAddr sdk.AccAddress, creatorPrivKey crypto.PrivKey, gas uint64, shouldSendOpenAck bool, channel v1types.IBCChannel, ) cosmwasm.StdError { // create new ctx with the same storage and a gas limit @@ -351,11 +351,77 @@ func TestIBCChannelOpen(t *testing.T) { Version: "1", ConnectionID: "1", } - _, err = ibcChannelOpenHelper(t, keeper, ctx, contractAddress, privKeyA, defaultGasForTests, false, ibcChannel) + + version, err := ibcChannelOpenHelper(t, keeper, ctx, contractAddress, privKeyA, defaultGasForTests, false, ibcChannel) require.Empty(t, err) + require.Equal(t, version, "ibc-v1") queryRes, err := queryHelper(t, keeper, ctx, contractAddress, `{"q":{}}`, true, true, math.MaxUint64) require.Empty(t, err) require.Equal(t, "1", queryRes) } + +func TestIBCChannelOpenTry(t *testing.T) { + ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, "./testdata/ibc/contract.wasm", sdk.NewCoins()) + + _, _, contractAddress, _, err := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"init":{}}`, true, true, defaultGasForTests) + require.Empty(t, err) + + ibcChannel := v1types.IBCChannel{ + Endpoint: createIBCEndpoint(PortIDForContract(contractAddress), "channel.0"), + CounterpartyEndpoint: createIBCEndpoint(PortIDForContract(contractAddress), "channel.1"), + Order: v1types.Unordered, + Version: "1", + ConnectionID: "1", + } + + version, err := ibcChannelOpenHelper(t, keeper, ctx, contractAddress, privKeyA, defaultGasForTests, true, ibcChannel) + require.Empty(t, err) + require.Equal(t, version, "ibc-v1") + + queryRes, err := queryHelper(t, keeper, ctx, contractAddress, `{"q":{}}`, true, true, math.MaxUint64) + require.Empty(t, err) + + require.Equal(t, "2", queryRes) +} + +func TestIBCChannelConnect(t *testing.T) { + ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, "./testdata/ibc/contract.wasm", sdk.NewCoins()) + + _, _, contractAddress, _, err := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"init":{}}`, true, true, defaultGasForTests) + require.Empty(t, err) + + for _, test := range []struct { + connectionID string + output string + hasAttributes bool + hasEvents bool + }{ + { + connectionID: "1", + output: ``, + isSuccuss: true, + balancesBefore: "5000assaf,200000denom 5000assaf,5000denom", + balancesAfter: "4998assaf,199998denom 5000assaf,5002denom", + }, + } { + t.Run(test.description, func(t *testing.T) { + ibcChannel := v1types.IBCChannel{ + Endpoint: createIBCEndpoint(PortIDForContract(contractAddress), "channel.0"), + CounterpartyEndpoint: createIBCEndpoint(PortIDForContract(contractAddress), "channel.1"), + Order: v1types.Unordered, + Version: "1", + ConnectionID: "1", + } + + err = ibcChannelConnectHelper(t, keeper, ctx, contractAddress, privKeyA, defaultGasForTests, false, ibcChannel) + require.Empty(t, err) + + queryRes, err := queryHelper(t, keeper, ctx, contractAddress, `{"q":{}}`, true, true, math.MaxUint64) + require.Empty(t, err) + + require.Equal(t, "3", queryRes) + }) + } +} diff --git a/x/compute/internal/keeper/testdata/ibc/Cargo.toml b/x/compute/internal/keeper/testdata/ibc/Cargo.toml index f9427e903..f1271dd60 100644 --- a/x/compute/internal/keeper/testdata/ibc/Cargo.toml +++ b/x/compute/internal/keeper/testdata/ibc/Cargo.toml @@ -33,7 +33,7 @@ stargate = [] ibc3 = ["stargate"] [dependencies] -cosmwasm-std = { git = "https://github.com/scrtlabs/cosmwasm", branch = "secret", features=["stargate"] } +cosmwasm-std = { git = "https://github.com/scrtlabs/cosmwasm", branch = "secret", features=["stargate", "ibc3"] } cosmwasm-storage = { git = "https://github.com/scrtlabs/cosmwasm", branch = "secret" } schemars = "0.8.1" serde = { version = "1.0.114", default-features = false, features = [ diff --git a/x/compute/internal/keeper/testdata/ibc/src/contract.rs b/x/compute/internal/keeper/testdata/ibc/src/contract.rs index 3f892ac72..8d24233eb 100644 --- a/x/compute/internal/keeper/testdata/ibc/src/contract.rs +++ b/x/compute/internal/keeper/testdata/ibc/src/contract.rs @@ -1,10 +1,14 @@ use crate::msg::{ExecuteMsg, InstantiateMsg, QueryMsg}; use crate::state::{count, count_read}; use cosmwasm_std::{ - entry_point, to_binary, Binary, Deps, DepsMut, Env, IbcChannelOpenMsg, MessageInfo, Response, - StdResult, + coins, entry_point, to_binary, Binary, CosmosMsg, Deps, DepsMut, Env, Event, + Ibc3ChannelOpenResponse, IbcBasicResponse, IbcChannelConnectMsg, IbcChannelOpenMsg, + IbcChannelOpenResponse, MessageInfo, Reply, ReplyOn, Response, StdError, StdResult, SubMsg, + SubMsgResult, WasmMsg, }; +pub const IBC_APP_VERSION: &str = "ibc-v1"; + #[entry_point] pub fn instantiate( _deps: DepsMut, @@ -17,12 +21,14 @@ pub fn instantiate( #[entry_point] pub fn execute( - _deps: DepsMut, + deps: DepsMut, _env: Env, _info: MessageInfo, - _msg: ExecuteMsg, + msg: ExecuteMsg, ) -> StdResult { - Ok(Response::default()) + match msg { + ExecuteMsg::Increment { addition } => increment(deps, addition), + } } #[entry_point] @@ -32,7 +38,100 @@ pub fn query(deps: Deps, _env: Env, _msg: QueryMsg) -> StdResult { } #[entry_point] -pub fn ibc_channel_open(deps: DepsMut, _env: Env, _msg: IbcChannelOpenMsg) -> StdResult<()> { - count(deps.storage).save(&1)?; - Ok(()) +pub fn reply(deps: DepsMut, _env: Env, reply: Reply) -> StdResult { + match (reply.id, reply.result) { + (1, SubMsgResult::Err(_)) => Err(StdError::generic_err("Failed to inc")), + (1, SubMsgResult::Ok(_)) => { + increment(deps, 6)?; + Ok(Response::default()) + } + _ => Err(StdError::generic_err("invalid reply id or result")), + } +} + +#[entry_point] +pub fn ibc_channel_open( + deps: DepsMut, + _env: Env, + msg: IbcChannelOpenMsg, +) -> StdResult { + match msg { + IbcChannelOpenMsg::OpenInit { channel: _ } => count(deps.storage).save(&1)?, + IbcChannelOpenMsg::OpenTry { + channel: _, + counterparty_version: _, + } => count(deps.storage).save(&2)?, + _ => {} + } + + Ok(Some(Ibc3ChannelOpenResponse { + version: IBC_APP_VERSION.to_string(), + })) +} + +pub fn increment(deps: DepsMut, c: u64) -> StdResult { + let new_count = count_read(deps.storage).load()? + c; + count(deps.storage).save(&new_count)?; + + let mut resp = Response::default(); + resp.data = Some((new_count as u32).to_be_bytes().into()); + + Ok(resp) +} + +#[entry_point] +pub fn ibc_channel_connect( + deps: DepsMut, + env: Env, + msg: IbcChannelConnectMsg, +) -> StdResult { + match msg { + IbcChannelConnectMsg::OpenAck { + channel: _, + counterparty_version: _, + } => { + count(deps.storage).save(&3)?; + Ok(IbcBasicResponse::default()) + } + IbcChannelConnectMsg::OpenConfirm { channel } => { + let num: u64 = channel.connection_id.parse::().map_err(|err| { + StdError::generic_err(format!("Got an error from parsing: {:?}", err)) + })?; + + count(deps.storage).save(&(num + 4))?; + + match num { + 0 => Ok(IbcBasicResponse::default()), + 1 => Ok(IbcBasicResponse::new().add_submessage(SubMsg { + id: 1, + msg: CosmosMsg::Wasm(WasmMsg::Execute { + code_hash: env.contract.code_hash, + contract_addr: env.contract.address.into_string(), + msg: Binary::from("{\"increment\":{\"addition\":5}}".as_bytes().to_vec()), + funds: vec![], + }) + .into(), + reply_on: ReplyOn::Never, + gas_limit: None, + })), + 2 => Ok(IbcBasicResponse::new().add_submessage(SubMsg { + id: 1, + msg: CosmosMsg::Wasm(WasmMsg::Execute { + code_hash: env.contract.code_hash, + contract_addr: env.contract.address.into_string(), + msg: Binary::from("{\"increment\":{\"addition\":5}}".as_bytes().to_vec()), + funds: vec![], + }) + .into(), + reply_on: ReplyOn::Always, + gas_limit: None, + })), + 3 => Ok(IbcBasicResponse::new().add_attribute("attr1", "😗")), + 4 => Ok(IbcBasicResponse::new() + .add_event(Event::new("cyber1".to_string()).add_attribute("attr1", "🤯"))), + _ => Err(StdError::generic_err("Unsupported channel connect type")), + } + } + _ => Err(StdError::generic_err("Unsupported channel connect")), + } } diff --git a/x/compute/internal/keeper/testdata/ibc/src/msg.rs b/x/compute/internal/keeper/testdata/ibc/src/msg.rs index 3d5253b37..8b51690a7 100644 --- a/x/compute/internal/keeper/testdata/ibc/src/msg.rs +++ b/x/compute/internal/keeper/testdata/ibc/src/msg.rs @@ -9,7 +9,9 @@ pub enum InstantiateMsg { #[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] #[serde(rename_all = "snake_case")] -pub enum ExecuteMsg {} +pub enum ExecuteMsg { + Increment { addition: u64 }, +} #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] #[serde(rename_all = "snake_case")] From 5833c681037ccd797581f5f022bbc728fb1883da Mon Sep 17 00:00:00 2001 From: Lior Bondarevski Date: Sun, 28 Aug 2022 18:28:31 +0300 Subject: [PATCH 78/93] Fix compilation --- .vscode/settings.json | 11 +---------- .../src/contract_operations.rs | 4 +++- x/compute/internal/keeper/test_common.go | 19 +++++++++++++++++++ 3 files changed, 23 insertions(+), 11 deletions(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index 8a277a9f9..8318189d7 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,22 +1,13 @@ { "rust-analyzer.linkedProjects": [ -<<<<<<< HEAD "cosmwasm/Cargo.toml", "cosmwasm/enclaves/Cargo.toml", "x/compute/internal/keeper/testdata/v1-sanity-contract/Cargo.toml", "x/compute/internal/keeper/testdata/test-contract/Cargo.toml", + "./x/compute/internal/keeper/testdata/ibc/Cargo.toml", "integration-tests/contract-v1/Cargo.toml", "integration-tests/contract-v0.10/Cargo.toml", "go-cosmwasm/Cargo.toml" -======= - "./cosmwasm/Cargo.toml", - "./cosmwasm/enclaves/Cargo.toml", - "./x/compute/internal/keeper/testdata/v1-sanity-contract/Cargo.toml", - "./x/compute/internal/keeper/testdata/test-contract/Cargo.toml", - "./x/compute/internal/keeper/testdata/ibc/Cargo.toml", - "./cosmwasm/enclaves/shared/cosmwasm-v1-types/Cargo.toml", - "./cosmwasm/enclaves/shared/cosmwasm-v010-types/Cargo.toml" ->>>>>>> cw-1-ibc-receive-hooks ], "rust-analyzer.diagnostics.experimental.enable": true, "rust-analyzer.rustfmt.rangeFormatting.enable": true, diff --git a/cosmwasm/enclaves/shared/contract-engine/src/contract_operations.rs b/cosmwasm/enclaves/shared/contract-engine/src/contract_operations.rs index d16b6667a..ddca7f1eb 100644 --- a/cosmwasm/enclaves/shared/contract-engine/src/contract_operations.rs +++ b/cosmwasm/enclaves/shared/contract-engine/src/contract_operations.rs @@ -169,7 +169,9 @@ pub fn handle( let canonical_contract_address = to_canonical(contract_address)?; - let contract_key = extract_contract_key(&env_v010)?; + let canonical_sender_address = to_canonical(sender)?; + + let contract_key = base_env.get_contract_key()?; validate_contract_key(&contract_key, &canonical_contract_address, &contract_code)?; diff --git a/x/compute/internal/keeper/test_common.go b/x/compute/internal/keeper/test_common.go index 2a8ec1969..b5f67681b 100644 --- a/x/compute/internal/keeper/test_common.go +++ b/x/compute/internal/keeper/test_common.go @@ -541,6 +541,25 @@ func PrepareExecSignedTx(t *testing.T, keeper Keeper, ctx sdk.Context, sender sd return ctx.WithTxBytes(txBytes) } +func PrepareInitSignedTx(t *testing.T, keeper Keeper, ctx sdk.Context, creator sdk.AccAddress, privKey crypto.PrivKey, encMsg []byte, codeID uint64, funds sdk.Coins) sdk.Context { + creatorAcc, err := ante.GetSignerAcc(ctx, keeper.accountKeeper, creator) + require.NoError(t, err) + + initMsg := wasmtypes.MsgInstantiateContract{ + Sender: creator, + CodeID: codeID, + Label: "demo contract 1", + InitMsg: encMsg, + InitFunds: funds, + } + tx := NewTestTx(&initMsg, creatorAcc, privKey) + + txBytes, err := tx.Marshal() + require.NoError(t, err) + + return ctx.WithTxBytes(txBytes) +} + func NewTestTx(msg sdk.Msg, creatorAcc authtypes.AccountI, privKey crypto.PrivKey) *tx.Tx { return NewTestTxMultiple([]sdk.Msg{msg}, []authtypes.AccountI{creatorAcc}, []crypto.PrivKey{privKey}) } From c29e8a6f03a2c060187b514649a81ab32e396531 Mon Sep 17 00:00:00 2001 From: Eshel Date: Sun, 28 Aug 2022 19:04:21 +0300 Subject: [PATCH 79/93] fixing compilation errors on contract_operations and io.rs --- .../shared/contract-engine/src/contract_operations.rs | 8 ++++---- cosmwasm/enclaves/shared/contract-engine/src/io.rs | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/cosmwasm/enclaves/shared/contract-engine/src/contract_operations.rs b/cosmwasm/enclaves/shared/contract-engine/src/contract_operations.rs index ddca7f1eb..56c607523 100644 --- a/cosmwasm/enclaves/shared/contract-engine/src/contract_operations.rs +++ b/cosmwasm/enclaves/shared/contract-engine/src/contract_operations.rs @@ -226,7 +226,7 @@ pub fn handle( )?; let mut versioned_env = - base_env.into_versioned_env(&engine.contract_instance.cosmwasm_api_version); + base_env.clone().into_versioned_env(&engine.contract_instance.cosmwasm_api_version); versioned_env.set_contract_hash(&contract_hash); @@ -250,10 +250,10 @@ pub fn handle( if was_msg_encrypted { - let canonical_sender_address = CanonicalAddr::from_human(&env_v010.message.sender).map_err(|err| { + let canonical_sender_address = CanonicalAddr::from_human(&sender).map_err(|err| { warn!( - "handle got an error while trying to deserialize env_v010.message.sender from bech32 string to bytes {:?}: {}", - env_v010.message.sender, err + "handle got an error while trying to deserialize sender from bech32 string to bytes {:?}: {}", + sender, err ); EnclaveError::FailedToDeserialize })?; diff --git a/cosmwasm/enclaves/shared/contract-engine/src/io.rs b/cosmwasm/enclaves/shared/contract-engine/src/io.rs index c5da71b39..3e2f8690f 100644 --- a/cosmwasm/enclaves/shared/contract-engine/src/io.rs +++ b/cosmwasm/enclaves/shared/contract-engine/src/io.rs @@ -62,7 +62,7 @@ pub enum RawWasmOutput { }, OkIBCOpenChannel { #[serde(rename = "Ok")] - ok: enclave_cosmwasm_v1_types::ibc::IbcChannelOpenResponse, + ok: cw_types_v1::ibc::IbcChannelOpenResponse, }, } From 4c43604535641019a7f9d136398ada2448e835a9 Mon Sep 17 00:00:00 2001 From: Lior Bondarevski Date: Sun, 28 Aug 2022 23:32:05 +0300 Subject: [PATCH 80/93] Channel connect is now workins (Including submessages) --- .../src/contract_operations.rs | 34 ++- .../enclaves/shared/contract-engine/src/io.rs | 196 +++++++++++------- .../shared/cosmwasm-v1-types/src/ibc.rs | 14 ++ .../cosmwasm-v1-types/src/results/response.rs | 4 +- go-cosmwasm/lib.go | 1 + x/compute/internal/keeper/ibc_test.go | 121 +++++++++-- x/compute/internal/keeper/keeper.go | 1 + x/compute/internal/keeper/msg_dispatcher.go | 16 +- x/compute/internal/keeper/relay.go | 7 +- .../keeper/testdata/ibc/src/contract.rs | 8 +- 10 files changed, 294 insertions(+), 108 deletions(-) diff --git a/cosmwasm/enclaves/shared/contract-engine/src/contract_operations.rs b/cosmwasm/enclaves/shared/contract-engine/src/contract_operations.rs index 2b0da1b0d..714ed49fe 100644 --- a/cosmwasm/enclaves/shared/contract-engine/src/contract_operations.rs +++ b/cosmwasm/enclaves/shared/contract-engine/src/contract_operations.rs @@ -30,7 +30,10 @@ use super::contract_validation::{ verify_params, ContractKey, }; use super::gas::WasmCosts; -use super::io::{encrypt_output, finalize_raw_output, RawWasmOutput}; +use super::io::{ + encrypt_output, finalize_raw_output, manipulate_callback_sig_for_plaintext, + set_all_logs_to_plaintext, +}; use super::module_cache::create_module_instance; use super::types::{IoNonce, SecretMessage}; use super::wasm::{ContractInstance, ContractOperation, Engine}; @@ -158,6 +161,7 @@ pub fn init( reply_params, &canonical_sender_address, false, + false, )?; Ok(output) @@ -361,7 +365,7 @@ pub fn parse_message( let decrypted_msg = secret_msg.msg.clone(); Ok(ParsedMessage { - should_validate_sig_info: true, + should_validate_sig_info: false, was_msg_encrypted: false, secret_msg, decrypted_msg, @@ -690,6 +694,18 @@ pub fn parse_message( }; } +pub fn is_ibc_msg(handle_type: HandleType) -> bool { + match handle_type { + HandleType::HANDLE_TYPE_EXECUTE | HandleType::HANDLE_TYPE_REPLY => false, + HandleType::HANDLE_TYPE_IBC_CHANNEL_OPEN + | HandleType::HANDLE_TYPE_IBC_CHANNEL_CONNECT + | HandleType::HANDLE_TYPE_IBC_CHANNEL_CLOSE + | HandleType::HANDLE_TYPE_IBC_PACKET_RECEIVE + | HandleType::HANDLE_TYPE_IBC_PACKET_ACK + | HandleType::HANDLE_TYPE_IBC_PACKET_TIMEOUT => true, + } +} + #[cfg_attr(feature = "cargo-clippy", allow(clippy::too_many_arguments))] pub fn handle( context: Ctx, @@ -804,7 +820,7 @@ pub fn handle( // This wrapper is used to coalesce all errors in this block to one object // so we can `.map_err()` in one place for all of them let output = coalesce!(EnclaveError, { - let vec_ptr = engine.handle(env_ptr, msg_info_ptr, msg_ptr, parsed_handle_type)?; + let vec_ptr = engine.handle(env_ptr, msg_info_ptr, msg_ptr, parsed_handle_type.clone())?; let mut output = engine.extract_vector(vec_ptr)?; @@ -831,15 +847,14 @@ pub fn handle( reply_params, &canonical_sender_address, false, + is_ibc_msg(parsed_handle_type.clone()), )?; } else { - let raw_output: RawWasmOutput = serde_json::from_slice(&output).map_err(|err| { - warn!("got an error while trying to deserialize output bytes into json"); - trace!("output: {:?} error: {:?}", output, err); - EnclaveError::FailedToDeserialize - })?; + let mut raw_output = manipulate_callback_sig_for_plaintext(output)?; + set_all_logs_to_plaintext(&mut raw_output); - let finalized_output = finalize_raw_output(raw_output, false); + let finalized_output = finalize_raw_output(raw_output, false, is_ibc_msg(parsed_handle_type), false); + trace!("Wasm output for plaintext message is: {:?}", finalized_output); output = serde_json::to_vec(&finalized_output).map_err(|err| { debug!( @@ -942,6 +957,7 @@ pub fn query( None, // Not used for queries (Query response is not replied to the caller), &CanonicalAddr(Binary(Vec::new())), // Not used for queries (used only for replies) true, + false, )?; Ok(output) }) diff --git a/cosmwasm/enclaves/shared/contract-engine/src/io.rs b/cosmwasm/enclaves/shared/contract-engine/src/io.rs index 6d747cddf..f3251cf6d 100644 --- a/cosmwasm/enclaves/shared/contract-engine/src/io.rs +++ b/cosmwasm/enclaves/shared/contract-engine/src/io.rs @@ -6,7 +6,7 @@ use crate::contract_validation::ReplyParams; /// use super::types::{IoNonce, SecretMessage}; use enclave_cosmwasm_v010_types::encoding::Binary; -use enclave_cosmwasm_v010_types::types::{CanonicalAddr, Coin}; +use enclave_cosmwasm_v010_types::types::{CanonicalAddr, Coin, LogAttribute}; use enclave_cosmwasm_v1_types::results::{Event, Reply, ReplyOn, SubMsgResponse, SubMsgResult}; use enclave_ffi_types::EnclaveError; @@ -52,10 +52,6 @@ pub enum RawWasmOutput { internal_reply_enclave_sig: Option, internal_msg_id: Option, }, - OkIBCBasic { - #[serde(rename = "Ok")] - ok: enclave_cosmwasm_v1_types::ibc::IbcBasicResponse, - }, OkIBCPacketReceive { #[serde(rename = "Ok")] ok: enclave_cosmwasm_v1_types::ibc::IbcReceiveResponse, @@ -193,7 +189,12 @@ fn b64_encode(data: &[u8]) -> String { base64::encode(data) } -pub fn finalize_raw_output(raw_output: RawWasmOutput, is_query_output: bool) -> WasmOutput { +pub fn finalize_raw_output( + raw_output: RawWasmOutput, + is_query_output: bool, + is_ibc: bool, + is_msg_encrypted: bool, +) -> WasmOutput { return match raw_output { RawWasmOutput::Err { err, @@ -217,7 +218,10 @@ pub fn finalize_raw_output(raw_output: RawWasmOutput, is_query_output: bool) -> } else { WasmOutput { v010: Some(V010WasmOutput { - err: Some(err), + err: match is_msg_encrypted { + true => Some(err), + false => Some(json!({"generic_err":{"msg":err}})), + }, ok: None, }), v1: None, @@ -251,18 +255,37 @@ pub fn finalize_raw_output(raw_output: RawWasmOutput, is_query_output: bool) -> ok, internal_reply_enclave_sig, internal_msg_id, - } => WasmOutput { - v010: None, - v1: Some(V1WasmOutput { - err: None, - ok: Some(ok), - }), - ibc_basic: None, - ibc_packet_receive: None, - ibc_open_channel: None, - query: None, - internal_reply_enclave_sig, - internal_msg_id, + } => match is_ibc { + false => WasmOutput { + v010: None, + v1: Some(V1WasmOutput { + err: None, + ok: Some(ok), + }), + ibc_basic: None, + ibc_packet_receive: None, + ibc_open_channel: None, + query: None, + internal_reply_enclave_sig, + internal_msg_id, + }, + true => WasmOutput { + v010: None, + v1: None, + ibc_basic: Some(IBCOutput { + err: None, + ok: Some(enclave_cosmwasm_v1_types::ibc::IbcBasicResponse::new( + ok.messages, + ok.attributes, + ok.events, + )), + }), + ibc_packet_receive: None, + ibc_open_channel: None, + query: None, + internal_reply_enclave_sig, + internal_msg_id, + }, }, RawWasmOutput::QueryOkV010 { ok } | RawWasmOutput::QueryOkV1 { ok } => WasmOutput { v010: None, @@ -277,19 +300,6 @@ pub fn finalize_raw_output(raw_output: RawWasmOutput, is_query_output: bool) -> internal_reply_enclave_sig: None, internal_msg_id: None, }, - RawWasmOutput::OkIBCBasic { ok } => WasmOutput { - v010: None, - v1: None, - ibc_basic: Some(IBCOutput { - err: None, - ok: Some(ok), - }), - ibc_packet_receive: None, - ibc_open_channel: None, - query: None, - internal_reply_enclave_sig: None, - internal_msg_id: None, - }, RawWasmOutput::OkIBCPacketReceive { ok } => WasmOutput { v010: None, v1: None, @@ -322,6 +332,82 @@ pub fn finalize_raw_output(raw_output: RawWasmOutput, is_query_output: bool) -> }; } +pub fn manipulate_callback_sig_for_plaintext( + output: Vec, +) -> Result { + let mut raw_output: RawWasmOutput = serde_json::from_slice(&output).map_err(|err| { + warn!("got an error while trying to deserialize output bytes into json"); + trace!("output: {:?} error: {:?}", output, err); + EnclaveError::FailedToDeserialize + })?; + + match &mut raw_output { + RawWasmOutput::OkV1 { ok, .. } => { + for sub_msg in &mut ok.messages { + if let enclave_cosmwasm_v1_types::results::CosmosMsg::Wasm(wasm_msg) = + &mut sub_msg.msg + { + match wasm_msg { + enclave_cosmwasm_v1_types::results::WasmMsg::Execute { + callback_sig, + .. + } + | enclave_cosmwasm_v1_types::results::WasmMsg::Instantiate { + callback_sig, + .. + } => *callback_sig = Some(vec![]), + } + } + } + } + RawWasmOutput::OkIBCPacketReceive { ok } => { + for sub_msg in &mut ok.messages { + if let enclave_cosmwasm_v1_types::results::CosmosMsg::Wasm(wasm_msg) = + &mut sub_msg.msg + { + match wasm_msg { + enclave_cosmwasm_v1_types::results::WasmMsg::Execute { + callback_sig, + .. + } + | enclave_cosmwasm_v1_types::results::WasmMsg::Instantiate { + callback_sig, + .. + } => *callback_sig = Some(vec![]), + } + } + } + } + _ => {} + } + + Ok(raw_output) +} + +pub fn set_attributes_to_plaintext(attributes: &mut Vec) { + for attr in attributes { + attr.encrypted = false; + } +} + +pub fn set_all_logs_to_plaintext(raw_output: &mut RawWasmOutput) { + match raw_output { + RawWasmOutput::OkV1 { ok, .. } => { + set_attributes_to_plaintext(&mut ok.attributes); + for ev in &mut ok.events { + set_attributes_to_plaintext(&mut ev.attributes); + } + } + RawWasmOutput::OkIBCPacketReceive { ok } => { + set_attributes_to_plaintext(&mut ok.attributes); + for ev in &mut ok.events { + set_attributes_to_plaintext(&mut ev.attributes); + } + } + _ => {} + } +} + pub fn encrypt_output( output: Vec, secret_msg: &SecretMessage, @@ -330,6 +416,7 @@ pub fn encrypt_output( reply_params: Option, sender_addr: &CanonicalAddr, is_query_output: bool, + is_ibc_output: bool, ) -> Result, EnclaveError> { // When encrypting an output we might encrypt an output that is a reply to a caller contract (Via "Reply" endpoint). // Therefore if reply_recipient_contract_hash is not "None" we append it to any encrypted data besided submessages that are irrelevant for replies. @@ -353,10 +440,7 @@ pub fn encrypt_output( internal_msg_id, } => { let encrypted_err = encrypt_serializable(&encryption_key, err, &reply_params)?; - - // Putting the error inside a 'generic_err' envelope, so we can encrypt the error itself *err = json!({"generic_err":{"msg":encrypted_err}}); - let msg_id = match reply_params { Some(ref r) => { let encrypted_id = Binary::from_base64(&encrypt_preserialized_string( @@ -527,6 +611,11 @@ pub fn encrypt_output( } if let Some(data) = &mut ok.data { + if is_ibc_output { + warn!("IBC output should not containt any data"); + return Err(EnclaveError::InternalError); + } + *data = Binary::from_base64(&encrypt_serializable( &encryption_key, data, @@ -597,41 +686,6 @@ pub fn encrypt_output( None => None, // Not a reply, we don't need enclave sig } } - RawWasmOutput::OkIBCBasic { ok } => { - for sub_msg in &mut ok.messages { - if let enclave_cosmwasm_v1_types::results::CosmosMsg::Wasm(wasm_msg) = - &mut sub_msg.msg - { - encrypt_v1_wasm_msg( - wasm_msg, - &sub_msg.reply_on, - sub_msg.id, - secret_msg.nonce, - secret_msg.user_public_key, - contract_addr, - contract_hash, - )?; - - // The ID can be extracted from the encrypted wasm msg - // We don't encrypt it here to remain with the same type (u64) - sub_msg.id = 0; - } - } - - // v1: The attributes that will be emitted as part of a "wasm" event. - for attr in ok.attributes.iter_mut().filter(|attr| attr.encrypted) { - attr.key = encrypt_preserialized_string(&encryption_key, &attr.key, &None)?; - attr.value = encrypt_preserialized_string(&encryption_key, &attr.value, &None)?; - } - - // v1: Extra, custom events separate from the main wasm one. These will have "wasm-"" prepended to the type. - for event in ok.events.iter_mut() { - for attr in event.attributes.iter_mut().filter(|attr| attr.encrypted) { - attr.key = encrypt_preserialized_string(&encryption_key, &attr.key, &None)?; - attr.value = encrypt_preserialized_string(&encryption_key, &attr.value, &None)?; - } - } - } RawWasmOutput::OkIBCPacketReceive { ok } => { for sub_msg in &mut ok.messages { if let enclave_cosmwasm_v1_types::results::CosmosMsg::Wasm(wasm_msg) = @@ -676,7 +730,7 @@ pub fn encrypt_output( RawWasmOutput::OkIBCOpenChannel { ok: _ } => {} }; - let final_output = finalize_raw_output(output, is_query_output); + let final_output = finalize_raw_output(output, is_query_output, is_ibc_output, true); trace!("WasmOutput: {:?}", final_output); let encrypted_output = serde_json::to_vec(&final_output).map_err(|err| { diff --git a/cosmwasm/enclaves/shared/cosmwasm-v1-types/src/ibc.rs b/cosmwasm/enclaves/shared/cosmwasm-v1-types/src/ibc.rs index 751bb4caf..53956fce0 100644 --- a/cosmwasm/enclaves/shared/cosmwasm-v1-types/src/ibc.rs +++ b/cosmwasm/enclaves/shared/cosmwasm-v1-types/src/ibc.rs @@ -74,6 +74,20 @@ where pub events: Vec, } +impl IbcBasicResponse { + pub fn new( + messages: Vec>, + attributes: Vec, + events: Vec, + ) -> Self { + IbcBasicResponse { + messages, + attributes, + events, + } + } +} + // This defines the return value on packet response processing. // This "success" case should be returned even in application-level errors, // Where the acknowledgement bytes contain an encoded error message to be returned to diff --git a/cosmwasm/enclaves/shared/cosmwasm-v1-types/src/results/response.rs b/cosmwasm/enclaves/shared/cosmwasm-v1-types/src/results/response.rs index 1a6054a0c..fceff9804 100644 --- a/cosmwasm/enclaves/shared/cosmwasm-v1-types/src/results/response.rs +++ b/cosmwasm/enclaves/shared/cosmwasm-v1-types/src/results/response.rs @@ -1,9 +1,9 @@ use serde::{Deserialize, Serialize}; use std::fmt; -use enclave_cosmwasm_v010_types::{encoding::Binary, types::LogAttribute}; +use enclave_cosmwasm_v010_types::{encoding::Binary, types::Empty, types::LogAttribute}; -use super::{Empty, Event, SubMsg}; +use super::{Event, SubMsg}; /// A response of a contract entry point, such as `instantiate` or `execute`. /// diff --git a/go-cosmwasm/lib.go b/go-cosmwasm/lib.go index dd28a2ddf..3add1592a 100644 --- a/go-cosmwasm/lib.go +++ b/go-cosmwasm/lib.go @@ -263,6 +263,7 @@ func (w *Wasmer) Execute( return nil, gasUsed, err } + fmt.Printf("LIORRR data %+v", data) var resp ContractExecResponse err = json.Unmarshal(data, &resp) diff --git a/x/compute/internal/keeper/ibc_test.go b/x/compute/internal/keeper/ibc_test.go index b67838c60..8d4edcd64 100644 --- a/x/compute/internal/keeper/ibc_test.go +++ b/x/compute/internal/keeper/ibc_test.go @@ -2,12 +2,14 @@ package keeper import ( "encoding/hex" + "fmt" "math" "testing" crypto "github.com/cosmos/cosmos-sdk/crypto/types" sdk "github.com/cosmos/cosmos-sdk/types" cosmwasm "github.com/enigmampc/SecretNetwork/go-cosmwasm/types" + v010cosmwasm "github.com/enigmampc/SecretNetwork/go-cosmwasm/types/v010" v1types "github.com/enigmampc/SecretNetwork/go-cosmwasm/types/v1" "github.com/enigmampc/SecretNetwork/x/compute/internal/types" "github.com/stretchr/testify/require" @@ -18,7 +20,7 @@ func ibcChannelConnectHelper( t *testing.T, keeper Keeper, ctx sdk.Context, contractAddr sdk.AccAddress, creatorPrivKey crypto.PrivKey, gas uint64, shouldSendOpenAck bool, channel v1types.IBCChannel, -) cosmwasm.StdError { +) (sdk.Context, []ContractEvent, cosmwasm.StdError) { // create new ctx with the same storage and a gas limit // this is to reset the event manager, so we won't get // events from past calls @@ -53,10 +55,13 @@ func ibcChannelConnectHelper( require.NotZero(t, gasMeter.GetWasmCounter(), err) if err != nil { - return cosmwasm.StdError{GenericErr: &cosmwasm.GenericErr{Msg: err.Error()}} + return ctx, nil, cosmwasm.StdError{GenericErr: &cosmwasm.GenericErr{Msg: err.Error()}} } - return cosmwasm.StdError{} + // wasmEvents comes from all the callbacks as well + wasmEvents := tryDecryptWasmEvents(ctx, []byte{}, true) + + return ctx, wasmEvents, cosmwasm.StdError{} } func ibcChannelOpenHelper( @@ -393,17 +398,60 @@ func TestIBCChannelConnect(t *testing.T) { require.Empty(t, err) for _, test := range []struct { + description string connectionID string output string + isSuccess bool hasAttributes bool hasEvents bool }{ { - connectionID: "1", - output: ``, - isSuccuss: true, - balancesBefore: "5000assaf,200000denom 5000assaf,5000denom", - balancesAfter: "4998assaf,199998denom 5000assaf,5002denom", + description: "Default", + connectionID: "0", + output: "4", + isSuccess: true, + hasAttributes: false, + hasEvents: false, + }, + { + description: "SubmessageNoReply", + connectionID: "1", + output: "10", + isSuccess: true, + hasAttributes: false, + hasEvents: false, + }, + { + description: "SubmessageWithReply", + connectionID: "2", + output: "17", + isSuccess: true, + hasAttributes: false, + hasEvents: false, + }, + { + description: "Attributes", + connectionID: "3", + output: "7", + isSuccess: true, + hasAttributes: true, + hasEvents: false, + }, + { + description: "Events", + connectionID: "4", + output: "8", + isSuccess: true, + hasAttributes: false, + hasEvents: true, + }, + { + description: "Error", + connectionID: "5", + output: "", + isSuccess: false, + hasAttributes: false, + hasEvents: false, }, } { t.Run(test.description, func(t *testing.T) { @@ -412,16 +460,57 @@ func TestIBCChannelConnect(t *testing.T) { CounterpartyEndpoint: createIBCEndpoint(PortIDForContract(contractAddress), "channel.1"), Order: v1types.Unordered, Version: "1", - ConnectionID: "1", + ConnectionID: test.connectionID, } - err = ibcChannelConnectHelper(t, keeper, ctx, contractAddress, privKeyA, defaultGasForTests, false, ibcChannel) - require.Empty(t, err) - - queryRes, err := queryHelper(t, keeper, ctx, contractAddress, `{"q":{}}`, true, true, math.MaxUint64) - require.Empty(t, err) - - require.Equal(t, "3", queryRes) + ctx, events, err := ibcChannelConnectHelper(t, keeper, ctx, contractAddress, privKeyA, defaultGasForTests, false, ibcChannel) + + if !test.isSuccess { + require.Contains(t, fmt.Sprintf("%+v", err), "Intentional") + } else { + require.Empty(t, err) + if test.hasAttributes { + require.Equal(t, + []ContractEvent{ + { + {Key: "contract_address", Value: contractAddress.String()}, + {Key: "attr1", Value: "😗"}, + }, + }, + events, + ) + } + + if test.hasEvents { + hadCyber1 := false + evts := ctx.EventManager().Events() + for _, e := range evts { + if e.Type == "wasm-cyber1" { + require.False(t, hadCyber1) + attrs, err := parseAndDecryptAttributes(e.Attributes, []byte{}, false) + require.Empty(t, err) + + require.Equal(t, + []v010cosmwasm.LogAttribute{ + {Key: "contract_address", Value: contractAddress.String()}, + {Key: "attr1", Value: "🤯"}, + }, + attrs, + ) + + hadCyber1 = true + } + } + + require.True(t, hadCyber1) + } + + queryRes, err := queryHelper(t, keeper, ctx, contractAddress, `{"q":{}}`, true, true, math.MaxUint64) + + require.Empty(t, err) + + require.Equal(t, test.output, queryRes) + } }) } } diff --git a/x/compute/internal/keeper/keeper.go b/x/compute/internal/keeper/keeper.go index 5f1b3a01f..2cb0b9968 100644 --- a/x/compute/internal/keeper/keeper.go +++ b/x/compute/internal/keeper/keeper.go @@ -885,6 +885,7 @@ func (k *Keeper) handleContractResponse( ogCosmosMessageVersion wasmTypes.CosmosMsgVersion, ) ([]byte, error) { events := types.ContractLogsToSdkEvents(logs, contractAddr) + ctx.EventManager().EmitEvents(events) if len(evts) > 0 { diff --git a/x/compute/internal/keeper/msg_dispatcher.go b/x/compute/internal/keeper/msg_dispatcher.go index 80486471f..17ef1d2ac 100644 --- a/x/compute/internal/keeper/msg_dispatcher.go +++ b/x/compute/internal/keeper/msg_dispatcher.go @@ -139,7 +139,19 @@ func (e UnsupportedRequest) Error() string { // Reply is encrypted only when it is a contract reply func isReplyEncrypted(msg v1wasmTypes.CosmosMsg, reply v1wasmTypes.Reply) bool { - return (msg.Wasm != nil) + if msg.Wasm == nil { + return false + } + + if msg.Wasm.Execute != nil { + return len(msg.Wasm.Execute.CallbackCodeHash) != 0 + } + + if msg.Wasm.Instantiate != nil { + return len(msg.Wasm.Instantiate.CallbackCodeHash) != 0 + } + + return true } // Issue #759 - we don't return error string for worries of non-determinism @@ -177,7 +189,7 @@ func (d MessageDispatcher) DispatchSubmessages(ctx sdk.Context, contractAddr sdk switch msg.ReplyOn { case v1wasmTypes.ReplySuccess, v1wasmTypes.ReplyError, v1wasmTypes.ReplyAlways, v1wasmTypes.ReplyNever: default: - return nil, sdkerrors.Wrap(types.ErrInvalid, "replyOn value") + return nil, sdkerrors.Wrap(types.ErrInvalid, "ReplyOn value") } // first, we build a sub-context which we can use inside the submessages diff --git a/x/compute/internal/keeper/relay.go b/x/compute/internal/keeper/relay.go index 4497b95c9..8fe04024d 100644 --- a/x/compute/internal/keeper/relay.go +++ b/x/compute/internal/keeper/relay.go @@ -132,10 +132,9 @@ func (k Keeper) OnConnectChannel( if err != nil { return sdkerrors.Wrap(types.ErrExecuteFailed, err.Error()) } - err = k.parseThenHandleIBCBasicContractResponse(ctx, contractAddress, msgBz, res) if err != nil { - sdkerrors.Wrap(err, "ibc-connect-channel") + return sdkerrors.Wrap(err, "ibc-connect-channel") } return nil } @@ -246,7 +245,7 @@ func (k Keeper) OnAckPacket( err = k.parseThenHandleIBCBasicContractResponse(ctx, contractAddress, msgBz, res) if err != nil { - sdkerrors.Wrap(err, "ibc-ack-packet") + return sdkerrors.Wrap(err, "ibc-ack-packet") } return nil } @@ -275,7 +274,7 @@ func (k Keeper) OnTimeoutPacket( err = k.parseThenHandleIBCBasicContractResponse(ctx, contractAddress, msgBz, res) if err != nil { - sdkerrors.Wrap(err, "ibc-timeout-packet") + return sdkerrors.Wrap(err, "ibc-timeout-packet") } return nil } diff --git a/x/compute/internal/keeper/testdata/ibc/src/contract.rs b/x/compute/internal/keeper/testdata/ibc/src/contract.rs index 8d24233eb..182027ba5 100644 --- a/x/compute/internal/keeper/testdata/ibc/src/contract.rs +++ b/x/compute/internal/keeper/testdata/ibc/src/contract.rs @@ -1,10 +1,9 @@ use crate::msg::{ExecuteMsg, InstantiateMsg, QueryMsg}; use crate::state::{count, count_read}; use cosmwasm_std::{ - coins, entry_point, to_binary, Binary, CosmosMsg, Deps, DepsMut, Env, Event, - Ibc3ChannelOpenResponse, IbcBasicResponse, IbcChannelConnectMsg, IbcChannelOpenMsg, - IbcChannelOpenResponse, MessageInfo, Reply, ReplyOn, Response, StdError, StdResult, SubMsg, - SubMsgResult, WasmMsg, + entry_point, to_binary, Binary, CosmosMsg, Deps, DepsMut, Env, Event, Ibc3ChannelOpenResponse, + IbcBasicResponse, IbcChannelConnectMsg, IbcChannelOpenMsg, IbcChannelOpenResponse, MessageInfo, + Reply, ReplyOn, Response, StdError, StdResult, SubMsg, SubMsgResult, WasmMsg, }; pub const IBC_APP_VERSION: &str = "ibc-v1"; @@ -129,6 +128,7 @@ pub fn ibc_channel_connect( 3 => Ok(IbcBasicResponse::new().add_attribute("attr1", "😗")), 4 => Ok(IbcBasicResponse::new() .add_event(Event::new("cyber1".to_string()).add_attribute("attr1", "🤯"))), + 5 => Err(StdError::generic_err("Intentional")), _ => Err(StdError::generic_err("Unsupported channel connect type")), } } From 4058c9e4c2558dc10e13afd94902bbf89b24ae6e Mon Sep 17 00:00:00 2001 From: Lior Bondarevski Date: Sun, 28 Aug 2022 23:48:28 +0300 Subject: [PATCH 81/93] Channel close tests --- x/compute/internal/keeper/ibc_test.go | 179 +++++++++++++++++- .../keeper/testdata/ibc/src/contract.rs | 98 ++++++---- 2 files changed, 240 insertions(+), 37 deletions(-) diff --git a/x/compute/internal/keeper/ibc_test.go b/x/compute/internal/keeper/ibc_test.go index 8d4edcd64..85d0c7282 100644 --- a/x/compute/internal/keeper/ibc_test.go +++ b/x/compute/internal/keeper/ibc_test.go @@ -113,7 +113,7 @@ func ibcChannelCloseHelper( t *testing.T, keeper Keeper, ctx sdk.Context, contractAddr sdk.AccAddress, creatorPrivKey crypto.PrivKey, gas uint64, shouldSendCloseConfirn bool, channel v1types.IBCChannel, -) cosmwasm.StdError { +) (sdk.Context, []ContractEvent, cosmwasm.StdError) { // create new ctx with the same storage and a gas limit // this is to reset the event manager, so we won't get // events from past calls @@ -147,10 +147,13 @@ func ibcChannelCloseHelper( require.NotZero(t, gasMeter.GetWasmCounter(), err) if err != nil { - return cosmwasm.StdError{GenericErr: &cosmwasm.GenericErr{Msg: err.Error()}} + return ctx, nil, cosmwasm.StdError{GenericErr: &cosmwasm.GenericErr{Msg: err.Error()}} } - return cosmwasm.StdError{} + // wasmEvents comes from all the callbacks as well + wasmEvents := tryDecryptWasmEvents(ctx, []byte{}, true) + + return ctx, wasmEvents, cosmwasm.StdError{} } func createIBCEndpoint(port string, channel string) v1types.IBCEndpoint { @@ -514,3 +517,173 @@ func TestIBCChannelConnect(t *testing.T) { }) } } + +func TestIBCChannelConnectOpenAck(t *testing.T) { + ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, "./testdata/ibc/contract.wasm", sdk.NewCoins()) + + _, _, contractAddress, _, err := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"init":{}}`, true, true, defaultGasForTests) + require.Empty(t, err) + + ibcChannel := v1types.IBCChannel{ + Endpoint: createIBCEndpoint(PortIDForContract(contractAddress), "channel.0"), + CounterpartyEndpoint: createIBCEndpoint(PortIDForContract(contractAddress), "channel.1"), + Order: v1types.Unordered, + Version: "1", + ConnectionID: "1", + } + + ctx, _, err = ibcChannelConnectHelper(t, keeper, ctx, contractAddress, privKeyA, defaultGasForTests, true, ibcChannel) + require.Empty(t, err) + + queryRes, err := queryHelper(t, keeper, ctx, contractAddress, `{"q":{}}`, true, true, math.MaxUint64) + require.Empty(t, err) + + require.Equal(t, "3", queryRes) +} + +func TestIBCChannelClose(t *testing.T) { + ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, "./testdata/ibc/contract.wasm", sdk.NewCoins()) + + _, _, contractAddress, _, err := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"init":{}}`, true, true, defaultGasForTests) + require.Empty(t, err) + + for _, test := range []struct { + description string + connectionID string + output string + isSuccess bool + hasAttributes bool + hasEvents bool + }{ + { + description: "Default", + connectionID: "0", + output: "6", + isSuccess: true, + hasAttributes: false, + hasEvents: false, + }, + { + description: "SubmessageNoReply", + connectionID: "1", + output: "12", + isSuccess: true, + hasAttributes: false, + hasEvents: false, + }, + { + description: "SubmessageWithReply", + connectionID: "2", + output: "19", + isSuccess: true, + hasAttributes: false, + hasEvents: false, + }, + { + description: "Attributes", + connectionID: "3", + output: "9", + isSuccess: true, + hasAttributes: true, + hasEvents: false, + }, + { + description: "Events", + connectionID: "4", + output: "10", + isSuccess: true, + hasAttributes: false, + hasEvents: true, + }, + { + description: "Error", + connectionID: "5", + output: "", + isSuccess: false, + hasAttributes: false, + hasEvents: false, + }, + } { + t.Run(test.description, func(t *testing.T) { + ibcChannel := v1types.IBCChannel{ + Endpoint: createIBCEndpoint(PortIDForContract(contractAddress), "channel.0"), + CounterpartyEndpoint: createIBCEndpoint(PortIDForContract(contractAddress), "channel.1"), + Order: v1types.Unordered, + Version: "1", + ConnectionID: test.connectionID, + } + + ctx, events, err := ibcChannelCloseHelper(t, keeper, ctx, contractAddress, privKeyA, defaultGasForTests, true, ibcChannel) + + if !test.isSuccess { + require.Contains(t, fmt.Sprintf("%+v", err), "Intentional") + } else { + require.Empty(t, err) + if test.hasAttributes { + require.Equal(t, + []ContractEvent{ + { + {Key: "contract_address", Value: contractAddress.String()}, + {Key: "attr1", Value: "😗"}, + }, + }, + events, + ) + } + + if test.hasEvents { + hadCyber1 := false + evts := ctx.EventManager().Events() + for _, e := range evts { + if e.Type == "wasm-cyber1" { + require.False(t, hadCyber1) + attrs, err := parseAndDecryptAttributes(e.Attributes, []byte{}, false) + require.Empty(t, err) + + require.Equal(t, + []v010cosmwasm.LogAttribute{ + {Key: "contract_address", Value: contractAddress.String()}, + {Key: "attr1", Value: "🤯"}, + }, + attrs, + ) + + hadCyber1 = true + } + } + + require.True(t, hadCyber1) + } + + queryRes, err := queryHelper(t, keeper, ctx, contractAddress, `{"q":{}}`, true, true, math.MaxUint64) + + require.Empty(t, err) + + require.Equal(t, test.output, queryRes) + } + }) + } +} + +func TestIBCChannelCloseInit(t *testing.T) { + ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, "./testdata/ibc/contract.wasm", sdk.NewCoins()) + + _, _, contractAddress, _, err := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"init":{}}`, true, true, defaultGasForTests) + require.Empty(t, err) + + ibcChannel := v1types.IBCChannel{ + Endpoint: createIBCEndpoint(PortIDForContract(contractAddress), "channel.0"), + CounterpartyEndpoint: createIBCEndpoint(PortIDForContract(contractAddress), "channel.1"), + Order: v1types.Unordered, + Version: "1", + ConnectionID: "1", + } + + ctx, _, err = ibcChannelCloseHelper(t, keeper, ctx, contractAddress, privKeyA, defaultGasForTests, false, ibcChannel) + require.Empty(t, err) + + queryRes, err := queryHelper(t, keeper, ctx, contractAddress, `{"q":{}}`, true, true, math.MaxUint64) + require.Empty(t, err) + + require.Equal(t, "5", queryRes) +} diff --git a/x/compute/internal/keeper/testdata/ibc/src/contract.rs b/x/compute/internal/keeper/testdata/ibc/src/contract.rs index 182027ba5..6d93290d9 100644 --- a/x/compute/internal/keeper/testdata/ibc/src/contract.rs +++ b/x/compute/internal/keeper/testdata/ibc/src/contract.rs @@ -2,8 +2,9 @@ use crate::msg::{ExecuteMsg, InstantiateMsg, QueryMsg}; use crate::state::{count, count_read}; use cosmwasm_std::{ entry_point, to_binary, Binary, CosmosMsg, Deps, DepsMut, Env, Event, Ibc3ChannelOpenResponse, - IbcBasicResponse, IbcChannelConnectMsg, IbcChannelOpenMsg, IbcChannelOpenResponse, MessageInfo, - Reply, ReplyOn, Response, StdError, StdResult, SubMsg, SubMsgResult, WasmMsg, + IbcBasicResponse, IbcChannelCloseMsg, IbcChannelConnectMsg, IbcChannelOpenMsg, + IbcChannelOpenResponse, MessageInfo, Reply, ReplyOn, Response, StdError, StdResult, SubMsg, + SubMsgResult, WasmMsg, }; pub const IBC_APP_VERSION: &str = "ibc-v1"; @@ -78,6 +79,41 @@ pub fn increment(deps: DepsMut, c: u64) -> StdResult { Ok(resp) } +pub fn get_resp_based_on_num(env: Env, num: u64) -> StdResult { + match num { + 0 => Ok(IbcBasicResponse::default()), + 1 => Ok(IbcBasicResponse::new().add_submessage(SubMsg { + id: 1, + msg: CosmosMsg::Wasm(WasmMsg::Execute { + code_hash: env.contract.code_hash, + contract_addr: env.contract.address.into_string(), + msg: Binary::from("{\"increment\":{\"addition\":5}}".as_bytes().to_vec()), + funds: vec![], + }) + .into(), + reply_on: ReplyOn::Never, + gas_limit: None, + })), + 2 => Ok(IbcBasicResponse::new().add_submessage(SubMsg { + id: 1, + msg: CosmosMsg::Wasm(WasmMsg::Execute { + code_hash: env.contract.code_hash, + contract_addr: env.contract.address.into_string(), + msg: Binary::from("{\"increment\":{\"addition\":5}}".as_bytes().to_vec()), + funds: vec![], + }) + .into(), + reply_on: ReplyOn::Always, + gas_limit: None, + })), + 3 => Ok(IbcBasicResponse::new().add_attribute("attr1", "😗")), + 4 => Ok(IbcBasicResponse::new() + .add_event(Event::new("cyber1".to_string()).add_attribute("attr1", "🤯"))), + 5 => Err(StdError::generic_err("Intentional")), + _ => Err(StdError::generic_err("Unsupported channel connect type")), + } +} + #[entry_point] pub fn ibc_channel_connect( deps: DepsMut, @@ -99,39 +135,33 @@ pub fn ibc_channel_connect( count(deps.storage).save(&(num + 4))?; - match num { - 0 => Ok(IbcBasicResponse::default()), - 1 => Ok(IbcBasicResponse::new().add_submessage(SubMsg { - id: 1, - msg: CosmosMsg::Wasm(WasmMsg::Execute { - code_hash: env.contract.code_hash, - contract_addr: env.contract.address.into_string(), - msg: Binary::from("{\"increment\":{\"addition\":5}}".as_bytes().to_vec()), - funds: vec![], - }) - .into(), - reply_on: ReplyOn::Never, - gas_limit: None, - })), - 2 => Ok(IbcBasicResponse::new().add_submessage(SubMsg { - id: 1, - msg: CosmosMsg::Wasm(WasmMsg::Execute { - code_hash: env.contract.code_hash, - contract_addr: env.contract.address.into_string(), - msg: Binary::from("{\"increment\":{\"addition\":5}}".as_bytes().to_vec()), - funds: vec![], - }) - .into(), - reply_on: ReplyOn::Always, - gas_limit: None, - })), - 3 => Ok(IbcBasicResponse::new().add_attribute("attr1", "😗")), - 4 => Ok(IbcBasicResponse::new() - .add_event(Event::new("cyber1".to_string()).add_attribute("attr1", "🤯"))), - 5 => Err(StdError::generic_err("Intentional")), - _ => Err(StdError::generic_err("Unsupported channel connect type")), - } + get_resp_based_on_num(env, num) } _ => Err(StdError::generic_err("Unsupported channel connect")), } } + +#[entry_point] +/// On closed channel, we take all tokens from reflect contract to this contract. +/// We also delete the channel entry from accounts. +pub fn ibc_channel_close( + deps: DepsMut, + env: Env, + msg: IbcChannelCloseMsg, +) -> StdResult { + match msg { + IbcChannelCloseMsg::CloseInit { channel: _ } => { + count(deps.storage).save(&5)?; + Ok(IbcBasicResponse::default()) + } + IbcChannelCloseMsg::CloseConfirm { channel } => { + let num: u64 = channel.connection_id.parse::().map_err(|err| { + StdError::generic_err(format!("Got an error from parsing: {:?}", err)) + })?; + + count(deps.storage).save(&(num + 6))?; + get_resp_based_on_num(env, num) + } + _ => Err(StdError::generic_err("Unsupported channel close")), + } +} From a0b0bbaa779fae8c02bb313c2f2f005c5282f9f2 Mon Sep 17 00:00:00 2001 From: Eshel Date: Mon, 29 Aug 2022 16:55:06 +0300 Subject: [PATCH 82/93] adding util file that lets me see a transaction more cleanly: converting attributes from the form of bytes to their string form --- integration-tests/utils.ts | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 integration-tests/utils.ts diff --git a/integration-tests/utils.ts b/integration-tests/utils.ts new file mode 100644 index 000000000..e69de29bb From b49d6643d78cccd3385c701098643bc23eaefe21 Mon Sep 17 00:00:00 2001 From: Lior Bondarevski Date: Mon, 29 Aug 2022 18:50:52 +0300 Subject: [PATCH 83/93] IBC packet receive tests and bag fixes --- .../src/contract_operations.rs | 19 +- .../src/contract_validation.rs | 65 +++++- .../enclaves/shared/contract-engine/src/io.rs | 2 +- .../shared/contract-engine/src/message.rs | 6 +- .../shared/cosmwasm-types/v0.10/src/types.rs | 1 + .../shared/cosmwasm-types/v1.0/src/ibc.rs | 1 + .../v1.0/src/results/response.rs | 1 + go-cosmwasm/lib.go | 1 - x/compute/internal/keeper/ibc_test.go | 190 +++++++++++++----- x/compute/internal/keeper/msg_dispatcher.go | 6 +- x/compute/internal/keeper/relay.go | 24 ++- .../internal/keeper/secret_contracts_test.go | 5 +- .../keeper/testdata/ibc/src/contract.rs | 60 +++++- 13 files changed, 299 insertions(+), 82 deletions(-) diff --git a/cosmwasm/enclaves/shared/contract-engine/src/contract_operations.rs b/cosmwasm/enclaves/shared/contract-engine/src/contract_operations.rs index 75540fbdd..274d3782a 100644 --- a/cosmwasm/enclaves/shared/contract-engine/src/contract_operations.rs +++ b/cosmwasm/enclaves/shared/contract-engine/src/contract_operations.rs @@ -86,7 +86,7 @@ pub fn init( let ValidatedMessage { validated_msg, reply_params, - } = validate_msg(&decrypted_msg, &contract_hash, None)?; + } = validate_msg(&decrypted_msg, &contract_hash, None, None)?; let mut engine = start_engine( context, @@ -191,10 +191,10 @@ pub fn handle( contract_hash_for_validation, } = parse_message(msg, &parsed_sig_info, &parsed_handle_type)?; - let mut canonical_sender_address = CanonicalAddr::from_vec(vec![]); - if should_validate_sig_info || was_msg_encrypted { - canonical_sender_address = to_canonical(sender)?; - } + let canonical_sender_address = match to_canonical(sender) { + Ok(can) => can, + Err(_) => CanonicalAddr::from_vec(vec![]), + }; // There is no signature to verify when the input isn't signed. // Receiving unsigned messages is only possible in Handle. (Init tx are always signed) @@ -215,7 +215,12 @@ pub fn handle( let mut validated_msg = decrypted_msg.clone(); let mut reply_params: Option = None; if was_msg_encrypted { - let x = validate_msg(&decrypted_msg, &contract_hash, contract_hash_for_validation)?; + let x = validate_msg( + &decrypted_msg, + &contract_hash, + contract_hash_for_validation, + Some(parsed_handle_type.clone()), + )?; validated_msg = x.validated_msg; reply_params = x.reply_params; } @@ -337,7 +342,7 @@ pub fn query( let decrypted_msg = secret_msg.decrypt()?; let ValidatedMessage { validated_msg, .. } = - validate_msg(&decrypted_msg, &contract_hash, None)?; + validate_msg(&decrypted_msg, &contract_hash, None, None)?; let mut engine = start_engine( context, diff --git a/cosmwasm/enclaves/shared/contract-engine/src/contract_validation.rs b/cosmwasm/enclaves/shared/contract-engine/src/contract_validation.rs index 95fa9fe9c..b2fe47d8f 100644 --- a/cosmwasm/enclaves/shared/contract-engine/src/contract_validation.rs +++ b/cosmwasm/enclaves/shared/contract-engine/src/contract_validation.rs @@ -1,17 +1,18 @@ +use cw_types_v1::ibc::IbcPacketReceiveMsg; use cw_types_v1::results::REPLY_ENCRYPTION_MAGIC_BYTES; use log::*; -use enclave_ffi_types::EnclaveError; - use cw_types_v010::types::{CanonicalAddr, Coin, HumanAddr}; use enclave_cosmos_types::traits::CosmosAminoPubkey; use enclave_cosmos_types::types::{ - ContractCode, CosmWasmMsg, CosmosPubKey, SigInfo, SignDoc, StdSignDoc, + ContractCode, CosmWasmMsg, CosmosPubKey, HandleType, SigInfo, SignDoc, StdSignDoc, }; use enclave_crypto::traits::VerifyingKey; use enclave_crypto::{sha_256, AESKey, Hmac, Kdf, HASH_SIZE, KEY_MANAGER}; +use enclave_ffi_types::EnclaveError; use crate::io::create_callback_signature; +use crate::message::is_ibc_msg; use crate::types::SecretMessage; pub type ContractKey = [u8; CONTRACT_KEY_LENGTH]; @@ -121,6 +122,64 @@ pub fn validate_msg( msg: &[u8], contract_hash: &[u8; HASH_SIZE], contract_hash_for_validation: Option>, + handle_type: Option, +) -> Result { + match handle_type { + None => validate_basic_msg(msg, contract_hash, contract_hash_for_validation), + Some(h) => match is_ibc_msg(h.clone()) { + false => validate_basic_msg(msg, contract_hash, contract_hash_for_validation), + true => validate_ibc_msg(msg, contract_hash, contract_hash_for_validation, h), + }, + } +} + +pub fn validate_ibc_msg( + msg: &[u8], + contract_hash: &[u8; HASH_SIZE], + contract_hash_for_validation: Option>, + handle_type: HandleType, +) -> Result { + match handle_type { + HandleType::HANDLE_TYPE_IBC_PACKET_RECEIVE => { + let mut parsed_ibc_packet: IbcPacketReceiveMsg = + serde_json::from_slice(&msg.to_vec()).map_err(|err| { + warn!( + "IbcPacketReceive msg got an error while trying to deserialize msg input bytes into json {:?}: {}", + String::from_utf8_lossy(&msg), + err + ); + EnclaveError::FailedToDeserialize + })?; + + let validated_msg = validate_basic_msg( + parsed_ibc_packet.packet.data.as_slice(), + contract_hash, + contract_hash_for_validation, + )?; + parsed_ibc_packet.packet.data = validated_msg.validated_msg.as_slice().into(); + + Ok(ValidatedMessage{ + validated_msg: serde_json::to_vec(&parsed_ibc_packet).map_err(|err| { + warn!( + "got an error while trying to serialize parsed_ibc_packet msg into bytes {:?}: {}", + parsed_ibc_packet, err + ); + EnclaveError::FailedToSerialize + })?, + reply_params: validated_msg.reply_params, + }) + } + _ => { + warn!("Malformed message - in IBC, only packet receive message can be encrypted"); + Err(EnclaveError::ValidationFailure) + } + } +} + +pub fn validate_basic_msg( + msg: &[u8], + contract_hash: &[u8; HASH_SIZE], + contract_hash_for_validation: Option>, ) -> Result { if contract_hash_for_validation.is_none() && msg.len() < HEX_ENCODED_HASH_SIZE { warn!("Malformed message - expected contract code hash to be prepended to the msg"); diff --git a/cosmwasm/enclaves/shared/contract-engine/src/io.rs b/cosmwasm/enclaves/shared/contract-engine/src/io.rs index 2c1c8f9fd..b5177c8cf 100644 --- a/cosmwasm/enclaves/shared/contract-engine/src/io.rs +++ b/cosmwasm/enclaves/shared/contract-engine/src/io.rs @@ -598,7 +598,7 @@ pub fn encrypt_output( if let Some(data) = &mut ok.data { if is_ibc_output { - warn!("IBC output should not containt any data"); + warn!("IBC output should not contain any data"); return Err(EnclaveError::InternalError); } diff --git a/cosmwasm/enclaves/shared/contract-engine/src/message.rs b/cosmwasm/enclaves/shared/contract-engine/src/message.rs index 605a48332..56fbf4749 100644 --- a/cosmwasm/enclaves/shared/contract-engine/src/message.rs +++ b/cosmwasm/enclaves/shared/contract-engine/src/message.rs @@ -505,7 +505,7 @@ pub fn parse_message( }) } HandleType::HANDLE_TYPE_IBC_PACKET_RECEIVE => { - // LIORRR TODO: Maybe mark whether the message was encrypted or not. + // TODO: Maybe mark whether the message was encrypted or not. parse_ibc_packet( IbcPacketReceiveMsg::default(), message, @@ -513,11 +513,11 @@ pub fn parse_message( ) } HandleType::HANDLE_TYPE_IBC_PACKET_ACK => { - // LIORRR TODO: Maybe mark whether the message was encrypted or not. + // TODO: Maybe mark whether the message was encrypted or not. parse_ibc_packet(IbcPacketAckMsg::default(), message, "ibc_packet_receive") } HandleType::HANDLE_TYPE_IBC_PACKET_TIMEOUT => { - // LIORRR TODO: Maybe mark whether the message was encrypted or not. + // TODO: Maybe mark whether the message was encrypted or not. parse_ibc_packet( IbcPacketTimeoutMsg::default(), message, diff --git a/cosmwasm/enclaves/shared/cosmwasm-types/v0.10/src/types.rs b/cosmwasm/enclaves/shared/cosmwasm-types/v0.10/src/types.rs index 54bb82dde..e0d828335 100644 --- a/cosmwasm/enclaves/shared/cosmwasm-types/v0.10/src/types.rs +++ b/cosmwasm/enclaves/shared/cosmwasm-types/v0.10/src/types.rs @@ -133,6 +133,7 @@ pub struct ContractInfo { // This should be in correlation with cosmwasm-std/init_handle's InitResponse and HandleResponse #[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] +#[serde(deny_unknown_fields)] pub struct ContractResult { pub messages: Vec, pub log: Vec, diff --git a/cosmwasm/enclaves/shared/cosmwasm-types/v1.0/src/ibc.rs b/cosmwasm/enclaves/shared/cosmwasm-types/v1.0/src/ibc.rs index 3d38d90b5..f598d984c 100644 --- a/cosmwasm/enclaves/shared/cosmwasm-types/v1.0/src/ibc.rs +++ b/cosmwasm/enclaves/shared/cosmwasm-types/v1.0/src/ibc.rs @@ -94,6 +94,7 @@ impl IbcBasicResponse { // the calling chain. (Returning ContractResult::Err will abort processing of this packet // and not inform the calling chain). #[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] +#[serde(deny_unknown_fields)] #[non_exhaustive] pub struct IbcReceiveResponse where diff --git a/cosmwasm/enclaves/shared/cosmwasm-types/v1.0/src/results/response.rs b/cosmwasm/enclaves/shared/cosmwasm-types/v1.0/src/results/response.rs index c6f005472..06a90890f 100644 --- a/cosmwasm/enclaves/shared/cosmwasm-types/v1.0/src/results/response.rs +++ b/cosmwasm/enclaves/shared/cosmwasm-types/v1.0/src/results/response.rs @@ -60,6 +60,7 @@ use super::{Event, SubMsg}; /// } /// ``` #[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] +#[serde(deny_unknown_fields)] pub struct Response where T: Clone + fmt::Debug + PartialEq, diff --git a/go-cosmwasm/lib.go b/go-cosmwasm/lib.go index cf478cf31..bf83e12a5 100644 --- a/go-cosmwasm/lib.go +++ b/go-cosmwasm/lib.go @@ -263,7 +263,6 @@ func (w *Wasmer) Execute( return nil, gasUsed, err } - fmt.Printf("LIORRR data %+v", data) var resp ContractExecResponse err = json.Unmarshal(data, &resp) diff --git a/x/compute/internal/keeper/ibc_test.go b/x/compute/internal/keeper/ibc_test.go index 85d0c7282..10ceb1325 100644 --- a/x/compute/internal/keeper/ibc_test.go +++ b/x/compute/internal/keeper/ibc_test.go @@ -184,7 +184,7 @@ func ibcPacketReceiveHelper( t *testing.T, keeper Keeper, ctx sdk.Context, contractAddr sdk.AccAddress, creatorPrivKey crypto.PrivKey, shouldEncryptMsg bool, gas uint64, packet v1types.IBCPacket, -) ([]byte, cosmwasm.StdError) { +) (sdk.Context, []byte, []ContractEvent, []byte, cosmwasm.StdError) { var nonce []byte internalPacket := packet @@ -224,40 +224,29 @@ func ibcPacketReceiveHelper( require.NotZero(t, gasMeter.GetWasmCounter(), err) + // wasmEvents comes from all the callbacks as well + wasmEvents := tryDecryptWasmEvents(ctx, nonce, !shouldEncryptMsg) + if err != nil { if shouldEncryptMsg { - return nil, extractInnerError(t, err, nonce, true, true) + return ctx, nil, nil, nil, extractInnerError(t, err, nonce, true, true) } - return nil, cosmwasm.StdError{GenericErr: &cosmwasm.GenericErr{Msg: err.Error()}} + return ctx, nil, nil, nil, cosmwasm.StdError{GenericErr: &cosmwasm.GenericErr{Msg: err.Error()}} } - return res, cosmwasm.StdError{} + data := res + if shouldEncryptMsg { + data = getDecryptedData(t, res, nonce) + } + + return ctx, nonce, wasmEvents, data, cosmwasm.StdError{} } func ibcPacketAckHelper( t *testing.T, keeper Keeper, ctx sdk.Context, - contractAddr sdk.AccAddress, creatorPrivKey crypto.PrivKey, - shouldEncryptMsg bool, gas uint64, originalPacket v1types.IBCPacket, ack []byte, + contractAddr sdk.AccAddress, creatorPrivKey crypto.PrivKey, gas uint64, originalPacket v1types.IBCPacket, ack []byte, ) cosmwasm.StdError { - var nonce []byte - - if shouldEncryptMsg { - contractHash, err := keeper.GetContractHash(ctx, contractAddr) - require.NoError(t, err) - hashStr := hex.EncodeToString(contractHash) - - msg := types.SecretMsg{ - CodeHash: []byte(hashStr), - Msg: ack, - } - - ackBz, err := wasmCtx.Encrypt(msg.Serialize()) - require.NoError(t, err) - nonce = ackBz[0:32] - ack = ackBz - } - // create new ctx with the same storage and a gas limit // this is to reset the event manager, so we won't get // events from past calls @@ -282,10 +271,6 @@ func ibcPacketAckHelper( require.NotZero(t, gasMeter.GetWasmCounter(), err) if err != nil { - if shouldEncryptMsg { - return extractInnerError(t, err, nonce, true, true) - } - return cosmwasm.StdError{GenericErr: &cosmwasm.GenericErr{Msg: err.Error()}} } @@ -294,27 +279,8 @@ func ibcPacketAckHelper( func ibcPacketTimeoutHelper( t *testing.T, keeper Keeper, ctx sdk.Context, - contractAddr sdk.AccAddress, creatorPrivKey crypto.PrivKey, - shouldEncryptMsg bool, gas uint64, originalPacket v1types.IBCPacket, + contractAddr sdk.AccAddress, creatorPrivKey crypto.PrivKey, gas uint64, originalPacket v1types.IBCPacket, ) cosmwasm.StdError { - var nonce []byte - - if shouldEncryptMsg { - contractHash, err := keeper.GetContractHash(ctx, contractAddr) - require.NoError(t, err) - hashStr := hex.EncodeToString(contractHash) - - msg := types.SecretMsg{ - CodeHash: []byte(hashStr), - Msg: originalPacket.Data, - } - - dataBz, err := wasmCtx.Encrypt(msg.Serialize()) - require.NoError(t, err) - nonce = dataBz[0:32] - originalPacket.Data = dataBz - } - // create new ctx with the same storage and a gas limit // this is to reset the event manager, so we won't get // events from past calls @@ -336,10 +302,6 @@ func ibcPacketTimeoutHelper( require.NotZero(t, gasMeter.GetWasmCounter(), err) if err != nil { - if shouldEncryptMsg { - return extractInnerError(t, err, nonce, true, true) - } - return cosmwasm.StdError{GenericErr: &cosmwasm.GenericErr{Msg: err.Error()}} } @@ -687,3 +649,127 @@ func TestIBCChannelCloseInit(t *testing.T) { require.Equal(t, "5", queryRes) } + +func TestIBCPacketReceive(t *testing.T) { + ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, "./testdata/ibc/contract.wasm", sdk.NewCoins()) + + _, _, contractAddress, _, err := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"init":{}}`, true, true, defaultGasForTests) + require.Empty(t, err) + for _, isEncrypted := range []bool{false, true} { + for _, test := range []struct { + description string + sequence uint64 + output string + isSuccess bool + hasAttributes bool + hasEvents bool + }{ + { + description: "Default", + sequence: 0, + output: "7", + isSuccess: true, + hasAttributes: false, + hasEvents: false, + }, + { + description: "SubmessageNoReply", + sequence: 1, + output: "13", + isSuccess: true, + hasAttributes: false, + hasEvents: false, + }, + { + description: "SubmessageWithReply", + sequence: 2, + output: "20", + isSuccess: true, + hasAttributes: false, + hasEvents: false, + }, + { + description: "Attributes", + sequence: 3, + output: "10", + isSuccess: true, + hasAttributes: true, + hasEvents: false, + }, + { + description: "Events", + sequence: 4, + output: "11", + isSuccess: true, + hasAttributes: false, + hasEvents: true, + }, + { + description: "Error", + sequence: 5, + output: "", + isSuccess: false, + hasAttributes: false, + hasEvents: false, + }, + } { + t.Run(fmt.Sprintf("%s-Encryption:%t", test.description, isEncrypted), func(t *testing.T) { + ibcPacket := createIBCPacket(createIBCEndpoint(PortIDForContract(contractAddress), "channel.1"), + createIBCEndpoint(PortIDForContract(contractAddress), "channel.0"), + test.sequence, + createIBCTimeout(math.MaxUint64), + []byte{}, + ) + ctx, nonce, events, data, err := ibcPacketReceiveHelper(t, keeper, ctx, contractAddress, privKeyA, isEncrypted, defaultGasForTests, ibcPacket) + + if !test.isSuccess { + require.Contains(t, fmt.Sprintf("%+v", err), "Intentional") + } else { + require.Empty(t, err) + require.Equal(t, "\"out\"", string(data)) + + if test.hasAttributes { + require.Equal(t, + []ContractEvent{ + { + {Key: "contract_address", Value: contractAddress.String()}, + {Key: "attr1", Value: "😗"}, + }, + }, + events, + ) + } + + if test.hasEvents { + hadCyber1 := false + evts := ctx.EventManager().Events() + for _, e := range evts { + if e.Type == "wasm-cyber1" { + require.False(t, hadCyber1) + attrs, err := parseAndDecryptAttributes(e.Attributes, nonce, isEncrypted) + require.Empty(t, err) + + require.Equal(t, + []v010cosmwasm.LogAttribute{ + {Key: "contract_address", Value: contractAddress.String()}, + {Key: "attr1", Value: "🤯"}, + }, + attrs, + ) + + hadCyber1 = true + } + } + + require.True(t, hadCyber1) + } + + queryRes, err := queryHelper(t, keeper, ctx, contractAddress, `{"q":{}}`, true, true, math.MaxUint64) + + require.Empty(t, err) + require.Equal(t, test.output, queryRes) + } + }) + } + } +} diff --git a/x/compute/internal/keeper/msg_dispatcher.go b/x/compute/internal/keeper/msg_dispatcher.go index c654a9514..92792f986 100644 --- a/x/compute/internal/keeper/msg_dispatcher.go +++ b/x/compute/internal/keeper/msg_dispatcher.go @@ -146,11 +146,11 @@ func isReplyEncrypted(msg v1wasmTypes.CosmosMsg, reply v1wasmTypes.Reply) bool { } if msg.Wasm.Execute != nil { - return len(msg.Wasm.Execute.CallbackCodeHash) != 0 + return len(msg.Wasm.Execute.CallbackSignature) != 0 } if msg.Wasm.Instantiate != nil { - return len(msg.Wasm.Instantiate.CallbackCodeHash) != 0 + return len(msg.Wasm.Instantiate.CallbackSignature) != 0 } return true @@ -255,7 +255,6 @@ func (d MessageDispatcher) DispatchSubmessages(ctx sdk.Context, contractAddr sdk if len(data) > 0 { responseData = data[0] } - result = v1wasmTypes.SubMsgResult{ // Copy first 64 bytes of the OG message in order to preserve the pubkey. Ok: &v1wasmTypes.SubMsgResponse{ @@ -322,7 +321,6 @@ func (d MessageDispatcher) DispatchSubmessages(ctx sdk.Context, contractAddr sdk replySigInfo = ogSigInfo reply.ID = dataWithInternalReplyInfo.InternalMsgId replySigInfo.CallbackSignature = dataWithInternalReplyInfo.InternaReplyEnclaveSig - } rspData, err := d.keeper.reply(ctx, contractAddr, reply, ogTx, replySigInfo) diff --git a/x/compute/internal/keeper/relay.go b/x/compute/internal/keeper/relay.go index 8fe04024d..2bef5b8e7 100644 --- a/x/compute/internal/keeper/relay.go +++ b/x/compute/internal/keeper/relay.go @@ -67,9 +67,9 @@ func (k Keeper) parseThenHandleIBCBasicContractResponse(ctx sdk.Context, } return k.handleIBCBasicContractResponse(ctx, contractAddress, contractInfo.IBCPortID, inputMsg, resp) - } else { - return sdkerrors.Wrap(types.ErrExecuteFailed, fmt.Sprintf("null pointer IBCBasicResponse: %+v", res)) } + + return sdkerrors.Wrap(types.ErrExecuteFailed, fmt.Sprintf("null pointer IBCBasicResponse: %+v", res)) default: return sdkerrors.Wrap(types.ErrExecuteFailed, fmt.Sprintf("cannot cast res to IBCBasicResponse: %+v", res)) } @@ -203,15 +203,23 @@ func (k Keeper) OnRecvPacket( if err != nil { return nil, err } - verificationInfo := types.NewVerificationInfo([]byte{}, sdktxsigning.SignMode_SIGN_MODE_UNSPECIFIED, []byte{}, []byte{}, []byte{}, nil) + verificationInfo := types.NewVerificationInfo([]byte{}, sdktxsigning.SignMode_SIGN_MODE_DIRECT, []byte{}, []byte{}, []byte{}, nil) + + ogTx := msg.Packet.Data + + // If the data contains less than 64 bytes (means plaintext) + // use the whole message just for compilation + if len(ogTx) < 64 { + ogTx = msgBz + } // note submessage reply results can overwrite the `Acknowledgement` data - return k.handleContractResponse(ctx, contractAddress, contractInfo.IBCPortID, resp.Messages, resp.Attributes, resp.Events, resp.Acknowledgement, msgBz, verificationInfo, wasmTypes.CosmosMsgVersionV1) - } else { - // should never get here as it's already checked in - // https://github.com/scrtlabs/SecretNetwork/blob/bd46776c/go-cosmwasm/lib.go#L358 - return nil, sdkerrors.Wrap(types.ErrExecuteFailed, fmt.Sprintf("ibc-recv-packet: null pointer IBCReceiveResponse: %+v", res)) + return k.handleContractResponse(ctx, contractAddress, contractInfo.IBCPortID, resp.Messages, resp.Attributes, resp.Events, resp.Acknowledgement, ogTx, verificationInfo, wasmTypes.CosmosMsgVersionV1) } + + // should never get here as it's already checked in + // https://github.com/scrtlabs/SecretNetwork/blob/bd46776c/go-cosmwasm/lib.go#L358 + return nil, sdkerrors.Wrap(types.ErrExecuteFailed, fmt.Sprintf("ibc-recv-packet: null pointer IBCReceiveResponse: %+v", res)) default: return nil, sdkerrors.Wrap(types.ErrExecuteFailed, fmt.Sprintf("ibc-recv-packet: cannot cast res to IBCReceiveResponse: %+v", res)) } diff --git a/x/compute/internal/keeper/secret_contracts_test.go b/x/compute/internal/keeper/secret_contracts_test.go index 77203516e..50c07f3c9 100644 --- a/x/compute/internal/keeper/secret_contracts_test.go +++ b/x/compute/internal/keeper/secret_contracts_test.go @@ -167,7 +167,7 @@ func decryptAttribute(attr v010cosmwasm.LogAttribute, nonce []byte) (v010cosmwas } keyPlainBz, err := wasmCtx.Decrypt(keyCipherBz, nonce) if err != nil { - return v010cosmwasm.LogAttribute{}, fmt.Errorf("Failed Decrypt for key %+v", keyPlainBz) + return v010cosmwasm.LogAttribute{}, fmt.Errorf("Failed Decrypt for key %+v", keyCipherBz) } newAttr.Key = string(keyPlainBz) @@ -232,8 +232,11 @@ func tryDecryptWasmEvents(ctx sdk.Context, nonce []byte, shouldSkipAttributes .. if !shouldSkip && newLog.Key != "contract_address" { // key + fmt.Printf("LIORRR before %+v nonce %+v", newLog, nonce) newAttr, err := decryptAttribute(newLog, nonce) + fmt.Printf("LIORRR after %+v", newAttr) if err != nil { + fmt.Printf("LIORRR here %+v", err) continue } diff --git a/x/compute/internal/keeper/testdata/ibc/src/contract.rs b/x/compute/internal/keeper/testdata/ibc/src/contract.rs index 6d93290d9..9b66e4936 100644 --- a/x/compute/internal/keeper/testdata/ibc/src/contract.rs +++ b/x/compute/internal/keeper/testdata/ibc/src/contract.rs @@ -3,8 +3,8 @@ use crate::state::{count, count_read}; use cosmwasm_std::{ entry_point, to_binary, Binary, CosmosMsg, Deps, DepsMut, Env, Event, Ibc3ChannelOpenResponse, IbcBasicResponse, IbcChannelCloseMsg, IbcChannelConnectMsg, IbcChannelOpenMsg, - IbcChannelOpenResponse, MessageInfo, Reply, ReplyOn, Response, StdError, StdResult, SubMsg, - SubMsgResult, WasmMsg, + IbcChannelOpenResponse, IbcPacketReceiveMsg, IbcReceiveResponse, MessageInfo, Reply, ReplyOn, + Response, StdError, StdResult, SubMsg, SubMsgResult, WasmMsg, }; pub const IBC_APP_VERSION: &str = "ibc-v1"; @@ -114,6 +114,41 @@ pub fn get_resp_based_on_num(env: Env, num: u64) -> StdResult } } +pub fn get_recv_resp_based_on_num(env: Env, num: u64) -> StdResult { + match num { + 0 => Ok(IbcReceiveResponse::default()), + 1 => Ok(IbcReceiveResponse::new().add_submessage(SubMsg { + id: 1, + msg: CosmosMsg::Wasm(WasmMsg::Execute { + code_hash: env.contract.code_hash, + contract_addr: env.contract.address.into_string(), + msg: Binary::from("{\"increment\":{\"addition\":5}}".as_bytes().to_vec()), + funds: vec![], + }) + .into(), + reply_on: ReplyOn::Never, + gas_limit: None, + })), + 2 => Ok(IbcReceiveResponse::new().add_submessage(SubMsg { + id: 1, + msg: CosmosMsg::Wasm(WasmMsg::Execute { + code_hash: env.contract.code_hash, + contract_addr: env.contract.address.into_string(), + msg: Binary::from("{\"increment\":{\"addition\":5}}".as_bytes().to_vec()), + funds: vec![], + }) + .into(), + reply_on: ReplyOn::Always, + gas_limit: None, + })), + 3 => Ok(IbcReceiveResponse::new().add_attribute("attr1", "😗")), + 4 => Ok(IbcReceiveResponse::new() + .add_event(Event::new("cyber1".to_string()).add_attribute("attr1", "🤯"))), + 5 => Err(StdError::generic_err("Intentional")), + _ => Err(StdError::generic_err("Unsupported channel connect type")), + } +} + #[entry_point] pub fn ibc_channel_connect( deps: DepsMut, @@ -165,3 +200,24 @@ pub fn ibc_channel_close( _ => Err(StdError::generic_err("Unsupported channel close")), } } + +#[entry_point] +/// we look for a the proper reflect contract to relay to and send the message +/// We cannot return any meaningful response value as we do not know the response value +/// of execution. We just return ok if we dispatched, error if we failed to dispatch +pub fn ibc_packet_receive( + deps: DepsMut, + env: Env, + msg: IbcPacketReceiveMsg, +) -> StdResult { + count(deps.storage).save(&(msg.packet.sequence + 7))?; + let mut resp = get_recv_resp_based_on_num(env, msg.packet.sequence); + match &mut resp { + Ok(r) => { + r.acknowledgement = to_binary(&"out".to_string())?; + } + Err(_) => {} + } + + resp +} From 7d0f85a4684e1e1d0c4c320b7f233c2d741f8b3c Mon Sep 17 00:00:00 2001 From: Lior Bondarevski Date: Mon, 29 Aug 2022 19:16:28 +0300 Subject: [PATCH 84/93] IBC ack and timeout should be encrypted --- .../shared/contract-engine/src/message.rs | 148 +++++++----------- .../shared/cosmwasm-types/v1.0/src/ibc.rs | 46 ------ 2 files changed, 53 insertions(+), 141 deletions(-) diff --git a/cosmwasm/enclaves/shared/contract-engine/src/message.rs b/cosmwasm/enclaves/shared/contract-engine/src/message.rs index 56fbf4749..fc484982a 100644 --- a/cosmwasm/enclaves/shared/contract-engine/src/message.rs +++ b/cosmwasm/enclaves/shared/contract-engine/src/message.rs @@ -1,10 +1,9 @@ use log::{trace, warn}; -use serde::de::DeserializeOwned; use serde::Serialize; use cosmos_proto::tx::signing::SignMode; use cw_types_v010::encoding::Binary; -use cw_types_v1::ibc::{IbcPacketAckMsg, IbcPacketReceiveMsg, IbcPacketTimeoutMsg, IbcPacketTrait}; +use cw_types_v1::ibc::IbcPacketReceiveMsg; use cw_types_v1::results::{DecryptedReply, Event, Reply, SubMsgResponse, SubMsgResult}; use enclave_cosmos_types::types::{HandleType, SigInfo}; use enclave_ffi_types::EnclaveError; @@ -91,81 +90,6 @@ pub fn try_get_decrypted_secret_msg(message: &[u8]) -> Option( - _t: T, - message: &[u8], - function_name: &str, -) -> Result -where - T: IbcPacketTrait + Serialize + DeserializeOwned + core::fmt::Debug, -{ - let mut parsed_encrypted_ibc_packet: T = - serde_json::from_slice(&message.to_vec()).map_err(|err| { - warn!( - "{} msg got an error while trying to deserialize msg input bytes into json {:?}: {}", - function_name, - String::from_utf8_lossy(&message), - err - ); - EnclaveError::FailedToDeserialize - })?; - - let tmp_secret_data = get_secret_msg(parsed_encrypted_ibc_packet.get_packet().as_slice()); - let mut was_msg_encrypted = false; - let mut orig_secret_msg = tmp_secret_data; - - match orig_secret_msg.decrypt() { - Ok(decrypted_msg) => { - // IBC packet was encrypted - - trace!( - "{} data before decryption: {:?}", - function_name, - base64::encode(&message) - ); - - parsed_encrypted_ibc_packet.set_packet(decrypted_msg.as_slice().into()); - was_msg_encrypted = true; - } - Err(_) => { - // assume data is not encrypted - - trace!( - "{} data was plaintext: {:?}", - function_name, - base64::encode(&message) - ); - } - } - - let ack = parsed_encrypted_ibc_packet.get_ack(); - let tmp_secret_ack = get_secret_msg(ack.unwrap_or(Binary::from(vec![].as_slice())).as_slice()); - - match tmp_secret_ack.decrypt() { - Ok(ack_data) => { - parsed_encrypted_ibc_packet.set_ack(ack_data.as_slice().into()); - was_msg_encrypted = true; - - orig_secret_msg = tmp_secret_ack; - } - Err(_) => {} - } - - Ok(ParsedMessage { - should_validate_sig_info: false, - was_msg_encrypted, - secret_msg: orig_secret_msg, - decrypted_msg: serde_json::to_vec(&parsed_encrypted_ibc_packet).map_err(|err| { - warn!( - "got an error while trying to serialize {} msg into bytes {:?}: {}", - function_name, parsed_encrypted_ibc_packet, err - ); - EnclaveError::FailedToSerialize - })?, - contract_hash_for_validation: None, - }) -} - // Parse the message that was passed to handle (Based on the assumption that it might be a reply or IBC as well) pub fn parse_message( message: &[u8], @@ -481,7 +405,9 @@ pub fn parse_message( } HandleType::HANDLE_TYPE_IBC_CHANNEL_OPEN | HandleType::HANDLE_TYPE_IBC_CHANNEL_CONNECT - | HandleType::HANDLE_TYPE_IBC_CHANNEL_CLOSE => { + | HandleType::HANDLE_TYPE_IBC_CHANNEL_CLOSE + | HandleType::HANDLE_TYPE_IBC_PACKET_ACK + | HandleType::HANDLE_TYPE_IBC_PACKET_TIMEOUT => { trace!( "parsing {} msg (Should always be plaintext): {:?}", HandleType::to_export_name(&handle_type), @@ -506,23 +432,55 @@ pub fn parse_message( } HandleType::HANDLE_TYPE_IBC_PACKET_RECEIVE => { // TODO: Maybe mark whether the message was encrypted or not. - parse_ibc_packet( - IbcPacketReceiveMsg::default(), - message, - "ibc_packet_receive", - ) - } - HandleType::HANDLE_TYPE_IBC_PACKET_ACK => { - // TODO: Maybe mark whether the message was encrypted or not. - parse_ibc_packet(IbcPacketAckMsg::default(), message, "ibc_packet_receive") - } - HandleType::HANDLE_TYPE_IBC_PACKET_TIMEOUT => { - // TODO: Maybe mark whether the message was encrypted or not. - parse_ibc_packet( - IbcPacketTimeoutMsg::default(), - message, - "ibc_packet_timeout", - ) + let mut parsed_encrypted_ibc_packet: IbcPacketReceiveMsg = + serde_json::from_slice(&message.to_vec()).map_err(|err| { + warn!( + "Got an error while trying to deserialize input bytes msg into IbcPacketReceiveMsg message {:?}: {}", + String::from_utf8_lossy(&message), + err + ); + EnclaveError::FailedToDeserialize + })?; + + let tmp_secret_data = + get_secret_msg(parsed_encrypted_ibc_packet.packet.data.as_slice()); + let mut was_msg_encrypted = false; + let orig_secret_msg = tmp_secret_data; + + match orig_secret_msg.decrypt() { + Ok(decrypted_msg) => { + // IBC packet was encrypted + + trace!( + "ibc_packet_receive data before decryption: {:?}", + base64::encode(&message) + ); + + parsed_encrypted_ibc_packet.packet.data = decrypted_msg.as_slice().into(); + was_msg_encrypted = true; + } + Err(_) => { + // assume data is not encrypted + + trace!( + "ibc_packet_receive data was plaintext: {:?}", + base64::encode(&message) + ); + } + } + Ok(ParsedMessage { + should_validate_sig_info: false, + was_msg_encrypted, + secret_msg: orig_secret_msg, + decrypted_msg: serde_json::to_vec(&parsed_encrypted_ibc_packet).map_err(|err| { + warn!( + "got an error while trying to serialize IbcPacketReceive msg into bytes {:?}: {}", + parsed_encrypted_ibc_packet, err + ); + EnclaveError::FailedToSerialize + })?, + contract_hash_for_validation: None, + }) } }; } diff --git a/cosmwasm/enclaves/shared/cosmwasm-types/v1.0/src/ibc.rs b/cosmwasm/enclaves/shared/cosmwasm-types/v1.0/src/ibc.rs index f598d984c..6c620e915 100644 --- a/cosmwasm/enclaves/shared/cosmwasm-types/v1.0/src/ibc.rs +++ b/cosmwasm/enclaves/shared/cosmwasm-types/v1.0/src/ibc.rs @@ -179,52 +179,6 @@ pub struct IbcPacketReceiveMsg { pub relayer: Addr, } -pub trait IbcPacketTrait { - type Data; - fn get_packet(&self) -> &Self::Data; - fn set_packet(&mut self, data: Self::Data); - fn get_ack(&self) -> Option; - fn set_ack(&mut self, data: Self::Data); -} - -macro_rules! impl_IbcPacketTrait { - ($($t:ty),+) => { - $(impl IbcPacketTrait for $t { - type Data = Binary; - fn get_packet(&self) -> &Self::Data { - &self.packet.data - } - fn set_packet(&mut self, data: Self::Data) { - self.packet.data = data; - } - fn get_ack(&self) -> Option { - return None; - } - fn set_ack(&mut self, _: Self::Data) { - // Nothing to do here - } - })* - } -} - -impl_IbcPacketTrait! {IbcPacketReceiveMsg, IbcPacketTimeoutMsg} - -impl IbcPacketTrait for IbcPacketAckMsg { - type Data = Binary; - fn get_packet(&self) -> &Self::Data { - &self.original_packet.data - } - fn set_packet(&mut self, data: Self::Data) { - self.original_packet.data = data; - } - fn get_ack(&self) -> Option { - Some(self.acknowledgement.data.clone()) - } - fn set_ack(&mut self, data: Self::Data) { - self.acknowledgement.data = data; - } -} - impl IbcPacketReceiveMsg { pub fn default() -> Self { Self { From b058d3ce0d9dc6ff42fd43687aaa58674812f610 Mon Sep 17 00:00:00 2001 From: Lior Bondarevski Date: Mon, 29 Aug 2022 19:16:40 +0300 Subject: [PATCH 85/93] IBC ack tests --- x/compute/internal/keeper/ibc_test.go | 144 +++++++++++++++++- .../keeper/testdata/ibc/src/contract.rs | 26 +++- 2 files changed, 157 insertions(+), 13 deletions(-) diff --git a/x/compute/internal/keeper/ibc_test.go b/x/compute/internal/keeper/ibc_test.go index 10ceb1325..ae042da74 100644 --- a/x/compute/internal/keeper/ibc_test.go +++ b/x/compute/internal/keeper/ibc_test.go @@ -1,6 +1,7 @@ package keeper import ( + "encoding/binary" "encoding/hex" "fmt" "math" @@ -246,7 +247,7 @@ func ibcPacketReceiveHelper( func ibcPacketAckHelper( t *testing.T, keeper Keeper, ctx sdk.Context, contractAddr sdk.AccAddress, creatorPrivKey crypto.PrivKey, gas uint64, originalPacket v1types.IBCPacket, ack []byte, -) cosmwasm.StdError { +) (sdk.Context, []ContractEvent, cosmwasm.StdError) { // create new ctx with the same storage and a gas limit // this is to reset the event manager, so we won't get // events from past calls @@ -271,16 +272,19 @@ func ibcPacketAckHelper( require.NotZero(t, gasMeter.GetWasmCounter(), err) if err != nil { - return cosmwasm.StdError{GenericErr: &cosmwasm.GenericErr{Msg: err.Error()}} + return ctx, nil, cosmwasm.StdError{GenericErr: &cosmwasm.GenericErr{Msg: err.Error()}} } - return cosmwasm.StdError{} + // wasmEvents comes from all the callbacks as well + wasmEvents := tryDecryptWasmEvents(ctx, []byte{}, true) + + return ctx, wasmEvents, cosmwasm.StdError{} } func ibcPacketTimeoutHelper( t *testing.T, keeper Keeper, ctx sdk.Context, contractAddr sdk.AccAddress, creatorPrivKey crypto.PrivKey, gas uint64, originalPacket v1types.IBCPacket, -) cosmwasm.StdError { +) (sdk.Context, []ContractEvent, cosmwasm.StdError) { // create new ctx with the same storage and a gas limit // this is to reset the event manager, so we won't get // events from past calls @@ -302,10 +306,13 @@ func ibcPacketTimeoutHelper( require.NotZero(t, gasMeter.GetWasmCounter(), err) if err != nil { - return cosmwasm.StdError{GenericErr: &cosmwasm.GenericErr{Msg: err.Error()}} + return ctx, nil, cosmwasm.StdError{GenericErr: &cosmwasm.GenericErr{Msg: err.Error()}} } - return cosmwasm.StdError{} + // wasmEvents comes from all the callbacks as well + wasmEvents := tryDecryptWasmEvents(ctx, []byte{}, true) + + return ctx, wasmEvents, cosmwasm.StdError{} } func TestIBCChannelOpen(t *testing.T) { @@ -773,3 +780,128 @@ func TestIBCPacketReceive(t *testing.T) { } } } + +func TestIBCPacketAck(t *testing.T) { + ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, "./testdata/ibc/contract.wasm", sdk.NewCoins()) + + _, _, contractAddress, _, err := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"init":{}}`, true, true, defaultGasForTests) + require.Empty(t, err) + + for _, test := range []struct { + description string + sequence uint64 + output string + isSuccess bool + hasAttributes bool + hasEvents bool + }{ + { + description: "Default", + sequence: 0, + output: "8", + isSuccess: true, + hasAttributes: false, + hasEvents: false, + }, + { + description: "SubmessageNoReply", + sequence: 1, + output: "14", + isSuccess: true, + hasAttributes: false, + hasEvents: false, + }, + { + description: "SubmessageWithReply", + sequence: 2, + output: "21", + isSuccess: true, + hasAttributes: false, + hasEvents: false, + }, + { + description: "Attributes", + sequence: 3, + output: "11", + isSuccess: true, + hasAttributes: true, + hasEvents: false, + }, + { + description: "Events", + sequence: 4, + output: "12", + isSuccess: true, + hasAttributes: false, + hasEvents: true, + }, + { + description: "Error", + sequence: 5, + output: "", + isSuccess: false, + hasAttributes: false, + hasEvents: false, + }, + } { + t.Run(test.description, func(t *testing.T) { + ibcPacket := createIBCPacket(createIBCEndpoint(PortIDForContract(contractAddress), "channel.1"), + createIBCEndpoint(PortIDForContract(contractAddress), "channel.0"), + test.sequence, + createIBCTimeout(math.MaxUint64), + []byte{}, + ) + ack := make([]byte, 8) + binary.LittleEndian.PutUint64(ack, uint64(test.sequence)) + + ctx, events, err := ibcPacketAckHelper(t, keeper, ctx, contractAddress, privKeyA, defaultGasForTests, ibcPacket, ack) + + if !test.isSuccess { + require.Contains(t, fmt.Sprintf("%+v", err), "Intentional") + } else { + require.Empty(t, err) + if test.hasAttributes { + require.Equal(t, + []ContractEvent{ + { + {Key: "contract_address", Value: contractAddress.String()}, + {Key: "attr1", Value: "😗"}, + }, + }, + events, + ) + } + + if test.hasEvents { + hadCyber1 := false + evts := ctx.EventManager().Events() + for _, e := range evts { + if e.Type == "wasm-cyber1" { + require.False(t, hadCyber1) + attrs, err := parseAndDecryptAttributes(e.Attributes, []byte{}, false) + require.Empty(t, err) + + require.Equal(t, + []v010cosmwasm.LogAttribute{ + {Key: "contract_address", Value: contractAddress.String()}, + {Key: "attr1", Value: "🤯"}, + }, + attrs, + ) + + hadCyber1 = true + } + } + + require.True(t, hadCyber1) + } + + queryRes, err := queryHelper(t, keeper, ctx, contractAddress, `{"q":{}}`, true, true, math.MaxUint64) + + require.Empty(t, err) + + require.Equal(t, test.output, queryRes) + } + }) + } +} diff --git a/x/compute/internal/keeper/testdata/ibc/src/contract.rs b/x/compute/internal/keeper/testdata/ibc/src/contract.rs index 9b66e4936..cb5016848 100644 --- a/x/compute/internal/keeper/testdata/ibc/src/contract.rs +++ b/x/compute/internal/keeper/testdata/ibc/src/contract.rs @@ -3,8 +3,8 @@ use crate::state::{count, count_read}; use cosmwasm_std::{ entry_point, to_binary, Binary, CosmosMsg, Deps, DepsMut, Env, Event, Ibc3ChannelOpenResponse, IbcBasicResponse, IbcChannelCloseMsg, IbcChannelConnectMsg, IbcChannelOpenMsg, - IbcChannelOpenResponse, IbcPacketReceiveMsg, IbcReceiveResponse, MessageInfo, Reply, ReplyOn, - Response, StdError, StdResult, SubMsg, SubMsgResult, WasmMsg, + IbcChannelOpenResponse, IbcPacketAckMsg, IbcPacketReceiveMsg, IbcReceiveResponse, MessageInfo, + Reply, ReplyOn, Response, StdError, StdResult, SubMsg, SubMsgResult, WasmMsg, }; pub const IBC_APP_VERSION: &str = "ibc-v1"; @@ -177,8 +177,6 @@ pub fn ibc_channel_connect( } #[entry_point] -/// On closed channel, we take all tokens from reflect contract to this contract. -/// We also delete the channel entry from accounts. pub fn ibc_channel_close( deps: DepsMut, env: Env, @@ -202,9 +200,6 @@ pub fn ibc_channel_close( } #[entry_point] -/// we look for a the proper reflect contract to relay to and send the message -/// We cannot return any meaningful response value as we do not know the response value -/// of execution. We just return ok if we dispatched, error if we failed to dispatch pub fn ibc_packet_receive( deps: DepsMut, env: Env, @@ -221,3 +216,20 @@ pub fn ibc_packet_receive( resp } + +#[entry_point] +pub fn ibc_packet_ack( + deps: DepsMut, + env: Env, + msg: IbcPacketAckMsg, +) -> StdResult { + let mut ack = [0u8; 8]; + ack.copy_from_slice(&msg.acknowledgement.data.as_slice()[0..8]); + + if u64::from_le_bytes(ack) != msg.original_packet.sequence { + return Err(StdError::generic_err("Wrong ack")); + } + + count(deps.storage).save(&(msg.original_packet.sequence + 8))?; + get_resp_based_on_num(env, msg.original_packet.sequence) +} From 5b97e6fef205809dca814dd4158cefbcab61bff8 Mon Sep 17 00:00:00 2001 From: Lior Bondarevski Date: Tue, 30 Aug 2022 11:11:24 +0300 Subject: [PATCH 86/93] Encrypt the output of every reply (Should be changed) --- .../src/contract_operations.rs | 3 +- .../enclaves/shared/contract-engine/src/io.rs | 4 +- .../shared/contract-engine/src/message.rs | 9 +- x/compute/internal/keeper/ibc_test.go | 123 ++++++++++++++++++ .../internal/keeper/secret_contracts_test.go | 3 - x/compute/internal/keeper/test_common.go | 3 + .../keeper/testdata/ibc/src/contract.rs | 17 ++- 7 files changed, 152 insertions(+), 10 deletions(-) diff --git a/cosmwasm/enclaves/shared/contract-engine/src/contract_operations.rs b/cosmwasm/enclaves/shared/contract-engine/src/contract_operations.rs index 274d3782a..195bf917c 100644 --- a/cosmwasm/enclaves/shared/contract-engine/src/contract_operations.rs +++ b/cosmwasm/enclaves/shared/contract-engine/src/contract_operations.rs @@ -186,6 +186,7 @@ pub fn handle( let ParsedMessage { should_validate_sig_info, was_msg_encrypted, + should_encrypt_output, secret_msg, decrypted_msg, contract_hash_for_validation, @@ -262,7 +263,7 @@ pub fn handle( secret_msg.nonce, secret_msg.user_public_key ); - if was_msg_encrypted { + if should_encrypt_output { output = encrypt_output( output, &secret_msg, diff --git a/cosmwasm/enclaves/shared/contract-engine/src/io.rs b/cosmwasm/enclaves/shared/contract-engine/src/io.rs index b5177c8cf..ac2666ee8 100644 --- a/cosmwasm/enclaves/shared/contract-engine/src/io.rs +++ b/cosmwasm/enclaves/shared/contract-engine/src/io.rs @@ -411,8 +411,8 @@ pub fn encrypt_output( // More info in: https://github.com/CosmWasm/cosmwasm/blob/v1.0.0/packages/std/src/results/submessages.rs#L192-L198 let encryption_key = calc_encryption_key(&secret_msg.nonce, &secret_msg.user_public_key); trace!( - "Output before encryption: {:?}", - String::from_utf8_lossy(&output) + "Output before encryption: {:?} {:?} {:?}", + String::from_utf8_lossy(&output), secret_msg.nonce, secret_msg.user_public_key ); let mut output: RawWasmOutput = serde_json::from_slice(&output).map_err(|err| { diff --git a/cosmwasm/enclaves/shared/contract-engine/src/message.rs b/cosmwasm/enclaves/shared/contract-engine/src/message.rs index fc484982a..4e959b088 100644 --- a/cosmwasm/enclaves/shared/contract-engine/src/message.rs +++ b/cosmwasm/enclaves/shared/contract-engine/src/message.rs @@ -1,5 +1,4 @@ use log::{trace, warn}; -use serde::Serialize; use cosmos_proto::tx::signing::SignMode; use cw_types_v010::encoding::Binary; @@ -15,6 +14,7 @@ const HEX_ENCODED_HASH_SIZE: usize = 64; pub struct ParsedMessage { pub should_validate_sig_info: bool, pub was_msg_encrypted: bool, + pub should_encrypt_output: bool, pub secret_msg: SecretMessage, pub decrypted_msg: Vec, pub contract_hash_for_validation: Option>, @@ -107,6 +107,7 @@ pub fn parse_message( Ok(ParsedMessage { should_validate_sig_info: true, was_msg_encrypted: true, + should_encrypt_output: true, secret_msg: decrypted_secret_msg.secret_msg, decrypted_msg: decrypted_secret_msg.decrypted_msg, contract_hash_for_validation: None, @@ -124,6 +125,7 @@ pub fn parse_message( Ok(ParsedMessage { should_validate_sig_info: false, was_msg_encrypted: false, + should_encrypt_output: false, secret_msg, decrypted_msg, contract_hash_for_validation: None, @@ -197,6 +199,7 @@ pub fn parse_message( return Ok(ParsedMessage { should_validate_sig_info: false, was_msg_encrypted: false, + should_encrypt_output: true, // When replies are plaintext it doesn't mean we can't encrypt them secret_msg: reply_secret_msg, decrypted_msg: serialized_reply, contract_hash_for_validation: None, @@ -301,6 +304,7 @@ pub fn parse_message( Ok(ParsedMessage { should_validate_sig_info: true, was_msg_encrypted: true, + should_encrypt_output: true, secret_msg: reply_secret_msg, decrypted_msg: decrypted_reply_as_vec, contract_hash_for_validation: Some( @@ -394,6 +398,7 @@ pub fn parse_message( Ok(ParsedMessage { should_validate_sig_info: true, was_msg_encrypted: true, + should_encrypt_output: true, secret_msg: reply_secret_msg, decrypted_msg: decrypted_reply_as_vec, contract_hash_for_validation: Some( @@ -425,6 +430,7 @@ pub fn parse_message( Ok(ParsedMessage { should_validate_sig_info: false, was_msg_encrypted: false, + should_encrypt_output: false, secret_msg: scrt_msg, decrypted_msg, contract_hash_for_validation: None, @@ -471,6 +477,7 @@ pub fn parse_message( Ok(ParsedMessage { should_validate_sig_info: false, was_msg_encrypted, + should_encrypt_output: was_msg_encrypted, secret_msg: orig_secret_msg, decrypted_msg: serde_json::to_vec(&parsed_encrypted_ibc_packet).map_err(|err| { warn!( diff --git a/x/compute/internal/keeper/ibc_test.go b/x/compute/internal/keeper/ibc_test.go index ae042da74..8d224b0d5 100644 --- a/x/compute/internal/keeper/ibc_test.go +++ b/x/compute/internal/keeper/ibc_test.go @@ -905,3 +905,126 @@ func TestIBCPacketAck(t *testing.T) { }) } } + +func TestIBCPacketTimeout(t *testing.T) { + ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, "./testdata/ibc/contract.wasm", sdk.NewCoins()) + + _, _, contractAddress, _, err := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"init":{}}`, true, true, defaultGasForTests) + require.Empty(t, err) + + for _, test := range []struct { + description string + sequence uint64 + output string + isSuccess bool + hasAttributes bool + hasEvents bool + }{ + { + description: "Default", + sequence: 0, + output: "9", + isSuccess: true, + hasAttributes: false, + hasEvents: false, + }, + { + description: "SubmessageNoReply", + sequence: 1, + output: "15", + isSuccess: true, + hasAttributes: false, + hasEvents: false, + }, + { + description: "SubmessageWithReply", + sequence: 2, + output: "22", + isSuccess: true, + hasAttributes: false, + hasEvents: false, + }, + { + description: "Attributes", + sequence: 3, + output: "12", + isSuccess: true, + hasAttributes: true, + hasEvents: false, + }, + { + description: "Events", + sequence: 4, + output: "13", + isSuccess: true, + hasAttributes: false, + hasEvents: true, + }, + { + description: "Error", + sequence: 5, + output: "", + isSuccess: false, + hasAttributes: false, + hasEvents: false, + }, + } { + t.Run(test.description, func(t *testing.T) { + ibcPacket := createIBCPacket(createIBCEndpoint(PortIDForContract(contractAddress), "channel.1"), + createIBCEndpoint(PortIDForContract(contractAddress), "channel.0"), + test.sequence, + createIBCTimeout(math.MaxUint64), + []byte{}, + ) + + ctx, events, err := ibcPacketTimeoutHelper(t, keeper, ctx, contractAddress, privKeyA, defaultGasForTests, ibcPacket) + + if !test.isSuccess { + require.Contains(t, fmt.Sprintf("%+v", err), "Intentional") + } else { + require.Empty(t, err) + if test.hasAttributes { + require.Equal(t, + []ContractEvent{ + { + {Key: "contract_address", Value: contractAddress.String()}, + {Key: "attr1", Value: "😗"}, + }, + }, + events, + ) + } + + if test.hasEvents { + hadCyber1 := false + evts := ctx.EventManager().Events() + for _, e := range evts { + if e.Type == "wasm-cyber1" { + require.False(t, hadCyber1) + attrs, err := parseAndDecryptAttributes(e.Attributes, []byte{}, false) + require.Empty(t, err) + + require.Equal(t, + []v010cosmwasm.LogAttribute{ + {Key: "contract_address", Value: contractAddress.String()}, + {Key: "attr1", Value: "🤯"}, + }, + attrs, + ) + + hadCyber1 = true + } + } + + require.True(t, hadCyber1) + } + + queryRes, err := queryHelper(t, keeper, ctx, contractAddress, `{"q":{}}`, true, true, math.MaxUint64) + + require.Empty(t, err) + + require.Equal(t, test.output, queryRes) + } + }) + } +} diff --git a/x/compute/internal/keeper/secret_contracts_test.go b/x/compute/internal/keeper/secret_contracts_test.go index 50c07f3c9..2ab742628 100644 --- a/x/compute/internal/keeper/secret_contracts_test.go +++ b/x/compute/internal/keeper/secret_contracts_test.go @@ -232,11 +232,8 @@ func tryDecryptWasmEvents(ctx sdk.Context, nonce []byte, shouldSkipAttributes .. if !shouldSkip && newLog.Key != "contract_address" { // key - fmt.Printf("LIORRR before %+v nonce %+v", newLog, nonce) newAttr, err := decryptAttribute(newLog, nonce) - fmt.Printf("LIORRR after %+v", newAttr) if err != nil { - fmt.Printf("LIORRR here %+v", err) continue } diff --git a/x/compute/internal/keeper/test_common.go b/x/compute/internal/keeper/test_common.go index b5f67681b..7c34ba7e8 100644 --- a/x/compute/internal/keeper/test_common.go +++ b/x/compute/internal/keeper/test_common.go @@ -369,6 +369,9 @@ func CreateTestInput(t *testing.T, isCheckTx bool, supportedFeatures string, enc ) memKeys := sdk.NewMemoryStoreKeys(capabilitytypes.MemStoreKey) + for _, v := range memKeys { + ms.MountStoreWithDB(v, sdk.StoreTypeMemory, db) + } upgradeKeeper := upgradekeeper.NewKeeper( map[int64]bool{}, diff --git a/x/compute/internal/keeper/testdata/ibc/src/contract.rs b/x/compute/internal/keeper/testdata/ibc/src/contract.rs index cb5016848..c8cd046b8 100644 --- a/x/compute/internal/keeper/testdata/ibc/src/contract.rs +++ b/x/compute/internal/keeper/testdata/ibc/src/contract.rs @@ -3,8 +3,9 @@ use crate::state::{count, count_read}; use cosmwasm_std::{ entry_point, to_binary, Binary, CosmosMsg, Deps, DepsMut, Env, Event, Ibc3ChannelOpenResponse, IbcBasicResponse, IbcChannelCloseMsg, IbcChannelConnectMsg, IbcChannelOpenMsg, - IbcChannelOpenResponse, IbcPacketAckMsg, IbcPacketReceiveMsg, IbcReceiveResponse, MessageInfo, - Reply, ReplyOn, Response, StdError, StdResult, SubMsg, SubMsgResult, WasmMsg, + IbcChannelOpenResponse, IbcPacketAckMsg, IbcPacketReceiveMsg, IbcPacketTimeoutMsg, + IbcReceiveResponse, MessageInfo, Reply, ReplyOn, Response, StdError, StdResult, SubMsg, + SubMsgResult, WasmMsg, }; pub const IBC_APP_VERSION: &str = "ibc-v1"; @@ -43,7 +44,7 @@ pub fn reply(deps: DepsMut, _env: Env, reply: Reply) -> StdResult { (1, SubMsgResult::Err(_)) => Err(StdError::generic_err("Failed to inc")), (1, SubMsgResult::Ok(_)) => { increment(deps, 6)?; - Ok(Response::default()) + Ok(Response::new().set_data(to_binary(&"out2".to_string())?)) } _ => Err(StdError::generic_err("invalid reply id or result")), } @@ -233,3 +234,13 @@ pub fn ibc_packet_ack( count(deps.storage).save(&(msg.original_packet.sequence + 8))?; get_resp_based_on_num(env, msg.original_packet.sequence) } + +// #[entry_point] +// pub fn ibc_packet_timeout( +// deps: DepsMut, +// env: Env, +// msg: IbcPacketTimeoutMsg, +// ) -> StdResult { +// count(deps.storage).save(&(msg.packet.sequence + 9))?; +// get_resp_based_on_num(env, msg.packet.sequence) +// } From 8152de24b0999e71c19ab9a4d79af0b38451625e Mon Sep 17 00:00:00 2001 From: Eshel Date: Mon, 29 Aug 2022 16:55:06 +0300 Subject: [PATCH 87/93] adding util file that lets me see a transaction more cleanly: converting attributes from the form of bytes to their string form --- integration-tests/utils.ts | 68 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) create mode 100644 integration-tests/utils.ts diff --git a/integration-tests/utils.ts b/integration-tests/utils.ts new file mode 100644 index 000000000..569cef2a7 --- /dev/null +++ b/integration-tests/utils.ts @@ -0,0 +1,68 @@ +const testInput = { + events: [ + { + type: "yes", + attributes: [ + { + key: { + "0": 115, + "1": 101, + "2": 110, + "3": 100, + "4": 101, + "5": 114 + }, + value: { + "0": 115, + "1": 101, + "2": 99, + "3": 114, + }, + index: true + } + ] + } + ], + "other": "value" +} + +interface BytesObj { + [key: string]: number +} + +const bytesToKv = (input: BytesObj) => { + let output = ""; + for (const v of Object.values(input)) { + output += String.fromCharCode(v); + } + + return output; +} + +const objToKv = (input) => { + // console.log("got object:", input); + const output = {}; + const key = bytesToKv(input.key); + output[key] = bytesToKv(input.value); + return output; +} + +export const cleanBytes = (tx) => { + // console.log("input:", JSON.stringify(testInput, null, 2), "\n\n"); + + const events = tx.events.map(e => { + return { + ...e, + attributes: e.attributes.map(i => objToKv(i)) + }; + } + ) + + const output = { + ...tx, + events, + txBytes: undefined, + }; + // console.log("output:", JSON.stringify(output, null, 2)); + return output; +} \ No newline at end of file From 7d65399ed9904314dbabc9ea8e86a552483b6b91 Mon Sep 17 00:00:00 2001 From: Lior Bondarevski Date: Tue, 30 Aug 2022 15:22:56 +0300 Subject: [PATCH 88/93] Encrypt plaintext replies only if the original message was encrypted --- .../enclaves/shared/contract-engine/src/io.rs | 11 ++- .../shared/contract-engine/src/message.rs | 2 +- .../v1.0/src/results/submessages.rs | 10 +++ go-cosmwasm/types/v1/subcall.go | 14 ++-- x/compute/internal/keeper/ibc_test.go | 72 +++++++++++++++++ x/compute/internal/keeper/msg_dispatcher.go | 5 +- x/compute/internal/keeper/test_common.go | 2 +- .../keeper/testdata/ibc/src/contract.rs | 78 +++++++++++++++++-- 8 files changed, 178 insertions(+), 16 deletions(-) diff --git a/cosmwasm/enclaves/shared/contract-engine/src/io.rs b/cosmwasm/enclaves/shared/contract-engine/src/io.rs index ac2666ee8..0818c2ee2 100644 --- a/cosmwasm/enclaves/shared/contract-engine/src/io.rs +++ b/cosmwasm/enclaves/shared/contract-engine/src/io.rs @@ -412,7 +412,9 @@ pub fn encrypt_output( let encryption_key = calc_encryption_key(&secret_msg.nonce, &secret_msg.user_public_key); trace!( "Output before encryption: {:?} {:?} {:?}", - String::from_utf8_lossy(&output), secret_msg.nonce, secret_msg.user_public_key + String::from_utf8_lossy(&output), + secret_msg.nonce, + secret_msg.user_public_key ); let mut output: RawWasmOutput = serde_json::from_slice(&output).map_err(|err| { @@ -449,6 +451,7 @@ pub fn encrypt_output( let reply = Reply { id: msg_id.unwrap(), result: SubMsgResult::Err(encrypted_err), + was_msg_encrypted: true, }; let reply_as_vec = serde_json::to_vec(&reply).map_err(|err| { warn!( @@ -537,6 +540,7 @@ pub fn encrypt_output( events, data: ok.data.clone(), }), + was_msg_encrypted: true, }; let reply_as_vec = serde_json::to_vec(&reply).map_err(|err| { @@ -580,6 +584,8 @@ pub fn encrypt_output( // We don't encrypt it here to remain with the same type (u64) sub_msg.id = 0; } + + sub_msg.was_msg_encrypted = true; } // v1: The attributes that will be emitted as part of a "wasm" event. @@ -649,6 +655,7 @@ pub fn encrypt_output( events, data: ok.data.clone(), }), + was_msg_encrypted: true, }; let reply_as_vec = serde_json::to_vec(&reply).map_err(|err| { @@ -689,6 +696,8 @@ pub fn encrypt_output( // We don't encrypt it here to remain with the same type (u64) sub_msg.id = 0; } + + sub_msg.was_msg_encrypted = true; } // v1: The attributes that will be emitted as part of a "wasm" event. diff --git a/cosmwasm/enclaves/shared/contract-engine/src/message.rs b/cosmwasm/enclaves/shared/contract-engine/src/message.rs index 4e959b088..d5bbf98fb 100644 --- a/cosmwasm/enclaves/shared/contract-engine/src/message.rs +++ b/cosmwasm/enclaves/shared/contract-engine/src/message.rs @@ -199,7 +199,7 @@ pub fn parse_message( return Ok(ParsedMessage { should_validate_sig_info: false, was_msg_encrypted: false, - should_encrypt_output: true, // When replies are plaintext it doesn't mean we can't encrypt them + should_encrypt_output: reply.was_msg_encrypted, secret_msg: reply_secret_msg, decrypted_msg: serialized_reply, contract_hash_for_validation: None, diff --git a/cosmwasm/enclaves/shared/cosmwasm-types/v1.0/src/results/submessages.rs b/cosmwasm/enclaves/shared/cosmwasm-types/v1.0/src/results/submessages.rs index 78e0c00bf..4a0f08412 100644 --- a/cosmwasm/enclaves/shared/cosmwasm-types/v1.0/src/results/submessages.rs +++ b/cosmwasm/enclaves/shared/cosmwasm-types/v1.0/src/results/submessages.rs @@ -21,6 +21,10 @@ pub enum ReplyOn { Never, } +fn bool_false() -> bool { + false +} + /// A submessage that will guarantee a `reply` call on success or error, depending on /// the `reply_on` setting. If you do not need to process the result, use regular messages instead. /// @@ -38,6 +42,11 @@ where pub msg: CosmosMsg, pub gas_limit: Option, pub reply_on: ReplyOn, + // An indication that will be passed to the reply that will indicate wether the original message, + // which is the one who create the submessages, was encrypted or not. + // Plaintext replies will be encrypted only if the original message was. + #[serde(default = "bool_false")] + pub was_msg_encrypted: bool, } /// The information we get back from a successful sub message execution, @@ -65,6 +74,7 @@ pub struct Reply { /// Use this to identify which submessage triggered the `reply`. pub id: Binary, pub result: SubMsgResult, + pub was_msg_encrypted: bool, } #[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] pub struct DecryptedReply { diff --git a/go-cosmwasm/types/v1/subcall.go b/go-cosmwasm/types/v1/subcall.go index 0be755b38..7732e600a 100644 --- a/go-cosmwasm/types/v1/subcall.go +++ b/go-cosmwasm/types/v1/subcall.go @@ -66,15 +66,17 @@ type SubMsgResult struct { // SubMsg wraps a CosmosMsg with some metadata for handling replies (ID) and optionally // limiting the gas usage (GasLimit) type SubMsg struct { - ID uint64 `json:"id"` - Msg CosmosMsg `json:"msg"` - GasLimit *uint64 `json:"gas_limit,omitempty"` - ReplyOn replyOn `json:"reply_on"` + ID uint64 `json:"id"` + Msg CosmosMsg `json:"msg"` + GasLimit *uint64 `json:"gas_limit,omitempty"` + ReplyOn replyOn `json:"reply_on"` + WasMsgEncrypted bool `json:"was_msg_encrypted"` } type Reply struct { - ID []byte `json:"id"` - Result SubMsgResult `json:"result"` + ID []byte `json:"id"` + Result SubMsgResult `json:"result"` + WasMsgEncrypted bool `json:"was_msg_encrypted"` } // SubcallResult is the raw response we return from the sdk -> reply after executing a SubMsg. diff --git a/x/compute/internal/keeper/ibc_test.go b/x/compute/internal/keeper/ibc_test.go index 8d224b0d5..13548318a 100644 --- a/x/compute/internal/keeper/ibc_test.go +++ b/x/compute/internal/keeper/ibc_test.go @@ -3,8 +3,10 @@ package keeper import ( "encoding/binary" "encoding/hex" + "encoding/json" "fmt" "math" + "os" "testing" crypto "github.com/cosmos/cosmos-sdk/crypto/types" @@ -719,6 +721,14 @@ func TestIBCPacketReceive(t *testing.T) { hasAttributes: false, hasEvents: false, }, + { + description: "SubmessageWithReplyThatCallsToSubmessage", + sequence: 6, + output: "35", + isSuccess: true, + hasAttributes: false, + hasEvents: false, + }, } { t.Run(fmt.Sprintf("%s-Encryption:%t", test.description, isEncrypted), func(t *testing.T) { ibcPacket := createIBCPacket(createIBCEndpoint(PortIDForContract(contractAddress), "channel.1"), @@ -781,6 +791,68 @@ func TestIBCPacketReceive(t *testing.T) { } } +type ContractInfo struct { + Address string `json:"address"` + Hash string `json:"hash"` +} + +func TestIBCPacketReceiveCallsV010Contract(t *testing.T) { + ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, "./testdata/ibc/contract.wasm", sdk.NewCoins()) + + wasmCode, err := os.ReadFile("./testdata/test-contract/contract.wasm") + require.NoError(t, err) + + v010CodeID, err := keeper.Create(ctx, walletA, wasmCode, "", "") + require.NoError(t, err) + + codeInfo, err := keeper.GetCodeInfo(ctx, v010CodeID) + require.NoError(t, err) + v010CodeHash := hex.EncodeToString(codeInfo.CodeHash) + + _, _, contractAddress, _, err := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"init":{}}`, true, true, defaultGasForTests) + require.Empty(t, err) + _, _, v010ContractAddress, _, err := initHelper(t, keeper, ctx, v010CodeID, walletA, privKeyA, `{"counter":{"counter":10}}`, true, false, defaultGasForTests) + require.Empty(t, err) + contractInfo := ContractInfo{ + Address: v010ContractAddress.String(), + Hash: v010CodeHash, + } + + contractInfoBz, err := json.Marshal(contractInfo) + require.NoError(t, err) + + ibcPacket := createIBCPacket(createIBCEndpoint(PortIDForContract(contractAddress), "channel.1"), + createIBCEndpoint(PortIDForContract(contractAddress), "channel.0"), + 7, + createIBCTimeout(math.MaxUint64), + contractInfoBz, + ) + + expected_v010_result := uint32(15) + + for _, isEncrypted := range []bool{true, true} { + t.Run(fmt.Sprintf("Encryption:%t", isEncrypted), func(t *testing.T) { + ctx, _, _, data, err := ibcPacketReceiveHelper(t, keeper, ctx, contractAddress, privKeyA, isEncrypted, defaultGasForTests, ibcPacket) + require.Empty(t, err) + require.Equal(t, "\"out\"", string(data)) + + queryRes, err := queryHelper(t, keeper, ctx, contractAddress, `{"q":{}}`, true, true, math.MaxUint64) + + require.Empty(t, err) + require.Equal(t, "20", queryRes) + + queryRes, qErr := queryHelper(t, keeper, ctx, v010ContractAddress, `{"get":{}}`, true, false, math.MaxUint64) + require.Empty(t, qErr) + + var resp v1QueryResponse + e := json.Unmarshal([]byte(queryRes), &resp) + require.NoError(t, e) + require.Equal(t, expected_v010_result, resp.Get.Count) + expected_v010_result += 5 + }) + } +} + func TestIBCPacketAck(t *testing.T) { ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, "./testdata/ibc/contract.wasm", sdk.NewCoins()) diff --git a/x/compute/internal/keeper/msg_dispatcher.go b/x/compute/internal/keeper/msg_dispatcher.go index 92792f986..234c90532 100644 --- a/x/compute/internal/keeper/msg_dispatcher.go +++ b/x/compute/internal/keeper/msg_dispatcher.go @@ -274,8 +274,9 @@ func (d MessageDispatcher) DispatchSubmessages(ctx sdk.Context, contractAddr sdk msg_id := []byte(fmt.Sprint(msg.ID)) // now handle the reply, we use the parent context, and abort on error reply := v1wasmTypes.Reply{ - ID: msg_id, - Result: result, + ID: msg_id, + Result: result, + WasMsgEncrypted: msg.WasMsgEncrypted, } // we can ignore any result returned as there is nothing to do with the data diff --git a/x/compute/internal/keeper/test_common.go b/x/compute/internal/keeper/test_common.go index 7c34ba7e8..249e2a37d 100644 --- a/x/compute/internal/keeper/test_common.go +++ b/x/compute/internal/keeper/test_common.go @@ -364,7 +364,7 @@ func CreateTestInput(t *testing.T, isCheckTx bool, supportedFeatures string, enc authtypes.StoreKey, banktypes.StoreKey, stakingtypes.StoreKey, minttypes.StoreKey, distrtypes.StoreKey, slashingtypes.StoreKey, govtypes.StoreKey, paramstypes.StoreKey, ibchost.StoreKey, upgradetypes.StoreKey, - evidencetypes.StoreKey, ibctransfertypes.StoreKey, capabilitytypes.StoreKey, + evidencetypes.StoreKey, ibctransfertypes.StoreKey, capabilitytypes.StoreKey, "compute", feegrant.StoreKey, authzkeeper.StoreKey, icahosttypes.StoreKey, ) diff --git a/x/compute/internal/keeper/testdata/ibc/src/contract.rs b/x/compute/internal/keeper/testdata/ibc/src/contract.rs index c8cd046b8..fa827d2e6 100644 --- a/x/compute/internal/keeper/testdata/ibc/src/contract.rs +++ b/x/compute/internal/keeper/testdata/ibc/src/contract.rs @@ -7,6 +7,8 @@ use cosmwasm_std::{ IbcReceiveResponse, MessageInfo, Reply, ReplyOn, Response, StdError, StdResult, SubMsg, SubMsgResult, WasmMsg, }; +use serde::{Deserialize, Serialize}; +use serde_json_wasm as serde_json; pub const IBC_APP_VERSION: &str = "ibc-v1"; @@ -39,12 +41,28 @@ pub fn query(deps: Deps, _env: Env, _msg: QueryMsg) -> StdResult { } #[entry_point] -pub fn reply(deps: DepsMut, _env: Env, reply: Reply) -> StdResult { +pub fn reply(deps: DepsMut, env: Env, reply: Reply) -> StdResult { match (reply.id, reply.result) { (1, SubMsgResult::Err(_)) => Err(StdError::generic_err("Failed to inc")), (1, SubMsgResult::Ok(_)) => { increment(deps, 6)?; - Ok(Response::new().set_data(to_binary(&"out2".to_string())?)) + Ok(Response::new().set_data(to_binary(&"out".to_string())?)) + } + (2, SubMsgResult::Err(_)) => Err(StdError::generic_err("Failed to inc")), + (2, SubMsgResult::Ok(_)) => { + increment(deps, 6)?; + Ok(Response::new().add_submessage(SubMsg { + id: 1, + msg: CosmosMsg::Wasm(WasmMsg::Execute { + code_hash: env.contract.code_hash, + contract_addr: env.contract.address.into_string(), + msg: Binary::from("{\"increment\":{\"addition\":5}}".as_bytes().to_vec()), + funds: vec![], + }) + .into(), + reply_on: ReplyOn::Always, + gas_limit: None, + })) } _ => Err(StdError::generic_err("invalid reply id or result")), } @@ -115,7 +133,24 @@ pub fn get_resp_based_on_num(env: Env, num: u64) -> StdResult } } -pub fn get_recv_resp_based_on_num(env: Env, num: u64) -> StdResult { +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] +pub struct ContractInfo { + pub address: String, + pub hash: String, +} + +pub fn is_reply_on(num: u64) -> bool { + match num { + 2 | 6 => true, + _ => false, + } +} + +pub fn get_recv_resp_based_on_num( + env: Env, + num: u64, + data: Binary, +) -> StdResult { match num { 0 => Ok(IbcReceiveResponse::default()), 1 => Ok(IbcReceiveResponse::new().add_submessage(SubMsg { @@ -146,6 +181,37 @@ pub fn get_recv_resp_based_on_num(env: Env, num: u64) -> StdResult Ok(IbcReceiveResponse::new() .add_event(Event::new("cyber1".to_string()).add_attribute("attr1", "🤯"))), 5 => Err(StdError::generic_err("Intentional")), + 6 => Ok(IbcReceiveResponse::new().add_submessage(SubMsg { + id: 2, + msg: CosmosMsg::Wasm(WasmMsg::Execute { + code_hash: env.contract.code_hash, + contract_addr: env.contract.address.into_string(), + msg: Binary::from("{\"increment\":{\"addition\":5}}".as_bytes().to_vec()), + funds: vec![], + }) + .into(), + reply_on: ReplyOn::Always, + gas_limit: None, + })), + 7 => { + let contract_info: ContractInfo = serde_json::from_slice(data.as_slice()).unwrap(); + Ok(IbcReceiveResponse::new().add_submessage(SubMsg { + id: 1, + msg: CosmosMsg::Wasm(WasmMsg::Execute { + code_hash: contract_info.hash, + contract_addr: contract_info.address, + msg: Binary::from( + "{\"increment_from_v1\":{\"addition\":5}}" + .as_bytes() + .to_vec(), + ), + funds: vec![], + }) + .into(), + reply_on: ReplyOn::Always, + gas_limit: None, + })) + } _ => Err(StdError::generic_err("Unsupported channel connect type")), } } @@ -207,10 +273,12 @@ pub fn ibc_packet_receive( msg: IbcPacketReceiveMsg, ) -> StdResult { count(deps.storage).save(&(msg.packet.sequence + 7))?; - let mut resp = get_recv_resp_based_on_num(env, msg.packet.sequence); + let mut resp = get_recv_resp_based_on_num(env, msg.packet.sequence, msg.packet.data); match &mut resp { Ok(r) => { - r.acknowledgement = to_binary(&"out".to_string())?; + if !is_reply_on(msg.packet.sequence) { + r.acknowledgement = to_binary(&"out".to_string())?; + } } Err(_) => {} } From add2302a864d79bf3c93250794dc5373cc788127 Mon Sep 17 00:00:00 2001 From: Lior Bondarevski Date: Tue, 30 Aug 2022 15:59:48 +0300 Subject: [PATCH 89/93] Fix gtests --- .../enclaves/shared/contract-engine/src/io.rs | 14 +++++++--- .../internal/keeper/secret_contracts_test.go | 27 ------------------- 2 files changed, 10 insertions(+), 31 deletions(-) diff --git a/cosmwasm/enclaves/shared/contract-engine/src/io.rs b/cosmwasm/enclaves/shared/contract-engine/src/io.rs index 0818c2ee2..f0c284535 100644 --- a/cosmwasm/enclaves/shared/contract-engine/src/io.rs +++ b/cosmwasm/enclaves/shared/contract-engine/src/io.rs @@ -528,10 +528,14 @@ pub fn encrypt_output( Some(_) => { let events = match ok.log.len() { 0 => vec![], - _ => vec![Event { - ty: "wasm".to_string(), - attributes: ok.log.clone(), - }], + _ => { + let mut logs = ok.log.clone(); + logs.sort_by(|a, b| a.key.cmp(&b.key)); + vec![Event { + ty: "wasm".to_string(), + attributes: logs, + }] + } }; let reply = Reply { @@ -647,6 +651,8 @@ pub fn encrypt_output( if event.ty != "wasm" { event.ty = custom_contract_event_prefix.clone() + event.ty.as_str(); } + + event.attributes.sort_by(|a, b| a.key.cmp(&b.key)); } let reply = Reply { diff --git a/x/compute/internal/keeper/secret_contracts_test.go b/x/compute/internal/keeper/secret_contracts_test.go index 2ab742628..733eab829 100644 --- a/x/compute/internal/keeper/secret_contracts_test.go +++ b/x/compute/internal/keeper/secret_contracts_test.go @@ -1280,33 +1280,6 @@ func TestInitNotEncryptedInputError(t *testing.T) { } } -func TestExecuteNotEncryptedInputError(t *testing.T) { - for _, testContract := range testContracts { - t.Run(testContract.CosmWasmVersion, func(t *testing.T) { - ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, testContract.WasmFilePath, sdk.NewCoins()) - - _, _, contractAddress, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, testContract.IsCosmWasmV1, defaultGasForTests) - require.Empty(t, initErr) - - //ctx = sdk.NewContext( - // ctx.MultiStore(), - // ctx.BlockHeader(), - // ctx.IsCheckTx(), - // log.NewNopLogger(), - //).WithGasMeter(sdk.NewGasMeter(defaultGas)) - - execMsg := []byte(`{"empty_log_key_value":{}}`) - - ctx = PrepareExecSignedTx(t, keeper, ctx, walletA, privKeyA, execMsg, contractAddress, nil) - - _, err := keeper.Execute(ctx, contractAddress, walletA, execMsg, sdk.NewCoins(sdk.NewInt64Coin("denom", 0)), nil) - require.Error(t, err) - - require.Contains(t, err.Error(), "failed to decrypt data") - }) - } -} - func TestQueryNotEncryptedInputError(t *testing.T) { for _, testContract := range testContracts { t.Run(testContract.CosmWasmVersion, func(t *testing.T) { From 5dfee90737eb995d5717631e8bbae655ebeb3886 Mon Sep 17 00:00:00 2001 From: Eshel Date: Tue, 30 Aug 2022 16:15:45 +0300 Subject: [PATCH 90/93] added the v010 integratoin-test for bankMsgSend --- .../contract-v0.10/src/contract.rs | 36 +++++++----- integration-tests/test.ts | 56 ++++++++++++++++++- 2 files changed, 76 insertions(+), 16 deletions(-) diff --git a/integration-tests/contract-v0.10/src/contract.rs b/integration-tests/contract-v0.10/src/contract.rs index 1abce32af..5e1cd82e4 100644 --- a/integration-tests/contract-v0.10/src/contract.rs +++ b/integration-tests/contract-v0.10/src/contract.rs @@ -1,8 +1,4 @@ -use cosmwasm_std::{ - to_binary, Api, BalanceResponse, BankQuery, Binary, Coin, Env, Extern, HandleResponse, - HandleResult, HumanAddr, InitResponse, InitResult, Querier, QueryRequest, QueryResult, Storage, - VoteOption, -}; +use cosmwasm_std::{to_binary, Api, BalanceResponse, BankQuery, Binary, Coin, Env, Extern, HandleResponse, HandleResult, HumanAddr, InitResponse, InitResult, Querier, QueryRequest, QueryResult, Storage, VoteOption, CosmosMsg, BankMsg}; /////////////////////////////// Messages /////////////////////////////// @@ -14,7 +10,7 @@ use serde::{Deserialize, Serialize}; pub enum Msg { Nop {}, BankMsgSend { - to_address: String, + to_address: HumanAddr, amount: Vec, }, StargateMsg { @@ -83,15 +79,27 @@ pub fn init( pub fn handle( _deps: &mut Extern, - _env: Env, - _msg: Msg, + env: Env, + msg: Msg, ) -> HandleResult { - // match msg {} - return Ok(HandleResponse { - messages: vec![], - log: vec![], - data: None, - }); + match msg { + Msg::BankMsgSend { to_address, amount } => Ok( + HandleResponse { + messages: vec![ + CosmosMsg::Bank(BankMsg::Send { from_address: env.contract.address, to_address, amount }) + ], + log: vec![], + data: None, + } + ), + _ => Ok( + HandleResponse { + messages: vec![], + log: vec![], + data: None, + } + ), + } } /////////////////////////////// Query /////////////////////////////// diff --git a/integration-tests/test.ts b/integration-tests/test.ts index b9a40053d..924d73f9a 100644 --- a/integration-tests/test.ts +++ b/integration-tests/test.ts @@ -150,9 +150,9 @@ async function waitForBlocks() { try { const { block } = await secretjs.query.tendermint.getLatestBlock({}); - console.log("block:", JSON.stringify(block)); if (Number(block?.header?.height) >= 1) { + console.log("blocks are running, current block:", JSON.stringify(block.header.height)); break; } } catch (e) { @@ -220,7 +220,59 @@ describe("Bank::MsgSend", () => { }); test("v0.10", async () => { - // TODO + const tx = await accounts.a.tx.compute.executeContract( + { + sender: accounts.a.address, + contractAddress: v010Address, + codeHash: v010CodeHash, + msg: { + bank_msg_send: { + to_address: accounts.b.address, + amount: [{ amount: "1", denom: "uscrt" }], + }, + }, + sentFunds: [{ amount: "1", denom: "uscrt" }], + }, + { gasLimit: 250_000 } + ); + if (tx.code !== 0) { + console.error(tx.rawLog); + } + expect(tx.code).toBe(0); + expect(tx.arrayLog.filter((x) => x.type === "coin_spent")).toStrictEqual([ + { + key: "spender", + msg: 0, + type: "coin_spent", + value: accounts.a.address, + }, + { key: "amount", msg: 0, type: "coin_spent", value: "1uscrt" }, + { + key: "spender", + msg: 0, + type: "coin_spent", + value: v010Address, + }, + { key: "amount", msg: 0, type: "coin_spent", value: "1uscrt" }, + ]); + expect(tx.arrayLog.filter((x) => x.type === "coin_received")).toStrictEqual( + [ + { + key: "receiver", + msg: 0, + type: "coin_received", + value: v010Address, + }, + { key: "amount", msg: 0, type: "coin_received", value: "1uscrt" }, + { + key: "receiver", + msg: 0, + type: "coin_received", + value: accounts.b.address, + }, + { key: "amount", msg: 0, type: "coin_received", value: "1uscrt" }, + ] + ); }); }); From 07d51f4122cb8c6b8b600acbbb5eb4b1c2767f73 Mon Sep 17 00:00:00 2001 From: Lior Bondarevski Date: Tue, 30 Aug 2022 17:09:22 +0300 Subject: [PATCH 91/93] Commented code --- .../keeper/testdata/ibc/src/contract.rs | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/x/compute/internal/keeper/testdata/ibc/src/contract.rs b/x/compute/internal/keeper/testdata/ibc/src/contract.rs index fa827d2e6..3bf55f262 100644 --- a/x/compute/internal/keeper/testdata/ibc/src/contract.rs +++ b/x/compute/internal/keeper/testdata/ibc/src/contract.rs @@ -303,12 +303,12 @@ pub fn ibc_packet_ack( get_resp_based_on_num(env, msg.original_packet.sequence) } -// #[entry_point] -// pub fn ibc_packet_timeout( -// deps: DepsMut, -// env: Env, -// msg: IbcPacketTimeoutMsg, -// ) -> StdResult { -// count(deps.storage).save(&(msg.packet.sequence + 9))?; -// get_resp_based_on_num(env, msg.packet.sequence) -// } +#[entry_point] +pub fn ibc_packet_timeout( + deps: DepsMut, + env: Env, + msg: IbcPacketTimeoutMsg, +) -> StdResult { + count(deps.storage).save(&(msg.packet.sequence + 9))?; + get_resp_based_on_num(env, msg.packet.sequence) +} From 2888b8a04a9fff895533d73b9d0ff11e3b5a803a Mon Sep 17 00:00:00 2001 From: Itzik Date: Tue, 30 Aug 2022 18:10:13 +0300 Subject: [PATCH 92/93] Fix test setup --- x/compute/internal/keeper/test_common.go | 111 ++++++++++++++--------- 1 file changed, 70 insertions(+), 41 deletions(-) diff --git a/x/compute/internal/keeper/test_common.go b/x/compute/internal/keeper/test_common.go index 249e2a37d..386735766 100644 --- a/x/compute/internal/keeper/test_common.go +++ b/x/compute/internal/keeper/test_common.go @@ -15,7 +15,6 @@ import ( "github.com/cosmos/cosmos-sdk/x/feegrant" upgradekeeper "github.com/cosmos/cosmos-sdk/x/upgrade/keeper" upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types" - icahosttypes "github.com/cosmos/ibc-go/v3/modules/apps/27-interchain-accounts/host/types" ibctransfertypes "github.com/cosmos/ibc-go/v3/modules/apps/transfer/types" ibchost "github.com/cosmos/ibc-go/v3/modules/core/24-host" ibckeeper "github.com/cosmos/ibc-go/v3/modules/core/keeper" @@ -188,27 +187,42 @@ func CreateTestInput(t *testing.T, isCheckTx bool, supportedFeatures string, enc require.NoError(t, err) t.Cleanup(func() { os.RemoveAll(tempDir) }) - keyContract := sdk.NewKVStoreKey(wasmtypes.StoreKey) - keyAcc := sdk.NewKVStoreKey(authtypes.StoreKey) - keyStaking := sdk.NewKVStoreKey(stakingtypes.StoreKey) - keyDistro := sdk.NewKVStoreKey(distrtypes.StoreKey) - mintStore := sdk.NewKVStoreKey(minttypes.StoreKey) - keyParams := sdk.NewKVStoreKey(paramstypes.StoreKey) - tkeyParams := sdk.NewTransientStoreKey(paramstypes.TStoreKey) - keyGov := sdk.NewKVStoreKey(govtypes.StoreKey) - keyBank := sdk.NewKVStoreKey(banktypes.StoreKey) + //keyContract := sdk.NewKVStoreKey(wasmtypes.StoreKey) + //keyAcc := sdk.NewKVStoreKey(authtypes.StoreKey) + //keyStaking := sdk.NewKVStoreKey(stakingtypes.StoreKey) + //keyDistro := sdk.NewKVStoreKey(distrtypes.StoreKey) + //mintStore := sdk.NewKVStoreKey(minttypes.StoreKey) + //keyParams := sdk.NewKVStoreKey(paramstypes.StoreKey) + //tkeyParams := sdk.NewTransientStoreKey(paramstypes.TStoreKey) + //keyGov := sdk.NewKVStoreKey(govtypes.StoreKey) + //keyBank := sdk.NewKVStoreKey(banktypes.StoreKey) + + keys := sdk.NewKVStoreKeys( + authtypes.StoreKey, banktypes.StoreKey, stakingtypes.StoreKey, + minttypes.StoreKey, distrtypes.StoreKey, slashingtypes.StoreKey, + govtypes.StoreKey, paramstypes.StoreKey, ibchost.StoreKey, upgradetypes.StoreKey, + evidencetypes.StoreKey, ibctransfertypes.StoreKey, + capabilitytypes.StoreKey, feegrant.StoreKey, authzkeeper.StoreKey, + wasmtypes.StoreKey, + ) db := dbm.NewMemDB() + ms := store.NewCommitMultiStore(db) - ms.MountStoreWithDB(keyContract, sdk.StoreTypeIAVL, db) - ms.MountStoreWithDB(keyAcc, sdk.StoreTypeIAVL, db) - ms.MountStoreWithDB(keyParams, sdk.StoreTypeIAVL, db) - ms.MountStoreWithDB(keyStaking, sdk.StoreTypeIAVL, db) - ms.MountStoreWithDB(mintStore, sdk.StoreTypeIAVL, db) - ms.MountStoreWithDB(keyDistro, sdk.StoreTypeIAVL, db) - ms.MountStoreWithDB(tkeyParams, sdk.StoreTypeTransient, db) - ms.MountStoreWithDB(keyGov, sdk.StoreTypeIAVL, db) - ms.MountStoreWithDB(keyBank, sdk.StoreTypeIAVL, db) + for _, v := range keys { + ms.MountStoreWithDB(v, sdk.StoreTypeIAVL, db) + } + + tkeys := sdk.NewTransientStoreKeys(paramstypes.TStoreKey) + for _, v := range tkeys { + ms.MountStoreWithDB(v, sdk.StoreTypeTransient, db) + } + + memKeys := sdk.NewMemoryStoreKeys(capabilitytypes.MemStoreKey) + for _, v := range memKeys { + ms.MountStoreWithDB(v, sdk.StoreTypeMemory, db) + } + require.NoError(t, ms.LoadLatestVersion()) ctx := sdk.NewContext(ms, tmproto.Header{ @@ -217,7 +231,12 @@ func CreateTestInput(t *testing.T, isCheckTx bool, supportedFeatures string, enc ChainID: TestConfig.ChainID, }, isCheckTx, log.NewNopLogger()) encodingConfig := MakeEncodingConfig() - paramsKeeper := paramskeeper.NewKeeper(encodingConfig.Marshaler, encodingConfig.Amino, keyParams, tkeyParams) + paramsKeeper := paramskeeper.NewKeeper( + encodingConfig.Marshaler, + encodingConfig.Amino, + keys[paramstypes.StoreKey], + tkeys[paramstypes.TStoreKey], + ) paramsKeeper.Subspace(authtypes.ModuleName) paramsKeeper.Subspace(banktypes.ModuleName) paramsKeeper.Subspace(stakingtypes.ModuleName) @@ -240,7 +259,7 @@ func CreateTestInput(t *testing.T, isCheckTx bool, supportedFeatures string, enc authSubsp, _ := paramsKeeper.GetSubspace(authtypes.ModuleName) authKeeper := authkeeper.NewAccountKeeper( encodingConfig.Marshaler, - keyAcc, // target store + keys[authtypes.StoreKey], // target store authSubsp, authtypes.ProtoBaseAccount, // prototype maccPerms, @@ -254,7 +273,7 @@ func CreateTestInput(t *testing.T, isCheckTx bool, supportedFeatures string, enc bankSubsp, _ := paramsKeeper.GetSubspace(banktypes.ModuleName) bankKeeper := bankkeeper.NewBaseKeeper( encodingConfig.Marshaler, - keyBank, + keys[banktypes.StoreKey], authKeeper, bankSubsp, blockedAddrs, @@ -264,7 +283,13 @@ func CreateTestInput(t *testing.T, isCheckTx bool, supportedFeatures string, enc bankKeeper.SetParams(ctx, banktypes.DefaultParams()) stakingSubsp, _ := paramsKeeper.GetSubspace(stakingtypes.ModuleName) - stakingKeeper := stakingkeeper.NewKeeper(encodingConfig.Marshaler, keyStaking, authKeeper, bankKeeper, stakingSubsp) + stakingKeeper := stakingkeeper.NewKeeper( + encodingConfig.Marshaler, + keys[stakingtypes.StoreKey], + authKeeper, + bankKeeper, + stakingSubsp, + ) stakingKeeper.SetParams(ctx, TestingStakeParams) // mintSubsp, _ := paramsKeeper.GetSubspace(minttypes.ModuleName) @@ -283,7 +308,7 @@ func CreateTestInput(t *testing.T, isCheckTx bool, supportedFeatures string, enc distSubsp, _ := paramsKeeper.GetSubspace(distrtypes.ModuleName) distKeeper := distrkeeper.NewKeeper( encodingConfig.Marshaler, - keyDistro, + keys[distrtypes.StoreKey], distSubsp, authKeeper, bankKeeper, @@ -336,14 +361,14 @@ func CreateTestInput(t *testing.T, isCheckTx bool, supportedFeatures string, enc // AddRoute(wasmtypes.RouterKey, NewWasmProposalHandler(keeper, wasmtypes.EnableAllProposals)) govKeeper := govkeeper.NewKeeper( - encodingConfig.Marshaler, keyGov, paramsKeeper.Subspace(govtypes.ModuleName).WithKeyTable(govtypes.ParamKeyTable()), authKeeper, bankKeeper, stakingKeeper, govRouter, + encodingConfig.Marshaler, keys[govtypes.StoreKey], paramsKeeper.Subspace(govtypes.ModuleName).WithKeyTable(govtypes.ParamKeyTable()), authKeeper, bankKeeper, stakingKeeper, govRouter, ) // bank := bankKeeper. // bk := bank.Keeper(bankKeeper) mintSubsp, _ := paramsKeeper.GetSubspace(minttypes.ModuleName) - mintKeeper := mintkeeper.NewKeeper(encodingConfig.Marshaler, mintStore, mintSubsp, stakingKeeper, authKeeper, bankKeeper, authtypes.FeeCollectorName) + mintKeeper := mintkeeper.NewKeeper(encodingConfig.Marshaler, keys[minttypes.StoreKey], mintSubsp, stakingKeeper, authKeeper, bankKeeper, authtypes.FeeCollectorName) mintKeeper.SetMinter(ctx, minttypes.DefaultInitialMinter()) // keeper := NewKeeper(cdc, keyContract, accountKeeper, &bk, &govKeeper, &distKeeper, &mintKeeper, &stakingKeeper, router, tempDir, wasmConfig, supportedFeatures, encoders, queriers) @@ -360,18 +385,17 @@ func CreateTestInput(t *testing.T, isCheckTx bool, supportedFeatures string, enc // Load default wasm config wasmConfig := wasmtypes.DefaultWasmConfig() - keys := sdk.NewKVStoreKeys( - authtypes.StoreKey, banktypes.StoreKey, stakingtypes.StoreKey, - minttypes.StoreKey, distrtypes.StoreKey, slashingtypes.StoreKey, - govtypes.StoreKey, paramstypes.StoreKey, ibchost.StoreKey, upgradetypes.StoreKey, - evidencetypes.StoreKey, ibctransfertypes.StoreKey, capabilitytypes.StoreKey, "compute", - feegrant.StoreKey, authzkeeper.StoreKey, icahosttypes.StoreKey, - ) - - memKeys := sdk.NewMemoryStoreKeys(capabilitytypes.MemStoreKey) - for _, v := range memKeys { - ms.MountStoreWithDB(v, sdk.StoreTypeMemory, db) - } + //keys := sdk.NewKVStoreKeys( + // authtypes.StoreKey, banktypes.StoreKey, stakingtypes.StoreKey, + // minttypes.StoreKey, distrtypes.StoreKey, slashingtypes.StoreKey, + // govtypes.StoreKey, paramstypes.StoreKey, ibchost.StoreKey, upgradetypes.StoreKey, + // evidencetypes.StoreKey, ibctransfertypes.StoreKey, capabilitytypes.StoreKey, "compute", + // feegrant.StoreKey, authzkeeper.StoreKey, icahosttypes.StoreKey, + //) + //memKeys := sdk.NewMemoryStoreKeys(capabilitytypes.MemStoreKey) + //for _, v := range memKeys { + // ms.MountStoreWithDB(v, sdk.StoreTypeMemory, db) + //} upgradeKeeper := upgradekeeper.NewKeeper( map[int64]bool{}, @@ -388,11 +412,16 @@ func CreateTestInput(t *testing.T, isCheckTx bool, supportedFeatures string, enc ) scopedIBCKeeper := capabilityKeeper.ScopeToModule(ibchost.ModuleName) - scopedWasmKeeper := capabilityKeeper.ScopeToModule("compute") + scopedWasmKeeper := capabilityKeeper.ScopeToModule(wasmtypes.ModuleName) ibchostSubSp, _ := paramsKeeper.GetSubspace(ibchost.ModuleName) ibcKeeper := ibckeeper.NewKeeper( - encodingConfig.Marshaler, keys[ibchost.StoreKey], ibchostSubSp, stakingKeeper, upgradeKeeper, scopedIBCKeeper, + encodingConfig.Marshaler, + keys[ibchost.StoreKey], + ibchostSubSp, + stakingKeeper, + upgradeKeeper, + scopedIBCKeeper, ) // todo: new grpc routing @@ -416,7 +445,7 @@ func CreateTestInput(t *testing.T, isCheckTx bool, supportedFeatures string, enc keeper := NewKeeper( encodingConfig.Marshaler, *encodingConfig.Amino, - keyContract, + keys[wasmtypes.StoreKey], authKeeper, bankKeeper, govKeeper, From b9312c197d31fcedf5f0fdd6dab6b845a7306aff Mon Sep 17 00:00:00 2001 From: Lior Bondarevski Date: Tue, 30 Aug 2022 18:39:21 +0300 Subject: [PATCH 93/93] Log with "code_id" when storing contract --- x/compute/internal/keeper/msg_server.go | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/x/compute/internal/keeper/msg_server.go b/x/compute/internal/keeper/msg_server.go index a74c07025..f5b73d4df 100644 --- a/x/compute/internal/keeper/msg_server.go +++ b/x/compute/internal/keeper/msg_server.go @@ -2,6 +2,7 @@ package keeper import ( "context" + "fmt" sdk "github.com/cosmos/cosmos-sdk/types" @@ -21,14 +22,18 @@ func NewMsgServerImpl(k Keeper) types.MsgServer { func (m msgServer) StoreCode(goCtx context.Context, msg *types.MsgStoreCode) (*types.MsgStoreCodeResponse, error) { ctx := sdk.UnwrapSDKContext(goCtx) - ctx.EventManager().EmitEvent(sdk.NewEvent( - sdk.EventTypeMessage, - sdk.NewAttribute(sdk.AttributeKeyModule, types.ModuleName), - sdk.NewAttribute(sdk.AttributeKeySender, msg.Sender.String()), - )) - codeID, err := m.keeper.Create(ctx, msg.Sender, msg.WASMByteCode, msg.Source, msg.Builder) + ctx.EventManager().EmitEvents(sdk.Events{ + sdk.NewEvent( + sdk.EventTypeMessage, + sdk.NewAttribute(sdk.AttributeKeyModule, types.ModuleName), + sdk.NewAttribute(types.AttributeKeySigner, msg.Sender.String()), + sdk.NewAttribute(sdk.AttributeKeySender, msg.Sender.String()), + sdk.NewAttribute(types.AttributeKeyCodeID, fmt.Sprintf("%d", codeID)), + ), + }) + return &types.MsgStoreCodeResponse{ CodeID: codeID, }, err