multinode/console: add summary to storage usage API

Change-Id: Ia8a1e598d667f25461f73f1626da22113cb7caeb
This commit is contained in:
Yaroslav Vorobiov 2021-07-01 15:07:40 +03:00
parent b0ef9b9b67
commit 818f6c6ea6
14 changed files with 372 additions and 279 deletions

View File

@ -38,7 +38,7 @@ func NewStorage(log *zap.Logger, service *storage.Service) *Storage {
}
// Usage handles retrieval of a node storage usage for a period interval.
func (storage *Storage) Usage(w http.ResponseWriter, r *http.Request) {
func (controller *Storage) Usage(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
var err error
defer mon.Task()(&ctx)(&err)
@ -48,12 +48,12 @@ func (storage *Storage) Usage(w http.ResponseWriter, r *http.Request) {
nodeIDEnc, ok := segments["nodeID"]
if !ok {
storage.serveError(w, http.StatusBadRequest, ErrStorage.New("could not receive node id segment"))
controller.serveError(w, http.StatusBadRequest, ErrStorage.New("could not receive node id segment"))
return
}
nodeID, err := storj.NodeIDFromString(nodeIDEnc)
if err != nil {
storage.serveError(w, http.StatusBadRequest, ErrStorage.Wrap(err))
controller.serveError(w, http.StatusBadRequest, ErrStorage.Wrap(err))
return
}
@ -63,7 +63,7 @@ func (storage *Storage) Usage(w http.ResponseWriter, r *http.Request) {
if periodParam := r.URL.Query().Get("period"); periodParam != "" {
period, err := compensation.PeriodFromString(periodParam)
if err != nil {
storage.serveError(w, http.StatusBadRequest, ErrStorage.Wrap(err))
controller.serveError(w, http.StatusBadRequest, ErrStorage.Wrap(err))
return
}
@ -71,26 +71,30 @@ func (storage *Storage) Usage(w http.ResponseWriter, r *http.Request) {
to = period.EndDateExclusive()
}
usage, err := storage.service.Usage(ctx, nodeID, from, to)
usage, err := controller.service.Usage(ctx, nodeID, from, to)
if err != nil {
if nodes.ErrNoNode.Has(err) {
storage.serveError(w, http.StatusNotFound, ErrStorage.Wrap(err))
controller.serveError(w, http.StatusNotFound, ErrStorage.Wrap(err))
return
}
storage.log.Error("usage internal error", zap.Error(ErrStorage.Wrap(err)))
storage.serveError(w, http.StatusInternalServerError, ErrStorage.Wrap(err))
controller.log.Error("usage internal error", zap.Error(ErrStorage.Wrap(err)))
controller.serveError(w, http.StatusInternalServerError, ErrStorage.Wrap(err))
return
}
// return empty slice instead of nil
if usage.Stamps == nil {
usage.Stamps = make([]storage.UsageStamp, 0)
}
if err = json.NewEncoder(w).Encode(usage); err != nil {
storage.log.Error("failed to write json response", zap.Error(ErrStorage.Wrap(err)))
controller.log.Error("failed to write json response", zap.Error(ErrStorage.Wrap(err)))
return
}
}
// UsageSatellite handles retrieval of a node storage usage for a satellite and period interval.
func (storage *Storage) UsageSatellite(w http.ResponseWriter, r *http.Request) {
func (controller *Storage) UsageSatellite(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
var err error
defer mon.Task()(&ctx)(&err)
@ -100,23 +104,23 @@ func (storage *Storage) UsageSatellite(w http.ResponseWriter, r *http.Request) {
nodeIDEnc, ok := segments["nodeID"]
if !ok {
storage.serveError(w, http.StatusBadRequest, ErrStorage.New("could not receive node id segment"))
controller.serveError(w, http.StatusBadRequest, ErrStorage.New("could not receive node id segment"))
return
}
satelliteIDEnc, ok := segments["satelliteID"]
if !ok {
storage.serveError(w, http.StatusBadRequest, ErrStorage.New("could not receive satellite id segment"))
controller.serveError(w, http.StatusBadRequest, ErrStorage.New("could not receive satellite id segment"))
return
}
nodeID, err := storj.NodeIDFromString(nodeIDEnc)
if err != nil {
storage.serveError(w, http.StatusBadRequest, ErrStorage.Wrap(err))
controller.serveError(w, http.StatusBadRequest, ErrStorage.Wrap(err))
return
}
satelliteID, err := storj.NodeIDFromString(satelliteIDEnc)
if err != nil {
storage.serveError(w, http.StatusBadRequest, ErrStorage.Wrap(err))
controller.serveError(w, http.StatusBadRequest, ErrStorage.Wrap(err))
return
}
@ -126,7 +130,7 @@ func (storage *Storage) UsageSatellite(w http.ResponseWriter, r *http.Request) {
if periodParam := r.URL.Query().Get("period"); periodParam != "" {
period, err := compensation.PeriodFromString(periodParam)
if err != nil {
storage.serveError(w, http.StatusBadRequest, ErrStorage.Wrap(err))
controller.serveError(w, http.StatusBadRequest, ErrStorage.Wrap(err))
return
}
@ -134,26 +138,30 @@ func (storage *Storage) UsageSatellite(w http.ResponseWriter, r *http.Request) {
to = period.EndDateExclusive()
}
usage, err := storage.service.UsageSatellite(ctx, nodeID, satelliteID, from, to)
usage, err := controller.service.UsageSatellite(ctx, nodeID, satelliteID, from, to)
if err != nil {
if nodes.ErrNoNode.Has(err) {
storage.serveError(w, http.StatusNotFound, ErrStorage.Wrap(err))
controller.serveError(w, http.StatusNotFound, ErrStorage.Wrap(err))
return
}
storage.log.Error("usage satellite internal error", zap.Error(ErrStorage.Wrap(err)))
storage.serveError(w, http.StatusInternalServerError, ErrStorage.Wrap(err))
controller.log.Error("usage satellite internal error", zap.Error(ErrStorage.Wrap(err)))
controller.serveError(w, http.StatusInternalServerError, ErrStorage.Wrap(err))
return
}
// return empty slice instead of nil
if usage.Stamps == nil {
usage.Stamps = make([]storage.UsageStamp, 0)
}
if err = json.NewEncoder(w).Encode(usage); err != nil {
storage.log.Error("failed to write json response", zap.Error(ErrStorage.Wrap(err)))
controller.log.Error("failed to write json response", zap.Error(ErrStorage.Wrap(err)))
return
}
}
// TotalUsage handles retrieval of aggregated storage usage for a period interval.
func (storage *Storage) TotalUsage(w http.ResponseWriter, r *http.Request) {
func (controller *Storage) TotalUsage(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
var err error
defer mon.Task()(&ctx)(&err)
@ -166,7 +174,7 @@ func (storage *Storage) TotalUsage(w http.ResponseWriter, r *http.Request) {
if periodParam := r.URL.Query().Get("period"); periodParam != "" {
period, err := compensation.PeriodFromString(periodParam)
if err != nil {
storage.serveError(w, http.StatusBadRequest, ErrStorage.Wrap(err))
controller.serveError(w, http.StatusBadRequest, ErrStorage.Wrap(err))
return
}
@ -174,26 +182,30 @@ func (storage *Storage) TotalUsage(w http.ResponseWriter, r *http.Request) {
to = period.EndDateExclusive()
}
usage, err := storage.service.TotalUsage(ctx, from, to)
usage, err := controller.service.TotalUsage(ctx, from, to)
if err != nil {
if nodes.ErrNoNode.Has(err) {
storage.serveError(w, http.StatusNotFound, ErrStorage.Wrap(err))
controller.serveError(w, http.StatusNotFound, ErrStorage.Wrap(err))
return
}
storage.log.Error("total usage internal error", zap.Error(ErrStorage.Wrap(err)))
storage.serveError(w, http.StatusInternalServerError, ErrStorage.Wrap(err))
controller.log.Error("total usage internal error", zap.Error(ErrStorage.Wrap(err)))
controller.serveError(w, http.StatusInternalServerError, ErrStorage.Wrap(err))
return
}
// return empty slice instead of nil
if usage.Stamps == nil {
usage.Stamps = make([]storage.UsageStamp, 0)
}
if err = json.NewEncoder(w).Encode(usage); err != nil {
storage.log.Error("failed to write json response", zap.Error(ErrStorage.Wrap(err)))
controller.log.Error("failed to write json response", zap.Error(ErrStorage.Wrap(err)))
return
}
}
// TotalUsageSatellite handles retrieval of aggregated storage usage for a satellite and period interval.
func (storage *Storage) TotalUsageSatellite(w http.ResponseWriter, r *http.Request) {
func (controller *Storage) TotalUsageSatellite(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
var err error
defer mon.Task()(&ctx)(&err)
@ -203,12 +215,12 @@ func (storage *Storage) TotalUsageSatellite(w http.ResponseWriter, r *http.Reque
satelliteIDEnc, ok := segments["satelliteID"]
if !ok {
storage.serveError(w, http.StatusBadRequest, ErrStorage.New("could not receive satellite id segment"))
controller.serveError(w, http.StatusBadRequest, ErrStorage.New("could not receive satellite id segment"))
return
}
satelliteID, err := storj.NodeIDFromString(satelliteIDEnc)
if err != nil {
storage.serveError(w, http.StatusBadRequest, ErrStorage.Wrap(err))
controller.serveError(w, http.StatusBadRequest, ErrStorage.Wrap(err))
return
}
@ -218,7 +230,7 @@ func (storage *Storage) TotalUsageSatellite(w http.ResponseWriter, r *http.Reque
if periodParam := r.URL.Query().Get("period"); periodParam != "" {
period, err := compensation.PeriodFromString(periodParam)
if err != nil {
storage.serveError(w, http.StatusBadRequest, ErrStorage.Wrap(err))
controller.serveError(w, http.StatusBadRequest, ErrStorage.Wrap(err))
return
}
@ -226,47 +238,51 @@ func (storage *Storage) TotalUsageSatellite(w http.ResponseWriter, r *http.Reque
to = period.EndDateExclusive()
}
usage, err := storage.service.TotalUsageSatellite(ctx, satelliteID, from, to)
usage, err := controller.service.TotalUsageSatellite(ctx, satelliteID, from, to)
if err != nil {
if nodes.ErrNoNode.Has(err) {
storage.serveError(w, http.StatusNotFound, ErrStorage.Wrap(err))
controller.serveError(w, http.StatusNotFound, ErrStorage.Wrap(err))
return
}
storage.log.Error("usage satellite internal error", zap.Error(ErrStorage.Wrap(err)))
storage.serveError(w, http.StatusInternalServerError, ErrStorage.Wrap(err))
controller.log.Error("usage satellite internal error", zap.Error(ErrStorage.Wrap(err)))
controller.serveError(w, http.StatusInternalServerError, ErrStorage.Wrap(err))
return
}
// return empty slice instead of nil
if usage.Stamps == nil {
usage.Stamps = make([]storage.UsageStamp, 0)
}
if err = json.NewEncoder(w).Encode(usage); err != nil {
storage.log.Error("failed to write json response", zap.Error(ErrStorage.Wrap(err)))
controller.log.Error("failed to write json response", zap.Error(ErrStorage.Wrap(err)))
return
}
}
// TotalDiskSpace returns all info about all storagenodes disk space usage.
func (storage *Storage) TotalDiskSpace(w http.ResponseWriter, r *http.Request) {
func (controller *Storage) TotalDiskSpace(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
var err error
defer mon.Task()(&ctx)(&err)
w.Header().Add("Content-Type", "application/json")
totalDiskSpace, err := storage.service.TotalDiskSpace(ctx)
totalDiskSpace, err := controller.service.TotalDiskSpace(ctx)
if err != nil {
storage.log.Error("could not get total disk space", zap.Error(err))
storage.serveError(w, http.StatusInternalServerError, ErrStorage.Wrap(err))
controller.log.Error("could not get total disk space", zap.Error(err))
controller.serveError(w, http.StatusInternalServerError, ErrStorage.Wrap(err))
return
}
if err = json.NewEncoder(w).Encode(totalDiskSpace); err != nil {
storage.log.Error("failed to write json response", zap.Error(err))
controller.log.Error("failed to write json response", zap.Error(err))
return
}
}
// DiskSpace returns all info about concrete storagenode disk space usage.
func (storage *Storage) DiskSpace(w http.ResponseWriter, r *http.Request) {
func (controller *Storage) DiskSpace(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
var err error
defer mon.Task()(&ctx)(&err)
@ -276,35 +292,35 @@ func (storage *Storage) DiskSpace(w http.ResponseWriter, r *http.Request) {
nodeIDparam, ok := segments["nodeID"]
if !ok {
storage.serveError(w, http.StatusBadRequest, ErrStorage.New("node id is missing"))
controller.serveError(w, http.StatusBadRequest, ErrStorage.New("node id is missing"))
return
}
nodeID, err := storj.NodeIDFromString(nodeIDparam)
if err != nil {
storage.serveError(w, http.StatusBadRequest, ErrStorage.Wrap(err))
controller.serveError(w, http.StatusBadRequest, ErrStorage.Wrap(err))
return
}
diskSpace, err := storage.service.DiskSpace(ctx, nodeID)
diskSpace, err := controller.service.DiskSpace(ctx, nodeID)
if err != nil {
if nodes.ErrNoNode.Has(err) {
storage.serveError(w, http.StatusNotFound, ErrStorage.Wrap(err))
controller.serveError(w, http.StatusNotFound, ErrStorage.Wrap(err))
return
}
storage.log.Error("could not get disk space", zap.Error(err))
storage.serveError(w, http.StatusInternalServerError, ErrStorage.Wrap(err))
controller.log.Error("could not get disk space", zap.Error(err))
controller.serveError(w, http.StatusInternalServerError, ErrStorage.Wrap(err))
return
}
if err = json.NewEncoder(w).Encode(diskSpace); err != nil {
storage.log.Error("failed to write json response", zap.Error(err))
controller.log.Error("failed to write json response", zap.Error(err))
return
}
}
// serveError set http statuses and send json error.
func (storage *Storage) serveError(w http.ResponseWriter, status int, err error) {
func (controller *Storage) serveError(w http.ResponseWriter, status int, err error) {
w.WriteHeader(status)
var response struct {
@ -314,6 +330,6 @@ func (storage *Storage) serveError(w http.ResponseWriter, status int, err error)
err = json.NewEncoder(w).Encode(response)
if err != nil {
storage.log.Error("failed to write json error response", zap.Error(err))
controller.log.Error("failed to write json error response", zap.Error(err))
}
}

View File

@ -42,87 +42,97 @@ func NewService(log *zap.Logger, dialer rpc.Dialer, nodes nodes.DB) *Service {
}
// Usage retrieves node's daily storage usage for provided interval.
func (service *Service) Usage(ctx context.Context, nodeID storj.NodeID, from, to time.Time) (_ []UsageStamp, err error) {
func (service *Service) Usage(ctx context.Context, nodeID storj.NodeID, from, to time.Time) (_ Usage, err error) {
defer mon.Task()(&ctx)(&err)
node, err := service.nodes.Get(ctx, nodeID)
if err != nil {
return nil, Error.Wrap(err)
return Usage{}, Error.Wrap(err)
}
stamps, err := service.dialUsage(ctx, node, from, to)
usage, err := service.dialUsage(ctx, node, from, to)
if err != nil {
return nil, Error.Wrap(err)
return Usage{}, Error.Wrap(err)
}
return stamps, nil
return usage, nil
}
// UsageSatellite retrieves node's daily storage usage for provided interval and satellite.
func (service *Service) UsageSatellite(ctx context.Context, nodeID, satelliteID storj.NodeID, from, to time.Time) (_ []UsageStamp, err error) {
func (service *Service) UsageSatellite(ctx context.Context, nodeID, satelliteID storj.NodeID, from, to time.Time) (_ Usage, err error) {
defer mon.Task()(&ctx)(&err)
node, err := service.nodes.Get(ctx, nodeID)
if err != nil {
return nil, Error.Wrap(err)
return Usage{}, Error.Wrap(err)
}
stamps, err := service.dialUsageSatellite(ctx, node, satelliteID, from, to)
usage, err := service.dialUsageSatellite(ctx, node, satelliteID, from, to)
if err != nil {
return nil, Error.Wrap(err)
return Usage{}, Error.Wrap(err)
}
return stamps, nil
return usage, nil
}
// TotalUsage retrieves aggregated daily storage usage for provided interval.
func (service *Service) TotalUsage(ctx context.Context, from, to time.Time) (_ []UsageStamp, err error) {
func (service *Service) TotalUsage(ctx context.Context, from, to time.Time) (_ Usage, err error) {
defer mon.Task()(&ctx)(&err)
nodesList, err := service.nodes.List(ctx)
if err != nil {
return nil, Error.Wrap(err)
return Usage{}, Error.Wrap(err)
}
var totalSummary float64
cache := make(UsageStampDailyCache)
for _, node := range nodesList {
stamps, err := service.dialUsage(ctx, node, from, to)
usage, err := service.dialUsage(ctx, node, from, to)
if err != nil {
return nil, Error.Wrap(err)
return Usage{}, Error.Wrap(err)
}
for _, stamp := range stamps {
totalSummary += usage.Summary
for _, stamp := range usage.Stamps {
cache.Add(stamp)
}
}
return cache.Sorted(), nil
return Usage{
Stamps: cache.Sorted(),
Summary: totalSummary,
}, nil
}
// TotalUsageSatellite retrieves aggregated daily storage usage for provided interval and satellite.
func (service *Service) TotalUsageSatellite(ctx context.Context, satelliteID storj.NodeID, from, to time.Time) (_ []UsageStamp, err error) {
func (service *Service) TotalUsageSatellite(ctx context.Context, satelliteID storj.NodeID, from, to time.Time) (_ Usage, err error) {
defer mon.Task()(&ctx)(&err)
nodesList, err := service.nodes.List(ctx)
if err != nil {
return nil, Error.Wrap(err)
return Usage{}, Error.Wrap(err)
}
var totalSummary float64
cache := make(UsageStampDailyCache)
for _, node := range nodesList {
stamps, err := service.dialUsageSatellite(ctx, node, satelliteID, from, to)
usage, err := service.dialUsageSatellite(ctx, node, satelliteID, from, to)
if err != nil {
return nil, Error.Wrap(err)
return Usage{}, Error.Wrap(err)
}
for _, stamp := range stamps {
totalSummary += usage.Summary
for _, stamp := range usage.Stamps {
cache.Add(stamp)
}
}
return cache.Sorted(), nil
return Usage{
Stamps: cache.Sorted(),
Summary: totalSummary,
}, nil
}
// TotalDiskSpace returns all info about all storagenodes disk space usage.
@ -193,7 +203,7 @@ func (service *Service) dialDiskSpace(ctx context.Context, node nodes.Node) (dis
}
// dialUsage dials node and retrieves it's storage usage for provided interval.
func (service *Service) dialUsage(ctx context.Context, node nodes.Node, from, to time.Time) (_ []UsageStamp, err error) {
func (service *Service) dialUsage(ctx context.Context, node nodes.Node, from, to time.Time) (_ Usage, err error) {
defer mon.Task()(&ctx)(&err)
conn, err := service.dialer.DialNodeURL(ctx, storj.NodeURL{
@ -201,7 +211,7 @@ func (service *Service) dialUsage(ctx context.Context, node nodes.Node, from, to
Address: node.PublicAddress,
})
if err != nil {
return nil, Error.Wrap(err)
return Usage{}, Error.Wrap(err)
}
defer func() {
err = errs.Combine(err, conn.Close())
@ -218,7 +228,7 @@ func (service *Service) dialUsage(ctx context.Context, node nodes.Node, from, to
}
resp, err := storageClient.Usage(ctx, req)
if err != nil {
return nil, Error.Wrap(err)
return Usage{}, Error.Wrap(err)
}
var stamps []UsageStamp
@ -229,11 +239,14 @@ func (service *Service) dialUsage(ctx context.Context, node nodes.Node, from, to
})
}
return stamps, nil
return Usage{
Stamps: stamps,
Summary: resp.GetSummary(),
}, nil
}
// dialUsageSatellite dials node and retrieves it's storage usage for provided interval and satellite.
func (service *Service) dialUsageSatellite(ctx context.Context, node nodes.Node, satelliteID storj.NodeID, from, to time.Time) (_ []UsageStamp, err error) {
func (service *Service) dialUsageSatellite(ctx context.Context, node nodes.Node, satelliteID storj.NodeID, from, to time.Time) (_ Usage, err error) {
defer mon.Task()(&ctx)(&err)
conn, err := service.dialer.DialNodeURL(ctx, storj.NodeURL{
@ -241,7 +254,7 @@ func (service *Service) dialUsageSatellite(ctx context.Context, node nodes.Node,
Address: node.PublicAddress,
})
if err != nil {
return nil, Error.Wrap(err)
return Usage{}, Error.Wrap(err)
}
defer func() {
err = errs.Combine(err, conn.Close())
@ -259,7 +272,7 @@ func (service *Service) dialUsageSatellite(ctx context.Context, node nodes.Node,
}
resp, err := storageClient.UsageSatellite(ctx, req)
if err != nil {
return nil, Error.Wrap(err)
return Usage{}, Error.Wrap(err)
}
var stamps []UsageStamp
@ -270,5 +283,8 @@ func (service *Service) dialUsageSatellite(ctx context.Context, node nodes.Node,
})
}
return stamps, nil
return Usage{
Stamps: stamps,
Summary: resp.GetSummary(),
}, nil
}

View File

@ -8,10 +8,16 @@ import (
"time"
)
// Usage holds storage usage stamps and summary for a particular period.
type Usage struct {
Stamps []UsageStamp `json:"stamps"`
Summary float64 `json:"summary"`
}
// UsageStamp holds data at rest total for an interval beginning at interval start.
type UsageStamp struct {
AtRestTotal float64
IntervalStart time.Time
AtRestTotal float64 `json:"atRestTotal"`
IntervalStart time.Time `json:"intervalStart"`
}
// UsageStampDailyCache caches storage usage stamps by interval date.

View File

@ -279,6 +279,7 @@ func (m *StorageUsageRequest) GetTo() time.Time {
type StorageUsageResponse struct {
StorageUsage []*StorageUsage `protobuf:"bytes,1,rep,name=storage_usage,json=storageUsage,proto3" json:"storage_usage,omitempty"`
Summary float64 `protobuf:"fixed64,2,opt,name=summary,proto3" json:"summary,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
@ -315,6 +316,13 @@ func (m *StorageUsageResponse) GetStorageUsage() []*StorageUsage {
return nil
}
func (m *StorageUsageResponse) GetSummary() float64 {
if m != nil {
return m.Summary
}
return 0
}
type StorageUsageSatelliteRequest struct {
Header *RequestHeader `protobuf:"bytes,1,opt,name=header,proto3" json:"header,omitempty"`
SatelliteId NodeID `protobuf:"bytes,2,opt,name=satellite_id,json=satelliteId,proto3,customtype=NodeID" json:"satellite_id"`
@ -372,6 +380,7 @@ func (m *StorageUsageSatelliteRequest) GetTo() time.Time {
type StorageUsageSatelliteResponse struct {
StorageUsage []*StorageUsage `protobuf:"bytes,1,rep,name=storage_usage,json=storageUsage,proto3" json:"storage_usage,omitempty"`
Summary float64 `protobuf:"fixed64,2,opt,name=summary,proto3" json:"summary,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
@ -408,6 +417,13 @@ func (m *StorageUsageSatelliteResponse) GetStorageUsage() []*StorageUsage {
return nil
}
func (m *StorageUsageSatelliteResponse) GetSummary() float64 {
if m != nil {
return m.Summary
}
return 0
}
type BandwidthMonthSummaryRequest struct {
Header *RequestHeader `protobuf:"bytes,1,opt,name=header,proto3" json:"header,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
@ -4165,182 +4181,183 @@ func init() {
func init() { proto.RegisterFile("multinode.proto", fileDescriptor_9a45fd79b06f3a1b) }
var fileDescriptor_9a45fd79b06f3a1b = []byte{
// 2829 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xcc, 0x5a, 0x4b, 0x73, 0x1b, 0xc7,
0xf1, 0xff, 0x83, 0x20, 0x01, 0xa2, 0x01, 0x10, 0xe4, 0x98, 0x0f, 0x70, 0xc5, 0x97, 0x96, 0xfa,
0x4b, 0x54, 0x2c, 0x53, 0x36, 0xed, 0x72, 0x62, 0xc7, 0xae, 0x18, 0x94, 0x64, 0x93, 0xb6, 0x64,
0x31, 0x4b, 0xc9, 0x71, 0x59, 0x89, 0xe1, 0x25, 0x76, 0x48, 0xae, 0xb5, 0xd8, 0x85, 0x77, 0x07,
0x64, 0x58, 0x95, 0x72, 0x72, 0x48, 0x9c, 0x53, 0xaa, 0x72, 0x76, 0xe5, 0x53, 0xe4, 0xe2, 0x63,
0x6e, 0x29, 0x57, 0xe5, 0x1b, 0xe4, 0xe0, 0x54, 0xe5, 0x96, 0x4b, 0x2e, 0xf9, 0x02, 0xa9, 0x79,
0xec, 0x62, 0x67, 0x5f, 0x20, 0x17, 0x74, 0x31, 0xb7, 0x9d, 0xe9, 0xee, 0xdf, 0xf4, 0xf4, 0xcc,
0xf4, 0x76, 0xf7, 0x0c, 0x34, 0xba, 0x7d, 0x8b, 0x98, 0xb6, 0x63, 0xe0, 0xcd, 0x9e, 0xeb, 0x10,
0x07, 0x55, 0x82, 0x0e, 0x05, 0x8e, 0x9c, 0x23, 0x87, 0x77, 0x2b, 0xab, 0x47, 0x8e, 0x73, 0x64,
0xe1, 0xbb, 0xac, 0x75, 0xd0, 0x3f, 0xbc, 0x4b, 0xcc, 0x2e, 0xf6, 0x88, 0xde, 0xed, 0x71, 0x06,
0x75, 0x03, 0xea, 0x1a, 0xfe, 0xa2, 0x8f, 0x3d, 0xb2, 0x83, 0x75, 0x03, 0xbb, 0x68, 0x01, 0xca,
0x7a, 0xcf, 0x6c, 0x3f, 0xc7, 0x67, 0xcd, 0xc2, 0x5a, 0x61, 0xa3, 0xa6, 0x95, 0xf4, 0x9e, 0xf9,
0x01, 0x3e, 0x53, 0xef, 0xc3, 0xf4, 0x7d, 0xd3, 0x7b, 0xbe, 0xdf, 0xd3, 0x3b, 0x58, 0x88, 0xa0,
0x97, 0xa1, 0x74, 0xcc, 0xc4, 0x18, 0x6f, 0x75, 0xab, 0xb9, 0x39, 0xd0, 0x4b, 0x82, 0xd5, 0x04,
0x9f, 0xfa, 0x97, 0x02, 0xcc, 0x84, 0x60, 0xbc, 0x9e, 0x63, 0x7b, 0x18, 0x2d, 0x41, 0x45, 0xb7,
0x2c, 0xa7, 0xa3, 0x13, 0x6c, 0x30, 0xa8, 0xa2, 0x36, 0xe8, 0x40, 0xab, 0x50, 0xed, 0x7b, 0xd8,
0x68, 0xf7, 0x4c, 0xdc, 0xc1, 0x5e, 0x73, 0x8c, 0xd1, 0x81, 0x76, 0xed, 0xb1, 0x1e, 0xb4, 0x0c,
0xac, 0xd5, 0x26, 0xae, 0xee, 0x1d, 0x37, 0x8b, 0x5c, 0x9e, 0xf6, 0x3c, 0xa1, 0x1d, 0x08, 0xc1,
0xf8, 0xa1, 0x8b, 0x71, 0x73, 0x9c, 0x11, 0xd8, 0x37, 0x1b, 0xf1, 0x44, 0x37, 0x2d, 0xfd, 0xc0,
0xc2, 0xcd, 0x09, 0x31, 0xa2, 0xdf, 0x81, 0x14, 0x98, 0x74, 0x4e, 0xb0, 0x4b, 0x21, 0x9a, 0x25,
0x46, 0x0c, 0xda, 0xea, 0xaf, 0xa1, 0xb6, 0x4f, 0x1c, 0x57, 0x3f, 0xc2, 0x4f, 0x3d, 0xfd, 0x08,
0x23, 0x15, 0xea, 0x3a, 0x69, 0xbb, 0xd8, 0x23, 0x6d, 0xe2, 0x10, 0xdd, 0x62, 0xfa, 0x17, 0xb4,
0xaa, 0x4e, 0x34, 0xec, 0x91, 0x27, 0xb4, 0x0b, 0x7d, 0x00, 0x53, 0xa6, 0x4d, 0xb0, 0x7b, 0xa2,
0x5b, 0x6d, 0x8f, 0xe8, 0x2e, 0x61, 0x93, 0xa8, 0x6e, 0x29, 0x9b, 0x7c, 0x7d, 0x36, 0xfd, 0xf5,
0xd9, 0x7c, 0xe2, 0xaf, 0xcf, 0xf6, 0xe4, 0xb7, 0xdf, 0xad, 0xfe, 0xdf, 0x1f, 0xff, 0xb1, 0x5a,
0xd0, 0xea, 0xbe, 0xec, 0x3e, 0x15, 0x55, 0xbf, 0x29, 0xc0, 0x0b, 0x61, 0x0d, 0x72, 0x2f, 0x06,
0xfa, 0x11, 0x35, 0x8c, 0xd3, 0xbd, 0x90, 0x32, 0x4c, 0x02, 0xbd, 0x06, 0x63, 0xc4, 0x61, 0x96,
0x3e, 0xaf, 0xdc, 0x18, 0x71, 0xd4, 0x27, 0x30, 0x2b, 0x2b, 0x2e, 0x96, 0xff, 0x2d, 0xa8, 0x7b,
0xbc, 0xbf, 0xdd, 0xa7, 0x84, 0x66, 0x61, 0xad, 0xb8, 0x51, 0xdd, 0x5a, 0x08, 0x4d, 0x40, 0x92,
0xab, 0x79, 0xa1, 0x96, 0xfa, 0x9f, 0x02, 0x2c, 0x85, 0xc9, 0xfb, 0x3a, 0xc1, 0x96, 0x65, 0x92,
0x11, 0x0c, 0xf3, 0x0a, 0xd4, 0x3c, 0x1f, 0xa5, 0x6d, 0x1a, 0xcc, 0x40, 0xb5, 0xed, 0x29, 0x3a,
0x99, 0xbf, 0x7f, 0xb7, 0x5a, 0xfa, 0xd0, 0x31, 0xf0, 0xee, 0x7d, 0xad, 0x1a, 0xf0, 0xec, 0x1a,
0x81, 0x2d, 0x8b, 0x39, 0x6d, 0x39, 0x7e, 0x41, 0x5b, 0xfe, 0x02, 0x96, 0x53, 0x26, 0x7d, 0x29,
0x46, 0xdd, 0x83, 0xa5, 0x6d, 0xdd, 0x36, 0x4e, 0x4d, 0x83, 0x1c, 0x3f, 0x72, 0x6c, 0x72, 0xbc,
0xdf, 0xef, 0x76, 0x75, 0xf7, 0x2c, 0xff, 0xc9, 0x7f, 0x15, 0x96, 0x53, 0x10, 0x85, 0xc2, 0x08,
0xc6, 0xd9, 0x81, 0xe3, 0xe7, 0x9f, 0x7d, 0xab, 0xbf, 0x2f, 0xc0, 0x5a, 0x20, 0x25, 0x04, 0xae,
0x64, 0x7d, 0xd5, 0xb7, 0xe1, 0x7a, 0x86, 0x22, 0x62, 0x0a, 0x4d, 0x28, 0x7b, 0x9c, 0x26, 0x66,
0xe1, 0x37, 0xd5, 0x0f, 0x60, 0x21, 0x2a, 0x9e, 0xdf, 0x94, 0xaf, 0x41, 0x33, 0x0e, 0x36, 0x54,
0x85, 0xdf, 0x16, 0x60, 0xf9, 0xc1, 0x91, 0x8b, 0x3d, 0xef, 0x4a, 0x0d, 0xf9, 0x26, 0xac, 0xa4,
0x69, 0x31, 0x74, 0x0a, 0x3b, 0x30, 0x2b, 0xc9, 0xe6, 0x37, 0xe1, 0x2b, 0x30, 0x17, 0x41, 0x1a,
0x3a, 0xf8, 0xef, 0x0a, 0xb0, 0xb2, 0x6b, 0x5f, 0xbd, 0x01, 0x7f, 0x0c, 0xab, 0xa9, 0x6a, 0x0c,
0x9d, 0xc4, 0x2e, 0xcc, 0xc9, 0xc2, 0xf9, 0x4d, 0xb8, 0x05, 0xf3, 0x51, 0xa8, 0xa1, 0xc3, 0xff,
0x0a, 0xe6, 0xee, 0xeb, 0xa6, 0x75, 0x45, 0x96, 0xdb, 0x87, 0xf9, 0xe8, 0xe8, 0x42, 0xe3, 0x37,
0xa0, 0xc6, 0x9c, 0x64, 0xdb, 0x75, 0x2c, 0xab, 0xdf, 0x13, 0xbe, 0x72, 0x3e, 0xa4, 0x04, 0x77,
0x92, 0x8c, 0xaa, 0x55, 0xfb, 0x83, 0x86, 0xfa, 0x0e, 0xd4, 0x18, 0x68, 0x7e, 0x43, 0xbe, 0x0f,
0x75, 0x81, 0x30, 0xba, 0x36, 0x7f, 0x2b, 0x40, 0x35, 0x44, 0x44, 0xb7, 0xa1, 0x84, 0xd9, 0x1a,
0x09, 0x6d, 0x66, 0x42, 0x20, 0xfc, 0x00, 0x68, 0x82, 0x01, 0xdd, 0x81, 0xb2, 0xc9, 0xd7, 0x53,
0x04, 0x04, 0x28, 0xc4, 0x2b, 0x56, 0x5a, 0xf3, 0x59, 0xd0, 0x3c, 0x94, 0x0c, 0x6c, 0x61, 0x82,
0x45, 0xbc, 0x25, 0x5a, 0x09, 0xa1, 0xce, 0x78, 0xfe, 0x50, 0xe7, 0x21, 0x94, 0x1e, 0x04, 0xc3,
0xb9, 0xb8, 0xa7, 0x9b, 0xae, 0xd8, 0x51, 0xa2, 0x85, 0x66, 0x61, 0x42, 0xef, 0x1b, 0x26, 0x11,
0x51, 0x21, 0x6f, 0xd0, 0x5e, 0xfe, 0xcf, 0xe3, 0xba, 0xf1, 0x86, 0xfa, 0x43, 0x28, 0xef, 0xda,
0x32, 0x9c, 0x21, 0xc1, 0x19, 0x03, 0xc1, 0xb1, 0xb0, 0xe0, 0x36, 0x4c, 0x7d, 0x84, 0x5d, 0xcf,
0x74, 0xec, 0xfc, 0x8b, 0xfc, 0x22, 0x34, 0x02, 0x8c, 0xc1, 0x31, 0x39, 0xe1, 0x5d, 0x0c, 0xa5,
0xa2, 0xf9, 0x4d, 0xf5, 0x5d, 0x40, 0x0f, 0x75, 0x8f, 0xdc, 0x73, 0x6c, 0xa2, 0x77, 0x48, 0xfe,
0x41, 0x3f, 0x85, 0x17, 0x24, 0x1c, 0x31, 0xf0, 0x7b, 0x50, 0xb3, 0x74, 0x8f, 0xb4, 0x3b, 0xbc,
0x5f, 0xc0, 0x9d, 0x6f, 0x85, 0xaa, 0xd6, 0x00, 0x50, 0xfd, 0x25, 0xcc, 0x68, 0xb8, 0xd7, 0x27,
0x3a, 0x19, 0xc5, 0x36, 0x79, 0x8e, 0xf2, 0xd7, 0x05, 0xa8, 0xb6, 0xe8, 0x5a, 0xff, 0xcc, 0xb4,
0x0d, 0xe7, 0x94, 0x4e, 0xe9, 0x94, 0x7d, 0x89, 0x4d, 0x77, 0xa1, 0x29, 0x71, 0x49, 0xb6, 0xe5,
0xd0, 0x75, 0xa8, 0x39, 0xb6, 0x65, 0xda, 0xb8, 0xdd, 0x71, 0xfa, 0x36, 0xdf, 0x57, 0x13, 0x5a,
0x95, 0xf7, 0xdd, 0xa3, 0x5d, 0x34, 0x1f, 0x61, 0x91, 0xbe, 0xe0, 0x28, 0x32, 0x0e, 0x60, 0x5d,
0x8c, 0x41, 0xfd, 0xa6, 0x0c, 0x28, 0x6c, 0x97, 0x20, 0x22, 0x2b, 0x71, 0x18, 0xa1, 0xdd, 0x0d,
0xc9, 0x30, 0x51, 0xf6, 0xcd, 0xc7, 0x8c, 0x57, 0x13, 0x32, 0xe8, 0x8d, 0xf0, 0x4e, 0xaf, 0x6e,
0xad, 0x67, 0x0b, 0x33, 0xdb, 0xf8, 0xc7, 0xe1, 0x11, 0x34, 0x0c, 0xd3, 0xfb, 0xa2, 0xaf, 0x5b,
0xe6, 0xa1, 0x89, 0x8d, 0xb6, 0x4e, 0xce, 0x19, 0xa6, 0x16, 0x98, 0x7d, 0xa6, 0xc2, 0xc2, 0x2d,
0x42, 0x6d, 0xed, 0xf5, 0xbd, 0x1e, 0xb6, 0x0d, 0x8e, 0x35, 0x7e, 0x01, 0xac, 0x6a, 0x20, 0xd9,
0x22, 0xe8, 0x23, 0x98, 0x75, 0x0e, 0x0f, 0x99, 0xb1, 0x25, 0xc0, 0x89, 0x0b, 0x00, 0x22, 0x81,
0xb0, 0x1f, 0xc2, 0x7d, 0x06, 0x0b, 0x3e, 0x6e, 0xdf, 0x36, 0xb0, 0xdb, 0x76, 0xf1, 0x89, 0x89,
0x4f, 0x29, 0x74, 0xe9, 0x02, 0xd0, 0xbe, 0x72, 0x4f, 0x29, 0x86, 0xc6, 0x20, 0x5a, 0x04, 0xdd,
0x03, 0xe8, 0xf7, 0x0c, 0x9a, 0x98, 0x52, 0xbc, 0xf2, 0x05, 0xf6, 0x59, 0x45, 0xc8, 0xb5, 0x08,
0x6a, 0x41, 0xe5, 0x73, 0xc7, 0xb4, 0x39, 0xc6, 0xe4, 0x05, 0x30, 0x26, 0xb9, 0x58, 0x8b, 0x28,
0x2b, 0x50, 0xe2, 0x3b, 0x84, 0x3a, 0x2d, 0xaf, 0xe3, 0xb8, 0x58, 0x64, 0x9e, 0xbc, 0xa1, 0xfc,
0x79, 0x0c, 0x26, 0x5a, 0xbe, 0x37, 0x8c, 0xd3, 0xd1, 0x6d, 0x98, 0xe6, 0x46, 0xa7, 0x1e, 0xa7,
0xcd, 0x19, 0xc6, 0x18, 0x43, 0x63, 0xd0, 0xbf, 0xcf, 0x58, 0x13, 0x36, 0x7c, 0x31, 0xbc, 0xe1,
0xd1, 0x3a, 0xd4, 0xbd, 0x7e, 0xa7, 0x83, 0x3d, 0x4f, 0xb0, 0xf0, 0x54, 0xbb, 0x26, 0x3a, 0x39,
0x13, 0x75, 0xd5, 0x56, 0xef, 0x58, 0x67, 0xcb, 0x5b, 0xd0, 0x78, 0x83, 0x46, 0xfd, 0x07, 0x98,
0xe8, 0x6c, 0x61, 0x0a, 0x1a, 0xfb, 0xa6, 0x70, 0x7d, 0xfb, 0xb9, 0xed, 0x9c, 0xda, 0x6d, 0x2e,
0x51, 0x66, 0xc4, 0x9a, 0xe8, 0x6c, 0x31, 0xc1, 0xeb, 0xe0, 0xb7, 0xdb, 0x0c, 0x60, 0x92, 0xa7,
0xdd, 0xa2, 0x6f, 0x9b, 0xe2, 0xbc, 0x0c, 0xe5, 0x63, 0x93, 0xa6, 0x35, 0x67, 0xcd, 0x4a, 0xec,
0x17, 0x1a, 0xf2, 0x1e, 0x9a, 0xcf, 0xa6, 0x3e, 0x84, 0xe6, 0x13, 0xb7, 0xef, 0x11, 0x6c, 0x04,
0x31, 0x82, 0x97, 0xdf, 0xfd, 0xfe, 0xb5, 0x00, 0x8b, 0x09, 0x70, 0xc2, 0x1d, 0x3c, 0x03, 0x44,
0x38, 0xb1, 0x1d, 0x78, 0x36, 0x4f, 0xfc, 0xeb, 0xef, 0x84, 0xb0, 0x53, 0x11, 0x36, 0xa9, 0x63,
0x7c, 0xaa, 0x3d, 0xd4, 0x66, 0x48, 0x94, 0x45, 0x79, 0x08, 0x65, 0x41, 0x45, 0xb7, 0xa0, 0x4c,
0x71, 0xda, 0xe2, 0x67, 0x17, 0x77, 0xac, 0x25, 0x4a, 0xde, 0x35, 0xe8, 0xff, 0x48, 0x37, 0x8c,
0x20, 0x00, 0xa8, 0x68, 0x7e, 0x53, 0xbd, 0x07, 0x8d, 0xc7, 0x3d, 0xec, 0xea, 0xc4, 0x71, 0xf3,
0x5b, 0xc3, 0x84, 0xe9, 0x01, 0x88, 0xb0, 0xc1, 0x2c, 0x4c, 0xe0, 0xae, 0x6e, 0x5a, 0xe2, 0x07,
0xc8, 0x1b, 0xf4, 0xef, 0x7c, 0xaa, 0x5b, 0x16, 0x26, 0x42, 0x0f, 0xd1, 0x42, 0xb7, 0xa0, 0xc1,
0xbf, 0xda, 0x87, 0x58, 0x27, 0x7d, 0x17, 0x7b, 0xcd, 0xe2, 0x5a, 0x71, 0xa3, 0xa2, 0x4d, 0xf1,
0xee, 0x77, 0x45, 0xaf, 0xfa, 0x55, 0x01, 0x56, 0x1f, 0x78, 0xc4, 0xec, 0xd2, 0xe3, 0xb6, 0xa7,
0x9f, 0x39, 0x7d, 0x72, 0x35, 0x11, 0xe7, 0x4f, 0x61, 0x2d, 0x5d, 0x0f, 0x61, 0x83, 0x97, 0x00,
0x61, 0x9f, 0xa7, 0x8d, 0x75, 0xd7, 0x36, 0xed, 0x23, 0x4f, 0xc4, 0x25, 0x33, 0x01, 0xe5, 0x81,
0x20, 0xa8, 0xef, 0xc3, 0x7c, 0x04, 0x32, 0xff, 0x92, 0xec, 0xc0, 0x42, 0x0c, 0x2b, 0x9f, 0x56,
0xdb, 0x30, 0x35, 0x72, 0x42, 0xb1, 0x0b, 0x8d, 0x68, 0x26, 0xf1, 0x3a, 0x54, 0x7b, 0x4c, 0xaf,
0xb6, 0x69, 0x1f, 0x3a, 0x02, 0x69, 0x2e, 0x84, 0xc4, 0xb5, 0xde, 0xb5, 0x0f, 0x1d, 0x0d, 0x7a,
0xc1, 0xb7, 0xfa, 0x19, 0xcc, 0x0a, 0xa8, 0x3d, 0xec, 0x9a, 0x8e, 0x91, 0x7f, 0xd1, 0xe7, 0xa1,
0xd4, 0x63, 0x10, 0xfe, 0x5e, 0xe4, 0x2d, 0xf5, 0x31, 0xcc, 0x45, 0x46, 0x18, 0x51, 0xe5, 0x2f,
0x61, 0xe1, 0x4a, 0xd3, 0x4a, 0x0d, 0x9a, 0xa9, 0xf9, 0x64, 0xde, 0x39, 0xfd, 0xa9, 0x00, 0xcb,
0x51, 0xd0, 0x51, 0x17, 0x24, 0x47, 0x6d, 0x6e, 0xb0, 0x86, 0x45, 0x69, 0x0d, 0x3f, 0x86, 0x95,
0x34, 0xed, 0x46, 0x9c, 0x78, 0x0b, 0xea, 0xf4, 0x68, 0xe0, 0xfc, 0xf3, 0x54, 0x6f, 0xc2, 0x94,
0x0f, 0x31, 0x70, 0x96, 0x83, 0x0a, 0x73, 0x51, 0xe3, 0x0d, 0xe6, 0x0f, 0x18, 0xdf, 0xe8, 0xdb,
0x46, 0xfd, 0x0c, 0x16, 0x62, 0x58, 0x62, 0xf0, 0x07, 0x30, 0x8d, 0x19, 0x69, 0xf0, 0xb3, 0x12,
0xff, 0x2a, 0x25, 0x9c, 0x52, 0x46, 0xa4, 0x1b, 0x58, 0xee, 0x50, 0x3f, 0x81, 0x46, 0x84, 0x27,
0x79, 0x5a, 0x79, 0x76, 0xf0, 0x0e, 0xcc, 0x3e, 0xb5, 0x0d, 0xd3, 0x23, 0xae, 0x79, 0xd0, 0x27,
0xa3, 0xd8, 0xfe, 0x25, 0x98, 0x8b, 0x20, 0x65, 0x2e, 0xc1, 0x97, 0xb0, 0xb0, 0xa7, 0x9f, 0x79,
0xa4, 0x7f, 0x70, 0x35, 0x47, 0x77, 0x07, 0x9a, 0xf1, 0xf1, 0x85, 0xc6, 0x77, 0xa0, 0xdc, 0xe3,
0x34, 0xa1, 0x01, 0x92, 0x77, 0x2f, 0xa5, 0x68, 0x3e, 0x0b, 0x75, 0xe3, 0x7e, 0x5f, 0x6e, 0xe3,
0xfd, 0x04, 0x1a, 0x01, 0x46, 0x2e, 0x25, 0x3e, 0x83, 0x59, 0xd1, 0xf7, 0x7d, 0x39, 0xef, 0x07,
0x30, 0x17, 0x19, 0x21, 0x97, 0xa2, 0xd4, 0xbd, 0x45, 0x0d, 0xff, 0x3f, 0xe4, 0xde, 0x3e, 0x84,
0x95, 0x34, 0xed, 0x72, 0x4d, 0xf7, 0x35, 0x80, 0x81, 0xbb, 0xa3, 0x81, 0xfb, 0x31, 0xb6, 0x82,
0x72, 0x3d, 0xfd, 0xa6, 0x7d, 0xac, 0xa8, 0xc2, 0xab, 0x27, 0xec, 0x5b, 0xfd, 0x43, 0x11, 0xca,
0x02, 0x0a, 0xa9, 0x50, 0xe7, 0x85, 0x2d, 0x71, 0x63, 0xe6, 0xdf, 0x95, 0xb1, 0xce, 0x16, 0xbb,
0x30, 0x43, 0xd7, 0xa0, 0xc2, 0x79, 0x8e, 0xb0, 0x5f, 0xd5, 0x99, 0x64, 0x1d, 0xef, 0x61, 0x82,
0x36, 0x60, 0x3a, 0x20, 0xb6, 0x45, 0x41, 0x88, 0xa7, 0x23, 0x53, 0x3e, 0x8f, 0xc6, 0x0b, 0x43,
0x37, 0xa1, 0x31, 0xe0, 0xe4, 0x89, 0x33, 0x4f, 0x4a, 0xea, 0x3e, 0x23, 0x4f, 0x8e, 0xd6, 0xa0,
0xd6, 0x71, 0xba, 0xbd, 0x40, 0x23, 0x7e, 0x17, 0x08, 0xb4, 0x4f, 0x28, 0xb4, 0x08, 0x93, 0x8c,
0x83, 0xea, 0xc3, 0x2f, 0x03, 0xcb, 0xb4, 0x4d, 0xd5, 0xb9, 0x09, 0x0d, 0x9f, 0xe4, 0x6b, 0x53,
0xe6, 0x83, 0x08, 0x0e, 0xa1, 0xcc, 0x0d, 0x98, 0x0a, 0xf8, 0xb8, 0x2e, 0x93, 0x3c, 0x41, 0x12,
0x6c, 0x5c, 0x15, 0xdf, 0xa2, 0x95, 0x04, 0x8b, 0xc2, 0xc0, 0xa2, 0x68, 0x0d, 0xaa, 0x21, 0xdf,
0xd4, 0xac, 0x32, 0x52, 0xb8, 0x0b, 0x29, 0x30, 0x69, 0x98, 0x5e, 0xcf, 0xf1, 0xb0, 0xd1, 0xac,
0x71, 0x13, 0xfa, 0x6d, 0x9a, 0xe2, 0xec, 0x60, 0xcb, 0x68, 0x75, 0x69, 0x52, 0xb6, 0xc3, 0xf3,
0x9e, 0xfc, 0x87, 0xfd, 0xdb, 0x31, 0x58, 0x4c, 0x80, 0x13, 0xfb, 0x6b, 0x6f, 0x90, 0x80, 0xf1,
0x7f, 0xc5, 0xeb, 0x21, 0xc0, 0x54, 0xb1, 0x04, 0x8a, 0x0f, 0xa3, 0xbc, 0x05, 0x30, 0xa0, 0x86,
0x76, 0x7e, 0x21, 0xbc, 0xf3, 0x69, 0xbf, 0xde, 0x0d, 0xca, 0x37, 0x45, 0x4d, 0xb4, 0x94, 0xaf,
0x0b, 0x30, 0x13, 0x03, 0x8f, 0x1d, 0xb9, 0xc2, 0xf0, 0x23, 0xa7, 0x41, 0x8d, 0x2e, 0x4f, 0x9b,
0xe3, 0xd2, 0x7c, 0x89, 0xce, 0xee, 0xee, 0x05, 0x67, 0xa7, 0x55, 0x8f, 0x83, 0x6f, 0x4f, 0x7d,
0x0c, 0xd7, 0x22, 0xc1, 0x38, 0xbb, 0x3c, 0xce, 0xbf, 0x36, 0x8f, 0x60, 0x29, 0x19, 0x30, 0x5f,
0x88, 0xff, 0x18, 0xae, 0xb5, 0x2c, 0x6b, 0x90, 0x63, 0x8e, 0x1c, 0xef, 0x7f, 0x04, 0x4b, 0xc9,
0x80, 0x23, 0x06, 0x5f, 0x5d, 0xb8, 0x2e, 0xe1, 0x72, 0xa7, 0x37, 0xaa, 0xba, 0xa9, 0x3f, 0x93,
0x9f, 0x83, 0x9a, 0x35, 0xdc, 0x25, 0xa4, 0x05, 0x3e, 0xf4, 0xc8, 0x53, 0xc8, 0x99, 0x16, 0xc4,
0xc6, 0xbf, 0x8c, 0xb4, 0x40, 0xfe, 0x25, 0x5d, 0xc1, 0xd4, 0x32, 0xd3, 0x82, 0x14, 0xed, 0x46,
0x9c, 0xf8, 0x23, 0x58, 0xe4, 0xd1, 0xef, 0x1e, 0x76, 0x2f, 0x21, 0x5c, 0xef, 0x80, 0x92, 0x04,
0x77, 0xb9, 0x11, 0x7b, 0x78, 0x03, 0x8e, 0x1a, 0x1b, 0xe6, 0x0c, 0x6e, 0xe3, 0xe3, 0xe7, 0x8e,
0x2b, 0xd9, 0x72, 0x8e, 0x3c, 0x8d, 0xac, 0xb8, 0x52, 0x1e, 0x21, 0x77, 0x5c, 0x19, 0xd9, 0x81,
0x57, 0x60, 0xf9, 0xac, 0xb8, 0x32, 0x4d, 0xbb, 0x3c, 0xd3, 0xdd, 0xfa, 0xcd, 0x18, 0x94, 0xc5,
0x53, 0x14, 0xf4, 0x2e, 0x54, 0x82, 0xe7, 0x61, 0xe8, 0x5a, 0x48, 0x2a, 0xfa, 0xf6, 0x4c, 0x59,
0x4a, 0x26, 0x0a, 0x0d, 0x76, 0x60, 0x82, 0x3f, 0xcf, 0x5a, 0x49, 0x7b, 0xef, 0x22, 0x60, 0x56,
0x53, 0xe9, 0x02, 0xa9, 0x03, 0x53, 0xf2, 0x0b, 0x1b, 0x74, 0x2b, 0x45, 0x24, 0x7a, 0xa2, 0x95,
0x8d, 0xe1, 0x8c, 0x7c, 0x90, 0xad, 0x7f, 0x96, 0xa0, 0x12, 0x3c, 0xe9, 0x40, 0x3a, 0xd4, 0xc2,
0x2f, 0x64, 0xa4, 0x01, 0xb3, 0x5e, 0xe5, 0x48, 0x03, 0x66, 0x3f, 0xb6, 0x39, 0x81, 0xc5, 0xd4,
0xe7, 0x2c, 0xe8, 0xc5, 0x24, 0x98, 0x94, 0xe2, 0x94, 0x72, 0xe7, 0x7c, 0xcc, 0x41, 0xd1, 0x7b,
0x3a, 0xca, 0x84, 0xd4, 0x0c, 0x04, 0x7f, 0x94, 0xf5, 0x4c, 0x1e, 0x01, 0xde, 0x85, 0xf9, 0xe4,
0xa7, 0x25, 0x68, 0x23, 0x76, 0xed, 0x9d, 0x36, 0x9d, 0xdb, 0xe7, 0xe0, 0x14, 0xc3, 0x69, 0x50,
0x97, 0x38, 0xd0, 0x6a, 0x9a, 0xac, 0x0f, 0xbe, 0x96, 0xce, 0x20, 0x30, 0x7b, 0xb0, 0x90, 0xf2,
0xb8, 0x03, 0xdd, 0x8e, 0x5f, 0xc7, 0xa7, 0x4d, 0xe2, 0x07, 0xe7, 0x61, 0x15, 0x23, 0x3e, 0x85,
0x29, 0x99, 0x05, 0xad, 0xa5, 0x4a, 0xfb, 0xf8, 0xd7, 0x33, 0x38, 0x06, 0xb0, 0xf2, 0x5b, 0x0b,
0x09, 0x36, 0xf1, 0x11, 0x88, 0x04, 0x9b, 0xf2, 0x50, 0xe3, 0x4d, 0x98, 0x60, 0x14, 0xb4, 0x10,
0xe5, 0xf5, 0x41, 0x9a, 0x71, 0x82, 0x38, 0x64, 0x5f, 0x15, 0x61, 0x9c, 0xfa, 0x39, 0xf4, 0x0e,
0x94, 0xc5, 0x5d, 0x3c, 0x5a, 0x0c, 0x71, 0xcb, 0x77, 0xfc, 0x8a, 0x92, 0x44, 0x12, 0x6a, 0x3c,
0x84, 0x6a, 0xe8, 0x62, 0x1d, 0x2d, 0x87, 0x58, 0xe3, 0x17, 0xf7, 0xca, 0x4a, 0x1a, 0x59, 0xa0,
0xed, 0x02, 0x0c, 0xae, 0x70, 0xd1, 0x52, 0xca, 0xcd, 0x2e, 0xc7, 0x5a, 0xce, 0xbc, 0xf7, 0x45,
0x9f, 0xc2, 0x4c, 0xec, 0xbe, 0x08, 0xad, 0x67, 0xdf, 0x26, 0x71, 0xe0, 0x1b, 0xe7, 0xb9, 0x72,
0x42, 0xf7, 0x60, 0xd2, 0xbf, 0xc4, 0x41, 0x61, 0x03, 0x45, 0xae, 0x87, 0x94, 0x6b, 0x89, 0x34,
0xb1, 0x10, 0xff, 0xaa, 0xb0, 0x92, 0x80, 0xd3, 0x27, 0x1e, 0x5d, 0x0b, 0x7f, 0xdf, 0x85, 0xd7,
0x22, 0xb2, 0xe1, 0x94, 0x24, 0xd2, 0xe0, 0x18, 0x4a, 0x95, 0x78, 0xe9, 0x18, 0x26, 0xdd, 0x02,
0x48, 0xc7, 0x30, 0xb9, 0x88, 0xff, 0x0c, 0xa6, 0x63, 0xe7, 0x4f, 0x8d, 0x4b, 0xc5, 0x76, 0xf0,
0x7a, 0x26, 0xcf, 0xc0, 0x4d, 0x25, 0x97, 0x9d, 0x25, 0x37, 0x95, 0x59, 0x37, 0x97, 0xdc, 0xd4,
0x90, 0x1a, 0xf6, 0xdb, 0x50, 0xe2, 0x41, 0x1e, 0x6a, 0xc6, 0xe2, 0x3e, 0x1f, 0x6e, 0x31, 0x81,
0x22, 0xc4, 0x3f, 0x8e, 0x57, 0x6c, 0xaf, 0x67, 0xc4, 0x8f, 0x02, 0x50, 0xcd, 0x62, 0x11, 0xc8,
0x1e, 0x34, 0xd3, 0x2e, 0xc7, 0x50, 0xd8, 0x83, 0x0d, 0xb9, 0xc9, 0x53, 0x5e, 0x3c, 0x17, 0x6f,
0x68, 0x3a, 0x32, 0x8f, 0x3c, 0x9d, 0xc4, 0xab, 0x35, 0x79, 0x3a, 0x29, 0x37, 0x66, 0x1a, 0xd4,
0xa5, 0xa2, 0xb1, 0xb4, 0x0f, 0x93, 0x0a, 0xd3, 0xd2, 0x3e, 0x4c, 0xae, 0x37, 0x3f, 0x83, 0xe9,
0x68, 0x09, 0x4f, 0xda, 0x87, 0x29, 0x65, 0x67, 0x69, 0x1f, 0xa6, 0x96, 0x86, 0xdf, 0x19, 0x14,
0xe6, 0x16, 0x13, 0xe2, 0xb3, 0x84, 0xa3, 0x17, 0x8d, 0xf3, 0x34, 0xa8, 0x4b, 0x75, 0x54, 0x69,
0xca, 0x49, 0x35, 0x5c, 0x69, 0xca, 0xc9, 0x25, 0xd8, 0x2e, 0xcc, 0x27, 0x57, 0x2d, 0xa5, 0xd3,
0x91, 0x59, 0x76, 0x95, 0x4e, 0xc7, 0x90, 0x12, 0xe8, 0xa7, 0x49, 0x15, 0xa1, 0xf5, 0xec, 0x42,
0x4e, 0xdc, 0x61, 0xa6, 0x56, 0x7b, 0xb6, 0xfe, 0x5d, 0x81, 0x92, 0xd8, 0x67, 0x47, 0x30, 0x9b,
0x54, 0xef, 0x40, 0x37, 0xc3, 0xaf, 0x12, 0xd2, 0x2b, 0x2c, 0xca, 0xad, 0xa1, 0x7c, 0x62, 0x4e,
0x67, 0xa0, 0xa4, 0x57, 0x24, 0xd0, 0x9d, 0x34, 0x98, 0xa4, 0x4c, 0x5c, 0x79, 0xe9, 0x9c, 0xdc,
0x21, 0xc7, 0x19, 0x29, 0x17, 0xc8, 0x8e, 0x33, 0xb9, 0x96, 0x21, 0x3b, 0xce, 0xb4, 0x7a, 0x03,
0x75, 0x9c, 0x89, 0x89, 0xb9, 0xec, 0x38, 0xb3, 0x2a, 0x0b, 0xb2, 0xe3, 0xcc, 0xce, 0xf2, 0x47,
0x74, 0x9c, 0x3a, 0xa0, 0x78, 0x76, 0x8e, 0x6e, 0xc4, 0x04, 0x12, 0x6a, 0x01, 0xca, 0xff, 0x0f,
0xe1, 0xba, 0x4a, 0x0f, 0x7a, 0x04, 0xb3, 0x49, 0x65, 0x45, 0x69, 0x1b, 0x67, 0x14, 0x32, 0xa5,
0x6d, 0x9c, 0x59, 0x9f, 0xfc, 0x9e, 0x1c, 0x6a, 0xb4, 0x9a, 0x90, 0xbc, 0x3f, 0x23, 0x5e, 0x70,
0x3d, 0x93, 0xe7, 0x52, 0x1d, 0x6a, 0x38, 0xa3, 0x96, 0x1d, 0x6a, 0x42, 0x25, 0x40, 0x76, 0xa8,
0x89, 0xc9, 0x78, 0xfc, 0xd4, 0xf8, 0xe0, 0x19, 0xa7, 0x26, 0x32, 0xca, 0xed, 0x73, 0x70, 0xf2,
0xe1, 0xb6, 0x6f, 0x7c, 0xa2, 0x52, 0x0f, 0xf8, 0xf9, 0xa6, 0xe9, 0xdc, 0x65, 0x1f, 0x77, 0x7b,
0xae, 0x79, 0xa2, 0x13, 0x7c, 0x37, 0x80, 0xe8, 0x1d, 0x1c, 0x94, 0xd8, 0x2b, 0xb7, 0x57, 0xff,
0x1b, 0x00, 0x00, 0xff, 0xff, 0xe0, 0x62, 0xfe, 0x6b, 0xc9, 0x36, 0x00, 0x00,
// 2835 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xcc, 0x5a, 0xcd, 0x73, 0xdb, 0xc6,
0x15, 0x2f, 0x45, 0x89, 0x14, 0x1f, 0x49, 0x51, 0xda, 0xe8, 0x83, 0x82, 0xf5, 0x65, 0xc8, 0xb5,
0xe5, 0xc6, 0x91, 0x13, 0x25, 0x93, 0x36, 0x69, 0x32, 0x0d, 0x65, 0x3b, 0x91, 0x12, 0x39, 0x56,
0x21, 0x3b, 0xcd, 0xc4, 0x9d, 0x30, 0x10, 0xb1, 0x92, 0x90, 0x80, 0x00, 0x03, 0x2c, 0xa5, 0x6a,
0xa6, 0x93, 0xf6, 0xd0, 0xa6, 0xa7, 0xce, 0xf4, 0x9c, 0xe9, 0x5f, 0xd1, 0x4b, 0x8e, 0xbd, 0x75,
0x32, 0xd3, 0xff, 0xa0, 0x87, 0x74, 0xa6, 0xb7, 0x5e, 0x7a, 0xe9, 0x3f, 0xd0, 0xd9, 0x0f, 0x80,
0x58, 0x7c, 0x51, 0x02, 0xed, 0x51, 0x6f, 0xd8, 0xdd, 0xf7, 0x7e, 0xfb, 0xde, 0xdb, 0xdd, 0x87,
0xf7, 0xde, 0x2e, 0x34, 0xba, 0x7d, 0x8b, 0x98, 0xb6, 0x63, 0xe0, 0xcd, 0x9e, 0xeb, 0x10, 0x07,
0x55, 0x82, 0x0e, 0x05, 0x8e, 0x9d, 0x63, 0x87, 0x77, 0x2b, 0xab, 0xc7, 0x8e, 0x73, 0x6c, 0xe1,
0xbb, 0xac, 0x75, 0xd8, 0x3f, 0xba, 0x4b, 0xcc, 0x2e, 0xf6, 0x88, 0xde, 0xed, 0x71, 0x02, 0x75,
0x03, 0xea, 0x1a, 0xfe, 0xb2, 0x8f, 0x3d, 0xb2, 0x83, 0x75, 0x03, 0xbb, 0x68, 0x01, 0xca, 0x7a,
0xcf, 0x6c, 0x7f, 0x81, 0xcf, 0x9b, 0x85, 0xb5, 0xc2, 0x46, 0x4d, 0x2b, 0xe9, 0x3d, 0xf3, 0x03,
0x7c, 0xae, 0xde, 0x87, 0xe9, 0xfb, 0xa6, 0xf7, 0xc5, 0x41, 0x4f, 0xef, 0x60, 0xc1, 0x82, 0x5e,
0x86, 0xd2, 0x09, 0x63, 0x63, 0xb4, 0xd5, 0xad, 0xe6, 0xe6, 0x40, 0x2e, 0x09, 0x56, 0x13, 0x74,
0xea, 0x5f, 0x0b, 0x30, 0x13, 0x82, 0xf1, 0x7a, 0x8e, 0xed, 0x61, 0xb4, 0x04, 0x15, 0xdd, 0xb2,
0x9c, 0x8e, 0x4e, 0xb0, 0xc1, 0xa0, 0x8a, 0xda, 0xa0, 0x03, 0xad, 0x42, 0xb5, 0xef, 0x61, 0xa3,
0xdd, 0x33, 0x71, 0x07, 0x7b, 0xcd, 0x31, 0x36, 0x0e, 0xb4, 0x6b, 0x9f, 0xf5, 0xa0, 0x65, 0x60,
0xad, 0x36, 0x71, 0x75, 0xef, 0xa4, 0x59, 0xe4, 0xfc, 0xb4, 0xe7, 0x31, 0xed, 0x40, 0x08, 0xc6,
0x8f, 0x5c, 0x8c, 0x9b, 0xe3, 0x6c, 0x80, 0x7d, 0xb3, 0x19, 0x4f, 0x75, 0xd3, 0xd2, 0x0f, 0x2d,
0xdc, 0x9c, 0x10, 0x33, 0xfa, 0x1d, 0x48, 0x81, 0x49, 0xe7, 0x14, 0xbb, 0x14, 0xa2, 0x59, 0x62,
0x83, 0x41, 0x5b, 0xfd, 0x0d, 0xd4, 0x0e, 0x88, 0xe3, 0xea, 0xc7, 0xf8, 0x89, 0xa7, 0x1f, 0x63,
0xa4, 0x42, 0x5d, 0x27, 0x6d, 0x17, 0x7b, 0xa4, 0x4d, 0x1c, 0xa2, 0x5b, 0x4c, 0xfe, 0x82, 0x56,
0xd5, 0x89, 0x86, 0x3d, 0xf2, 0x98, 0x76, 0xa1, 0x0f, 0x60, 0xca, 0xb4, 0x09, 0x76, 0x4f, 0x75,
0xab, 0xed, 0x11, 0xdd, 0x25, 0x4c, 0x89, 0xea, 0x96, 0xb2, 0xc9, 0xd7, 0x67, 0xd3, 0x5f, 0x9f,
0xcd, 0xc7, 0xfe, 0xfa, 0x6c, 0x4f, 0x7e, 0xf7, 0xfd, 0xea, 0x0f, 0xfe, 0xf4, 0xcf, 0xd5, 0x82,
0x56, 0xf7, 0x79, 0x0f, 0x28, 0xab, 0xfa, 0x6d, 0x01, 0x5e, 0x08, 0x4b, 0x90, 0x7b, 0x31, 0xd0,
0x4f, 0xa8, 0x61, 0x9c, 0xee, 0xa5, 0x84, 0x61, 0x1c, 0xe8, 0x35, 0x18, 0x23, 0x0e, 0xb3, 0xf4,
0x45, 0xf9, 0xc6, 0x88, 0xa3, 0xda, 0x30, 0x2b, 0x0b, 0x2e, 0x96, 0xff, 0x2d, 0xa8, 0x7b, 0xbc,
0xbf, 0xdd, 0xa7, 0x03, 0xcd, 0xc2, 0x5a, 0x71, 0xa3, 0xba, 0xb5, 0x10, 0x52, 0x40, 0xe2, 0xab,
0x79, 0xe1, 0x05, 0x68, 0x42, 0xd9, 0xeb, 0x77, 0xbb, 0xba, 0x7b, 0xce, 0x14, 0x29, 0x68, 0x7e,
0x53, 0xfd, 0x6f, 0x01, 0x96, 0xc2, 0x8c, 0x07, 0x3a, 0xc1, 0x96, 0x65, 0x92, 0x11, 0x4c, 0xf6,
0x0a, 0xd4, 0x3c, 0x1f, 0xa5, 0x6d, 0x1a, 0x6c, 0xc6, 0xda, 0xf6, 0x14, 0x55, 0xf3, 0x1f, 0xdf,
0xaf, 0x96, 0x3e, 0x74, 0x0c, 0xbc, 0x7b, 0x5f, 0xab, 0x06, 0x34, 0xbb, 0x46, 0x60, 0xe5, 0x62,
0x4e, 0x2b, 0x8f, 0x5f, 0xd2, 0xca, 0x67, 0xb0, 0x9c, 0xa2, 0xf4, 0x73, 0x36, 0xf7, 0x3e, 0x2c,
0x6d, 0xeb, 0xb6, 0x71, 0x66, 0x1a, 0xe4, 0xe4, 0xa1, 0x63, 0x93, 0x93, 0x03, 0x3e, 0x90, 0xdf,
0x5b, 0xbc, 0x0a, 0xcb, 0x29, 0x88, 0x42, 0x15, 0x04, 0xe3, 0xec, 0x90, 0x72, 0x9f, 0xc1, 0xbe,
0xd5, 0x3f, 0x14, 0x60, 0x2d, 0xe0, 0x12, 0x0c, 0x57, 0xb2, 0xf2, 0xea, 0xdb, 0x70, 0x3d, 0x43,
0x10, 0xa1, 0x42, 0xc8, 0x9e, 0x5c, 0x8b, 0xc0, 0x9e, 0x1f, 0xc0, 0x42, 0x94, 0x3d, 0xbf, 0x29,
0x5f, 0x83, 0x66, 0x1c, 0x6c, 0xa8, 0x08, 0xbf, 0x2b, 0xc0, 0xf2, 0x83, 0x63, 0x17, 0x7b, 0xde,
0x95, 0x1a, 0xf2, 0x4d, 0x58, 0x49, 0x93, 0x62, 0xa8, 0x0a, 0x3b, 0x30, 0x2b, 0xf1, 0xe6, 0x37,
0xe1, 0x2b, 0x30, 0x17, 0x41, 0x1a, 0x3a, 0xf9, 0xef, 0x0b, 0xb0, 0xb2, 0x6b, 0x5f, 0xbd, 0x01,
0x7f, 0x0a, 0xab, 0xa9, 0x62, 0x0c, 0x55, 0x62, 0x17, 0xe6, 0x64, 0xe6, 0xfc, 0x26, 0xdc, 0x82,
0xf9, 0x28, 0xd4, 0xd0, 0xe9, 0x7f, 0x0d, 0x73, 0xf7, 0x75, 0xd3, 0xba, 0x22, 0xcb, 0x1d, 0xc0,
0x7c, 0x74, 0x76, 0x21, 0xf1, 0x1b, 0x50, 0x63, 0xee, 0xb3, 0xed, 0x3a, 0x96, 0xd5, 0xef, 0x09,
0x2f, 0x3a, 0x1f, 0x12, 0x82, 0xbb, 0x4f, 0x36, 0xaa, 0x55, 0xfb, 0x83, 0x86, 0xfa, 0x0e, 0xd4,
0x18, 0x68, 0x7e, 0x43, 0xbe, 0x0f, 0x75, 0x81, 0x30, 0xba, 0x34, 0x7f, 0x2f, 0x40, 0x35, 0x34,
0x88, 0x6e, 0x43, 0x09, 0xb3, 0x35, 0x12, 0xd2, 0xcc, 0x84, 0x40, 0xf8, 0x01, 0xd0, 0x04, 0x01,
0xba, 0x03, 0x65, 0x93, 0xaf, 0xa7, 0x08, 0x22, 0x50, 0x88, 0x56, 0xac, 0xb4, 0xe6, 0x93, 0xa0,
0x79, 0x28, 0x19, 0xd8, 0xc2, 0x04, 0x8b, 0x18, 0x4d, 0xb4, 0x12, 0xc2, 0xa3, 0xf1, 0xfc, 0xe1,
0xd1, 0x1e, 0x94, 0x1e, 0x04, 0xd3, 0xb9, 0xb8, 0xa7, 0x9b, 0xae, 0xd8, 0x51, 0xa2, 0x85, 0x66,
0x61, 0x42, 0xef, 0x1b, 0x26, 0x11, 0x91, 0x24, 0x6f, 0xd0, 0x5e, 0xfe, 0x37, 0xe4, 0xb2, 0xf1,
0x86, 0xfa, 0x63, 0x28, 0xef, 0xda, 0x32, 0x9c, 0x21, 0xc1, 0x19, 0x03, 0xc6, 0xb1, 0x30, 0xe3,
0x36, 0x4c, 0x7d, 0x84, 0x5d, 0xcf, 0x74, 0xec, 0xfc, 0x8b, 0xfc, 0x22, 0x34, 0x02, 0x8c, 0xc1,
0x31, 0x39, 0xe5, 0x5d, 0x0c, 0xa5, 0xa2, 0xf9, 0x4d, 0xf5, 0x5d, 0x40, 0x7b, 0xba, 0x47, 0xee,
0x39, 0x36, 0xd1, 0x3b, 0x24, 0xff, 0xa4, 0x9f, 0xc2, 0x0b, 0x12, 0x8e, 0x98, 0xf8, 0x3d, 0xa8,
0x59, 0xba, 0x47, 0xda, 0x1d, 0xde, 0x2f, 0xe0, 0x2e, 0xb6, 0x42, 0x55, 0x6b, 0x00, 0xa8, 0xfe,
0x0a, 0x66, 0x34, 0xdc, 0xeb, 0x13, 0x9d, 0x8c, 0x62, 0x9b, 0x3c, 0x47, 0xf9, 0x9b, 0x02, 0x54,
0x5b, 0x74, 0xad, 0x7f, 0x61, 0xda, 0x86, 0x73, 0x46, 0x55, 0x3a, 0x63, 0x5f, 0x62, 0xd3, 0x5d,
0x4a, 0x25, 0xce, 0xc9, 0xb6, 0x1c, 0xba, 0x0e, 0x35, 0xc7, 0xb6, 0x4c, 0x1b, 0xb7, 0x3b, 0x4e,
0xdf, 0xe6, 0xfb, 0x6a, 0x42, 0xab, 0xf2, 0xbe, 0x7b, 0xb4, 0x8b, 0xe6, 0x30, 0x2c, 0x3b, 0x10,
0x14, 0x45, 0x46, 0x01, 0xac, 0x8b, 0x11, 0xa8, 0xdf, 0x96, 0x01, 0x85, 0xed, 0x12, 0xc4, 0x6a,
0x25, 0x0e, 0x23, 0xa4, 0xbb, 0x21, 0x19, 0x26, 0x4a, 0xbe, 0xf9, 0x88, 0xd1, 0x6a, 0x82, 0x07,
0xbd, 0x11, 0xde, 0xe9, 0xd5, 0xad, 0xf5, 0x6c, 0x66, 0x66, 0x1b, 0xff, 0x38, 0x3c, 0x84, 0x86,
0x61, 0x7a, 0x5f, 0xf6, 0x75, 0xcb, 0x3c, 0x32, 0xb1, 0xd1, 0xd6, 0xc9, 0x05, 0x03, 0xd8, 0x02,
0xb3, 0xcf, 0x54, 0x98, 0xb9, 0x45, 0xa8, 0xad, 0xbd, 0xbe, 0xd7, 0xc3, 0xb6, 0xc1, 0xb1, 0xc6,
0x2f, 0x81, 0x55, 0x0d, 0x38, 0x5b, 0x04, 0x7d, 0x04, 0xb3, 0xce, 0xd1, 0x11, 0x33, 0xb6, 0x04,
0x38, 0x71, 0x09, 0x40, 0x24, 0x10, 0x0e, 0x42, 0xb8, 0x4f, 0x61, 0xc1, 0xc7, 0xed, 0xdb, 0x06,
0x76, 0xdb, 0x2e, 0x3e, 0x35, 0xf1, 0x19, 0x85, 0x2e, 0x5d, 0x02, 0xda, 0x17, 0xee, 0x09, 0xc5,
0xd0, 0x18, 0x44, 0x8b, 0xa0, 0x7b, 0x00, 0xfd, 0x9e, 0x41, 0x93, 0x59, 0x8a, 0x57, 0xbe, 0xc4,
0x3e, 0xab, 0x08, 0xbe, 0x16, 0x41, 0x2d, 0xa8, 0x7c, 0xee, 0x98, 0x36, 0xc7, 0x98, 0xbc, 0x04,
0xc6, 0x24, 0x67, 0x6b, 0x11, 0x65, 0x05, 0x4a, 0x7c, 0x87, 0x50, 0xa7, 0xe5, 0x75, 0x1c, 0x17,
0x8b, 0x6c, 0x95, 0x37, 0x94, 0xbf, 0x8c, 0xc1, 0x44, 0xcb, 0xf7, 0x86, 0xf1, 0x71, 0x74, 0x1b,
0xa6, 0xb9, 0xd1, 0xa9, 0xc7, 0x69, 0x73, 0x02, 0x9e, 0x04, 0x34, 0x06, 0xfd, 0x07, 0x8c, 0x34,
0x61, 0xc3, 0x17, 0xc3, 0x1b, 0x1e, 0xad, 0x43, 0xdd, 0xeb, 0x77, 0x3a, 0xd8, 0xf3, 0x04, 0x09,
0x4f, 0xcf, 0x6b, 0xa2, 0x93, 0x13, 0x51, 0x57, 0x6d, 0xf5, 0x4e, 0x74, 0xb6, 0xbc, 0x05, 0x8d,
0x37, 0x68, 0xd4, 0x7f, 0x88, 0x89, 0xce, 0x16, 0xa6, 0xa0, 0xb1, 0x6f, 0x0a, 0xd7, 0xb7, 0xbf,
0xb0, 0x9d, 0x33, 0xbb, 0xcd, 0x39, 0xca, 0x6c, 0xb0, 0x26, 0x3a, 0x5b, 0x8c, 0xf1, 0x3a, 0xf8,
0xed, 0x36, 0x03, 0x98, 0xe4, 0xa9, 0xba, 0xe8, 0xdb, 0xa6, 0x38, 0x2f, 0x43, 0xf9, 0xc4, 0xa4,
0x09, 0xcf, 0x79, 0xb3, 0x12, 0xfb, 0x85, 0x86, 0xbc, 0x87, 0xe6, 0x93, 0xa9, 0x7b, 0xd0, 0x7c,
0xec, 0xf6, 0x3d, 0x82, 0x8d, 0x20, 0x46, 0xf0, 0xf2, 0xbb, 0xdf, 0xbf, 0x15, 0x60, 0x31, 0x01,
0x4e, 0xb8, 0x83, 0xa7, 0x80, 0x08, 0x1f, 0x6c, 0x07, 0x9e, 0xcd, 0x13, 0xff, 0xfa, 0x3b, 0x21,
0xec, 0x54, 0x84, 0x4d, 0xea, 0x18, 0x9f, 0x68, 0x7b, 0xda, 0x0c, 0x89, 0x92, 0x28, 0x7b, 0x50,
0x16, 0xa3, 0xe8, 0x16, 0x94, 0x29, 0x4e, 0x5b, 0xfc, 0xec, 0xe2, 0x8e, 0xb5, 0x44, 0x87, 0x77,
0x0d, 0xfa, 0x3f, 0xd2, 0x0d, 0x23, 0x08, 0x00, 0x2a, 0x9a, 0xdf, 0x54, 0xef, 0x41, 0xe3, 0x51,
0x0f, 0xbb, 0x3a, 0x71, 0xdc, 0xfc, 0xd6, 0x30, 0x61, 0x7a, 0x00, 0x22, 0x6c, 0x30, 0x0b, 0x13,
0xb8, 0xab, 0x9b, 0x96, 0xf8, 0x01, 0xf2, 0x06, 0xfd, 0x3b, 0x9f, 0xe9, 0x96, 0x85, 0x89, 0x90,
0x43, 0xb4, 0xd0, 0x2d, 0x68, 0xf0, 0xaf, 0xf6, 0x11, 0xd6, 0x49, 0xdf, 0xc5, 0x5e, 0xb3, 0xb8,
0x56, 0xdc, 0xa8, 0x68, 0x53, 0xbc, 0xfb, 0x5d, 0xd1, 0xab, 0x7e, 0x5d, 0x80, 0xd5, 0x07, 0x1e,
0x31, 0xbb, 0xf4, 0xb8, 0xed, 0xeb, 0xe7, 0x4e, 0x9f, 0x5c, 0x4d, 0xc4, 0xf9, 0x73, 0x58, 0x4b,
0x97, 0x43, 0xd8, 0xe0, 0x25, 0x40, 0xd8, 0xa7, 0x69, 0x63, 0xdd, 0xb5, 0x4d, 0xfb, 0xd8, 0x13,
0x71, 0xc9, 0x4c, 0x30, 0xf2, 0x40, 0x0c, 0xa8, 0xef, 0xc3, 0x7c, 0x04, 0x32, 0xff, 0x92, 0xec,
0xc0, 0x42, 0x0c, 0x2b, 0x9f, 0x54, 0xdb, 0x30, 0x35, 0x72, 0x42, 0xb1, 0x0b, 0x8d, 0x68, 0x26,
0xf1, 0x3a, 0x54, 0x7b, 0x4c, 0xae, 0xb6, 0x69, 0x1f, 0x39, 0x02, 0x69, 0x2e, 0x84, 0xc4, 0xa5,
0xde, 0xb5, 0x8f, 0x1c, 0x0d, 0x7a, 0xc1, 0xb7, 0xfa, 0x19, 0xcc, 0x0a, 0xa8, 0x7d, 0xec, 0x9a,
0x8e, 0x91, 0x7f, 0xd1, 0xe7, 0xa1, 0xd4, 0x63, 0x10, 0xfe, 0x5e, 0xe4, 0x2d, 0xf5, 0x11, 0xcc,
0x45, 0x66, 0x18, 0x51, 0xe4, 0xaf, 0x60, 0xe1, 0x4a, 0xd3, 0x4a, 0x0d, 0x9a, 0xa9, 0xf9, 0x64,
0x5e, 0x9d, 0xfe, 0x5c, 0x80, 0xe5, 0x28, 0xe8, 0xa8, 0x0b, 0x92, 0xa3, 0x6a, 0x37, 0x58, 0xc3,
0xa2, 0xb4, 0x86, 0x1f, 0xc3, 0x4a, 0x9a, 0x74, 0x23, 0x2a, 0xde, 0x82, 0x3a, 0x3d, 0x1a, 0x38,
0xbf, 0x9e, 0xea, 0x4d, 0x98, 0xf2, 0x21, 0x06, 0xce, 0x72, 0x50, 0x95, 0x2e, 0x6a, 0xbc, 0xc1,
0xfc, 0x01, 0xa3, 0x1b, 0x7d, 0xdb, 0xa8, 0x9f, 0xc1, 0x42, 0x0c, 0x4b, 0x4c, 0xfe, 0x00, 0xa6,
0x31, 0x1b, 0x1a, 0xfc, 0xac, 0xc4, 0xbf, 0x4a, 0x09, 0xa7, 0x94, 0x11, 0xee, 0x06, 0x96, 0x3b,
0xd4, 0x4f, 0xa0, 0x11, 0xa1, 0x49, 0x56, 0x2b, 0xcf, 0x0e, 0xde, 0x81, 0xd9, 0x27, 0xb6, 0x61,
0x7a, 0xc4, 0x35, 0x0f, 0xfb, 0x64, 0x14, 0xdb, 0xbf, 0x04, 0x73, 0x11, 0xa4, 0xcc, 0x25, 0xf8,
0x0a, 0x16, 0xf6, 0xf5, 0x73, 0x8f, 0xf4, 0x0f, 0xaf, 0xe6, 0xe8, 0xee, 0x40, 0x33, 0x3e, 0xbf,
0x90, 0xf8, 0x0e, 0x94, 0x7b, 0x7c, 0x4c, 0x48, 0x80, 0xe4, 0xdd, 0x4b, 0x47, 0x34, 0x9f, 0x84,
0xba, 0x71, 0xbf, 0x2f, 0xb7, 0xf1, 0x7e, 0x06, 0x8d, 0x00, 0x23, 0x97, 0x10, 0x9f, 0xc1, 0xac,
0xe8, 0x7b, 0x5e, 0xce, 0xfb, 0x01, 0xcc, 0x45, 0x66, 0xc8, 0x25, 0x28, 0x75, 0x6f, 0x51, 0xc3,
0xff, 0x1f, 0xb9, 0xb7, 0x0f, 0x61, 0x25, 0x4d, 0xba, 0x5c, 0xea, 0xbe, 0x06, 0x30, 0x70, 0x77,
0x34, 0x70, 0x3f, 0xc1, 0x56, 0x50, 0xae, 0xa7, 0xdf, 0xb4, 0x8f, 0x15, 0x55, 0x78, 0xf5, 0x84,
0x7d, 0xab, 0x7f, 0x2c, 0x42, 0x59, 0x40, 0x21, 0x15, 0xea, 0xbc, 0xb0, 0x25, 0x6e, 0xd9, 0xfc,
0xfb, 0x35, 0xd6, 0xd9, 0x62, 0x97, 0x6c, 0xe8, 0x1a, 0x54, 0x38, 0xcd, 0x31, 0xf6, 0xab, 0x3a,
0x93, 0xac, 0xe3, 0x3d, 0x4c, 0xd0, 0x06, 0x4c, 0x07, 0x83, 0x6d, 0x51, 0x10, 0xe2, 0xe9, 0xc8,
0x94, 0x4f, 0xa3, 0xf1, 0xc2, 0xd0, 0x4d, 0x68, 0x0c, 0x28, 0x79, 0xe2, 0xcc, 0x93, 0x92, 0xba,
0x4f, 0xc8, 0x93, 0xa3, 0x35, 0xa8, 0x75, 0x9c, 0x6e, 0x2f, 0x90, 0x88, 0xdf, 0x1f, 0x02, 0xed,
0x13, 0x02, 0x2d, 0xc2, 0x24, 0xa3, 0xa0, 0xf2, 0xf0, 0x0b, 0xc4, 0x32, 0x6d, 0x53, 0x71, 0x6e,
0x42, 0xc3, 0x1f, 0xf2, 0xa5, 0x29, 0xf3, 0x49, 0x04, 0x85, 0x10, 0xe6, 0x06, 0x4c, 0x05, 0x74,
0x5c, 0x96, 0x49, 0x9e, 0x20, 0x09, 0x32, 0x2e, 0x8a, 0x6f, 0xd1, 0x4a, 0x82, 0x45, 0x61, 0x60,
0x51, 0xb4, 0x06, 0xd5, 0x90, 0x6f, 0x6a, 0x56, 0xd9, 0x50, 0xb8, 0x0b, 0x29, 0x30, 0x69, 0x98,
0x5e, 0xcf, 0xf1, 0xb0, 0xd1, 0xac, 0x71, 0x13, 0xfa, 0x6d, 0x9a, 0xe2, 0xec, 0x60, 0xcb, 0x68,
0x75, 0x69, 0x52, 0xb6, 0xc3, 0xf3, 0x9e, 0xfc, 0x87, 0xfd, 0xbb, 0x31, 0x58, 0x4c, 0x80, 0x13,
0xfb, 0x6b, 0x7f, 0x90, 0x80, 0xf1, 0x7f, 0xc5, 0xeb, 0x21, 0xc0, 0x54, 0xb6, 0x84, 0x11, 0x1f,
0x46, 0x79, 0x0b, 0x60, 0x30, 0x1a, 0xda, 0xf9, 0x85, 0xf0, 0xce, 0xa7, 0xfd, 0x7a, 0x37, 0x28,
0xdf, 0x14, 0x35, 0xd1, 0x52, 0xbe, 0x29, 0xc0, 0x4c, 0x0c, 0x3c, 0x76, 0xe4, 0x0a, 0xc3, 0x8f,
0x9c, 0x06, 0x35, 0xba, 0x3c, 0x6d, 0x8e, 0x4b, 0xf3, 0x25, 0xaa, 0xdd, 0xdd, 0x4b, 0x6a, 0xa7,
0x55, 0x4f, 0x82, 0x6f, 0x4f, 0x7d, 0x04, 0xd7, 0x22, 0xc1, 0x38, 0xbb, 0x70, 0xce, 0xbf, 0x36,
0x0f, 0x61, 0x29, 0x19, 0x30, 0x5f, 0x88, 0xff, 0x08, 0xae, 0xb5, 0x2c, 0x6b, 0x90, 0x63, 0x8e,
0x1c, 0xef, 0x7f, 0x04, 0x4b, 0xc9, 0x80, 0x23, 0x06, 0x5f, 0x5d, 0xb8, 0x2e, 0xe1, 0x72, 0xa7,
0x37, 0xaa, 0xb8, 0xa9, 0x3f, 0x93, 0x5f, 0x82, 0x9a, 0x35, 0xdd, 0x33, 0x48, 0x0b, 0x7c, 0xe8,
0x91, 0x55, 0xc8, 0x99, 0x16, 0xc4, 0xe6, 0x7f, 0x16, 0x69, 0x81, 0xfc, 0x4b, 0xba, 0x02, 0xd5,
0x32, 0xd3, 0x82, 0x14, 0xe9, 0x46, 0x54, 0xfc, 0x21, 0x2c, 0xf2, 0xe8, 0x77, 0x1f, 0xbb, 0xcf,
0x20, 0x5c, 0xef, 0x80, 0x92, 0x04, 0xf7, 0x6c, 0x23, 0xf6, 0xf0, 0x06, 0x1c, 0x35, 0x36, 0xcc,
0x19, 0xdc, 0xc6, 0xe7, 0xcf, 0x1d, 0x57, 0xb2, 0xe5, 0x1c, 0x59, 0x8d, 0xac, 0xb8, 0x52, 0x9e,
0x21, 0x77, 0x5c, 0x19, 0xd9, 0x81, 0x57, 0x60, 0xf9, 0xac, 0xb8, 0x32, 0x4d, 0xba, 0x3c, 0xea,
0x6e, 0xfd, 0x76, 0x0c, 0xca, 0xe2, 0x91, 0x0a, 0x7a, 0x17, 0x2a, 0xc1, 0x93, 0x32, 0x74, 0x2d,
0xc4, 0x15, 0x7d, 0xaf, 0xa6, 0x2c, 0x25, 0x0f, 0x0a, 0x09, 0x76, 0x60, 0x82, 0x3f, 0x71, 0x59,
0x49, 0x7b, 0x09, 0x23, 0x60, 0x56, 0x53, 0xc7, 0x05, 0x52, 0x07, 0xa6, 0xe4, 0xb7, 0x37, 0xe8,
0x56, 0x0a, 0x4b, 0xf4, 0x44, 0x2b, 0x1b, 0xc3, 0x09, 0xf9, 0x24, 0x5b, 0xff, 0x2a, 0x41, 0x25,
0x78, 0xd2, 0x81, 0x74, 0xa8, 0x85, 0x5f, 0xc8, 0x48, 0x13, 0x66, 0xbd, 0xca, 0x91, 0x26, 0xcc,
0x7e, 0x6c, 0x73, 0x0a, 0x8b, 0xa9, 0xcf, 0x59, 0xd0, 0x8b, 0x49, 0x30, 0x29, 0xc5, 0x29, 0xe5,
0xce, 0xc5, 0x88, 0x83, 0xa2, 0xf7, 0x74, 0x94, 0x08, 0xa9, 0x19, 0x08, 0xfe, 0x2c, 0xeb, 0x99,
0x34, 0x02, 0xbc, 0x0b, 0xf3, 0xc9, 0x4f, 0x4b, 0xd0, 0x46, 0xec, 0xda, 0x3b, 0x4d, 0x9d, 0xdb,
0x17, 0xa0, 0x14, 0xd3, 0x69, 0x50, 0x97, 0x28, 0xd0, 0x6a, 0x1a, 0xaf, 0x0f, 0xbe, 0x96, 0x4e,
0x20, 0x30, 0x7b, 0xb0, 0x90, 0xf2, 0xb8, 0x03, 0xdd, 0x8e, 0x5f, 0xc7, 0xa7, 0x29, 0xf1, 0xa3,
0x8b, 0x90, 0x8a, 0x19, 0x9f, 0xc0, 0x94, 0x4c, 0x82, 0xd6, 0x52, 0xb9, 0x7d, 0xfc, 0xeb, 0x19,
0x14, 0x03, 0x58, 0xf9, 0xad, 0x85, 0x04, 0x9b, 0xf8, 0x08, 0x44, 0x82, 0x4d, 0x79, 0xa8, 0xf1,
0x26, 0x4c, 0xb0, 0x11, 0xb4, 0x10, 0xa5, 0xf5, 0x41, 0x9a, 0xf1, 0x01, 0x71, 0xc8, 0xbe, 0x2e,
0xc2, 0x38, 0xf5, 0x73, 0xe8, 0x1d, 0x28, 0x8b, 0xbb, 0x78, 0xb4, 0x18, 0xa2, 0x96, 0xef, 0xf8,
0x15, 0x25, 0x69, 0x48, 0x88, 0xb1, 0x07, 0xd5, 0xd0, 0xc5, 0x3a, 0x5a, 0x0e, 0x91, 0xc6, 0x2f,
0xee, 0x95, 0x95, 0xb4, 0x61, 0x81, 0xb6, 0x0b, 0x30, 0xb8, 0xc2, 0x45, 0x4b, 0x29, 0x37, 0xbb,
0x1c, 0x6b, 0x39, 0xf3, 0xde, 0x17, 0x7d, 0x0a, 0x33, 0xb1, 0xfb, 0x22, 0xb4, 0x9e, 0x7d, 0x9b,
0xc4, 0x81, 0x6f, 0x5c, 0xe4, 0xca, 0x09, 0xdd, 0x83, 0x49, 0xff, 0x12, 0x07, 0x85, 0x0d, 0x14,
0xb9, 0x1e, 0x52, 0xae, 0x25, 0x8e, 0x89, 0x85, 0xf8, 0x77, 0x85, 0x95, 0x04, 0x9c, 0x3e, 0xf1,
0xe8, 0x5a, 0xf8, 0xfb, 0x2e, 0xbc, 0x16, 0x91, 0x0d, 0xa7, 0x24, 0x0d, 0x0d, 0x8e, 0xa1, 0x54,
0x89, 0x97, 0x8e, 0x61, 0xd2, 0x2d, 0x80, 0x74, 0x0c, 0x93, 0x8b, 0xf8, 0x4f, 0x61, 0x3a, 0x76,
0xfe, 0xd4, 0x38, 0x57, 0x6c, 0x07, 0xaf, 0x67, 0xd2, 0x0c, 0xdc, 0x54, 0x72, 0xd9, 0x59, 0x72,
0x53, 0x99, 0x75, 0x73, 0xc9, 0x4d, 0x0d, 0xa9, 0x61, 0xbf, 0x0d, 0x25, 0x1e, 0xe4, 0xa1, 0x66,
0x2c, 0xee, 0xf3, 0xe1, 0x16, 0x13, 0x46, 0x04, 0xfb, 0xc7, 0xf1, 0x8a, 0xed, 0xf5, 0x8c, 0xf8,
0x51, 0x00, 0xaa, 0x59, 0x24, 0x02, 0xd9, 0x83, 0x66, 0xda, 0xe5, 0x18, 0x0a, 0x7b, 0xb0, 0x21,
0x37, 0x79, 0xca, 0x8b, 0x17, 0xa2, 0x0d, 0xa9, 0x23, 0xd3, 0xc8, 0xea, 0x24, 0x5e, 0xad, 0xc9,
0xea, 0xa4, 0xdc, 0x98, 0x69, 0x50, 0x97, 0x8a, 0xc6, 0xd2, 0x3e, 0x4c, 0x2a, 0x4c, 0x4b, 0xfb,
0x30, 0xb9, 0xde, 0xfc, 0x14, 0xa6, 0xa3, 0x25, 0x3c, 0x69, 0x1f, 0xa6, 0x94, 0x9d, 0xa5, 0x7d,
0x98, 0x5a, 0x1a, 0x7e, 0x67, 0x50, 0x98, 0x5b, 0x4c, 0x88, 0xcf, 0x12, 0x8e, 0x5e, 0x34, 0xce,
0xd3, 0xa0, 0x2e, 0xd5, 0x51, 0x25, 0x95, 0x93, 0x6a, 0xb8, 0x92, 0xca, 0xc9, 0x25, 0xd8, 0x2e,
0xcc, 0x27, 0x57, 0x2d, 0xa5, 0xd3, 0x91, 0x59, 0x76, 0x95, 0x4e, 0xc7, 0x90, 0x12, 0xe8, 0xa7,
0x49, 0x15, 0xa1, 0xf5, 0xec, 0x42, 0x4e, 0xdc, 0x61, 0xa6, 0x56, 0x7b, 0xb6, 0xfe, 0x53, 0x81,
0x92, 0xd8, 0x67, 0xc7, 0x30, 0x9b, 0x54, 0xef, 0x40, 0x37, 0xc3, 0xaf, 0x12, 0xd2, 0x2b, 0x2c,
0xca, 0xad, 0xa1, 0x74, 0x42, 0xa7, 0x73, 0x50, 0xd2, 0x2b, 0x12, 0xe8, 0x4e, 0x1a, 0x4c, 0x52,
0x26, 0xae, 0xbc, 0x74, 0x41, 0xea, 0x90, 0xe3, 0x8c, 0x94, 0x0b, 0x64, 0xc7, 0x99, 0x5c, 0xcb,
0x90, 0x1d, 0x67, 0x5a, 0xbd, 0x81, 0x3a, 0xce, 0xc4, 0xc4, 0x5c, 0x76, 0x9c, 0x59, 0x95, 0x05,
0xd9, 0x71, 0x66, 0x67, 0xf9, 0x23, 0x3a, 0x4e, 0x1d, 0x50, 0x3c, 0x3b, 0x47, 0x37, 0x62, 0x0c,
0x09, 0xb5, 0x00, 0xe5, 0x87, 0x43, 0xa8, 0xae, 0xd2, 0x83, 0x1e, 0xc3, 0x6c, 0x52, 0x59, 0x51,
0xda, 0xc6, 0x19, 0x85, 0x4c, 0x69, 0x1b, 0x67, 0xd6, 0x27, 0x9f, 0x93, 0x43, 0x8d, 0x56, 0x13,
0x92, 0xf7, 0x67, 0xc4, 0x0b, 0xae, 0x67, 0xd2, 0x3c, 0x53, 0x87, 0x1a, 0xce, 0xa8, 0x65, 0x87,
0x9a, 0x50, 0x09, 0x90, 0x1d, 0x6a, 0x62, 0x32, 0x1e, 0x3f, 0x35, 0x3e, 0x78, 0xc6, 0xa9, 0x89,
0xcc, 0x72, 0xfb, 0x02, 0x94, 0x7c, 0xba, 0xed, 0x1b, 0x9f, 0xa8, 0xd4, 0x03, 0x7e, 0xbe, 0x69,
0x3a, 0x77, 0xd9, 0xc7, 0xdd, 0x9e, 0x6b, 0x9e, 0xea, 0x04, 0xdf, 0x0d, 0x20, 0x7a, 0x87, 0x87,
0x25, 0xf6, 0xca, 0xed, 0xd5, 0xff, 0x05, 0x00, 0x00, 0xff, 0xff, 0x2a, 0xa5, 0x2c, 0x52, 0xfd,
0x36, 0x00, 0x00,
}

View File

@ -45,6 +45,7 @@ message StorageUsageRequest {
message StorageUsageResponse {
repeated StorageUsage storage_usage = 1;
double summary = 2;
}
message StorageUsageSatelliteRequest {
@ -56,6 +57,7 @@ message StorageUsageSatelliteRequest {
message StorageUsageSatelliteResponse {
repeated StorageUsage storage_usage = 1;
double summary = 2;
}
service Bandwidth {

View File

@ -1,5 +1,5 @@
// Code generated by protoc-gen-go-drpc. DO NOT EDIT.
// protoc-gen-go-drpc version: v0.0.20
// protoc-gen-go-drpc version: v0.0.23
// source: multinode.proto
package multinodepb

View File

@ -85,6 +85,10 @@ func (storage *StorageEndpoint) Usage(ctx context.Context, req *multinodepb.Stor
if err != nil {
return nil, rpcstatus.Wrap(rpcstatus.Internal, err)
}
summary, err := storage.usage.Summary(ctx, from, to)
if err != nil {
return nil, rpcstatus.Wrap(rpcstatus.Internal, err)
}
var usage []*multinodepb.StorageUsage
for _, stamp := range stamps {
@ -96,6 +100,7 @@ func (storage *StorageEndpoint) Usage(ctx context.Context, req *multinodepb.Stor
return &multinodepb.StorageUsageResponse{
StorageUsage: usage,
Summary: summary,
}, nil
}
@ -124,6 +129,10 @@ func (storage *StorageEndpoint) UsageSatellite(ctx context.Context, req *multino
if err != nil {
return nil, rpcstatus.Wrap(rpcstatus.Internal, err)
}
summary, err := storage.usage.SatelliteSummary(ctx, req.SatelliteId, from, to)
if err != nil {
return nil, rpcstatus.Wrap(rpcstatus.Internal, err)
}
var usage []*multinodepb.StorageUsage
for _, stamp := range stamps {
@ -135,5 +144,6 @@ func (storage *StorageEndpoint) UsageSatellite(ctx context.Context, req *multino
return &multinodepb.StorageUsageSatelliteResponse{
StorageUsage: usage,
Summary: summary,
}, nil
}

View File

@ -2,7 +2,7 @@
// See LICENSE for copying information.
import { APIClient } from '@/api/index';
import { DiskSpace, Stamp } from '@/storage';
import { DiskSpace, DiskSpaceUsage, Stamp } from '@/storage';
/**
* Client for storage controller of MND api.
@ -22,7 +22,7 @@ export class StorageClient extends APIClient {
* @throws {@link InternalError}
* Thrown if something goes wrong on server side.
*/
public async usage(satelliteId: string | null, nodeId: string | null): Promise<Stamp[]> {
public async usage(satelliteId: string | null, nodeId: string | null): Promise<DiskSpaceUsage> {
let path = `${this.ROOT_PATH}/usage`;
if (satelliteId) {
@ -46,11 +46,15 @@ export class StorageClient extends APIClient {
await this.handleError(response);
}
const usage = await response.json() || [];
const data = await response.json();
const usage = data.stamps || [];
return usage.map(stamp => {
return new DiskSpaceUsage(
usage.map(stamp => {
return new Stamp(stamp.atRestTotal, new Date(stamp.intervalStart));
});
}),
data.summary,
);
}
/**

View File

@ -42,11 +42,11 @@ class StampTooltip {
export default class DiskSpaceChart extends BaseChart {
private get allStamps(): Stamp[] {
return ChartUtils.populateEmptyStamps(this.$store.state.storage.usage);
return ChartUtils.populateEmptyStamps(this.$store.state.storage.usage.diskSpaceDaily);
}
public get chartDataDimension(): string {
if (!this.$store.state.storage.usage.length) {
if (!this.$store.state.storage.usage.diskSpaceDaily.length) {
return 'Bytes';
}

View File

@ -4,14 +4,14 @@
import { ActionContext, ActionTree, GetterTree, Module, MutationTree } from 'vuex';
import { RootState } from '@/app/store/index';
import { DiskSpace, Stamp } from '@/storage';
import { DiskSpace, DiskSpaceUsage, Stamp } from '@/storage';
import { StorageService } from '@/storage/service';
/**
* StorageState is a representation of by day and total storage usage.
*/
export class StorageState {
public usage: Stamp[] = [];
public usage: DiskSpaceUsage = new DiskSpaceUsage();
public diskSpace: DiskSpace = new DiskSpace();
}
@ -47,7 +47,7 @@ export class StorageModule implements Module<StorageState, RootState> {
* @param state - state of the module.
* @param usage
*/
public setUsage(state: StorageState, usage: Stamp[]): void {
public setUsage(state: StorageState, usage: DiskSpaceUsage): void {
state.usage = usage;
}

View File

@ -52,7 +52,7 @@
<div class="chart-container__title-area disk-space-title">
<p class="chart-container__title-area__title">Disk Space Used This Month</p>
</div>
<p class="chart-container__amount disk-space-amount"><b>{{ 0 | bytesToBase10String }}*h</b></p>
<p class="chart-container__amount disk-space-amount"><b>{{ diskSpaceUsageSummary | bytesToBase10String }}*h</b></p>
<div class="chart-container__chart" ref="diskSpaceChart" onresize="recalculateChartDimensions()" >
<disk-space-chart :height="diskSpaceChartHeight" :width="diskSpaceChartWidth"/>
</div>
@ -104,6 +104,10 @@ export default class BandwidthPage extends Vue {
return this.$store.state.bandwidth.traffic;
}
public get diskSpaceUsageSummary(): number {
return this.$store.state.storage.usage.diskSpaceSummary;
}
/**
* Used container size recalculation for charts resizing.
*/

View File

@ -2,7 +2,7 @@
// See LICENSE for copying information.
/**
* Stamp is storage usage stamp for satellite at some point in time
* Stamp is storage usage stamp for satellite at some point in time.
*/
export class Stamp {
public atRestTotal: number;
@ -14,7 +14,7 @@ export class Stamp {
}
/**
* Creates new empty instance of stamp with defined date
* Creates new empty instance of stamp with defined date.
* @param date - holds specific date of the month
* @returns Stamp - new empty instance of stamp with defined date
*/
@ -28,7 +28,7 @@ export class Stamp {
}
/**
* DiskSpace is total storage usage for node if any selected
* DiskSpace is total storage usage for node if any selected.
*/
export class DiskSpace {
public constructor(
@ -40,3 +40,13 @@ export class DiskSpace {
public overused: number = 0,
) {}
}
/**
* DiskSpaceUsage contains daily and total disk space usage.
*/
export class DiskSpaceUsage {
public constructor(
public diskSpaceDaily: Stamp[] = [],
public diskSpaceSummary: number = 0,
) {}
}

View File

@ -2,7 +2,7 @@
// See LICENSE for copying information.
import { StorageClient } from '@/api/storage';
import { DiskSpace, Stamp } from '@/storage';
import { DiskSpace, DiskSpaceUsage } from '@/storage';
/**
* Exposes all bandwidth related logic
@ -26,7 +26,7 @@ export class StorageService {
* @throws {@link InternalError}
* Thrown if something goes wrong on server side.
*/
public async usage(satelliteId: string | null, nodeId: string | null): Promise<Stamp[]> {
public async usage(satelliteId: string | null, nodeId: string | null): Promise<DiskSpaceUsage> {
return await this.storage.usage(satelliteId, nodeId);
}

View File

@ -7,14 +7,17 @@ import { BandwidthClient } from '@/api/bandwidth';
import { NodesClient } from '@/api/nodes';
import { Operators as OperatorsClient } from '@/api/operators';
import { PayoutsClient } from '@/api/payouts';
import { StorageClient } from '@/api/storage';
import { BandwidthModule } from '@/app/store/bandwidth';
import { NodesModule } from '@/app/store/nodes';
import { OperatorsModule } from '@/app/store/operators';
import { PayoutsModule } from '@/app/store/payouts';
import { StorageModule } from '@/app/store/storage';
import { Bandwidth } from '@/bandwidth/service';
import { Nodes } from '@/nodes/service';
import { Operators } from '@/operators';
import { Payouts } from '@/payouts/service';
import { StorageService } from '@/storage/service';
import { createLocalVue } from '@vue/test-utils';
const Vue = createLocalVue();
@ -37,11 +40,16 @@ const operatorsClient: OperatorsClient = new OperatorsClient();
export const operatorsService: Operators = new Operators(operatorsClient);
const operatorsModule: OperatorsModule = new OperatorsModule(operatorsService);
const storageClient = new StorageClient();
export const storageService = new StorageService(storageClient);
const storageModule: StorageModule = new StorageModule(storageService);
const store = new Vuex.Store({ modules: {
payouts: payoutsModule,
nodes: nodesModule,
operators: operatorsModule,
bandwidth: bandwidthModule,
storage: storageModule,
}});
export default store;