From 5480b79f354199accfdc6e7052aec1939630fb6c Mon Sep 17 00:00:00 2001 From: Kush Sharma Date: Thu, 19 Sep 2024 22:22:45 +0530 Subject: [PATCH] feat: set billing customer credit min limit - If a billing account credit min limit is set less then 0, it works as overdraft. Default is 0. - If a org billing account is in overdraft state, it's not allowed to create new billing account unless the dues are settled. - Setting this limit more then 0 works as min purchase requirement for the account. - Only platform admins can change the account limits. - https://github.com/raystack/proton/pull/370 Signed-off-by: Kush Sharma --- Makefile | 2 +- billing/credit/service.go | 13 +- billing/credit/service_test.go | 21 +- billing/customer/customer.go | 5 +- billing/customer/errors.go | 15 +- billing/customer/mocks/credit_service.go | 93 ++ billing/customer/mocks/repository.go | 58 + billing/customer/service.go | 42 +- billing/customer/service_test.go | 75 +- cmd/serve.go | 4 +- internal/api/v1beta1/billing_customer.go | 23 +- .../api/v1beta1/mocks/customer_service.go | 60 +- .../postgres/billing_customer_repository.go | 52 +- .../billing_transactions_repository.go | 111 +- .../billing_transactions_repository_test.go | 90 ++ ...83506_billing_customer_credit_min.down.sql | 1 + ...7183506_billing_customer_credit_min.up.sql | 1 + pkg/server/interceptors/authorization.go | 3 + proto/apidocs.swagger.yaml | 60 + proto/v1beta1/admin.pb.go | 1420 +++++++++-------- proto/v1beta1/admin.pb.gw.go | 139 ++ proto/v1beta1/admin.pb.validate.go | 247 +++ proto/v1beta1/admin_grpc.pb.go | 39 + test/e2e/regression/billing_test.go | 80 + 24 files changed, 1911 insertions(+), 743 deletions(-) create mode 100644 billing/customer/mocks/credit_service.go create mode 100644 internal/store/postgres/billing_transactions_repository_test.go create mode 100644 internal/store/postgres/migrations/20240917183506_billing_customer_credit_min.down.sql create mode 100644 internal/store/postgres/migrations/20240917183506_billing_customer_credit_min.up.sql diff --git a/Makefile b/Makefile index ab408443f..dd341af11 100644 --- a/Makefile +++ b/Makefile @@ -4,7 +4,7 @@ TAG := $(shell git rev-list --tags --max-count=1) VERSION := $(shell git describe --tags ${TAG}) .PHONY: build check fmt lint test test-race vet test-cover-html help install proto ui compose-up-dev .DEFAULT_GOAL := build -PROTON_COMMIT := "37eef9d41df218eb19d07a3b7f75d089c328c575" +PROTON_COMMIT := "145667ee53b037d636c09df0a529c351069132dc" ui: @echo " > generating ui build" diff --git a/billing/credit/service.go b/billing/credit/service.go index abaf5a96a..a42527bbb 100644 --- a/billing/credit/service.go +++ b/billing/credit/service.go @@ -74,17 +74,6 @@ func (s Service) Deduct(ctx context.Context, cred Credit) error { return errors.New("credit amount is negative") } - // check balance, if enough, sub credits - currentBalance, err := s.GetBalance(ctx, cred.CustomerID) - if err != nil { - return fmt.Errorf("failed to apply transaction: %w", err) - } - // TODO(kushsharma): this is prone to timing attacks and better we do this - // in a transaction - if currentBalance < cred.Amount { - return ErrInsufficientCredits - } - txSource := "system" if cred.Source != "" { txSource = cred.Source @@ -110,6 +99,8 @@ func (s Service) Deduct(ctx context.Context, cred Credit) error { }); err != nil { if errors.Is(err, ErrAlreadyApplied) { return ErrAlreadyApplied + } else if errors.Is(err, ErrInsufficientCredits) { + return ErrInsufficientCredits } return fmt.Errorf("failed to deduct credits: %w", err) } diff --git a/billing/credit/service_test.go b/billing/credit/service_test.go index fbb0f1815..d4dd470bf 100644 --- a/billing/credit/service_test.go +++ b/billing/credit/service_test.go @@ -291,27 +291,10 @@ func TestService_Deduct(t *testing.T) { setup: func() *credit.Service { s, mockTransactionRepo := mockService(t) - mockTransactionRepo.EXPECT().GetBalance(ctx, "customer_id").Return(10, nil) mockTransactionRepo.EXPECT().CreateEntry(ctx, mock.Anything, mock.Anything).Return(nil, credit.ErrAlreadyApplied) return s }, }, - { - name: "should return an error if balance cannot be fetched", - args: args{ - cred: credit.Credit{ - ID: "12", - CustomerID: "customer_id", - Amount: 10, - }, - }, - want: errors.New(fmt.Sprintf("failed to apply transaction: %v", dummyError)), - setup: func() *credit.Service { - s, mockTransactionRepo := mockService(t) - mockTransactionRepo.EXPECT().GetBalance(ctx, "customer_id").Return(0, dummyError) - return s - }, - }, { name: "should return ErrInsufficientCredits error if customer's balance is less than transaction amount", args: args{ @@ -324,7 +307,7 @@ func TestService_Deduct(t *testing.T) { want: credit.ErrInsufficientCredits, setup: func() *credit.Service { s, mockTransactionRepo := mockService(t) - mockTransactionRepo.EXPECT().GetBalance(ctx, "customer_id").Return(5, nil) + mockTransactionRepo.EXPECT().CreateEntry(ctx, mock.Anything, mock.Anything).Return(nil, credit.ErrInsufficientCredits) return s }, }, @@ -340,7 +323,6 @@ func TestService_Deduct(t *testing.T) { want: errors.New(fmt.Sprintf("failed to deduct credits: %v", dummyError)), setup: func() *credit.Service { s, mockTransactionRepo := mockService(t) - mockTransactionRepo.EXPECT().GetBalance(ctx, "customer_id").Return(20, nil) mockTransactionRepo.EXPECT().CreateEntry(ctx, mock.Anything, mock.Anything).Return([]credit.Transaction{}, dummyError) return s }, @@ -360,7 +342,6 @@ func TestService_Deduct(t *testing.T) { want: nil, setup: func() *credit.Service { s, mockTransactionRepo := mockService(t) - mockTransactionRepo.EXPECT().GetBalance(ctx, "customer_id").Return(20, nil) mockTransactionRepo.EXPECT().CreateEntry(ctx, credit.Transaction{ID: "12", CustomerID: "customer_id", Type: credit.DebitType, Amount: 10, Source: "system", Metadata: metadata.Metadata{"a": "a"}}, credit.Transaction{Type: credit.CreditType, CustomerID: schema.PlatformOrgID.String(), Amount: 10, Source: "system", Metadata: metadata.Metadata{"a": "a"}}).Return([]credit.Transaction{}, nil) return s }, diff --git a/billing/customer/customer.go b/billing/customer/customer.go index bd859a13f..5d9a16072 100644 --- a/billing/customer/customer.go +++ b/billing/customer/customer.go @@ -39,8 +39,9 @@ type Customer struct { Address Address TaxData []Tax // Currency Three-letter ISO 4217 currency code in lower case - Currency string `default:"usd"` - Metadata metadata.Metadata + Currency string `default:"usd"` + Metadata metadata.Metadata + CreditMin int64 // Stripe specific fields // StripeTestClockID is used for testing purposes only to simulate a subscription diff --git a/billing/customer/errors.go b/billing/customer/errors.go index bafc13dc9..60913e50f 100644 --- a/billing/customer/errors.go +++ b/billing/customer/errors.go @@ -5,11 +5,12 @@ import ( ) var ( - ErrNotFound = errors.New("customer not found") - ErrInvalidUUID = errors.New("invalid syntax of uuid") - ErrInvalidID = errors.New("billing customer id is invalid") - ErrConflict = errors.New("customer already exist") - ErrActiveConflict = errors.New("an active account already exists for the organization") - ErrInvalidDetail = errors.New("invalid billing customer detail") - ErrDisabled = errors.New("billing customer is disabled") + ErrNotFound = errors.New("customer not found") + ErrInvalidUUID = errors.New("invalid syntax of uuid") + ErrInvalidID = errors.New("billing customer id is invalid") + ErrConflict = errors.New("customer already exist") + ErrActiveConflict = errors.New("an active account already exists for the organization") + ErrInvalidDetail = errors.New("invalid billing customer detail") + ErrDisabled = errors.New("billing customer is disabled") + ErrExistingAccountWithPendingDues = errors.New("existing account with pending dues found") ) diff --git a/billing/customer/mocks/credit_service.go b/billing/customer/mocks/credit_service.go new file mode 100644 index 000000000..d17632b52 --- /dev/null +++ b/billing/customer/mocks/credit_service.go @@ -0,0 +1,93 @@ +// Code generated by mockery v2.45.0. DO NOT EDIT. + +package mocks + +import ( + context "context" + + mock "github.com/stretchr/testify/mock" +) + +// CreditService is an autogenerated mock type for the CreditService type +type CreditService struct { + mock.Mock +} + +type CreditService_Expecter struct { + mock *mock.Mock +} + +func (_m *CreditService) EXPECT() *CreditService_Expecter { + return &CreditService_Expecter{mock: &_m.Mock} +} + +// GetBalance provides a mock function with given fields: ctx, id +func (_m *CreditService) GetBalance(ctx context.Context, id string) (int64, error) { + ret := _m.Called(ctx, id) + + if len(ret) == 0 { + panic("no return value specified for GetBalance") + } + + var r0 int64 + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, string) (int64, error)); ok { + return rf(ctx, id) + } + if rf, ok := ret.Get(0).(func(context.Context, string) int64); ok { + r0 = rf(ctx, id) + } else { + r0 = ret.Get(0).(int64) + } + + if rf, ok := ret.Get(1).(func(context.Context, string) error); ok { + r1 = rf(ctx, id) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// CreditService_GetBalance_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetBalance' +type CreditService_GetBalance_Call struct { + *mock.Call +} + +// GetBalance is a helper method to define mock.On call +// - ctx context.Context +// - id string +func (_e *CreditService_Expecter) GetBalance(ctx interface{}, id interface{}) *CreditService_GetBalance_Call { + return &CreditService_GetBalance_Call{Call: _e.mock.On("GetBalance", ctx, id)} +} + +func (_c *CreditService_GetBalance_Call) Run(run func(ctx context.Context, id string)) *CreditService_GetBalance_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context), args[1].(string)) + }) + return _c +} + +func (_c *CreditService_GetBalance_Call) Return(_a0 int64, _a1 error) *CreditService_GetBalance_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *CreditService_GetBalance_Call) RunAndReturn(run func(context.Context, string) (int64, error)) *CreditService_GetBalance_Call { + _c.Call.Return(run) + return _c +} + +// NewCreditService creates a new instance of CreditService. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +// The first argument is typically a *testing.T value. +func NewCreditService(t interface { + mock.TestingT + Cleanup(func()) +}) *CreditService { + mock := &CreditService{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/billing/customer/mocks/repository.go b/billing/customer/mocks/repository.go index 4ce759f65..dfda9c688 100644 --- a/billing/customer/mocks/repository.go +++ b/billing/customer/mocks/repository.go @@ -299,6 +299,64 @@ func (_c *Repository_UpdateByID_Call) RunAndReturn(run func(context.Context, cus return _c } +// UpdateCreditMinByID provides a mock function with given fields: ctx, customerID, limit +func (_m *Repository) UpdateCreditMinByID(ctx context.Context, customerID string, limit int64) (customer.Customer, error) { + ret := _m.Called(ctx, customerID, limit) + + if len(ret) == 0 { + panic("no return value specified for UpdateCreditMinByID") + } + + var r0 customer.Customer + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, string, int64) (customer.Customer, error)); ok { + return rf(ctx, customerID, limit) + } + if rf, ok := ret.Get(0).(func(context.Context, string, int64) customer.Customer); ok { + r0 = rf(ctx, customerID, limit) + } else { + r0 = ret.Get(0).(customer.Customer) + } + + if rf, ok := ret.Get(1).(func(context.Context, string, int64) error); ok { + r1 = rf(ctx, customerID, limit) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// Repository_UpdateCreditMinByID_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'UpdateCreditMinByID' +type Repository_UpdateCreditMinByID_Call struct { + *mock.Call +} + +// UpdateCreditMinByID is a helper method to define mock.On call +// - ctx context.Context +// - customerID string +// - limit int64 +func (_e *Repository_Expecter) UpdateCreditMinByID(ctx interface{}, customerID interface{}, limit interface{}) *Repository_UpdateCreditMinByID_Call { + return &Repository_UpdateCreditMinByID_Call{Call: _e.mock.On("UpdateCreditMinByID", ctx, customerID, limit)} +} + +func (_c *Repository_UpdateCreditMinByID_Call) Run(run func(ctx context.Context, customerID string, limit int64)) *Repository_UpdateCreditMinByID_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context), args[1].(string), args[2].(int64)) + }) + return _c +} + +func (_c *Repository_UpdateCreditMinByID_Call) Return(_a0 customer.Customer, _a1 error) *Repository_UpdateCreditMinByID_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *Repository_UpdateCreditMinByID_Call) RunAndReturn(run func(context.Context, string, int64) (customer.Customer, error)) *Repository_UpdateCreditMinByID_Call { + _c.Call.Return(run) + return _c +} + // NewRepository creates a new instance of Repository. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. // The first argument is typically a *testing.T value. func NewRepository(t interface { diff --git a/billing/customer/service.go b/billing/customer/service.go index db0b40b09..450277c11 100644 --- a/billing/customer/service.go +++ b/billing/customer/service.go @@ -7,6 +7,8 @@ import ( "sync" "time" + "github.com/raystack/frontier/pkg/utils" + "github.com/robfig/cron/v3" "github.com/stripe/stripe-go/v79" @@ -28,23 +30,31 @@ type Repository interface { Create(ctx context.Context, customer Customer) (Customer, error) UpdateByID(ctx context.Context, customer Customer) (Customer, error) Delete(ctx context.Context, id string) error + UpdateCreditMinByID(ctx context.Context, customerID string, limit int64) (Customer, error) +} + +type CreditService interface { + GetBalance(ctx context.Context, id string) (int64, error) } type Service struct { - stripeClient *client.API - repository Repository + stripeClient *client.API + repository Repository + creditService CreditService syncJob *cron.Cron mu sync.Mutex syncDelay time.Duration } -func NewService(stripeClient *client.API, repository Repository, cfg billing.Config) *Service { +func NewService(stripeClient *client.API, repository Repository, cfg billing.Config, + creditService CreditService) *Service { return &Service{ - stripeClient: stripeClient, - repository: repository, - mu: sync.Mutex{}, - syncDelay: cfg.RefreshInterval.Customer, + stripeClient: stripeClient, + repository: repository, + mu: sync.Mutex{}, + syncDelay: cfg.RefreshInterval.Customer, + creditService: creditService, } } @@ -57,15 +67,25 @@ func (s *Service) Create(ctx context.Context, customer Customer, offline bool) ( // do not allow creating a new customer account if there exists already an active billing account existingAccounts, err := s.repository.List(ctx, Filter{ OrgID: customer.OrgID, - State: ActiveState, }) if err != nil { return Customer{}, err } - if len(existingAccounts) > 0 { + activeAccounts := utils.Filter(existingAccounts, func(i Customer) bool { + return i.State == ActiveState + }) + if len(activeAccounts) > 0 { return Customer{}, ErrActiveConflict } + // do not allow creating account if the balance of a previous account within org + // is less than 0 + for _, account := range existingAccounts { + if balance, err := s.creditService.GetBalance(ctx, account.ID); err == nil && balance < 0 { + return Customer{}, ErrExistingAccountWithPendingDues + } + } + // offline mode, we don't need to create the customer in billing provider if !offline { stripeCustomer, err := s.RegisterToProvider(ctx, customer) @@ -482,3 +502,7 @@ func (s *Service) TriggerSyncByProviderID(ctx context.Context, id string) error } return s.SyncWithProvider(ctx, customrs[0]) } + +func (s *Service) UpdateCreditMinByID(ctx context.Context, customerID string, limit int64) (Customer, error) { + return s.repository.UpdateCreditMinByID(ctx, customerID, limit) +} diff --git a/billing/customer/service_test.go b/billing/customer/service_test.go index 323aa58a7..3ca486a8f 100644 --- a/billing/customer/service_test.go +++ b/billing/customer/service_test.go @@ -18,16 +18,17 @@ import ( var sampleError = errors.New("sample error") -func mockService(t *testing.T) (*client.API, *stripemock.Backend, *mocks.Repository) { +func mockService(t *testing.T) (*client.API, *stripemock.Backend, *mocks.Repository, *mocks.CreditService) { t.Helper() mockRepository := mocks.NewRepository(t) mockBackend := stripemock.NewBackend(t) + mockCredit := mocks.NewCreditService(t) stripeClient := client.New("key_123", &stripe.Backends{ API: mockBackend, }) - return stripeClient, mockBackend, mockRepository + return stripeClient, mockBackend, mockRepository, mockCredit } func TestService_Create(t *testing.T) { @@ -57,11 +58,10 @@ func TestService_Create(t *testing.T) { want: customer.Customer{}, wantErr: customer.ErrActiveConflict, setup: func() *customer.Service { - stripeClient, _, mockRepo := mockService(t) + stripeClient, _, mockRepo, mockCredit := mockService(t) mockRepo.EXPECT().List(ctx, customer.Filter{ OrgID: "org1", - State: customer.ActiveState, }).Return([]customer.Customer{{ ID: "1", Name: "customer1", @@ -72,7 +72,39 @@ func TestService_Create(t *testing.T) { cfg := billing.Config{} - return customer.NewService(stripeClient, mockRepo, cfg) + return customer.NewService(stripeClient, mockRepo, cfg, mockCredit) + }, + }, + { + name: "should return error if customer with negative balance is found", + args: args{ + customer: customer.Customer{ + ID: "1", + Name: "customer1", + OrgID: "org1", + State: customer.ActiveState, + }, + offline: false, + }, + want: customer.Customer{}, + wantErr: customer.ErrExistingAccountWithPendingDues, + setup: func() *customer.Service { + stripeClient, _, mockRepo, mockCredit := mockService(t) + + mockRepo.EXPECT().List(ctx, customer.Filter{ + OrgID: "org1", + }).Return([]customer.Customer{{ + ID: "1", + Name: "customer1", + OrgID: "org1", + State: customer.DisabledState, + }, + }, nil) + mockCredit.EXPECT().GetBalance(ctx, "1").Return(int64(-100), nil) + + cfg := billing.Config{} + + return customer.NewService(stripeClient, mockRepo, cfg, mockCredit) }, }, { @@ -93,11 +125,10 @@ func TestService_Create(t *testing.T) { }, wantErr: nil, setup: func() *customer.Service { - stripeClient, mockStripeBackend, mockRepo := mockService(t) + stripeClient, mockStripeBackend, mockRepo, mockCredit := mockService(t) mockRepo.EXPECT().List(ctx, customer.Filter{ OrgID: "org1", - State: customer.ActiveState, }).Return([]customer.Customer{}, nil) // No existing active accounts mockStripeBackend.EXPECT().Call("POST", "/v1/customers", "key_123", @@ -137,7 +168,7 @@ func TestService_Create(t *testing.T) { cfg := billing.Config{} - return customer.NewService(stripeClient, mockRepo, cfg) + return customer.NewService(stripeClient, mockRepo, cfg, mockCredit) }, }, } @@ -186,7 +217,7 @@ func TestService_Update(t *testing.T) { }, wantErr: nil, setup: func() *customer.Service { - stripeClient, mockStripeBackend, mockRepo := mockService(t) + stripeClient, mockStripeBackend, mockRepo, mockCredit := mockService(t) mockRepo.EXPECT().GetByID(ctx, "1").Return(customer.Customer{ ID: "1", @@ -230,7 +261,7 @@ func TestService_Update(t *testing.T) { cfg := billing.Config{} - return customer.NewService(stripeClient, mockRepo, cfg) + return customer.NewService(stripeClient, mockRepo, cfg, mockCredit) }, }, { @@ -247,13 +278,13 @@ func TestService_Update(t *testing.T) { wantErr: sampleError, setup: func() *customer.Service { - stripeClient, _, mockRepo := mockService(t) + stripeClient, _, mockRepo, mockCredit := mockService(t) mockRepo.EXPECT().GetByID(ctx, "1").Return(customer.Customer{}, sampleError) cfg := billing.Config{} - return customer.NewService(stripeClient, mockRepo, cfg) + return customer.NewService(stripeClient, mockRepo, cfg, mockCredit) }, }, { @@ -268,7 +299,7 @@ func TestService_Update(t *testing.T) { want: customer.Customer{}, wantErr: sampleError, setup: func() *customer.Service { - stripeClient, mockStripeBackend, mockRepo := mockService(t) + stripeClient, mockStripeBackend, mockRepo, mockCredit := mockService(t) mockRepo.EXPECT().GetByID(ctx, "1").Return(customer.Customer{ ID: "1", @@ -301,7 +332,7 @@ func TestService_Update(t *testing.T) { cfg := billing.Config{} - return customer.NewService(stripeClient, mockRepo, cfg) + return customer.NewService(stripeClient, mockRepo, cfg, mockCredit) }, }, } @@ -346,7 +377,7 @@ func TestService_GetByID(t *testing.T) { }, wantErr: nil, setup: func() *customer.Service { - stripeClient, _, mockRepo := mockService(t) + stripeClient, _, mockRepo, mockCredit := mockService(t) mockRepo.EXPECT().GetByID(ctx, "1").Return( customer.Customer{ ID: "1", @@ -356,7 +387,7 @@ func TestService_GetByID(t *testing.T) { cfg := billing.Config{} - return customer.NewService(stripeClient, mockRepo, cfg) + return customer.NewService(stripeClient, mockRepo, cfg, mockCredit) }, }, { @@ -367,13 +398,13 @@ func TestService_GetByID(t *testing.T) { want: customer.Customer{}, wantErr: sampleError, setup: func() *customer.Service { - stripeClient, _, mockRepo := mockService(t) + stripeClient, _, mockRepo, mockCredit := mockService(t) mockRepo.EXPECT().GetByID(ctx, "1").Return( customer.Customer{}, sampleError) cfg := billing.Config{} - return customer.NewService(stripeClient, mockRepo, cfg) + return customer.NewService(stripeClient, mockRepo, cfg, mockCredit) }, }, } @@ -424,7 +455,7 @@ func TestService_List(t *testing.T) { }, wantErr: nil, setup: func() *customer.Service { - stripeClient, _, mockRepo := mockService(t) + stripeClient, _, mockRepo, mockCredit := mockService(t) mockRepo.EXPECT().List(ctx, customer.Filter{}).Return( []customer.Customer{ {ID: "1", @@ -440,7 +471,7 @@ func TestService_List(t *testing.T) { cfg := billing.Config{} - return customer.NewService(stripeClient, mockRepo, cfg) + return customer.NewService(stripeClient, mockRepo, cfg, mockCredit) }, }, { @@ -451,13 +482,13 @@ func TestService_List(t *testing.T) { want: []customer.Customer{}, wantErr: sampleError, setup: func() *customer.Service { - stripeClient, _, mockRepo := mockService(t) + stripeClient, _, mockRepo, mockCredit := mockService(t) mockRepo.EXPECT().List(ctx, customer.Filter{}).Return( []customer.Customer{}, sampleError) cfg := billing.Config{} - return customer.NewService(stripeClient, mockRepo, cfg) + return customer.NewService(stripeClient, mockRepo, cfg, mockCredit) }, }, } diff --git a/cmd/serve.go b/cmd/serve.go index 33d3cb2a8..da26c4d95 100644 --- a/cmd/serve.go +++ b/cmd/serve.go @@ -416,9 +416,10 @@ func buildAPIDependencies( } stripeClient := GetStripeClientFunc(logger, cfg) + creditService := credit.NewService(postgres.NewBillingTransactionRepository(dbc)) customerService := customer.NewService( stripeClient, - postgres.NewBillingCustomerRepository(dbc), cfg.Billing) + postgres.NewBillingCustomerRepository(dbc), cfg.Billing, creditService) productService := product.NewService( stripeClient, postgres.NewBillingProductRepository(dbc), @@ -430,7 +431,6 @@ func buildAPIDependencies( postgres.NewBillingPlanRepository(dbc), productService, ) - creditService := credit.NewService(postgres.NewBillingTransactionRepository(dbc)) subscriptionService := subscription.NewService( stripeClient, cfg.Billing, postgres.NewBillingSubscriptionRepository(dbc), diff --git a/internal/api/v1beta1/billing_customer.go b/internal/api/v1beta1/billing_customer.go index 9b8906cfa..aad0834c1 100644 --- a/internal/api/v1beta1/billing_customer.go +++ b/internal/api/v1beta1/billing_customer.go @@ -11,7 +11,6 @@ import ( "google.golang.org/grpc/codes" "google.golang.org/grpc/status" - grpczap "github.com/grpc-ecosystem/go-grpc-middleware/logging/zap/ctxzap" "github.com/raystack/frontier/billing/customer" "github.com/raystack/frontier/pkg/metadata" frontierv1beta1 "github.com/raystack/frontier/proto/v1beta1" @@ -32,6 +31,7 @@ type CustomerService interface { RegisterToProviderIfRequired(ctx context.Context, customerID string) (customer.Customer, error) Disable(ctx context.Context, id string) error Enable(ctx context.Context, id string) error + UpdateCreditMinByID(ctx context.Context, customerID string, limit int64) (customer.Customer, error) } func (h Handler) CreateBillingAccount(ctx context.Context, request *frontierv1beta1.CreateBillingAccountRequest) (*frontierv1beta1.CreateBillingAccountResponse, error) { @@ -134,8 +134,6 @@ func (h Handler) ListBillingAccounts(ctx context.Context, request *frontierv1bet } func (h Handler) GetBillingAccount(ctx context.Context, request *frontierv1beta1.GetBillingAccountRequest) (*frontierv1beta1.GetBillingAccountResponse, error) { - logger := grpczap.Extract(ctx) - customerOb, err := h.customerService.GetByID(ctx, request.GetId()) if err != nil { if errors.Is(err, customer.ErrNotFound) { @@ -148,13 +146,11 @@ func (h Handler) GetBillingAccount(ctx context.Context, request *frontierv1beta1 if request.GetWithPaymentMethods() { pms, err := h.customerService.ListPaymentMethods(ctx, request.GetId()) if err != nil { - logger.Error(err.Error()) return nil, err } for _, v := range pms { pmPB, err := transformPaymentMethodToPB(v) if err != nil { - logger.Error(err.Error()) return nil, err } paymentMethodsPbs = append(paymentMethodsPbs, pmPB) @@ -163,7 +159,6 @@ func (h Handler) GetBillingAccount(ctx context.Context, request *frontierv1beta1 customerPB, err := transformCustomerToPB(customerOb) if err != nil { - logger.Error(err.Error()) return nil, err } return &frontierv1beta1.GetBillingAccountResponse{ @@ -173,11 +168,8 @@ func (h Handler) GetBillingAccount(ctx context.Context, request *frontierv1beta1 } func (h Handler) DeleteBillingAccount(ctx context.Context, request *frontierv1beta1.DeleteBillingAccountRequest) (*frontierv1beta1.DeleteBillingAccountResponse, error) { - logger := grpczap.Extract(ctx) - err := h.customerService.Delete(ctx, request.GetId()) if err != nil { - logger.Error(err.Error()) return nil, err } @@ -185,11 +177,8 @@ func (h Handler) DeleteBillingAccount(ctx context.Context, request *frontierv1be } func (h Handler) GetBillingBalance(ctx context.Context, request *frontierv1beta1.GetBillingBalanceRequest) (*frontierv1beta1.GetBillingBalanceResponse, error) { - logger := grpczap.Extract(ctx) - balanceAmount, err := h.creditService.GetBalance(ctx, request.GetId()) if err != nil { - logger.Error(err.Error()) return nil, err } @@ -369,6 +358,16 @@ func (h Handler) HasTrialed(ctx context.Context, request *frontierv1beta1.HasTri }, nil } +func (h Handler) UpdateBillingAccountLimits(ctx context.Context, + request *frontierv1beta1.UpdateBillingAccountLimitsRequest) (*frontierv1beta1.UpdateBillingAccountLimitsResponse, error) { + _, err := h.customerService.UpdateCreditMinByID(ctx, request.GetId(), request.GetCreditMin()) + if err != nil { + return nil, err + } + + return &frontierv1beta1.UpdateBillingAccountLimitsResponse{}, nil +} + func transformPaymentMethodToPB(pm customer.PaymentMethod) (*frontierv1beta1.PaymentMethod, error) { metaData, err := pm.Metadata.ToStructPB() if err != nil { diff --git a/internal/api/v1beta1/mocks/customer_service.go b/internal/api/v1beta1/mocks/customer_service.go index dca3ac11a..899bc0c81 100644 --- a/internal/api/v1beta1/mocks/customer_service.go +++ b/internal/api/v1beta1/mocks/customer_service.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.38.0. DO NOT EDIT. +// Code generated by mockery v2.45.0. DO NOT EDIT. package mocks @@ -510,6 +510,64 @@ func (_c *CustomerService_Update_Call) RunAndReturn(run func(context.Context, cu return _c } +// UpdateCreditMinByID provides a mock function with given fields: ctx, customerID, limit +func (_m *CustomerService) UpdateCreditMinByID(ctx context.Context, customerID string, limit int64) (customer.Customer, error) { + ret := _m.Called(ctx, customerID, limit) + + if len(ret) == 0 { + panic("no return value specified for UpdateCreditMinByID") + } + + var r0 customer.Customer + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, string, int64) (customer.Customer, error)); ok { + return rf(ctx, customerID, limit) + } + if rf, ok := ret.Get(0).(func(context.Context, string, int64) customer.Customer); ok { + r0 = rf(ctx, customerID, limit) + } else { + r0 = ret.Get(0).(customer.Customer) + } + + if rf, ok := ret.Get(1).(func(context.Context, string, int64) error); ok { + r1 = rf(ctx, customerID, limit) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// CustomerService_UpdateCreditMinByID_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'UpdateCreditMinByID' +type CustomerService_UpdateCreditMinByID_Call struct { + *mock.Call +} + +// UpdateCreditMinByID is a helper method to define mock.On call +// - ctx context.Context +// - customerID string +// - limit int64 +func (_e *CustomerService_Expecter) UpdateCreditMinByID(ctx interface{}, customerID interface{}, limit interface{}) *CustomerService_UpdateCreditMinByID_Call { + return &CustomerService_UpdateCreditMinByID_Call{Call: _e.mock.On("UpdateCreditMinByID", ctx, customerID, limit)} +} + +func (_c *CustomerService_UpdateCreditMinByID_Call) Run(run func(ctx context.Context, customerID string, limit int64)) *CustomerService_UpdateCreditMinByID_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context), args[1].(string), args[2].(int64)) + }) + return _c +} + +func (_c *CustomerService_UpdateCreditMinByID_Call) Return(_a0 customer.Customer, _a1 error) *CustomerService_UpdateCreditMinByID_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *CustomerService_UpdateCreditMinByID_Call) RunAndReturn(run func(context.Context, string, int64) (customer.Customer, error)) *CustomerService_UpdateCreditMinByID_Call { + _c.Call.Return(run) + return _c +} + // NewCustomerService creates a new instance of CustomerService. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. // The first argument is typically a *testing.T value. func NewCustomerService(t interface { diff --git a/internal/store/postgres/billing_customer_repository.go b/internal/store/postgres/billing_customer_repository.go index 4778702d2..fa7e82923 100644 --- a/internal/store/postgres/billing_customer_repository.go +++ b/internal/store/postgres/billing_customer_repository.go @@ -41,13 +41,14 @@ type Customer struct { OrgID string `db:"org_id"` ProviderID *string `db:"provider_id"` // this could be empty if the customer is created as offline - Name string `db:"name"` - Email string `db:"email"` - Phone *string `db:"phone"` - Currency string `db:"currency"` - Address types.NullJSONText `db:"address"` - Metadata types.NullJSONText `db:"metadata"` - Tax Tax `db:"tax"` + Name string `db:"name"` + Email string `db:"email"` + Phone *string `db:"phone"` + Currency string `db:"currency"` + Address types.NullJSONText `db:"address"` + Metadata types.NullJSONText `db:"metadata"` + Tax Tax `db:"tax"` + CreditMin int64 `db:"credit_min"` State string `db:"state"` CreatedAt time.Time `db:"created_at"` @@ -93,6 +94,7 @@ func (c Customer) transform() (customer.Customer, error) { Currency: c.Currency, Address: unmarshalledAddress, TaxData: customerTax, + CreditMin: c.CreditMin, Metadata: unmarshalledMetadata, State: customer.State(c.State), CreatedAt: c.CreatedAt, @@ -141,7 +143,8 @@ func (r BillingCustomerRepository) Create(ctx context.Context, toCreate customer "tax": Tax{ TaxIDs: toCreate.TaxData, }, - "metadata": marshaledMetadata, + "credit_min": toCreate.CreditMin, + "metadata": marshaledMetadata, }).Returning(&Customer{}).ToSQL() if err != nil { return customer.Customer{}, fmt.Errorf("%w: %s", parseErr, err) @@ -283,6 +286,39 @@ func (r BillingCustomerRepository) UpdateByID(ctx context.Context, toUpdate cust return customerModel.transform() } +func (r BillingCustomerRepository) UpdateCreditMinByID(ctx context.Context, customerID string, limit int64) (customer.Customer, error) { + if strings.TrimSpace(customerID) == "" { + return customer.Customer{}, customer.ErrInvalidID + } + updateRecord := goqu.Record{ + "credit_min": limit, + "updated_at": goqu.L("now()"), + } + query, params, err := dialect.Update(TABLE_BILLING_CUSTOMERS).Set(updateRecord).Where(goqu.Ex{ + "id": customerID, + }).Returning(&Customer{}).ToSQL() + if err != nil { + return customer.Customer{}, fmt.Errorf("%w: %s", queryErr, err) + } + + var customerModel Customer + if err = r.dbc.WithTimeout(ctx, TABLE_BILLING_CUSTOMERS, "Update", func(ctx context.Context) error { + return r.dbc.QueryRowxContext(ctx, query, params...).StructScan(&customerModel) + }); err != nil { + err = checkPostgresError(err) + switch { + case errors.Is(err, sql.ErrNoRows): + return customer.Customer{}, customer.ErrNotFound + case errors.Is(err, ErrInvalidTextRepresentation): + return customer.Customer{}, customer.ErrInvalidUUID + default: + return customer.Customer{}, fmt.Errorf("%s: %w", txnErr, err) + } + } + + return customerModel.transform() +} + func (r BillingCustomerRepository) Delete(ctx context.Context, id string) error { stmt := dialect.Delete(TABLE_BILLING_CUSTOMERS).Where(goqu.Ex{ "id": id, diff --git a/internal/store/postgres/billing_transactions_repository.go b/internal/store/postgres/billing_transactions_repository.go index 97d012213..2d2e08525 100644 --- a/internal/store/postgres/billing_transactions_repository.go +++ b/internal/store/postgres/billing_transactions_repository.go @@ -9,6 +9,9 @@ import ( "strings" "time" + "github.com/raystack/frontier/billing/customer" + "github.com/raystack/frontier/internal/bootstrap/schema" + "github.com/jackc/pgconn" "github.com/jmoiron/sqlx" @@ -67,17 +70,29 @@ func (c Transaction) transform() (credit.Transaction, error) { } type BillingTransactionRepository struct { - dbc *db.Client + dbc *db.Client + customerRepo *BillingCustomerRepository } func NewBillingTransactionRepository(dbc *db.Client) *BillingTransactionRepository { return &BillingTransactionRepository{ - dbc: dbc, + dbc: dbc, + customerRepo: NewBillingCustomerRepository(dbc), } } func (r BillingTransactionRepository) CreateEntry(ctx context.Context, debitEntry credit.Transaction, creditEntry credit.Transaction) ([]credit.Transaction, error) { + var customerAcc customer.Customer + var err error + if debitEntry.CustomerID != schema.PlatformOrgID.String() { + // only fetch if it's a customer debit entry + customerAcc, err = r.customerRepo.GetByID(ctx, debitEntry.CustomerID) + if err != nil { + return nil, fmt.Errorf("failed to get customer account: %w", err) + } + } + if debitEntry.Metadata == nil { debitEntry.Metadata = make(map[string]any) } @@ -124,6 +139,17 @@ func (r BillingTransactionRepository) CreateEntry(ctx context.Context, debitEntr var creditReturnedEntry, debitReturnedEntry credit.Transaction if err := r.dbc.WithTxn(ctx, sql.TxOptions{}, func(tx *sqlx.Tx) error { + // check if balance is enough if it's a customer entry + if customerAcc.ID != "" { + currentBalance, err := r.getBalanceInTx(ctx, tx, customerAcc.ID) + if err != nil { + return fmt.Errorf("failed to apply transaction: %w", err) + } + if err := isSufficientBalance(customerAcc.CreditMin, currentBalance, debitEntry.Amount); err != nil { + return err + } + } + var debitModel Transaction var creditModel Transaction query, params, err := dialect.Insert(TABLE_BILLING_TRANSACTIONS).Rows(debitRecord).Returning(&Transaction{}).ToSQL() @@ -164,12 +190,31 @@ func (r BillingTransactionRepository) CreateEntry(ctx context.Context, debitEntr return nil }); err != nil { + if errors.Is(err, credit.ErrAlreadyApplied) { + return nil, credit.ErrAlreadyApplied + } else if errors.Is(err, credit.ErrInsufficientCredits) { + return nil, credit.ErrInsufficientCredits + } return nil, fmt.Errorf("failed to create transaction entry: %w", err) } return []credit.Transaction{debitReturnedEntry, creditReturnedEntry}, nil } +// isSufficientBalance checks if the customer has enough balance to perform the transaction. +// If the customer has a credit min limit set, then a negative balance means loaner/overdraft limit and +// a positive limit mean at least that much balance should be there in the account. +func isSufficientBalance(customerMinLimit int64, currentBalance int64, txAmount int64) error { + if customerMinLimit < 0 { + if currentBalance-customerMinLimit < txAmount { + return credit.ErrInsufficientCredits + } + } else if currentBalance < txAmount+customerMinLimit { + return credit.ErrInsufficientCredits + } + return nil +} + func (r BillingTransactionRepository) GetByID(ctx context.Context, id string) (credit.Transaction, error) { stmt := dialect.Select().From(TABLE_BILLING_TRANSACTIONS).Where(goqu.Ex{ "id": id, @@ -271,49 +316,77 @@ func (r BillingTransactionRepository) List(ctx context.Context, filter credit.Fi return transactions, nil } -// GetBalance currently sums all transactions for a customer and returns the balance. -// Ideally to speed this up we should create another table transaction_statement which -// will in batch compute the monthly summary for each customer, and then we can just -// query that table to get the balance since last month end date and add it to the entries -// in transaction table till now. -func (r BillingTransactionRepository) GetBalance(ctx context.Context, accountID string) (int64, error) { +func (r BillingTransactionRepository) getDebitBalance(ctx context.Context, tx *sqlx.Tx, accountID string) (*int64, error) { stmt := dialect.Select(goqu.SUM("amount")).From(TABLE_BILLING_TRANSACTIONS).Where(goqu.Ex{ "account_id": accountID, "type": credit.DebitType, }) query, params, err := stmt.ToSQL() if err != nil { - return 0, fmt.Errorf("%w: %s", parseErr, err) + return nil, fmt.Errorf("%w: %s", parseErr, err) } var debitBalance *int64 - if err = r.dbc.WithTimeout(ctx, TABLE_BILLING_TRANSACTIONS, "GetBalance", func(ctx context.Context) error { - return r.dbc.QueryRowxContext(ctx, query, params...).Scan(&debitBalance) + if err = r.dbc.WithTimeout(ctx, TABLE_BILLING_TRANSACTIONS, "GetDebitBalance", func(ctx context.Context) error { + return tx.QueryRowxContext(ctx, query, params...).Scan(&debitBalance) }); err != nil { - return 0, fmt.Errorf("%w: %s", dbErr, err) + return nil, fmt.Errorf("%w: %s", dbErr, err) } + return debitBalance, nil +} - stmt = dialect.Select(goqu.SUM("amount")).From(TABLE_BILLING_TRANSACTIONS).Where(goqu.Ex{ +func (r BillingTransactionRepository) getCreditBalance(ctx context.Context, tx *sqlx.Tx, accountID string) (*int64, error) { + stmt := dialect.Select(goqu.SUM("amount")).From(TABLE_BILLING_TRANSACTIONS).Where(goqu.Ex{ "account_id": accountID, "type": credit.CreditType, }) - query, params, err = stmt.ToSQL() + query, params, err := stmt.ToSQL() if err != nil { - return 0, fmt.Errorf("%w: %s", parseErr, err) + return nil, fmt.Errorf("%w: %s", parseErr, err) } var creditBalance *int64 - if err = r.dbc.WithTimeout(ctx, TABLE_BILLING_TRANSACTIONS, "GetBalance", func(ctx context.Context) error { - return r.dbc.QueryRowxContext(ctx, query, params...).Scan(&creditBalance) + if err = r.dbc.WithTimeout(ctx, TABLE_BILLING_TRANSACTIONS, "GetCreditBalance", func(ctx context.Context) error { + return tx.QueryRowxContext(ctx, query, params...).Scan(&creditBalance) }); err != nil { - return 0, fmt.Errorf("%w: %s", dbErr, err) + return nil, fmt.Errorf("%w: %s", dbErr, err) } + return creditBalance, nil +} +func (r BillingTransactionRepository) getBalanceInTx(ctx context.Context, tx *sqlx.Tx, accountID string) (int64, error) { + var creditBalance *int64 + var debitBalance *int64 + + var err error + if debitBalance, err = r.getDebitBalance(ctx, tx, accountID); err != nil { + return 0, fmt.Errorf("failed to get debit balance: %w", err) + } + if creditBalance, err = r.getCreditBalance(ctx, tx, accountID); err != nil { + return 0, fmt.Errorf("failed to get credit balance: %w", err) + } if creditBalance == nil { creditBalance = new(int64) } if debitBalance == nil { debitBalance = new(int64) } - return max(*creditBalance-*debitBalance, 0), nil + return *creditBalance - *debitBalance, nil +} + +// GetBalance currently sums all transactions for a customer and returns the balance. +// Ideally to speed this up we should create another table transaction_statement which +// will in batch compute the monthly summary for each customer, and then we can just +// query that table to get the balance since last month end date and add it to the entries +// in transaction table till now. +func (r BillingTransactionRepository) GetBalance(ctx context.Context, accountID string) (int64, error) { + var amount int64 + if err := r.dbc.WithTxn(ctx, sql.TxOptions{}, func(tx *sqlx.Tx) error { + var err error + amount, err = r.getBalanceInTx(ctx, tx, accountID) + return err + }); err != nil { + return 0, fmt.Errorf("failed to get balance: %w", err) + } + return amount, nil } diff --git a/internal/store/postgres/billing_transactions_repository_test.go b/internal/store/postgres/billing_transactions_repository_test.go new file mode 100644 index 000000000..39e4884e0 --- /dev/null +++ b/internal/store/postgres/billing_transactions_repository_test.go @@ -0,0 +1,90 @@ +package postgres + +import ( + "fmt" + "testing" + + "github.com/stretchr/testify/assert" +) + +func Test_isSufficientBalance(t *testing.T) { + type args struct { + customerMinLimit int64 + currentBalance int64 + txAmount int64 + } + tests := []struct { + name string + args args + wantErr assert.ErrorAssertionFunc + }{ + { + name: "sufficient balance with 0 limit", + args: args{ + customerMinLimit: 0, + currentBalance: 1000, + txAmount: 100, + }, + wantErr: assert.NoError, + }, + { + name: "sufficient balance with positive limit", + args: args{ + customerMinLimit: 100, + currentBalance: 1000, + txAmount: 100, + }, + wantErr: assert.NoError, + }, + { + name: "sufficient balance with negative limit", + args: args{ + customerMinLimit: -100, + currentBalance: 1000, + txAmount: 100, + }, + wantErr: assert.NoError, + }, + { + name: "insufficient balance with positive limit", + args: args{ + customerMinLimit: 100, + currentBalance: 80, + txAmount: 100, + }, + wantErr: assert.Error, + }, + { + name: "insufficient balance with 0 limit", + args: args{ + customerMinLimit: 0, + currentBalance: 80, + txAmount: 100, + }, + wantErr: assert.Error, + }, + { + name: "insufficient balance with sufficient negative limit", + args: args{ + customerMinLimit: -100, + currentBalance: 80, + txAmount: 100, + }, + wantErr: assert.NoError, + }, + { + name: "insufficient balance with insufficient negative limit", + args: args{ + customerMinLimit: -100, + currentBalance: 80, + txAmount: 200, + }, + wantErr: assert.Error, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + tt.wantErr(t, isSufficientBalance(tt.args.customerMinLimit, tt.args.currentBalance, tt.args.txAmount), fmt.Sprintf("isSufficientBalance(%v, %v, %v)", tt.args.customerMinLimit, tt.args.currentBalance, tt.args.txAmount)) + }) + } +} diff --git a/internal/store/postgres/migrations/20240917183506_billing_customer_credit_min.down.sql b/internal/store/postgres/migrations/20240917183506_billing_customer_credit_min.down.sql new file mode 100644 index 000000000..c7c3fac3f --- /dev/null +++ b/internal/store/postgres/migrations/20240917183506_billing_customer_credit_min.down.sql @@ -0,0 +1 @@ +ALTER TABLE billing_customers DROP COLUMN IF EXISTS credit_min; diff --git a/internal/store/postgres/migrations/20240917183506_billing_customer_credit_min.up.sql b/internal/store/postgres/migrations/20240917183506_billing_customer_credit_min.up.sql new file mode 100644 index 000000000..728a4c5c6 --- /dev/null +++ b/internal/store/postgres/migrations/20240917183506_billing_customer_credit_min.up.sql @@ -0,0 +1 @@ +ALTER TABLE billing_customers ADD COLUMN IF NOT EXISTS credit_min int8 DEFAULT 0; diff --git a/pkg/server/interceptors/authorization.go b/pkg/server/interceptors/authorization.go index 5eb796cac..ec64b738d 100644 --- a/pkg/server/interceptors/authorization.go +++ b/pkg/server/interceptors/authorization.go @@ -951,6 +951,9 @@ var authorizationValidationMap = map[string]func(ctx context.Context, handler *v "/raystack.frontier.v1beta1.AdminService/ListAllBillingAccounts": func(ctx context.Context, handler *v1beta1.Handler, req any) error { return handler.IsSuperUser(ctx) }, + "/raystack.frontier.v1beta1.AdminService/UpdateBillingAccountLimits": func(ctx context.Context, handler *v1beta1.Handler, req any) error { + return handler.IsSuperUser(ctx) + }, "/raystack.frontier.v1beta1.AdminService/RevertBillingUsage": func(ctx context.Context, handler *v1beta1.Handler, req any) error { return handler.IsAuthorized(ctx, relation.Object{Namespace: schema.PlatformNamespace, ID: schema.PlatformID}, schema.PlatformCheckPermission) }, diff --git a/proto/apidocs.swagger.yaml b/proto/apidocs.swagger.yaml index 9ab16a35f..79eb98dc4 100644 --- a/proto/apidocs.swagger.yaml +++ b/proto/apidocs.swagger.yaml @@ -431,6 +431,64 @@ paths: title: amount should be equal or less than the usage amount tags: - Billing + /v1beta1/admin/organizations/{org_id}/billing/{id}/limits: + put: + summary: Update billing account limits + description: Update billing account limits. + operationId: AdminService_UpdateBillingAccountLimits + responses: + "200": + description: A successful response. + schema: + $ref: '#/definitions/v1beta1UpdateBillingAccountLimitsResponse' + "400": + description: Bad Request - The request was malformed or contained invalid parameters. + schema: + $ref: '#/definitions/rpcStatus' + "401": + description: Unauthorized - Authentication is required + schema: + $ref: '#/definitions/rpcStatus' + "403": + description: Forbidden - User does not have permission to access the resource + schema: + $ref: '#/definitions/rpcStatus' + "404": + description: Not Found - The requested resource was not found + schema: + $ref: '#/definitions/rpcStatus' + "500": + description: Internal Server Error. Returned when theres is something wrong with Frontier server. + schema: + $ref: '#/definitions/rpcStatus' + default: + description: An unexpected error response. + schema: + $ref: '#/definitions/rpcStatus' + parameters: + - name: org_id + in: path + required: true + type: string + - name: id + in: path + required: true + type: string + - name: body + in: body + required: true + schema: + type: object + properties: + credit_min: + type: string + format: int64 + title: |- + credit_min is the minimum credit limit for the billing account + default is 0, negative numbers work as overdraft, positive + numbers work as minimum purchase limit + tags: + - Billing /v1beta1/admin/organizations/{org_id}/billing/checkouts: post: summary: Checkout a product or subscription @@ -12519,6 +12577,8 @@ definitions: plan: $ref: '#/definitions/v1beta1Plan' readOnly: true + v1beta1UpdateBillingAccountLimitsResponse: + type: object v1beta1UpdateBillingAccountResponse: type: object properties: diff --git a/proto/v1beta1/admin.pb.go b/proto/v1beta1/admin.pb.go index 7cc315e1c..c09ed4033 100644 --- a/proto/v1beta1/admin.pb.go +++ b/proto/v1beta1/admin.pb.go @@ -2862,6 +2862,110 @@ func (x *ListWebhooksResponse) GetWebhooks() []*Webhook { return nil } +type UpdateBillingAccountLimitsRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + OrgId string `protobuf:"bytes,1,opt,name=org_id,json=orgId,proto3" json:"org_id,omitempty"` + Id string `protobuf:"bytes,2,opt,name=id,proto3" json:"id,omitempty"` + // credit_min is the minimum credit limit for the billing account + // default is 0, negative numbers work as overdraft, positive + // numbers work as minimum purchase limit + CreditMin int64 `protobuf:"varint,3,opt,name=credit_min,json=creditMin,proto3" json:"credit_min,omitempty"` +} + +func (x *UpdateBillingAccountLimitsRequest) Reset() { + *x = UpdateBillingAccountLimitsRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_raystack_frontier_v1beta1_admin_proto_msgTypes[54] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *UpdateBillingAccountLimitsRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UpdateBillingAccountLimitsRequest) ProtoMessage() {} + +func (x *UpdateBillingAccountLimitsRequest) ProtoReflect() protoreflect.Message { + mi := &file_raystack_frontier_v1beta1_admin_proto_msgTypes[54] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use UpdateBillingAccountLimitsRequest.ProtoReflect.Descriptor instead. +func (*UpdateBillingAccountLimitsRequest) Descriptor() ([]byte, []int) { + return file_raystack_frontier_v1beta1_admin_proto_rawDescGZIP(), []int{54} +} + +func (x *UpdateBillingAccountLimitsRequest) GetOrgId() string { + if x != nil { + return x.OrgId + } + return "" +} + +func (x *UpdateBillingAccountLimitsRequest) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +func (x *UpdateBillingAccountLimitsRequest) GetCreditMin() int64 { + if x != nil { + return x.CreditMin + } + return 0 +} + +type UpdateBillingAccountLimitsResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *UpdateBillingAccountLimitsResponse) Reset() { + *x = UpdateBillingAccountLimitsResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_raystack_frontier_v1beta1_admin_proto_msgTypes[55] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *UpdateBillingAccountLimitsResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UpdateBillingAccountLimitsResponse) ProtoMessage() {} + +func (x *UpdateBillingAccountLimitsResponse) ProtoReflect() protoreflect.Message { + mi := &file_raystack_frontier_v1beta1_admin_proto_msgTypes[55] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use UpdateBillingAccountLimitsResponse.ProtoReflect.Descriptor instead. +func (*UpdateBillingAccountLimitsResponse) Descriptor() ([]byte, []int) { + return file_raystack_frontier_v1beta1_admin_proto_rawDescGZIP(), []int{55} +} + var File_raystack_frontier_v1beta1_admin_proto protoreflect.FileDescriptor var file_raystack_frontier_v1beta1_admin_proto_rawDesc = []byte{ @@ -3401,365 +3505,397 @@ var file_raystack_frontier_v1beta1_admin_proto_rawDesc = []byte{ 0x3e, 0x0a, 0x08, 0x77, 0x65, 0x62, 0x68, 0x6f, 0x6f, 0x6b, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x66, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x57, 0x65, - 0x62, 0x68, 0x6f, 0x6f, 0x6b, 0x52, 0x08, 0x77, 0x65, 0x62, 0x68, 0x6f, 0x6f, 0x6b, 0x73, 0x32, - 0xbd, 0x39, 0x0a, 0x0c, 0x41, 0x64, 0x6d, 0x69, 0x6e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, - 0x12, 0xaf, 0x02, 0x0a, 0x0c, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x6c, 0x6c, 0x55, 0x73, 0x65, 0x72, - 0x73, 0x12, 0x2e, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x66, 0x72, 0x6f, - 0x6e, 0x74, 0x69, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4c, 0x69, - 0x73, 0x74, 0x41, 0x6c, 0x6c, 0x55, 0x73, 0x65, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x1a, 0x2f, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x66, 0x72, 0x6f, - 0x6e, 0x74, 0x69, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4c, 0x69, - 0x73, 0x74, 0x41, 0x6c, 0x6c, 0x55, 0x73, 0x65, 0x72, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x22, 0xbd, 0x01, 0x92, 0x41, 0x9d, 0x01, 0x0a, 0x04, 0x55, 0x73, 0x65, 0x72, 0x12, - 0x0e, 0x4c, 0x69, 0x73, 0x74, 0x20, 0x61, 0x6c, 0x6c, 0x20, 0x75, 0x73, 0x65, 0x72, 0x73, 0x1a, - 0x84, 0x01, 0x4c, 0x69, 0x73, 0x74, 0x73, 0x20, 0x61, 0x6c, 0x6c, 0x20, 0x74, 0x68, 0x65, 0x20, - 0x75, 0x73, 0x65, 0x72, 0x73, 0x20, 0x66, 0x72, 0x6f, 0x6d, 0x20, 0x61, 0x6c, 0x6c, 0x20, 0x74, - 0x68, 0x65, 0x20, 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, - 0x20, 0x69, 0x6e, 0x20, 0x61, 0x20, 0x46, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x20, 0x69, - 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x2e, 0x20, 0x49, 0x74, 0x20, 0x63, 0x61, 0x6e, 0x20, - 0x62, 0x65, 0x20, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x65, 0x64, 0x20, 0x62, 0x79, 0x20, 0x6b, - 0x65, 0x79, 0x77, 0x6f, 0x72, 0x64, 0x2c, 0x20, 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x2c, 0x20, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x20, 0x61, 0x6e, 0x64, 0x20, - 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x16, 0x12, 0x14, 0x2f, 0x76, - 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x2f, 0x75, 0x73, 0x65, - 0x72, 0x73, 0x12, 0x9c, 0x02, 0x0a, 0x0a, 0x4c, 0x69, 0x73, 0x74, 0x47, 0x72, 0x6f, 0x75, 0x70, - 0x73, 0x12, 0x2c, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x66, 0x72, 0x6f, - 0x6e, 0x74, 0x69, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4c, 0x69, - 0x73, 0x74, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, - 0x2d, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x66, 0x72, 0x6f, 0x6e, 0x74, - 0x69, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, - 0x47, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xb0, - 0x01, 0x92, 0x41, 0x8f, 0x01, 0x0a, 0x05, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x12, 0x0f, 0x4c, 0x69, - 0x73, 0x74, 0x20, 0x61, 0x6c, 0x6c, 0x20, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x1a, 0x75, 0x4c, - 0x69, 0x73, 0x74, 0x73, 0x20, 0x61, 0x6c, 0x6c, 0x20, 0x74, 0x68, 0x65, 0x20, 0x67, 0x72, 0x6f, - 0x75, 0x70, 0x73, 0x20, 0x66, 0x72, 0x6f, 0x6d, 0x20, 0x61, 0x6c, 0x6c, 0x20, 0x74, 0x68, 0x65, - 0x20, 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x69, - 0x6e, 0x20, 0x61, 0x20, 0x46, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x20, 0x69, 0x6e, 0x73, - 0x74, 0x61, 0x6e, 0x63, 0x65, 0x2e, 0x20, 0x49, 0x74, 0x20, 0x63, 0x61, 0x6e, 0x20, 0x62, 0x65, - 0x20, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x65, 0x64, 0x20, 0x62, 0x79, 0x20, 0x6f, 0x72, 0x67, - 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x73, 0x74, - 0x61, 0x74, 0x65, 0x2e, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x17, 0x12, 0x15, 0x2f, 0x76, 0x31, 0x62, - 0x65, 0x74, 0x61, 0x31, 0x2f, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x2f, 0x67, 0x72, 0x6f, 0x75, 0x70, - 0x73, 0x12, 0xb3, 0x02, 0x0a, 0x14, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x6c, 0x6c, 0x4f, 0x72, 0x67, - 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x36, 0x2e, 0x72, 0x61, 0x79, - 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x66, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x2e, 0x76, - 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x6c, 0x6c, 0x4f, 0x72, - 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x1a, 0x37, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x66, 0x72, - 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4c, - 0x69, 0x73, 0x74, 0x41, 0x6c, 0x6c, 0x4f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xa9, 0x01, 0x92, 0x41, - 0x81, 0x01, 0x0a, 0x0c, 0x4f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x12, 0x16, 0x4c, 0x69, 0x73, 0x74, 0x20, 0x61, 0x6c, 0x6c, 0x20, 0x6f, 0x72, 0x67, 0x61, 0x6e, - 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x1a, 0x59, 0x4c, 0x69, 0x73, 0x74, 0x73, 0x20, - 0x61, 0x6c, 0x6c, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x69, 0x6e, 0x20, 0x61, 0x20, 0x46, 0x72, 0x6f, 0x6e, 0x74, - 0x69, 0x65, 0x72, 0x20, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x2e, 0x20, 0x49, 0x74, - 0x20, 0x63, 0x61, 0x6e, 0x20, 0x62, 0x65, 0x20, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x65, 0x64, - 0x20, 0x62, 0x79, 0x20, 0x75, 0x73, 0x65, 0x72, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x73, 0x74, 0x61, - 0x74, 0x65, 0x2e, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1e, 0x12, 0x1c, 0x2f, 0x76, 0x31, 0x62, 0x65, - 0x74, 0x61, 0x31, 0x2f, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x2f, 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x69, - 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0xaa, 0x02, 0x0a, 0x0c, 0x4c, 0x69, 0x73, 0x74, - 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x12, 0x2e, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, + 0x62, 0x68, 0x6f, 0x6f, 0x6b, 0x52, 0x08, 0x77, 0x65, 0x62, 0x68, 0x6f, 0x6f, 0x6b, 0x73, 0x22, + 0x7f, 0x0a, 0x21, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x42, 0x69, 0x6c, 0x6c, 0x69, 0x6e, 0x67, + 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x73, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x12, 0x1e, 0x0a, 0x06, 0x6f, 0x72, 0x67, 0x5f, 0x69, 0x64, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xfa, 0x42, 0x04, 0x72, 0x02, 0x10, 0x03, 0x52, 0x05, 0x6f, + 0x72, 0x67, 0x49, 0x64, 0x12, 0x1b, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, + 0x42, 0x0b, 0xfa, 0x42, 0x08, 0x72, 0x06, 0xd0, 0x01, 0x01, 0xb0, 0x01, 0x01, 0x52, 0x02, 0x69, + 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x5f, 0x6d, 0x69, 0x6e, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x4d, 0x69, 0x6e, + 0x22, 0x24, 0x0a, 0x22, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x42, 0x69, 0x6c, 0x6c, 0x69, 0x6e, + 0x67, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x73, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x32, 0xeb, 0x3b, 0x0a, 0x0c, 0x41, 0x64, 0x6d, 0x69, 0x6e, + 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0xaf, 0x02, 0x0a, 0x0c, 0x4c, 0x69, 0x73, 0x74, + 0x41, 0x6c, 0x6c, 0x55, 0x73, 0x65, 0x72, 0x73, 0x12, 0x2e, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x66, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, - 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, + 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x6c, 0x6c, 0x55, 0x73, 0x65, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2f, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x66, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, - 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, - 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xb8, 0x01, 0x92, 0x41, 0x95, 0x01, - 0x0a, 0x07, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x11, 0x4c, 0x69, 0x73, 0x74, 0x20, - 0x61, 0x6c, 0x6c, 0x20, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x1a, 0x77, 0x4c, 0x69, - 0x73, 0x74, 0x73, 0x20, 0x61, 0x6c, 0x6c, 0x20, 0x74, 0x68, 0x65, 0x20, 0x70, 0x72, 0x6f, 0x6a, - 0x65, 0x63, 0x74, 0x73, 0x20, 0x66, 0x72, 0x6f, 0x6d, 0x20, 0x61, 0x6c, 0x6c, 0x20, 0x74, 0x68, - 0x65, 0x20, 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, - 0x69, 0x6e, 0x20, 0x61, 0x20, 0x46, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x20, 0x69, 0x6e, - 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x2e, 0x20, 0x49, 0x74, 0x20, 0x63, 0x61, 0x6e, 0x20, 0x62, - 0x65, 0x20, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x65, 0x64, 0x20, 0x62, 0x79, 0x20, 0x6f, 0x72, - 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x73, - 0x74, 0x61, 0x74, 0x65, 0x2e, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x19, 0x12, 0x17, 0x2f, 0x76, 0x31, - 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x2f, 0x70, 0x72, 0x6f, 0x6a, - 0x65, 0x63, 0x74, 0x73, 0x12, 0xb5, 0x01, 0x0a, 0x0d, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x6c, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x2f, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, + 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x6c, 0x6c, 0x55, 0x73, 0x65, 0x72, + 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xbd, 0x01, 0x92, 0x41, 0x9d, 0x01, + 0x0a, 0x04, 0x55, 0x73, 0x65, 0x72, 0x12, 0x0e, 0x4c, 0x69, 0x73, 0x74, 0x20, 0x61, 0x6c, 0x6c, + 0x20, 0x75, 0x73, 0x65, 0x72, 0x73, 0x1a, 0x84, 0x01, 0x4c, 0x69, 0x73, 0x74, 0x73, 0x20, 0x61, + 0x6c, 0x6c, 0x20, 0x74, 0x68, 0x65, 0x20, 0x75, 0x73, 0x65, 0x72, 0x73, 0x20, 0x66, 0x72, 0x6f, + 0x6d, 0x20, 0x61, 0x6c, 0x6c, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x69, + 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x69, 0x6e, 0x20, 0x61, 0x20, 0x46, 0x72, 0x6f, + 0x6e, 0x74, 0x69, 0x65, 0x72, 0x20, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x2e, 0x20, + 0x49, 0x74, 0x20, 0x63, 0x61, 0x6e, 0x20, 0x62, 0x65, 0x20, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, + 0x65, 0x64, 0x20, 0x62, 0x79, 0x20, 0x6b, 0x65, 0x79, 0x77, 0x6f, 0x72, 0x64, 0x2c, 0x20, 0x6f, + 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2c, 0x20, 0x67, 0x72, 0x6f, + 0x75, 0x70, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x82, 0xd3, 0xe4, + 0x93, 0x02, 0x16, 0x12, 0x14, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x61, 0x64, + 0x6d, 0x69, 0x6e, 0x2f, 0x75, 0x73, 0x65, 0x72, 0x73, 0x12, 0x9c, 0x02, 0x0a, 0x0a, 0x4c, 0x69, + 0x73, 0x74, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x12, 0x2c, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, + 0x61, 0x63, 0x6b, 0x2e, 0x66, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, + 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2d, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x66, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, - 0x61, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x30, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, - 0x63, 0x6b, 0x2e, 0x66, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, - 0x74, 0x61, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x41, 0x92, 0x41, 0x1e, 0x0a, 0x08, - 0x52, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x12, 0x4c, 0x69, 0x73, 0x74, 0x20, 0x61, - 0x6c, 0x6c, 0x20, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x82, 0xd3, 0xe4, 0x93, - 0x02, 0x1a, 0x12, 0x18, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x61, 0x64, 0x6d, - 0x69, 0x6e, 0x2f, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0xc5, 0x02, 0x0a, - 0x0d, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x12, 0x2f, - 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x66, 0x72, 0x6f, 0x6e, 0x74, 0x69, - 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x52, - 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, - 0x30, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x66, 0x72, 0x6f, 0x6e, 0x74, + 0x61, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xb0, 0x01, 0x92, 0x41, 0x8f, 0x01, 0x0a, 0x05, 0x47, 0x72, + 0x6f, 0x75, 0x70, 0x12, 0x0f, 0x4c, 0x69, 0x73, 0x74, 0x20, 0x61, 0x6c, 0x6c, 0x20, 0x67, 0x72, + 0x6f, 0x75, 0x70, 0x73, 0x1a, 0x75, 0x4c, 0x69, 0x73, 0x74, 0x73, 0x20, 0x61, 0x6c, 0x6c, 0x20, + 0x74, 0x68, 0x65, 0x20, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x20, 0x66, 0x72, 0x6f, 0x6d, 0x20, + 0x61, 0x6c, 0x6c, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x69, 0x6e, 0x20, 0x61, 0x20, 0x46, 0x72, 0x6f, 0x6e, 0x74, + 0x69, 0x65, 0x72, 0x20, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x2e, 0x20, 0x49, 0x74, + 0x20, 0x63, 0x61, 0x6e, 0x20, 0x62, 0x65, 0x20, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x65, 0x64, + 0x20, 0x62, 0x79, 0x20, 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x20, 0x61, 0x6e, 0x64, 0x20, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x82, 0xd3, 0xe4, 0x93, 0x02, + 0x17, 0x12, 0x15, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x61, 0x64, 0x6d, 0x69, + 0x6e, 0x2f, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x12, 0xb3, 0x02, 0x0a, 0x14, 0x4c, 0x69, 0x73, + 0x74, 0x41, 0x6c, 0x6c, 0x4f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x73, 0x12, 0x36, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x66, 0x72, 0x6f, + 0x6e, 0x74, 0x69, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4c, 0x69, + 0x73, 0x74, 0x41, 0x6c, 0x6c, 0x4f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x37, 0x2e, 0x72, 0x61, 0x79, 0x73, + 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x66, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x2e, 0x76, 0x31, + 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x6c, 0x6c, 0x4f, 0x72, 0x67, + 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x22, 0xa9, 0x01, 0x92, 0x41, 0x81, 0x01, 0x0a, 0x0c, 0x4f, 0x72, 0x67, 0x61, 0x6e, + 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x16, 0x4c, 0x69, 0x73, 0x74, 0x20, 0x61, 0x6c, + 0x6c, 0x20, 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x1a, + 0x59, 0x4c, 0x69, 0x73, 0x74, 0x73, 0x20, 0x61, 0x6c, 0x6c, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6f, + 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x69, 0x6e, 0x20, + 0x61, 0x20, 0x46, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x20, 0x69, 0x6e, 0x73, 0x74, 0x61, + 0x6e, 0x63, 0x65, 0x2e, 0x20, 0x49, 0x74, 0x20, 0x63, 0x61, 0x6e, 0x20, 0x62, 0x65, 0x20, 0x66, + 0x69, 0x6c, 0x74, 0x65, 0x72, 0x65, 0x64, 0x20, 0x62, 0x79, 0x20, 0x75, 0x73, 0x65, 0x72, 0x20, + 0x61, 0x6e, 0x64, 0x20, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1e, + 0x12, 0x1c, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x61, 0x64, 0x6d, 0x69, 0x6e, + 0x2f, 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0xaa, + 0x02, 0x0a, 0x0c, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x12, + 0x2e, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x66, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, - 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x22, 0xd0, 0x01, 0x92, 0x41, 0xac, 0x01, 0x0a, 0x08, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, - 0x63, 0x65, 0x12, 0x12, 0x4c, 0x69, 0x73, 0x74, 0x20, 0x61, 0x6c, 0x6c, 0x20, 0x72, 0x65, 0x73, - 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x1a, 0x8b, 0x01, 0x4c, 0x69, 0x73, 0x74, 0x73, 0x20, 0x61, - 0x6c, 0x6c, 0x20, 0x74, 0x68, 0x65, 0x20, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, - 0x20, 0x66, 0x72, 0x6f, 0x6d, 0x20, 0x61, 0x6c, 0x6c, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6f, 0x72, - 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x69, 0x6e, 0x20, 0x61, - 0x20, 0x46, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x20, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, - 0x63, 0x65, 0x2e, 0x20, 0x49, 0x74, 0x20, 0x63, 0x61, 0x6e, 0x20, 0x62, 0x65, 0x20, 0x66, 0x69, - 0x6c, 0x74, 0x65, 0x72, 0x65, 0x64, 0x20, 0x62, 0x79, 0x20, 0x75, 0x73, 0x65, 0x72, 0x2c, 0x20, - 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x2c, 0x20, 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, - 0x61, 0x63, 0x65, 0x2e, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1a, 0x12, 0x18, 0x2f, 0x76, 0x31, 0x62, - 0x65, 0x74, 0x61, 0x31, 0x2f, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, - 0x72, 0x63, 0x65, 0x73, 0x12, 0x98, 0x02, 0x0a, 0x0a, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, - 0x6f, 0x6c, 0x65, 0x12, 0x2c, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x66, - 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, - 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x6f, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x1a, 0x2d, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x66, 0x72, 0x6f, - 0x6e, 0x74, 0x69, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x43, 0x72, - 0x65, 0x61, 0x74, 0x65, 0x52, 0x6f, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x22, 0xac, 0x01, 0x92, 0x41, 0x8c, 0x01, 0x0a, 0x04, 0x52, 0x6f, 0x6c, 0x65, 0x12, 0x14, 0x43, - 0x72, 0x65, 0x61, 0x74, 0x65, 0x20, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x72, - 0x6f, 0x6c, 0x65, 0x1a, 0x6e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x73, 0x20, 0x61, 0x20, 0x70, - 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x77, 0x69, 0x64, 0x65, 0x20, 0x72, 0x6f, 0x6c, - 0x65, 0x2e, 0x20, 0x49, 0x74, 0x20, 0x63, 0x61, 0x6e, 0x20, 0x62, 0x65, 0x20, 0x75, 0x73, 0x65, - 0x64, 0x20, 0x74, 0x6f, 0x20, 0x67, 0x72, 0x61, 0x6e, 0x74, 0x20, 0x70, 0x65, 0x72, 0x6d, 0x69, - 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x74, 0x6f, 0x20, 0x61, 0x6c, 0x6c, 0x20, 0x74, 0x68, - 0x65, 0x20, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x20, 0x69, 0x6e, 0x20, 0x61, - 0x20, 0x46, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x20, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, - 0x63, 0x65, 0x2e, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x16, 0x3a, 0x04, 0x62, 0x6f, 0x64, 0x79, 0x22, - 0x0e, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x72, 0x6f, 0x6c, 0x65, 0x73, 0x12, - 0xd5, 0x01, 0x0a, 0x0a, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x6f, 0x6c, 0x65, 0x12, 0x2c, + 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x2f, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x66, 0x72, 0x6f, 0x6e, 0x74, + 0x69, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, + 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x22, 0xb8, 0x01, 0x92, 0x41, 0x95, 0x01, 0x0a, 0x07, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, + 0x12, 0x11, 0x4c, 0x69, 0x73, 0x74, 0x20, 0x61, 0x6c, 0x6c, 0x20, 0x70, 0x72, 0x6f, 0x6a, 0x65, + 0x63, 0x74, 0x73, 0x1a, 0x77, 0x4c, 0x69, 0x73, 0x74, 0x73, 0x20, 0x61, 0x6c, 0x6c, 0x20, 0x74, + 0x68, 0x65, 0x20, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x20, 0x66, 0x72, 0x6f, 0x6d, + 0x20, 0x61, 0x6c, 0x6c, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x69, 0x6e, 0x20, 0x61, 0x20, 0x46, 0x72, 0x6f, 0x6e, + 0x74, 0x69, 0x65, 0x72, 0x20, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x2e, 0x20, 0x49, + 0x74, 0x20, 0x63, 0x61, 0x6e, 0x20, 0x62, 0x65, 0x20, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x65, + 0x64, 0x20, 0x62, 0x79, 0x20, 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x82, 0xd3, 0xe4, 0x93, + 0x02, 0x19, 0x12, 0x17, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x61, 0x64, 0x6d, + 0x69, 0x6e, 0x2f, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x12, 0xb5, 0x01, 0x0a, 0x0d, + 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x2f, 0x2e, + 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x66, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, + 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, + 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x30, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x66, 0x72, 0x6f, 0x6e, 0x74, 0x69, - 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, - 0x65, 0x52, 0x6f, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2d, 0x2e, 0x72, - 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x66, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, - 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, - 0x6f, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x6a, 0x92, 0x41, 0x46, - 0x0a, 0x04, 0x52, 0x6f, 0x6c, 0x65, 0x12, 0x0b, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x20, 0x72, - 0x6f, 0x6c, 0x65, 0x1a, 0x31, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x20, 0x61, 0x20, 0x72, 0x6f, - 0x6c, 0x65, 0x20, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x2c, 0x20, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, - 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, - 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1b, 0x3a, 0x04, 0x62, 0x6f, - 0x64, 0x79, 0x1a, 0x13, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x72, 0x6f, 0x6c, - 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x12, 0xdc, 0x01, 0x0a, 0x0a, 0x44, 0x65, 0x6c, 0x65, - 0x74, 0x65, 0x52, 0x6f, 0x6c, 0x65, 0x12, 0x2c, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, - 0x6b, 0x2e, 0x66, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, - 0x61, 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x6f, 0x6c, 0x65, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2d, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, - 0x66, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, - 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x6f, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x22, 0x71, 0x92, 0x41, 0x53, 0x0a, 0x04, 0x52, 0x6f, 0x6c, 0x65, 0x12, 0x14, - 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x20, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x20, - 0x72, 0x6f, 0x6c, 0x65, 0x1a, 0x35, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x20, 0x61, 0x20, 0x70, - 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x77, 0x69, 0x64, 0x65, 0x20, 0x72, 0x6f, 0x6c, - 0x65, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x61, 0x6c, 0x6c, 0x20, 0x6f, 0x66, 0x20, 0x69, 0x74, 0x73, - 0x20, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x82, 0xd3, 0xe4, 0x93, 0x02, - 0x15, 0x2a, 0x13, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x72, 0x6f, 0x6c, 0x65, - 0x73, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x12, 0xb1, 0x02, 0x0a, 0x10, 0x43, 0x72, 0x65, 0x61, 0x74, - 0x65, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x32, 0x2e, 0x72, 0x61, - 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x66, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x2e, - 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x50, 0x65, - 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, - 0x33, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x66, 0x72, 0x6f, 0x6e, 0x74, - 0x69, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, - 0x74, 0x65, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xb3, 0x01, 0x92, 0x41, 0x90, 0x01, 0x0a, 0x0a, 0x50, 0x65, 0x72, - 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x1a, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x20, - 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, - 0x69, 0x6f, 0x6e, 0x1a, 0x66, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x73, 0x20, 0x61, 0x20, 0x70, - 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x2e, 0x20, 0x49, 0x74, 0x20, 0x63, 0x61, - 0x6e, 0x20, 0x62, 0x65, 0x20, 0x75, 0x73, 0x65, 0x64, 0x20, 0x74, 0x6f, 0x20, 0x67, 0x72, 0x61, - 0x6e, 0x74, 0x20, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x74, - 0x6f, 0x20, 0x61, 0x6c, 0x6c, 0x20, 0x74, 0x68, 0x65, 0x20, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, - 0x63, 0x65, 0x73, 0x20, 0x69, 0x6e, 0x20, 0x61, 0x20, 0x46, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, - 0x72, 0x20, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x2e, 0x82, 0xd3, 0xe4, 0x93, 0x02, - 0x19, 0x3a, 0x01, 0x2a, 0x22, 0x14, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x70, - 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0xbf, 0x02, 0x0a, 0x10, 0x55, - 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, - 0x32, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x66, 0x72, 0x6f, 0x6e, 0x74, - 0x69, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, - 0x74, 0x65, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x1a, 0x33, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x66, - 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, - 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xc1, 0x01, 0x92, 0x41, 0x96, 0x01, 0x0a, - 0x0a, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x1a, 0x55, 0x70, 0x64, - 0x61, 0x74, 0x65, 0x20, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x70, 0x65, 0x72, - 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x1a, 0x6c, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x73, - 0x20, 0x61, 0x20, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x62, 0x79, - 0x20, 0x49, 0x44, 0x2e, 0x20, 0x49, 0x74, 0x20, 0x63, 0x61, 0x6e, 0x20, 0x62, 0x65, 0x20, 0x75, - 0x73, 0x65, 0x64, 0x20, 0x74, 0x6f, 0x20, 0x67, 0x72, 0x61, 0x6e, 0x74, 0x20, 0x70, 0x65, 0x72, - 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x74, 0x6f, 0x20, 0x61, 0x6c, 0x6c, 0x20, - 0x74, 0x68, 0x65, 0x20, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x20, 0x69, 0x6e, - 0x20, 0x61, 0x20, 0x46, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x20, 0x69, 0x6e, 0x73, 0x74, - 0x61, 0x6e, 0x63, 0x65, 0x2e, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x21, 0x3a, 0x04, 0x62, 0x6f, 0x64, - 0x79, 0x1a, 0x19, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x70, 0x65, 0x72, 0x6d, - 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x12, 0xc9, 0x01, 0x0a, - 0x10, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, - 0x6e, 0x12, 0x32, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x66, 0x72, 0x6f, - 0x6e, 0x74, 0x69, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x44, 0x65, - 0x6c, 0x65, 0x74, 0x65, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x33, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, + 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x52, + 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x22, 0x41, 0x92, 0x41, 0x1e, 0x0a, 0x08, 0x52, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, + 0x12, 0x4c, 0x69, 0x73, 0x74, 0x20, 0x61, 0x6c, 0x6c, 0x20, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x73, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1a, 0x12, 0x18, 0x2f, 0x76, 0x31, 0x62, 0x65, + 0x74, 0x61, 0x31, 0x2f, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x2f, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x73, 0x12, 0xc5, 0x02, 0x0a, 0x0d, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x6f, + 0x75, 0x72, 0x63, 0x65, 0x73, 0x12, 0x2f, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x66, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, - 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, - 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x4c, 0x92, 0x41, 0x28, 0x0a, - 0x0a, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x1a, 0x44, 0x65, 0x6c, - 0x65, 0x74, 0x65, 0x20, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x70, 0x65, 0x72, - 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1b, 0x2a, 0x19, 0x2f, - 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, - 0x6f, 0x6e, 0x73, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x12, 0xb0, 0x02, 0x0a, 0x0f, 0x4c, 0x69, 0x73, - 0x74, 0x50, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x12, 0x31, 0x2e, 0x72, - 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x66, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, - 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x72, 0x65, - 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, - 0x32, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x66, 0x72, 0x6f, 0x6e, 0x74, - 0x69, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, - 0x50, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x22, 0xb5, 0x01, 0x92, 0x41, 0x95, 0x01, 0x0a, 0x0a, 0x50, 0x72, 0x65, 0x66, - 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x12, 0x19, 0x4c, 0x69, 0x73, 0x74, 0x20, 0x70, 0x6c, 0x61, - 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x70, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, - 0x73, 0x1a, 0x6c, 0x52, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x73, 0x20, 0x61, 0x20, 0x6c, 0x69, 0x73, - 0x74, 0x20, 0x6f, 0x66, 0x20, 0x61, 0x6c, 0x6c, 0x20, 0x70, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, - 0x6e, 0x63, 0x65, 0x73, 0x20, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x65, 0x64, 0x20, - 0x6f, 0x6e, 0x20, 0x61, 0x6e, 0x20, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x20, 0x69, - 0x6e, 0x20, 0x46, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x2e, 0x20, 0x65, 0x2e, 0x67, 0x20, - 0x75, 0x73, 0x65, 0x72, 0x2c, 0x20, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x2c, 0x20, 0x6f, - 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x65, 0x74, 0x63, 0x82, - 0xd3, 0xe4, 0x93, 0x02, 0x16, 0x12, 0x14, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, - 0x70, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x12, 0xfb, 0x02, 0x0a, 0x11, - 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x50, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, - 0x73, 0x12, 0x33, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x66, 0x72, 0x6f, - 0x6e, 0x74, 0x69, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x43, 0x72, - 0x65, 0x61, 0x74, 0x65, 0x50, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x34, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, + 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x30, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x66, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, - 0x61, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x50, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, - 0x6e, 0x63, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xfa, 0x01, 0x92, - 0x41, 0xd7, 0x01, 0x0a, 0x0a, 0x50, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x12, - 0x1b, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x20, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, - 0x20, 0x70, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x1a, 0xab, 0x01, 0x43, - 0x72, 0x65, 0x61, 0x74, 0x65, 0x20, 0x6e, 0x65, 0x77, 0x20, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, - 0x72, 0x6d, 0x20, 0x70, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x2e, 0x20, - 0x54, 0x68, 0x65, 0x20, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x70, 0x72, 0x65, - 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x20, 0x2a, 0x2a, 0x6e, 0x61, 0x6d, 0x65, 0x2a, - 0x2a, 0x20, 0x6d, 0x75, 0x73, 0x74, 0x20, 0x62, 0x65, 0x20, 0x75, 0x6e, 0x69, 0x71, 0x75, 0x65, - 0x20, 0x77, 0x69, 0x74, 0x68, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x70, 0x6c, 0x61, 0x74, - 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x63, 0x61, 0x6e, 0x20, 0x63, 0x6f, 0x6e, - 0x74, 0x61, 0x69, 0x6e, 0x20, 0x6f, 0x6e, 0x6c, 0x79, 0x20, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x6e, - 0x75, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x20, 0x63, 0x68, 0x61, 0x72, 0x61, 0x63, 0x74, 0x65, 0x72, - 0x73, 0x2c, 0x20, 0x64, 0x61, 0x73, 0x68, 0x65, 0x73, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x75, 0x6e, - 0x64, 0x65, 0x72, 0x73, 0x63, 0x6f, 0x72, 0x65, 0x73, 0x2e, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x19, - 0x3a, 0x01, 0x2a, 0x22, 0x14, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x70, 0x72, - 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x12, 0x83, 0x03, 0x0a, 0x20, 0x43, 0x68, - 0x65, 0x63, 0x6b, 0x46, 0x65, 0x64, 0x65, 0x72, 0x61, 0x74, 0x65, 0x64, 0x52, 0x65, 0x73, 0x6f, - 0x75, 0x72, 0x63, 0x65, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x42, - 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x66, 0x72, 0x6f, 0x6e, 0x74, 0x69, - 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x43, 0x68, 0x65, 0x63, 0x6b, - 0x46, 0x65, 0x64, 0x65, 0x72, 0x61, 0x74, 0x65, 0x64, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, - 0x65, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x1a, 0x43, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x66, 0x72, + 0x61, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xd0, 0x01, 0x92, 0x41, 0xac, 0x01, 0x0a, + 0x08, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x12, 0x4c, 0x69, 0x73, 0x74, 0x20, + 0x61, 0x6c, 0x6c, 0x20, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x1a, 0x8b, 0x01, + 0x4c, 0x69, 0x73, 0x74, 0x73, 0x20, 0x61, 0x6c, 0x6c, 0x20, 0x74, 0x68, 0x65, 0x20, 0x72, 0x65, + 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x20, 0x66, 0x72, 0x6f, 0x6d, 0x20, 0x61, 0x6c, 0x6c, + 0x20, 0x74, 0x68, 0x65, 0x20, 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x73, 0x20, 0x69, 0x6e, 0x20, 0x61, 0x20, 0x46, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, + 0x20, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x2e, 0x20, 0x49, 0x74, 0x20, 0x63, 0x61, + 0x6e, 0x20, 0x62, 0x65, 0x20, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x65, 0x64, 0x20, 0x62, 0x79, + 0x20, 0x75, 0x73, 0x65, 0x72, 0x2c, 0x20, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x2c, 0x20, + 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x61, 0x6e, 0x64, + 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x2e, 0x82, 0xd3, 0xe4, 0x93, 0x02, + 0x1a, 0x12, 0x18, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x61, 0x64, 0x6d, 0x69, + 0x6e, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x12, 0x98, 0x02, 0x0a, 0x0a, + 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x6f, 0x6c, 0x65, 0x12, 0x2c, 0x2e, 0x72, 0x61, 0x79, + 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x66, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x2e, 0x76, + 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x6f, 0x6c, + 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2d, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, + 0x61, 0x63, 0x6b, 0x2e, 0x66, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, + 0x65, 0x74, 0x61, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x6f, 0x6c, 0x65, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xac, 0x01, 0x92, 0x41, 0x8c, 0x01, 0x0a, 0x04, + 0x52, 0x6f, 0x6c, 0x65, 0x12, 0x14, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x20, 0x70, 0x6c, 0x61, + 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x72, 0x6f, 0x6c, 0x65, 0x1a, 0x6e, 0x43, 0x72, 0x65, 0x61, + 0x74, 0x65, 0x73, 0x20, 0x61, 0x20, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x77, + 0x69, 0x64, 0x65, 0x20, 0x72, 0x6f, 0x6c, 0x65, 0x2e, 0x20, 0x49, 0x74, 0x20, 0x63, 0x61, 0x6e, + 0x20, 0x62, 0x65, 0x20, 0x75, 0x73, 0x65, 0x64, 0x20, 0x74, 0x6f, 0x20, 0x67, 0x72, 0x61, 0x6e, + 0x74, 0x20, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x74, 0x6f, + 0x20, 0x61, 0x6c, 0x6c, 0x20, 0x74, 0x68, 0x65, 0x20, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, + 0x65, 0x73, 0x20, 0x69, 0x6e, 0x20, 0x61, 0x20, 0x46, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, + 0x20, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x2e, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x16, + 0x3a, 0x04, 0x62, 0x6f, 0x64, 0x79, 0x22, 0x0e, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, + 0x2f, 0x72, 0x6f, 0x6c, 0x65, 0x73, 0x12, 0xd5, 0x01, 0x0a, 0x0a, 0x55, 0x70, 0x64, 0x61, 0x74, + 0x65, 0x52, 0x6f, 0x6c, 0x65, 0x12, 0x2c, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, + 0x2e, 0x66, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, + 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x6f, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x2d, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x66, + 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, + 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x6f, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x22, 0x6a, 0x92, 0x41, 0x46, 0x0a, 0x04, 0x52, 0x6f, 0x6c, 0x65, 0x12, 0x0b, 0x55, + 0x70, 0x64, 0x61, 0x74, 0x65, 0x20, 0x72, 0x6f, 0x6c, 0x65, 0x1a, 0x31, 0x55, 0x70, 0x64, 0x61, + 0x74, 0x65, 0x20, 0x61, 0x20, 0x72, 0x6f, 0x6c, 0x65, 0x20, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x2c, + 0x20, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x61, 0x6e, 0x64, + 0x20, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x82, 0xd3, 0xe4, + 0x93, 0x02, 0x1b, 0x3a, 0x04, 0x62, 0x6f, 0x64, 0x79, 0x1a, 0x13, 0x2f, 0x76, 0x31, 0x62, 0x65, + 0x74, 0x61, 0x31, 0x2f, 0x72, 0x6f, 0x6c, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x12, 0xdc, + 0x01, 0x0a, 0x0a, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x6f, 0x6c, 0x65, 0x12, 0x2c, 0x2e, + 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x66, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, + 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, + 0x52, 0x6f, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2d, 0x2e, 0x72, 0x61, + 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x66, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x2e, + 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x6f, + 0x6c, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x71, 0x92, 0x41, 0x53, 0x0a, + 0x04, 0x52, 0x6f, 0x6c, 0x65, 0x12, 0x14, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x20, 0x70, 0x6c, + 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x72, 0x6f, 0x6c, 0x65, 0x1a, 0x35, 0x44, 0x65, 0x6c, + 0x65, 0x74, 0x65, 0x20, 0x61, 0x20, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x77, + 0x69, 0x64, 0x65, 0x20, 0x72, 0x6f, 0x6c, 0x65, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x61, 0x6c, 0x6c, + 0x20, 0x6f, 0x66, 0x20, 0x69, 0x74, 0x73, 0x20, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x73, 0x2e, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x15, 0x2a, 0x13, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, + 0x61, 0x31, 0x2f, 0x72, 0x6f, 0x6c, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x12, 0xb1, 0x02, + 0x0a, 0x10, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, + 0x6f, 0x6e, 0x12, 0x32, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x66, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x43, - 0x68, 0x65, 0x63, 0x6b, 0x46, 0x65, 0x64, 0x65, 0x72, 0x61, 0x74, 0x65, 0x64, 0x52, 0x65, 0x73, - 0x6f, 0x75, 0x72, 0x63, 0x65, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xd5, 0x01, 0x92, 0x41, 0xb2, 0x01, 0x0a, 0x05, - 0x41, 0x75, 0x74, 0x68, 0x7a, 0x12, 0x05, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x1a, 0xa1, 0x01, 0x52, - 0x65, 0x74, 0x75, 0x72, 0x6e, 0x73, 0x20, 0x74, 0x72, 0x75, 0x65, 0x20, 0x69, 0x66, 0x20, 0x61, - 0x20, 0x70, 0x72, 0x69, 0x6e, 0x63, 0x69, 0x70, 0x61, 0x6c, 0x20, 0x68, 0x61, 0x73, 0x20, 0x72, - 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x20, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, - 0x6f, 0x6e, 0x73, 0x20, 0x74, 0x6f, 0x20, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x20, 0x61, 0x20, - 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x66, 0x61, 0x6c, - 0x73, 0x65, 0x20, 0x6f, 0x74, 0x68, 0x65, 0x72, 0x77, 0x69, 0x73, 0x65, 0x2e, 0x3c, 0x62, 0x72, - 0x2f, 0x3e, 0x20, 0x4e, 0x6f, 0x74, 0x65, 0x20, 0x74, 0x68, 0x65, 0x20, 0x70, 0x72, 0x69, 0x6e, - 0x63, 0x69, 0x70, 0x61, 0x6c, 0x20, 0x63, 0x61, 0x6e, 0x20, 0x62, 0x65, 0x20, 0x61, 0x20, 0x75, - 0x73, 0x65, 0x72, 0x2c, 0x20, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x20, 0x6f, 0x72, 0x20, 0x61, 0x20, - 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x20, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x2e, - 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x19, 0x3a, 0x01, 0x2a, 0x22, 0x14, 0x2f, 0x76, 0x31, 0x62, 0x65, - 0x74, 0x61, 0x31, 0x2f, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x2f, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x12, - 0xe0, 0x01, 0x0a, 0x0f, 0x41, 0x64, 0x64, 0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x55, - 0x73, 0x65, 0x72, 0x12, 0x31, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x66, + 0x72, 0x65, 0x61, 0x74, 0x65, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x33, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, + 0x6b, 0x2e, 0x66, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, + 0x61, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, + 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xb3, 0x01, 0x92, 0x41, + 0x90, 0x01, 0x0a, 0x0a, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x1a, + 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x20, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x20, + 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x1a, 0x66, 0x43, 0x72, 0x65, 0x61, + 0x74, 0x65, 0x73, 0x20, 0x61, 0x20, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, + 0x2e, 0x20, 0x49, 0x74, 0x20, 0x63, 0x61, 0x6e, 0x20, 0x62, 0x65, 0x20, 0x75, 0x73, 0x65, 0x64, + 0x20, 0x74, 0x6f, 0x20, 0x67, 0x72, 0x61, 0x6e, 0x74, 0x20, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, + 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x74, 0x6f, 0x20, 0x61, 0x6c, 0x6c, 0x20, 0x74, 0x68, 0x65, + 0x20, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x20, 0x69, 0x6e, 0x20, 0x61, 0x20, + 0x46, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x20, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, + 0x65, 0x2e, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x19, 0x3a, 0x01, 0x2a, 0x22, 0x14, 0x2f, 0x76, 0x31, + 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, + 0x73, 0x12, 0xbf, 0x02, 0x0a, 0x10, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, 0x65, 0x72, 0x6d, + 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x32, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, + 0x6b, 0x2e, 0x66, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, + 0x61, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, + 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x33, 0x2e, 0x72, 0x61, 0x79, + 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x66, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x2e, 0x76, + 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, 0x65, 0x72, + 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, + 0xc1, 0x01, 0x92, 0x41, 0x96, 0x01, 0x0a, 0x0a, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, + 0x6f, 0x6e, 0x12, 0x1a, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x20, 0x70, 0x6c, 0x61, 0x74, 0x66, + 0x6f, 0x72, 0x6d, 0x20, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x1a, 0x6c, + 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x73, 0x20, 0x61, 0x20, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, + 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x62, 0x79, 0x20, 0x49, 0x44, 0x2e, 0x20, 0x49, 0x74, 0x20, 0x63, + 0x61, 0x6e, 0x20, 0x62, 0x65, 0x20, 0x75, 0x73, 0x65, 0x64, 0x20, 0x74, 0x6f, 0x20, 0x67, 0x72, + 0x61, 0x6e, 0x74, 0x20, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x20, + 0x74, 0x6f, 0x20, 0x61, 0x6c, 0x6c, 0x20, 0x74, 0x68, 0x65, 0x20, 0x72, 0x65, 0x73, 0x6f, 0x75, + 0x72, 0x63, 0x65, 0x73, 0x20, 0x69, 0x6e, 0x20, 0x61, 0x20, 0x46, 0x72, 0x6f, 0x6e, 0x74, 0x69, + 0x65, 0x72, 0x20, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x2e, 0x82, 0xd3, 0xe4, 0x93, + 0x02, 0x21, 0x3a, 0x04, 0x62, 0x6f, 0x64, 0x79, 0x1a, 0x19, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, + 0x61, 0x31, 0x2f, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x7b, + 0x69, 0x64, 0x7d, 0x12, 0xc9, 0x01, 0x0a, 0x10, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x50, 0x65, + 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x32, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, + 0x61, 0x63, 0x6b, 0x2e, 0x66, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, + 0x65, 0x74, 0x61, 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x50, 0x65, 0x72, 0x6d, 0x69, + 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x33, 0x2e, 0x72, + 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x66, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, + 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x50, + 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x22, 0x4c, 0x92, 0x41, 0x28, 0x0a, 0x0a, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, + 0x6f, 0x6e, 0x12, 0x1a, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x20, 0x70, 0x6c, 0x61, 0x74, 0x66, + 0x6f, 0x72, 0x6d, 0x20, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x82, 0xd3, + 0xe4, 0x93, 0x02, 0x1b, 0x2a, 0x19, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x70, + 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x12, + 0xb0, 0x02, 0x0a, 0x0f, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, + 0x63, 0x65, 0x73, 0x12, 0x31, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x66, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, - 0x41, 0x64, 0x64, 0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x55, 0x73, 0x65, 0x72, 0x52, + 0x4c, 0x69, 0x73, 0x74, 0x50, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x32, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x66, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, - 0x61, 0x31, 0x2e, 0x41, 0x64, 0x64, 0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x55, 0x73, - 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x66, 0x92, 0x41, 0x3b, 0x0a, - 0x08, 0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x12, 0x11, 0x41, 0x64, 0x64, 0x20, 0x70, - 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x75, 0x73, 0x65, 0x72, 0x1a, 0x1c, 0x41, 0x64, - 0x64, 0x73, 0x20, 0x61, 0x20, 0x75, 0x73, 0x65, 0x72, 0x20, 0x74, 0x6f, 0x20, 0x74, 0x68, 0x65, - 0x20, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x2e, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x22, - 0x3a, 0x01, 0x2a, 0x22, 0x1d, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x61, 0x64, - 0x6d, 0x69, 0x6e, 0x2f, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x2f, 0x75, 0x73, 0x65, - 0x72, 0x73, 0x12, 0xf3, 0x01, 0x0a, 0x11, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x6c, 0x61, 0x74, 0x66, - 0x6f, 0x72, 0x6d, 0x55, 0x73, 0x65, 0x72, 0x73, 0x12, 0x33, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, + 0x61, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, + 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xb5, 0x01, 0x92, 0x41, 0x95, + 0x01, 0x0a, 0x0a, 0x50, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x12, 0x19, 0x4c, + 0x69, 0x73, 0x74, 0x20, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x70, 0x72, 0x65, + 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x1a, 0x6c, 0x52, 0x65, 0x74, 0x75, 0x72, 0x6e, + 0x73, 0x20, 0x61, 0x20, 0x6c, 0x69, 0x73, 0x74, 0x20, 0x6f, 0x66, 0x20, 0x61, 0x6c, 0x6c, 0x20, + 0x70, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x20, 0x63, 0x6f, 0x6e, 0x66, + 0x69, 0x67, 0x75, 0x72, 0x65, 0x64, 0x20, 0x6f, 0x6e, 0x20, 0x61, 0x6e, 0x20, 0x69, 0x6e, 0x73, + 0x74, 0x61, 0x6e, 0x63, 0x65, 0x20, 0x69, 0x6e, 0x20, 0x46, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, + 0x72, 0x2e, 0x20, 0x65, 0x2e, 0x67, 0x20, 0x75, 0x73, 0x65, 0x72, 0x2c, 0x20, 0x70, 0x72, 0x6f, + 0x6a, 0x65, 0x63, 0x74, 0x2c, 0x20, 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x20, 0x65, 0x74, 0x63, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x16, 0x12, 0x14, 0x2f, 0x76, + 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x70, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, + 0x65, 0x73, 0x12, 0xfb, 0x02, 0x0a, 0x11, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x50, 0x72, 0x65, + 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x12, 0x33, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x66, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, - 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, - 0x6d, 0x55, 0x73, 0x65, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x34, 0x2e, + 0x65, 0x74, 0x61, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x50, 0x72, 0x65, 0x66, 0x65, + 0x72, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x34, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x66, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, - 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x6c, - 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x55, 0x73, 0x65, 0x72, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x22, 0x73, 0x92, 0x41, 0x4b, 0x0a, 0x08, 0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f, - 0x72, 0x6d, 0x12, 0x13, 0x4c, 0x69, 0x73, 0x74, 0x20, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, - 0x6d, 0x20, 0x75, 0x73, 0x65, 0x72, 0x73, 0x1a, 0x2a, 0x4c, 0x69, 0x73, 0x74, 0x73, 0x20, 0x61, - 0x6c, 0x6c, 0x20, 0x74, 0x68, 0x65, 0x20, 0x75, 0x73, 0x65, 0x72, 0x73, 0x20, 0x61, 0x64, 0x64, - 0x65, 0x64, 0x20, 0x74, 0x6f, 0x20, 0x74, 0x68, 0x65, 0x20, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, - 0x72, 0x6d, 0x2e, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1f, 0x12, 0x1d, 0x2f, 0x76, 0x31, 0x62, 0x65, - 0x74, 0x61, 0x31, 0x2f, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x2f, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, - 0x72, 0x6d, 0x2f, 0x75, 0x73, 0x65, 0x72, 0x73, 0x12, 0xf8, 0x01, 0x0a, 0x12, 0x52, 0x65, 0x6d, - 0x6f, 0x76, 0x65, 0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x55, 0x73, 0x65, 0x72, 0x12, - 0x34, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x66, 0x72, 0x6f, 0x6e, 0x74, - 0x69, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x52, 0x65, 0x6d, 0x6f, - 0x76, 0x65, 0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x35, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, + 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, + 0x50, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x22, 0xfa, 0x01, 0x92, 0x41, 0xd7, 0x01, 0x0a, 0x0a, 0x50, 0x72, 0x65, 0x66, + 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x12, 0x1b, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x20, 0x70, + 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x70, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, + 0x63, 0x65, 0x73, 0x1a, 0xab, 0x01, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x20, 0x6e, 0x65, 0x77, + 0x20, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x70, 0x72, 0x65, 0x66, 0x65, 0x72, + 0x65, 0x6e, 0x63, 0x65, 0x73, 0x2e, 0x20, 0x54, 0x68, 0x65, 0x20, 0x70, 0x6c, 0x61, 0x74, 0x66, + 0x6f, 0x72, 0x6d, 0x20, 0x70, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x20, + 0x2a, 0x2a, 0x6e, 0x61, 0x6d, 0x65, 0x2a, 0x2a, 0x20, 0x6d, 0x75, 0x73, 0x74, 0x20, 0x62, 0x65, + 0x20, 0x75, 0x6e, 0x69, 0x71, 0x75, 0x65, 0x20, 0x77, 0x69, 0x74, 0x68, 0x69, 0x6e, 0x20, 0x74, + 0x68, 0x65, 0x20, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x61, 0x6e, 0x64, 0x20, + 0x63, 0x61, 0x6e, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x20, 0x6f, 0x6e, 0x6c, 0x79, + 0x20, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x6e, 0x75, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x20, 0x63, 0x68, + 0x61, 0x72, 0x61, 0x63, 0x74, 0x65, 0x72, 0x73, 0x2c, 0x20, 0x64, 0x61, 0x73, 0x68, 0x65, 0x73, + 0x20, 0x61, 0x6e, 0x64, 0x20, 0x75, 0x6e, 0x64, 0x65, 0x72, 0x73, 0x63, 0x6f, 0x72, 0x65, 0x73, + 0x2e, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x19, 0x3a, 0x01, 0x2a, 0x22, 0x14, 0x2f, 0x76, 0x31, 0x62, + 0x65, 0x74, 0x61, 0x31, 0x2f, 0x70, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x73, + 0x12, 0x83, 0x03, 0x0a, 0x20, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x46, 0x65, 0x64, 0x65, 0x72, 0x61, + 0x74, 0x65, 0x64, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x50, 0x65, 0x72, 0x6d, 0x69, + 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x42, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x66, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, - 0x31, 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, - 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x75, 0x92, 0x41, - 0x43, 0x0a, 0x08, 0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x12, 0x14, 0x52, 0x65, 0x6d, - 0x6f, 0x76, 0x65, 0x20, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x75, 0x73, 0x65, - 0x72, 0x1a, 0x21, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x73, 0x20, 0x61, 0x20, 0x75, 0x73, 0x65, - 0x72, 0x20, 0x66, 0x72, 0x6f, 0x6d, 0x20, 0x74, 0x68, 0x65, 0x20, 0x70, 0x6c, 0x61, 0x74, 0x66, - 0x6f, 0x72, 0x6d, 0x2e, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x29, 0x3a, 0x01, 0x2a, 0x22, 0x24, 0x2f, - 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x2f, 0x70, 0x6c, - 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x2f, 0x75, 0x73, 0x65, 0x72, 0x73, 0x2f, 0x72, 0x65, 0x6d, - 0x6f, 0x76, 0x65, 0x12, 0xc0, 0x03, 0x0a, 0x11, 0x44, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x65, - 0x64, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x6f, 0x75, 0x74, 0x12, 0x33, 0x2e, 0x72, 0x61, 0x79, 0x73, + 0x31, 0x2e, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x46, 0x65, 0x64, 0x65, 0x72, 0x61, 0x74, 0x65, 0x64, + 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, + 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x43, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x66, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x2e, 0x76, 0x31, - 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x65, 0x64, 0x43, - 0x68, 0x65, 0x63, 0x6b, 0x6f, 0x75, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x34, - 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x66, 0x72, 0x6f, 0x6e, 0x74, 0x69, - 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x67, - 0x61, 0x74, 0x65, 0x64, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x6f, 0x75, 0x74, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xbf, 0x02, 0x92, 0x41, 0xad, 0x01, 0x0a, 0x08, 0x43, 0x68, 0x65, - 0x63, 0x6b, 0x6f, 0x75, 0x74, 0x12, 0x22, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x6f, 0x75, 0x74, 0x20, - 0x61, 0x20, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x20, 0x6f, 0x72, 0x20, 0x73, 0x75, 0x62, - 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x1a, 0x7d, 0x43, 0x68, 0x65, 0x63, 0x6b, - 0x6f, 0x75, 0x74, 0x20, 0x61, 0x20, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x20, 0x74, 0x6f, - 0x20, 0x62, 0x75, 0x79, 0x20, 0x69, 0x74, 0x20, 0x6f, 0x6e, 0x65, 0x20, 0x74, 0x69, 0x6d, 0x65, - 0x20, 0x6f, 0x72, 0x20, 0x73, 0x74, 0x61, 0x72, 0x74, 0x20, 0x61, 0x20, 0x73, 0x75, 0x62, 0x73, - 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x70, 0x6c, 0x61, 0x6e, 0x20, 0x6f, 0x6e, - 0x20, 0x61, 0x20, 0x62, 0x69, 0x6c, 0x6c, 0x69, 0x6e, 0x67, 0x20, 0x61, 0x63, 0x63, 0x6f, 0x75, - 0x6e, 0x74, 0x20, 0x6d, 0x61, 0x6e, 0x75, 0x61, 0x6c, 0x6c, 0x79, 0x2e, 0x20, 0x49, 0x74, 0x20, - 0x62, 0x79, 0x70, 0x61, 0x73, 0x73, 0x65, 0x73, 0x20, 0x62, 0x69, 0x6c, 0x6c, 0x69, 0x6e, 0x67, - 0x20, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x2e, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x87, 0x01, 0x3a, - 0x01, 0x2a, 0x5a, 0x3c, 0x3a, 0x01, 0x2a, 0x22, 0x37, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, - 0x31, 0x2f, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x2f, 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x7b, 0x6f, 0x72, 0x67, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x62, - 0x69, 0x6c, 0x6c, 0x69, 0x6e, 0x67, 0x2f, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x6f, 0x75, 0x74, 0x73, - 0x22, 0x44, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x61, 0x64, 0x6d, 0x69, 0x6e, - 0x2f, 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x7b, - 0x6f, 0x72, 0x67, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x62, 0x69, 0x6c, 0x6c, 0x69, 0x6e, 0x67, 0x2f, - 0x7b, 0x62, 0x69, 0x6c, 0x6c, 0x69, 0x6e, 0x67, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x63, 0x68, 0x65, - 0x63, 0x6b, 0x6f, 0x75, 0x74, 0x73, 0x12, 0xb1, 0x02, 0x0a, 0x0f, 0x4c, 0x69, 0x73, 0x74, 0x41, - 0x6c, 0x6c, 0x49, 0x6e, 0x76, 0x6f, 0x69, 0x63, 0x65, 0x73, 0x12, 0x31, 0x2e, 0x72, 0x61, 0x79, + 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x46, 0x65, 0x64, 0x65, 0x72, + 0x61, 0x74, 0x65, 0x64, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x50, 0x65, 0x72, 0x6d, + 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xd5, + 0x01, 0x92, 0x41, 0xb2, 0x01, 0x0a, 0x05, 0x41, 0x75, 0x74, 0x68, 0x7a, 0x12, 0x05, 0x43, 0x68, + 0x65, 0x63, 0x6b, 0x1a, 0xa1, 0x01, 0x52, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x73, 0x20, 0x74, 0x72, + 0x75, 0x65, 0x20, 0x69, 0x66, 0x20, 0x61, 0x20, 0x70, 0x72, 0x69, 0x6e, 0x63, 0x69, 0x70, 0x61, + 0x6c, 0x20, 0x68, 0x61, 0x73, 0x20, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x20, 0x70, + 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x74, 0x6f, 0x20, 0x61, 0x63, + 0x63, 0x65, 0x73, 0x73, 0x20, 0x61, 0x20, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x20, + 0x61, 0x6e, 0x64, 0x20, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x20, 0x6f, 0x74, 0x68, 0x65, 0x72, 0x77, + 0x69, 0x73, 0x65, 0x2e, 0x3c, 0x62, 0x72, 0x2f, 0x3e, 0x20, 0x4e, 0x6f, 0x74, 0x65, 0x20, 0x74, + 0x68, 0x65, 0x20, 0x70, 0x72, 0x69, 0x6e, 0x63, 0x69, 0x70, 0x61, 0x6c, 0x20, 0x63, 0x61, 0x6e, + 0x20, 0x62, 0x65, 0x20, 0x61, 0x20, 0x75, 0x73, 0x65, 0x72, 0x2c, 0x20, 0x67, 0x72, 0x6f, 0x75, + 0x70, 0x20, 0x6f, 0x72, 0x20, 0x61, 0x20, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x20, 0x61, + 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x2e, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x19, 0x3a, 0x01, 0x2a, + 0x22, 0x14, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x61, 0x64, 0x6d, 0x69, 0x6e, + 0x2f, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x12, 0xe0, 0x01, 0x0a, 0x0f, 0x41, 0x64, 0x64, 0x50, 0x6c, + 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x55, 0x73, 0x65, 0x72, 0x12, 0x31, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x66, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x2e, 0x76, - 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x6c, 0x6c, 0x49, 0x6e, - 0x76, 0x6f, 0x69, 0x63, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x32, 0x2e, + 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x41, 0x64, 0x64, 0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f, + 0x72, 0x6d, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x32, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x66, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, - 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x6c, - 0x6c, 0x49, 0x6e, 0x76, 0x6f, 0x69, 0x63, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x22, 0xb6, 0x01, 0x92, 0x41, 0x8b, 0x01, 0x0a, 0x07, 0x49, 0x6e, 0x76, 0x6f, 0x69, 0x63, - 0x65, 0x12, 0x11, 0x4c, 0x69, 0x73, 0x74, 0x20, 0x61, 0x6c, 0x6c, 0x20, 0x69, 0x6e, 0x76, 0x6f, - 0x69, 0x63, 0x65, 0x73, 0x1a, 0x6d, 0x4c, 0x69, 0x73, 0x74, 0x73, 0x20, 0x61, 0x6c, 0x6c, 0x20, - 0x74, 0x68, 0x65, 0x20, 0x69, 0x6e, 0x76, 0x6f, 0x69, 0x63, 0x65, 0x73, 0x20, 0x66, 0x72, 0x6f, + 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x41, 0x64, 0x64, 0x50, 0x6c, 0x61, + 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x22, 0x66, 0x92, 0x41, 0x3b, 0x0a, 0x08, 0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, + 0x12, 0x11, 0x41, 0x64, 0x64, 0x20, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x75, + 0x73, 0x65, 0x72, 0x1a, 0x1c, 0x41, 0x64, 0x64, 0x73, 0x20, 0x61, 0x20, 0x75, 0x73, 0x65, 0x72, + 0x20, 0x74, 0x6f, 0x20, 0x74, 0x68, 0x65, 0x20, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, + 0x2e, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x22, 0x3a, 0x01, 0x2a, 0x22, 0x1d, 0x2f, 0x76, 0x31, 0x62, + 0x65, 0x74, 0x61, 0x31, 0x2f, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x2f, 0x70, 0x6c, 0x61, 0x74, 0x66, + 0x6f, 0x72, 0x6d, 0x2f, 0x75, 0x73, 0x65, 0x72, 0x73, 0x12, 0xf3, 0x01, 0x0a, 0x11, 0x4c, 0x69, + 0x73, 0x74, 0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x55, 0x73, 0x65, 0x72, 0x73, 0x12, + 0x33, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x66, 0x72, 0x6f, 0x6e, 0x74, + 0x69, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, + 0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x55, 0x73, 0x65, 0x72, 0x73, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x1a, 0x34, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, + 0x66, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, + 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x55, 0x73, 0x65, + 0x72, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x73, 0x92, 0x41, 0x4b, 0x0a, + 0x08, 0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x12, 0x13, 0x4c, 0x69, 0x73, 0x74, 0x20, + 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x75, 0x73, 0x65, 0x72, 0x73, 0x1a, 0x2a, + 0x4c, 0x69, 0x73, 0x74, 0x73, 0x20, 0x61, 0x6c, 0x6c, 0x20, 0x74, 0x68, 0x65, 0x20, 0x75, 0x73, + 0x65, 0x72, 0x73, 0x20, 0x61, 0x64, 0x64, 0x65, 0x64, 0x20, 0x74, 0x6f, 0x20, 0x74, 0x68, 0x65, + 0x20, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x2e, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1f, + 0x12, 0x1d, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x61, 0x64, 0x6d, 0x69, 0x6e, + 0x2f, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x2f, 0x75, 0x73, 0x65, 0x72, 0x73, 0x12, + 0xf8, 0x01, 0x0a, 0x12, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f, + 0x72, 0x6d, 0x55, 0x73, 0x65, 0x72, 0x12, 0x34, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, + 0x6b, 0x2e, 0x66, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, + 0x61, 0x31, 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, + 0x6d, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x35, 0x2e, 0x72, + 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x66, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, + 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x50, + 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x22, 0x75, 0x92, 0x41, 0x43, 0x0a, 0x08, 0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f, + 0x72, 0x6d, 0x12, 0x14, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x20, 0x70, 0x6c, 0x61, 0x74, 0x66, + 0x6f, 0x72, 0x6d, 0x20, 0x75, 0x73, 0x65, 0x72, 0x1a, 0x21, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, + 0x73, 0x20, 0x61, 0x20, 0x75, 0x73, 0x65, 0x72, 0x20, 0x66, 0x72, 0x6f, 0x6d, 0x20, 0x74, 0x68, + 0x65, 0x20, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x2e, 0x82, 0xd3, 0xe4, 0x93, 0x02, + 0x29, 0x3a, 0x01, 0x2a, 0x22, 0x24, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x61, + 0x64, 0x6d, 0x69, 0x6e, 0x2f, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x2f, 0x75, 0x73, + 0x65, 0x72, 0x73, 0x2f, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x12, 0xc0, 0x03, 0x0a, 0x11, 0x44, + 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x65, 0x64, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x6f, 0x75, 0x74, + 0x12, 0x33, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x66, 0x72, 0x6f, 0x6e, + 0x74, 0x69, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x44, 0x65, 0x6c, + 0x65, 0x67, 0x61, 0x74, 0x65, 0x64, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x6f, 0x75, 0x74, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x34, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, + 0x2e, 0x66, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, + 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x65, 0x64, 0x43, 0x68, 0x65, 0x63, 0x6b, + 0x6f, 0x75, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xbf, 0x02, 0x92, 0x41, + 0xad, 0x01, 0x0a, 0x08, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x6f, 0x75, 0x74, 0x12, 0x22, 0x43, 0x68, + 0x65, 0x63, 0x6b, 0x6f, 0x75, 0x74, 0x20, 0x61, 0x20, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, + 0x20, 0x6f, 0x72, 0x20, 0x73, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, + 0x1a, 0x7d, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x6f, 0x75, 0x74, 0x20, 0x61, 0x20, 0x70, 0x72, 0x6f, + 0x64, 0x75, 0x63, 0x74, 0x20, 0x74, 0x6f, 0x20, 0x62, 0x75, 0x79, 0x20, 0x69, 0x74, 0x20, 0x6f, + 0x6e, 0x65, 0x20, 0x74, 0x69, 0x6d, 0x65, 0x20, 0x6f, 0x72, 0x20, 0x73, 0x74, 0x61, 0x72, 0x74, + 0x20, 0x61, 0x20, 0x73, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x20, + 0x70, 0x6c, 0x61, 0x6e, 0x20, 0x6f, 0x6e, 0x20, 0x61, 0x20, 0x62, 0x69, 0x6c, 0x6c, 0x69, 0x6e, + 0x67, 0x20, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x20, 0x6d, 0x61, 0x6e, 0x75, 0x61, 0x6c, + 0x6c, 0x79, 0x2e, 0x20, 0x49, 0x74, 0x20, 0x62, 0x79, 0x70, 0x61, 0x73, 0x73, 0x65, 0x73, 0x20, + 0x62, 0x69, 0x6c, 0x6c, 0x69, 0x6e, 0x67, 0x20, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x2e, 0x82, + 0xd3, 0xe4, 0x93, 0x02, 0x87, 0x01, 0x3a, 0x01, 0x2a, 0x5a, 0x3c, 0x3a, 0x01, 0x2a, 0x22, 0x37, + 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x2f, 0x6f, + 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x7b, 0x6f, 0x72, + 0x67, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x62, 0x69, 0x6c, 0x6c, 0x69, 0x6e, 0x67, 0x2f, 0x63, 0x68, + 0x65, 0x63, 0x6b, 0x6f, 0x75, 0x74, 0x73, 0x22, 0x44, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, + 0x31, 0x2f, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x2f, 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x7b, 0x6f, 0x72, 0x67, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x62, + 0x69, 0x6c, 0x6c, 0x69, 0x6e, 0x67, 0x2f, 0x7b, 0x62, 0x69, 0x6c, 0x6c, 0x69, 0x6e, 0x67, 0x5f, + 0x69, 0x64, 0x7d, 0x2f, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x6f, 0x75, 0x74, 0x73, 0x12, 0xb1, 0x02, + 0x0a, 0x0f, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x6c, 0x6c, 0x49, 0x6e, 0x76, 0x6f, 0x69, 0x63, 0x65, + 0x73, 0x12, 0x31, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x66, 0x72, 0x6f, + 0x6e, 0x74, 0x69, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4c, 0x69, + 0x73, 0x74, 0x41, 0x6c, 0x6c, 0x49, 0x6e, 0x76, 0x6f, 0x69, 0x63, 0x65, 0x73, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x1a, 0x32, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, + 0x66, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, + 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x6c, 0x6c, 0x49, 0x6e, 0x76, 0x6f, 0x69, 0x63, 0x65, 0x73, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xb6, 0x01, 0x92, 0x41, 0x8b, 0x01, 0x0a, + 0x07, 0x49, 0x6e, 0x76, 0x6f, 0x69, 0x63, 0x65, 0x12, 0x11, 0x4c, 0x69, 0x73, 0x74, 0x20, 0x61, + 0x6c, 0x6c, 0x20, 0x69, 0x6e, 0x76, 0x6f, 0x69, 0x63, 0x65, 0x73, 0x1a, 0x6d, 0x4c, 0x69, 0x73, + 0x74, 0x73, 0x20, 0x61, 0x6c, 0x6c, 0x20, 0x74, 0x68, 0x65, 0x20, 0x69, 0x6e, 0x76, 0x6f, 0x69, + 0x63, 0x65, 0x73, 0x20, 0x66, 0x72, 0x6f, 0x6d, 0x20, 0x61, 0x6c, 0x6c, 0x20, 0x74, 0x68, 0x65, + 0x20, 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x69, + 0x6e, 0x20, 0x61, 0x20, 0x46, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x20, 0x69, 0x6e, 0x73, + 0x74, 0x61, 0x6e, 0x63, 0x65, 0x2e, 0x20, 0x49, 0x74, 0x20, 0x63, 0x61, 0x6e, 0x20, 0x62, 0x65, + 0x20, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x65, 0x64, 0x20, 0x62, 0x79, 0x20, 0x6f, 0x72, 0x67, + 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x21, + 0x12, 0x1f, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x61, 0x64, 0x6d, 0x69, 0x6e, + 0x2f, 0x62, 0x69, 0x6c, 0x6c, 0x69, 0x6e, 0x67, 0x2f, 0x69, 0x6e, 0x76, 0x6f, 0x69, 0x63, 0x65, + 0x73, 0x12, 0xd6, 0x02, 0x0a, 0x16, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x6c, 0x6c, 0x42, 0x69, 0x6c, + 0x6c, 0x69, 0x6e, 0x67, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x12, 0x38, 0x2e, 0x72, + 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x66, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, + 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x6c, 0x6c, + 0x42, 0x69, 0x6c, 0x6c, 0x69, 0x6e, 0x67, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x39, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, + 0x6b, 0x2e, 0x66, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, + 0x61, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x6c, 0x6c, 0x42, 0x69, 0x6c, 0x6c, 0x69, 0x6e, + 0x67, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x22, 0xc6, 0x01, 0x92, 0x41, 0x9b, 0x01, 0x0a, 0x07, 0x42, 0x69, 0x6c, 0x6c, 0x69, 0x6e, + 0x67, 0x12, 0x19, 0x4c, 0x69, 0x73, 0x74, 0x20, 0x61, 0x6c, 0x6c, 0x20, 0x62, 0x69, 0x6c, 0x6c, + 0x69, 0x6e, 0x67, 0x20, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x1a, 0x75, 0x4c, 0x69, + 0x73, 0x74, 0x73, 0x20, 0x61, 0x6c, 0x6c, 0x20, 0x74, 0x68, 0x65, 0x20, 0x62, 0x69, 0x6c, 0x6c, + 0x69, 0x6e, 0x67, 0x20, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x20, 0x66, 0x72, 0x6f, 0x6d, 0x20, 0x61, 0x6c, 0x6c, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x69, 0x6e, 0x20, 0x61, 0x20, 0x46, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x20, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x2e, 0x20, @@ -3767,221 +3903,219 @@ var file_raystack_frontier_v1beta1_admin_proto_rawDesc = []byte{ 0x65, 0x64, 0x20, 0x62, 0x79, 0x20, 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x21, 0x12, 0x1f, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x2f, 0x62, 0x69, 0x6c, 0x6c, 0x69, 0x6e, - 0x67, 0x2f, 0x69, 0x6e, 0x76, 0x6f, 0x69, 0x63, 0x65, 0x73, 0x12, 0xd6, 0x02, 0x0a, 0x16, 0x4c, - 0x69, 0x73, 0x74, 0x41, 0x6c, 0x6c, 0x42, 0x69, 0x6c, 0x6c, 0x69, 0x6e, 0x67, 0x41, 0x63, 0x63, - 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x12, 0x38, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, - 0x2e, 0x66, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, - 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x6c, 0x6c, 0x42, 0x69, 0x6c, 0x6c, 0x69, 0x6e, 0x67, - 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, - 0x39, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x66, 0x72, 0x6f, 0x6e, 0x74, - 0x69, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, - 0x41, 0x6c, 0x6c, 0x42, 0x69, 0x6c, 0x6c, 0x69, 0x6e, 0x67, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, - 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xc6, 0x01, 0x92, 0x41, 0x9b, - 0x01, 0x0a, 0x07, 0x42, 0x69, 0x6c, 0x6c, 0x69, 0x6e, 0x67, 0x12, 0x19, 0x4c, 0x69, 0x73, 0x74, - 0x20, 0x61, 0x6c, 0x6c, 0x20, 0x62, 0x69, 0x6c, 0x6c, 0x69, 0x6e, 0x67, 0x20, 0x61, 0x63, 0x63, - 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x1a, 0x75, 0x4c, 0x69, 0x73, 0x74, 0x73, 0x20, 0x61, 0x6c, 0x6c, - 0x20, 0x74, 0x68, 0x65, 0x20, 0x62, 0x69, 0x6c, 0x6c, 0x69, 0x6e, 0x67, 0x20, 0x61, 0x63, 0x63, - 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x20, 0x66, 0x72, 0x6f, 0x6d, 0x20, 0x61, 0x6c, 0x6c, 0x20, 0x74, - 0x68, 0x65, 0x20, 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, - 0x20, 0x69, 0x6e, 0x20, 0x61, 0x20, 0x46, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x20, 0x69, - 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x2e, 0x20, 0x49, 0x74, 0x20, 0x63, 0x61, 0x6e, 0x20, - 0x62, 0x65, 0x20, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x65, 0x64, 0x20, 0x62, 0x79, 0x20, 0x6f, - 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x82, 0xd3, 0xe4, 0x93, - 0x02, 0x21, 0x12, 0x1f, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x61, 0x64, 0x6d, - 0x69, 0x6e, 0x2f, 0x62, 0x69, 0x6c, 0x6c, 0x69, 0x6e, 0x67, 0x2f, 0x61, 0x63, 0x63, 0x6f, 0x75, - 0x6e, 0x74, 0x73, 0x12, 0xe4, 0x02, 0x0a, 0x12, 0x52, 0x65, 0x76, 0x65, 0x72, 0x74, 0x42, 0x69, - 0x6c, 0x6c, 0x69, 0x6e, 0x67, 0x55, 0x73, 0x61, 0x67, 0x65, 0x12, 0x34, 0x2e, 0x72, 0x61, 0x79, - 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x66, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x2e, 0x76, - 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x52, 0x65, 0x76, 0x65, 0x72, 0x74, 0x42, 0x69, 0x6c, - 0x6c, 0x69, 0x6e, 0x67, 0x55, 0x73, 0x61, 0x67, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x1a, 0x35, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x66, 0x72, 0x6f, 0x6e, - 0x74, 0x69, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x52, 0x65, 0x76, - 0x65, 0x72, 0x74, 0x42, 0x69, 0x6c, 0x6c, 0x69, 0x6e, 0x67, 0x55, 0x73, 0x61, 0x67, 0x65, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xe0, 0x01, 0x92, 0x41, 0x4c, 0x0a, 0x07, 0x42, - 0x69, 0x6c, 0x6c, 0x69, 0x6e, 0x67, 0x12, 0x14, 0x52, 0x65, 0x76, 0x65, 0x72, 0x74, 0x20, 0x62, - 0x69, 0x6c, 0x6c, 0x69, 0x6e, 0x67, 0x20, 0x75, 0x73, 0x61, 0x67, 0x65, 0x1a, 0x2b, 0x52, 0x65, - 0x76, 0x65, 0x72, 0x74, 0x20, 0x62, 0x69, 0x6c, 0x6c, 0x69, 0x6e, 0x67, 0x20, 0x75, 0x73, 0x61, - 0x67, 0x65, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x61, 0x20, 0x62, 0x69, 0x6c, 0x6c, 0x69, 0x6e, 0x67, - 0x20, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x2e, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x8a, 0x01, - 0x3a, 0x01, 0x2a, 0x5a, 0x31, 0x3a, 0x01, 0x2a, 0x22, 0x2c, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, - 0x61, 0x31, 0x2f, 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, - 0x2f, 0x62, 0x69, 0x6c, 0x6c, 0x69, 0x6e, 0x67, 0x2f, 0x75, 0x73, 0x61, 0x67, 0x65, 0x73, 0x2f, - 0x72, 0x65, 0x76, 0x65, 0x72, 0x74, 0x22, 0x52, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, - 0x2f, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x2f, 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x7b, 0x6f, 0x72, 0x67, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x62, 0x69, - 0x6c, 0x6c, 0x69, 0x6e, 0x67, 0x2f, 0x7b, 0x62, 0x69, 0x6c, 0x6c, 0x69, 0x6e, 0x67, 0x5f, 0x69, - 0x64, 0x7d, 0x2f, 0x75, 0x73, 0x61, 0x67, 0x65, 0x2f, 0x7b, 0x75, 0x73, 0x61, 0x67, 0x65, 0x5f, - 0x69, 0x64, 0x7d, 0x2f, 0x72, 0x65, 0x76, 0x65, 0x72, 0x74, 0x12, 0xc9, 0x01, 0x0a, 0x0d, 0x43, - 0x72, 0x65, 0x61, 0x74, 0x65, 0x57, 0x65, 0x62, 0x68, 0x6f, 0x6f, 0x6b, 0x12, 0x2f, 0x2e, 0x72, + 0x67, 0x2f, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x12, 0xe4, 0x02, 0x0a, 0x12, 0x52, + 0x65, 0x76, 0x65, 0x72, 0x74, 0x42, 0x69, 0x6c, 0x6c, 0x69, 0x6e, 0x67, 0x55, 0x73, 0x61, 0x67, + 0x65, 0x12, 0x34, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x66, 0x72, 0x6f, + 0x6e, 0x74, 0x69, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x52, 0x65, + 0x76, 0x65, 0x72, 0x74, 0x42, 0x69, 0x6c, 0x6c, 0x69, 0x6e, 0x67, 0x55, 0x73, 0x61, 0x67, 0x65, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x35, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, + 0x63, 0x6b, 0x2e, 0x66, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, + 0x74, 0x61, 0x31, 0x2e, 0x52, 0x65, 0x76, 0x65, 0x72, 0x74, 0x42, 0x69, 0x6c, 0x6c, 0x69, 0x6e, + 0x67, 0x55, 0x73, 0x61, 0x67, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xe0, + 0x01, 0x92, 0x41, 0x4c, 0x0a, 0x07, 0x42, 0x69, 0x6c, 0x6c, 0x69, 0x6e, 0x67, 0x12, 0x14, 0x52, + 0x65, 0x76, 0x65, 0x72, 0x74, 0x20, 0x62, 0x69, 0x6c, 0x6c, 0x69, 0x6e, 0x67, 0x20, 0x75, 0x73, + 0x61, 0x67, 0x65, 0x1a, 0x2b, 0x52, 0x65, 0x76, 0x65, 0x72, 0x74, 0x20, 0x62, 0x69, 0x6c, 0x6c, + 0x69, 0x6e, 0x67, 0x20, 0x75, 0x73, 0x61, 0x67, 0x65, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x61, 0x20, + 0x62, 0x69, 0x6c, 0x6c, 0x69, 0x6e, 0x67, 0x20, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x2e, + 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x8a, 0x01, 0x3a, 0x01, 0x2a, 0x5a, 0x31, 0x3a, 0x01, 0x2a, 0x22, + 0x2c, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x69, + 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x62, 0x69, 0x6c, 0x6c, 0x69, 0x6e, 0x67, 0x2f, + 0x75, 0x73, 0x61, 0x67, 0x65, 0x73, 0x2f, 0x72, 0x65, 0x76, 0x65, 0x72, 0x74, 0x22, 0x52, 0x2f, + 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x2f, 0x6f, 0x72, + 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x7b, 0x6f, 0x72, 0x67, + 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x62, 0x69, 0x6c, 0x6c, 0x69, 0x6e, 0x67, 0x2f, 0x7b, 0x62, 0x69, + 0x6c, 0x6c, 0x69, 0x6e, 0x67, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x75, 0x73, 0x61, 0x67, 0x65, 0x2f, + 0x7b, 0x75, 0x73, 0x61, 0x67, 0x65, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x72, 0x65, 0x76, 0x65, 0x72, + 0x74, 0x12, 0xc9, 0x01, 0x0a, 0x0d, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x57, 0x65, 0x62, 0x68, + 0x6f, 0x6f, 0x6b, 0x12, 0x2f, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x66, + 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, + 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x57, 0x65, 0x62, 0x68, 0x6f, 0x6f, 0x6b, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x1a, 0x30, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, + 0x66, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, + 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x57, 0x65, 0x62, 0x68, 0x6f, 0x6f, 0x6b, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x55, 0x92, 0x41, 0x30, 0x0a, 0x07, 0x57, 0x65, 0x62, + 0x68, 0x6f, 0x6f, 0x6b, 0x12, 0x0e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x20, 0x77, 0x65, 0x62, + 0x68, 0x6f, 0x6f, 0x6b, 0x1a, 0x15, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x20, 0x61, 0x20, 0x6e, + 0x65, 0x77, 0x20, 0x77, 0x65, 0x62, 0x68, 0x6f, 0x6f, 0x6b, 0x2e, 0x82, 0xd3, 0xe4, 0x93, 0x02, + 0x1c, 0x3a, 0x01, 0x2a, 0x22, 0x17, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x61, + 0x64, 0x6d, 0x69, 0x6e, 0x2f, 0x77, 0x65, 0x62, 0x68, 0x6f, 0x6f, 0x6b, 0x73, 0x12, 0xca, 0x01, + 0x0a, 0x0d, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x57, 0x65, 0x62, 0x68, 0x6f, 0x6f, 0x6b, 0x12, + 0x2f, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x66, 0x72, 0x6f, 0x6e, 0x74, + 0x69, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, + 0x74, 0x65, 0x57, 0x65, 0x62, 0x68, 0x6f, 0x6f, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x30, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x66, 0x72, 0x6f, 0x6e, + 0x74, 0x69, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x55, 0x70, 0x64, + 0x61, 0x74, 0x65, 0x57, 0x65, 0x62, 0x68, 0x6f, 0x6f, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x22, 0x56, 0x92, 0x41, 0x2c, 0x0a, 0x07, 0x57, 0x65, 0x62, 0x68, 0x6f, 0x6f, 0x6b, + 0x12, 0x0e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x20, 0x77, 0x65, 0x62, 0x68, 0x6f, 0x6f, 0x6b, + 0x1a, 0x11, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x20, 0x61, 0x20, 0x77, 0x65, 0x62, 0x68, 0x6f, + 0x6f, 0x6b, 0x2e, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x21, 0x3a, 0x01, 0x2a, 0x1a, 0x1c, 0x2f, 0x76, + 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x2f, 0x77, 0x65, 0x62, + 0x68, 0x6f, 0x6f, 0x6b, 0x73, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x12, 0xc7, 0x01, 0x0a, 0x0d, 0x44, + 0x65, 0x6c, 0x65, 0x74, 0x65, 0x57, 0x65, 0x62, 0x68, 0x6f, 0x6f, 0x6b, 0x12, 0x2f, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x66, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, - 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x57, + 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x57, 0x65, 0x62, 0x68, 0x6f, 0x6f, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x30, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x66, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, - 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, + 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x57, 0x65, 0x62, 0x68, 0x6f, 0x6f, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, - 0x55, 0x92, 0x41, 0x30, 0x0a, 0x07, 0x57, 0x65, 0x62, 0x68, 0x6f, 0x6f, 0x6b, 0x12, 0x0e, 0x43, - 0x72, 0x65, 0x61, 0x74, 0x65, 0x20, 0x77, 0x65, 0x62, 0x68, 0x6f, 0x6f, 0x6b, 0x1a, 0x15, 0x43, - 0x72, 0x65, 0x61, 0x74, 0x65, 0x20, 0x61, 0x20, 0x6e, 0x65, 0x77, 0x20, 0x77, 0x65, 0x62, 0x68, - 0x6f, 0x6f, 0x6b, 0x2e, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1c, 0x3a, 0x01, 0x2a, 0x22, 0x17, 0x2f, + 0x53, 0x92, 0x41, 0x2c, 0x0a, 0x07, 0x57, 0x65, 0x62, 0x68, 0x6f, 0x6f, 0x6b, 0x12, 0x0e, 0x44, + 0x65, 0x6c, 0x65, 0x74, 0x65, 0x20, 0x77, 0x65, 0x62, 0x68, 0x6f, 0x6f, 0x6b, 0x1a, 0x11, 0x44, + 0x65, 0x6c, 0x65, 0x74, 0x65, 0x20, 0x61, 0x20, 0x77, 0x65, 0x62, 0x68, 0x6f, 0x6f, 0x6b, 0x2e, + 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1e, 0x2a, 0x1c, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, + 0x2f, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x2f, 0x77, 0x65, 0x62, 0x68, 0x6f, 0x6f, 0x6b, 0x73, 0x2f, + 0x7b, 0x69, 0x64, 0x7d, 0x12, 0xbf, 0x01, 0x0a, 0x0c, 0x4c, 0x69, 0x73, 0x74, 0x57, 0x65, 0x62, + 0x68, 0x6f, 0x6f, 0x6b, 0x73, 0x12, 0x2e, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, + 0x2e, 0x66, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, + 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x57, 0x65, 0x62, 0x68, 0x6f, 0x6f, 0x6b, 0x73, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2f, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, + 0x2e, 0x66, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, + 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x57, 0x65, 0x62, 0x68, 0x6f, 0x6f, 0x6b, 0x73, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x4e, 0x92, 0x41, 0x2c, 0x0a, 0x07, 0x57, 0x65, 0x62, + 0x68, 0x6f, 0x6f, 0x6b, 0x12, 0x0d, 0x4c, 0x69, 0x73, 0x74, 0x20, 0x77, 0x65, 0x62, 0x68, 0x6f, + 0x6f, 0x6b, 0x73, 0x1a, 0x12, 0x4c, 0x69, 0x73, 0x74, 0x20, 0x61, 0x6c, 0x6c, 0x20, 0x77, 0x65, + 0x62, 0x68, 0x6f, 0x6f, 0x6b, 0x73, 0x2e, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x19, 0x12, 0x17, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x2f, 0x77, 0x65, - 0x62, 0x68, 0x6f, 0x6f, 0x6b, 0x73, 0x12, 0xca, 0x01, 0x0a, 0x0d, 0x55, 0x70, 0x64, 0x61, 0x74, - 0x65, 0x57, 0x65, 0x62, 0x68, 0x6f, 0x6f, 0x6b, 0x12, 0x2f, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, - 0x61, 0x63, 0x6b, 0x2e, 0x66, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, - 0x65, 0x74, 0x61, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x57, 0x65, 0x62, 0x68, 0x6f, - 0x6f, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x30, 0x2e, 0x72, 0x61, 0x79, 0x73, - 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x66, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x2e, 0x76, 0x31, - 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x57, 0x65, 0x62, 0x68, - 0x6f, 0x6f, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x56, 0x92, 0x41, 0x2c, - 0x0a, 0x07, 0x57, 0x65, 0x62, 0x68, 0x6f, 0x6f, 0x6b, 0x12, 0x0e, 0x55, 0x70, 0x64, 0x61, 0x74, - 0x65, 0x20, 0x77, 0x65, 0x62, 0x68, 0x6f, 0x6f, 0x6b, 0x1a, 0x11, 0x55, 0x70, 0x64, 0x61, 0x74, - 0x65, 0x20, 0x61, 0x20, 0x77, 0x65, 0x62, 0x68, 0x6f, 0x6f, 0x6b, 0x2e, 0x82, 0xd3, 0xe4, 0x93, - 0x02, 0x21, 0x3a, 0x01, 0x2a, 0x1a, 0x1c, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, - 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x2f, 0x77, 0x65, 0x62, 0x68, 0x6f, 0x6f, 0x6b, 0x73, 0x2f, 0x7b, - 0x69, 0x64, 0x7d, 0x12, 0xc7, 0x01, 0x0a, 0x0d, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x57, 0x65, - 0x62, 0x68, 0x6f, 0x6f, 0x6b, 0x12, 0x2f, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, + 0x62, 0x68, 0x6f, 0x6f, 0x6b, 0x73, 0x12, 0xab, 0x02, 0x0a, 0x1a, 0x55, 0x70, 0x64, 0x61, 0x74, + 0x65, 0x42, 0x69, 0x6c, 0x6c, 0x69, 0x6e, 0x67, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x4c, + 0x69, 0x6d, 0x69, 0x74, 0x73, 0x12, 0x3c, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x66, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, - 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x57, 0x65, 0x62, 0x68, 0x6f, 0x6f, 0x6b, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x30, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, - 0x6b, 0x2e, 0x66, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, - 0x61, 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x57, 0x65, 0x62, 0x68, 0x6f, 0x6f, 0x6b, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x53, 0x92, 0x41, 0x2c, 0x0a, 0x07, 0x57, - 0x65, 0x62, 0x68, 0x6f, 0x6f, 0x6b, 0x12, 0x0e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x20, 0x77, - 0x65, 0x62, 0x68, 0x6f, 0x6f, 0x6b, 0x1a, 0x11, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x20, 0x61, - 0x20, 0x77, 0x65, 0x62, 0x68, 0x6f, 0x6f, 0x6b, 0x2e, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1e, 0x2a, - 0x1c, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x2f, - 0x77, 0x65, 0x62, 0x68, 0x6f, 0x6f, 0x6b, 0x73, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x12, 0xbf, 0x01, - 0x0a, 0x0c, 0x4c, 0x69, 0x73, 0x74, 0x57, 0x65, 0x62, 0x68, 0x6f, 0x6f, 0x6b, 0x73, 0x12, 0x2e, - 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x66, 0x72, 0x6f, 0x6e, 0x74, 0x69, - 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x57, - 0x65, 0x62, 0x68, 0x6f, 0x6f, 0x6b, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2f, - 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x66, 0x72, 0x6f, 0x6e, 0x74, 0x69, - 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x57, - 0x65, 0x62, 0x68, 0x6f, 0x6f, 0x6b, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, - 0x4e, 0x92, 0x41, 0x2c, 0x0a, 0x07, 0x57, 0x65, 0x62, 0x68, 0x6f, 0x6f, 0x6b, 0x12, 0x0d, 0x4c, - 0x69, 0x73, 0x74, 0x20, 0x77, 0x65, 0x62, 0x68, 0x6f, 0x6f, 0x6b, 0x73, 0x1a, 0x12, 0x4c, 0x69, - 0x73, 0x74, 0x20, 0x61, 0x6c, 0x6c, 0x20, 0x77, 0x65, 0x62, 0x68, 0x6f, 0x6f, 0x6b, 0x73, 0x2e, - 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x19, 0x12, 0x17, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, - 0x2f, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x2f, 0x77, 0x65, 0x62, 0x68, 0x6f, 0x6f, 0x6b, 0x73, 0x42, - 0xf4, 0x0e, 0x92, 0x41, 0x84, 0x0e, 0x12, 0xfe, 0x06, 0x0a, 0x1b, 0x46, 0x72, 0x6f, 0x6e, 0x74, - 0x69, 0x65, 0x72, 0x20, 0x41, 0x64, 0x6d, 0x69, 0x6e, 0x69, 0x73, 0x74, 0x72, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x20, 0x41, 0x50, 0x49, 0x12, 0xcf, 0x05, 0x54, 0x68, 0x65, 0x20, 0x46, 0x72, 0x6f, - 0x6e, 0x74, 0x69, 0x65, 0x72, 0x20, 0x41, 0x50, 0x49, 0x73, 0x20, 0x61, 0x64, 0x68, 0x65, 0x72, - 0x65, 0x20, 0x74, 0x6f, 0x20, 0x74, 0x68, 0x65, 0x20, 0x4f, 0x70, 0x65, 0x6e, 0x41, 0x50, 0x49, - 0x20, 0x73, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2c, 0x20, - 0x61, 0x6c, 0x73, 0x6f, 0x20, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x20, 0x61, 0x73, 0x20, 0x53, 0x77, - 0x61, 0x67, 0x67, 0x65, 0x72, 0x2c, 0x20, 0x77, 0x68, 0x69, 0x63, 0x68, 0x20, 0x70, 0x72, 0x6f, - 0x76, 0x69, 0x64, 0x65, 0x73, 0x20, 0x61, 0x20, 0x73, 0x74, 0x61, 0x6e, 0x64, 0x61, 0x72, 0x64, - 0x69, 0x7a, 0x65, 0x64, 0x20, 0x61, 0x70, 0x70, 0x72, 0x6f, 0x61, 0x63, 0x68, 0x20, 0x66, 0x6f, - 0x72, 0x20, 0x64, 0x65, 0x73, 0x69, 0x67, 0x6e, 0x69, 0x6e, 0x67, 0x2c, 0x20, 0x64, 0x6f, 0x63, - 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x69, 0x6e, 0x67, 0x2c, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x63, 0x6f, - 0x6e, 0x73, 0x75, 0x6d, 0x69, 0x6e, 0x67, 0x20, 0x52, 0x45, 0x53, 0x54, 0x66, 0x75, 0x6c, 0x20, - 0x41, 0x50, 0x49, 0x73, 0x2e, 0x20, 0x57, 0x69, 0x74, 0x68, 0x20, 0x4f, 0x70, 0x65, 0x6e, 0x41, - 0x50, 0x49, 0x2c, 0x20, 0x79, 0x6f, 0x75, 0x20, 0x67, 0x61, 0x69, 0x6e, 0x20, 0x61, 0x20, 0x63, - 0x6c, 0x65, 0x61, 0x72, 0x20, 0x75, 0x6e, 0x64, 0x65, 0x72, 0x73, 0x74, 0x61, 0x6e, 0x64, 0x69, - 0x6e, 0x67, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x41, 0x50, 0x49, 0x20, 0x65, 0x6e, - 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x73, 0x2c, 0x20, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x2f, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x20, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, - 0x75, 0x72, 0x65, 0x73, 0x2c, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x61, 0x75, 0x74, 0x68, 0x65, 0x6e, - 0x74, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6d, 0x65, 0x63, 0x68, 0x61, 0x6e, 0x69, - 0x73, 0x6d, 0x73, 0x20, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x20, 0x62, 0x79, - 0x20, 0x74, 0x68, 0x65, 0x20, 0x46, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x20, 0x41, 0x50, - 0x49, 0x73, 0x2e, 0x20, 0x42, 0x79, 0x20, 0x6c, 0x65, 0x76, 0x65, 0x72, 0x61, 0x67, 0x69, 0x6e, - 0x67, 0x20, 0x74, 0x68, 0x65, 0x20, 0x4f, 0x70, 0x65, 0x6e, 0x41, 0x50, 0x49, 0x20, 0x73, 0x70, - 0x65, 0x63, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2c, 0x20, 0x64, 0x65, 0x76, - 0x65, 0x6c, 0x6f, 0x70, 0x65, 0x72, 0x73, 0x20, 0x63, 0x61, 0x6e, 0x20, 0x65, 0x61, 0x73, 0x69, - 0x6c, 0x79, 0x20, 0x65, 0x78, 0x70, 0x6c, 0x6f, 0x72, 0x65, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x69, - 0x6e, 0x74, 0x65, 0x72, 0x61, 0x63, 0x74, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x74, 0x68, 0x65, - 0x20, 0x46, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x20, 0x41, 0x50, 0x49, 0x73, 0x20, 0x75, - 0x73, 0x69, 0x6e, 0x67, 0x20, 0x61, 0x20, 0x76, 0x61, 0x72, 0x69, 0x65, 0x74, 0x79, 0x20, 0x6f, - 0x66, 0x20, 0x74, 0x6f, 0x6f, 0x6c, 0x73, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x6c, 0x69, 0x62, 0x72, - 0x61, 0x72, 0x69, 0x65, 0x73, 0x2e, 0x20, 0x54, 0x68, 0x65, 0x20, 0x4f, 0x70, 0x65, 0x6e, 0x41, + 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x42, 0x69, 0x6c, 0x6c, 0x69, 0x6e, 0x67, 0x41, + 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x3d, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x66, + 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, + 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x42, 0x69, 0x6c, 0x6c, 0x69, 0x6e, 0x67, 0x41, 0x63, 0x63, + 0x6f, 0x75, 0x6e, 0x74, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x22, 0x8f, 0x01, 0x92, 0x41, 0x48, 0x0a, 0x07, 0x42, 0x69, 0x6c, 0x6c, 0x69, 0x6e, + 0x67, 0x12, 0x1d, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x20, 0x62, 0x69, 0x6c, 0x6c, 0x69, 0x6e, + 0x67, 0x20, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x20, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x73, + 0x1a, 0x1e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x20, 0x62, 0x69, 0x6c, 0x6c, 0x69, 0x6e, 0x67, + 0x20, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x20, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x73, 0x2e, + 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x3e, 0x3a, 0x01, 0x2a, 0x1a, 0x39, 0x2f, 0x76, 0x31, 0x62, 0x65, + 0x74, 0x61, 0x31, 0x2f, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x2f, 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x69, + 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x7b, 0x6f, 0x72, 0x67, 0x5f, 0x69, 0x64, 0x7d, + 0x2f, 0x62, 0x69, 0x6c, 0x6c, 0x69, 0x6e, 0x67, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x2f, 0x6c, 0x69, + 0x6d, 0x69, 0x74, 0x73, 0x42, 0xf4, 0x0e, 0x92, 0x41, 0x84, 0x0e, 0x12, 0xfe, 0x06, 0x0a, 0x1b, + 0x46, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x20, 0x41, 0x64, 0x6d, 0x69, 0x6e, 0x69, 0x73, + 0x74, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x50, 0x49, 0x12, 0xcf, 0x05, 0x54, 0x68, + 0x65, 0x20, 0x46, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x20, 0x41, 0x50, 0x49, 0x73, 0x20, + 0x61, 0x64, 0x68, 0x65, 0x72, 0x65, 0x20, 0x74, 0x6f, 0x20, 0x74, 0x68, 0x65, 0x20, 0x4f, 0x70, + 0x65, 0x6e, 0x41, 0x50, 0x49, 0x20, 0x73, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x2c, 0x20, 0x61, 0x6c, 0x73, 0x6f, 0x20, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x20, + 0x61, 0x73, 0x20, 0x53, 0x77, 0x61, 0x67, 0x67, 0x65, 0x72, 0x2c, 0x20, 0x77, 0x68, 0x69, 0x63, + 0x68, 0x20, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x73, 0x20, 0x61, 0x20, 0x73, 0x74, 0x61, + 0x6e, 0x64, 0x61, 0x72, 0x64, 0x69, 0x7a, 0x65, 0x64, 0x20, 0x61, 0x70, 0x70, 0x72, 0x6f, 0x61, + 0x63, 0x68, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x64, 0x65, 0x73, 0x69, 0x67, 0x6e, 0x69, 0x6e, 0x67, + 0x2c, 0x20, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x69, 0x6e, 0x67, 0x2c, 0x20, 0x61, + 0x6e, 0x64, 0x20, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x69, 0x6e, 0x67, 0x20, 0x52, 0x45, 0x53, + 0x54, 0x66, 0x75, 0x6c, 0x20, 0x41, 0x50, 0x49, 0x73, 0x2e, 0x20, 0x57, 0x69, 0x74, 0x68, 0x20, + 0x4f, 0x70, 0x65, 0x6e, 0x41, 0x50, 0x49, 0x2c, 0x20, 0x79, 0x6f, 0x75, 0x20, 0x67, 0x61, 0x69, + 0x6e, 0x20, 0x61, 0x20, 0x63, 0x6c, 0x65, 0x61, 0x72, 0x20, 0x75, 0x6e, 0x64, 0x65, 0x72, 0x73, + 0x74, 0x61, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x41, + 0x50, 0x49, 0x20, 0x65, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x73, 0x2c, 0x20, 0x72, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x2f, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x20, 0x73, + 0x74, 0x72, 0x75, 0x63, 0x74, 0x75, 0x72, 0x65, 0x73, 0x2c, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x61, + 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6d, 0x65, + 0x63, 0x68, 0x61, 0x6e, 0x69, 0x73, 0x6d, 0x73, 0x20, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, + 0x65, 0x64, 0x20, 0x62, 0x79, 0x20, 0x74, 0x68, 0x65, 0x20, 0x46, 0x72, 0x6f, 0x6e, 0x74, 0x69, + 0x65, 0x72, 0x20, 0x41, 0x50, 0x49, 0x73, 0x2e, 0x20, 0x42, 0x79, 0x20, 0x6c, 0x65, 0x76, 0x65, + 0x72, 0x61, 0x67, 0x69, 0x6e, 0x67, 0x20, 0x74, 0x68, 0x65, 0x20, 0x4f, 0x70, 0x65, 0x6e, 0x41, 0x50, 0x49, 0x20, 0x73, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x20, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x20, 0x61, 0x75, 0x74, 0x6f, 0x6d, 0x61, 0x74, - 0x69, 0x63, 0x20, 0x63, 0x6f, 0x64, 0x65, 0x20, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x2c, 0x20, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x20, - 0x41, 0x50, 0x49, 0x20, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x2c, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x73, 0x65, 0x61, 0x6d, 0x6c, 0x65, 0x73, 0x73, 0x20, - 0x69, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x77, 0x69, 0x74, 0x68, - 0x20, 0x41, 0x50, 0x49, 0x20, 0x74, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x20, 0x66, 0x72, 0x61, - 0x6d, 0x65, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x2c, 0x20, 0x6d, 0x61, 0x6b, 0x69, 0x6e, 0x67, 0x20, - 0x69, 0x74, 0x20, 0x65, 0x61, 0x73, 0x69, 0x65, 0x72, 0x20, 0x74, 0x68, 0x61, 0x6e, 0x20, 0x65, - 0x76, 0x65, 0x72, 0x20, 0x74, 0x6f, 0x20, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x65, - 0x20, 0x46, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x20, 0x69, 0x6e, 0x74, 0x6f, 0x20, 0x79, - 0x6f, 0x75, 0x72, 0x20, 0x65, 0x78, 0x69, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x20, 0x61, 0x70, 0x70, - 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x77, 0x6f, - 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x73, 0x2e, 0x22, 0x40, 0x0a, 0x13, 0x52, 0x61, 0x79, 0x73, - 0x74, 0x61, 0x63, 0x6b, 0x20, 0x46, 0x6f, 0x75, 0x6e, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, - 0x15, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, - 0x6b, 0x2e, 0x6f, 0x72, 0x67, 0x2f, 0x1a, 0x12, 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x40, 0x72, 0x61, - 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x6f, 0x72, 0x67, 0x2a, 0x44, 0x0a, 0x0a, 0x41, 0x70, - 0x61, 0x63, 0x68, 0x65, 0x20, 0x32, 0x2e, 0x30, 0x12, 0x36, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, - 0x2f, 0x2f, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x72, 0x61, 0x79, - 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2f, 0x66, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x2f, 0x62, - 0x6c, 0x6f, 0x62, 0x2f, 0x6d, 0x61, 0x69, 0x6e, 0x2f, 0x4c, 0x49, 0x43, 0x45, 0x4e, 0x53, 0x45, - 0x32, 0x05, 0x30, 0x2e, 0x32, 0x2e, 0x30, 0x1a, 0x0e, 0x31, 0x32, 0x37, 0x2e, 0x30, 0x2e, 0x30, - 0x2e, 0x31, 0x3a, 0x37, 0x34, 0x30, 0x30, 0x2a, 0x01, 0x01, 0x32, 0x10, 0x61, 0x70, 0x70, 0x6c, - 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x6a, 0x73, 0x6f, 0x6e, 0x3a, 0x10, 0x61, 0x70, - 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x6a, 0x73, 0x6f, 0x6e, 0x52, 0x3c, - 0x0a, 0x03, 0x32, 0x30, 0x30, 0x12, 0x35, 0x0a, 0x1b, 0x4f, 0x4b, 0x20, 0x2d, 0x20, 0x41, 0x20, - 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x66, 0x75, 0x6c, 0x20, 0x72, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x2e, 0x12, 0x16, 0x0a, 0x14, 0x1a, 0x12, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, - 0x65, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x69, 0x0a, 0x03, - 0x34, 0x30, 0x30, 0x12, 0x62, 0x0a, 0x48, 0x42, 0x61, 0x64, 0x20, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x20, 0x2d, 0x20, 0x54, 0x68, 0x65, 0x20, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x20, 0x77, 0x61, 0x73, 0x20, 0x6d, 0x61, 0x6c, 0x66, 0x6f, 0x72, 0x6d, 0x65, 0x64, 0x20, 0x6f, - 0x72, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x64, 0x20, 0x69, 0x6e, 0x76, 0x61, - 0x6c, 0x69, 0x64, 0x20, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x2e, 0x12, - 0x16, 0x0a, 0x14, 0x1a, 0x12, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x72, 0x70, 0x63, - 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x4a, 0x0a, 0x03, 0x34, 0x30, 0x31, 0x12, 0x43, - 0x0a, 0x29, 0x55, 0x6e, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x64, 0x20, 0x2d, - 0x20, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, - 0x69, 0x73, 0x20, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x12, 0x16, 0x0a, 0x14, 0x1a, - 0x12, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x74, 0x61, - 0x74, 0x75, 0x73, 0x52, 0x61, 0x0a, 0x03, 0x34, 0x30, 0x33, 0x12, 0x5a, 0x0a, 0x40, 0x46, 0x6f, - 0x72, 0x62, 0x69, 0x64, 0x64, 0x65, 0x6e, 0x20, 0x2d, 0x20, 0x55, 0x73, 0x65, 0x72, 0x20, 0x64, - 0x6f, 0x65, 0x73, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x68, 0x61, 0x76, 0x65, 0x20, 0x70, 0x65, 0x72, - 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x74, 0x6f, 0x20, 0x61, 0x63, 0x63, 0x65, 0x73, - 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x16, - 0x0a, 0x14, 0x1a, 0x12, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x72, 0x70, 0x63, 0x2e, - 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x51, 0x0a, 0x03, 0x34, 0x30, 0x34, 0x12, 0x4a, 0x0a, - 0x30, 0x4e, 0x6f, 0x74, 0x20, 0x46, 0x6f, 0x75, 0x6e, 0x64, 0x20, 0x2d, 0x20, 0x54, 0x68, 0x65, - 0x20, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x65, 0x64, 0x20, 0x72, 0x65, 0x73, 0x6f, 0x75, - 0x72, 0x63, 0x65, 0x20, 0x77, 0x61, 0x73, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x66, 0x6f, 0x75, 0x6e, - 0x64, 0x12, 0x16, 0x0a, 0x14, 0x1a, 0x12, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x72, - 0x70, 0x63, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x75, 0x0a, 0x03, 0x35, 0x30, 0x30, - 0x12, 0x6e, 0x0a, 0x54, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x20, 0x53, 0x65, 0x72, - 0x76, 0x65, 0x72, 0x20, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x2e, 0x20, 0x52, 0x65, 0x74, 0x75, 0x72, - 0x6e, 0x65, 0x64, 0x20, 0x77, 0x68, 0x65, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x72, 0x65, 0x73, 0x20, - 0x69, 0x73, 0x20, 0x73, 0x6f, 0x6d, 0x65, 0x74, 0x68, 0x69, 0x6e, 0x67, 0x20, 0x77, 0x72, 0x6f, - 0x6e, 0x67, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x46, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, - 0x20, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x12, 0x16, 0x0a, 0x14, 0x1a, 0x12, 0x2e, 0x67, - 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, - 0x5a, 0xa8, 0x01, 0x0a, 0x4e, 0x0a, 0x05, 0x42, 0x61, 0x73, 0x69, 0x63, 0x12, 0x45, 0x08, 0x01, - 0x12, 0x37, 0x75, 0x73, 0x65, 0x20, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x20, 0x49, 0x44, 0x20, - 0x61, 0x73, 0x20, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x61, 0x6e, 0x64, 0x20, - 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x20, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x20, 0x61, 0x73, - 0x20, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x1a, 0x06, 0x42, 0x61, 0x73, 0x69, 0x63, - 0x20, 0x20, 0x02, 0x0a, 0x56, 0x0a, 0x06, 0x42, 0x65, 0x61, 0x72, 0x65, 0x72, 0x12, 0x4c, 0x08, - 0x03, 0x12, 0x3d, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x20, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x20, - 0x6f, 0x72, 0x20, 0x4a, 0x57, 0x54, 0x20, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x2c, 0x20, 0x70, 0x72, - 0x65, 0x66, 0x69, 0x78, 0x65, 0x64, 0x20, 0x62, 0x79, 0x20, 0x42, 0x65, 0x61, 0x72, 0x65, 0x72, - 0x3a, 0x20, 0x42, 0x65, 0x61, 0x72, 0x65, 0x72, 0x20, 0x3c, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x3e, - 0x1a, 0x07, 0x42, 0x65, 0x61, 0x72, 0x65, 0x72, 0x20, 0x20, 0x02, 0x62, 0x0b, 0x0a, 0x09, 0x0a, - 0x05, 0x42, 0x61, 0x73, 0x69, 0x63, 0x12, 0x00, 0x62, 0x0c, 0x0a, 0x0a, 0x0a, 0x06, 0x42, 0x65, - 0x61, 0x72, 0x65, 0x72, 0x12, 0x00, 0x6a, 0x06, 0x0a, 0x04, 0x55, 0x73, 0x65, 0x72, 0x6a, 0x07, - 0x0a, 0x05, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x6a, 0x0e, 0x0a, 0x0c, 0x4f, 0x72, 0x67, 0x61, 0x6e, - 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x6a, 0x09, 0x0a, 0x07, 0x50, 0x72, 0x6f, 0x6a, 0x65, - 0x63, 0x74, 0x6a, 0x0a, 0x0a, 0x08, 0x52, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x6a, 0x0a, - 0x0a, 0x08, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x6a, 0x08, 0x0a, 0x06, 0x50, 0x6f, - 0x6c, 0x69, 0x63, 0x79, 0x6a, 0x06, 0x0a, 0x04, 0x52, 0x6f, 0x6c, 0x65, 0x6a, 0x0c, 0x0a, 0x0a, - 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x0a, 0x23, 0x69, 0x6f, 0x2e, 0x72, - 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x6e, 0x2e, 0x66, - 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x42, - 0x08, 0x46, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x5a, 0x3b, 0x67, 0x69, 0x74, 0x68, 0x75, - 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2f, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x6e, 0x2f, 0x66, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x2f, 0x76, - 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x3b, 0x66, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x76, - 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x2c, 0x20, 0x64, 0x65, 0x76, 0x65, 0x6c, 0x6f, 0x70, 0x65, 0x72, 0x73, 0x20, 0x63, 0x61, 0x6e, + 0x20, 0x65, 0x61, 0x73, 0x69, 0x6c, 0x79, 0x20, 0x65, 0x78, 0x70, 0x6c, 0x6f, 0x72, 0x65, 0x20, + 0x61, 0x6e, 0x64, 0x20, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x61, 0x63, 0x74, 0x20, 0x77, 0x69, 0x74, + 0x68, 0x20, 0x74, 0x68, 0x65, 0x20, 0x46, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x20, 0x41, + 0x50, 0x49, 0x73, 0x20, 0x75, 0x73, 0x69, 0x6e, 0x67, 0x20, 0x61, 0x20, 0x76, 0x61, 0x72, 0x69, + 0x65, 0x74, 0x79, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x6f, 0x6f, 0x6c, 0x73, 0x20, 0x61, 0x6e, 0x64, + 0x20, 0x6c, 0x69, 0x62, 0x72, 0x61, 0x72, 0x69, 0x65, 0x73, 0x2e, 0x20, 0x54, 0x68, 0x65, 0x20, + 0x4f, 0x70, 0x65, 0x6e, 0x41, 0x50, 0x49, 0x20, 0x73, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x63, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x20, 0x61, 0x75, + 0x74, 0x6f, 0x6d, 0x61, 0x74, 0x69, 0x63, 0x20, 0x63, 0x6f, 0x64, 0x65, 0x20, 0x67, 0x65, 0x6e, + 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2c, 0x20, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x61, 0x63, + 0x74, 0x69, 0x76, 0x65, 0x20, 0x41, 0x50, 0x49, 0x20, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, + 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2c, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x73, 0x65, 0x61, 0x6d, + 0x6c, 0x65, 0x73, 0x73, 0x20, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x41, 0x50, 0x49, 0x20, 0x74, 0x65, 0x73, 0x74, 0x69, 0x6e, + 0x67, 0x20, 0x66, 0x72, 0x61, 0x6d, 0x65, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x2c, 0x20, 0x6d, 0x61, + 0x6b, 0x69, 0x6e, 0x67, 0x20, 0x69, 0x74, 0x20, 0x65, 0x61, 0x73, 0x69, 0x65, 0x72, 0x20, 0x74, + 0x68, 0x61, 0x6e, 0x20, 0x65, 0x76, 0x65, 0x72, 0x20, 0x74, 0x6f, 0x20, 0x69, 0x6e, 0x74, 0x65, + 0x67, 0x72, 0x61, 0x74, 0x65, 0x20, 0x46, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x20, 0x69, + 0x6e, 0x74, 0x6f, 0x20, 0x79, 0x6f, 0x75, 0x72, 0x20, 0x65, 0x78, 0x69, 0x73, 0x74, 0x69, 0x6e, + 0x67, 0x20, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x61, + 0x6e, 0x64, 0x20, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x73, 0x2e, 0x22, 0x40, 0x0a, + 0x13, 0x52, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x20, 0x46, 0x6f, 0x75, 0x6e, 0x64, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x15, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x72, 0x61, + 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x6f, 0x72, 0x67, 0x2f, 0x1a, 0x12, 0x68, 0x65, 0x6c, + 0x6c, 0x6f, 0x40, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x6f, 0x72, 0x67, 0x2a, + 0x44, 0x0a, 0x0a, 0x41, 0x70, 0x61, 0x63, 0x68, 0x65, 0x20, 0x32, 0x2e, 0x30, 0x12, 0x36, 0x68, + 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, + 0x6d, 0x2f, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2f, 0x66, 0x72, 0x6f, 0x6e, 0x74, + 0x69, 0x65, 0x72, 0x2f, 0x62, 0x6c, 0x6f, 0x62, 0x2f, 0x6d, 0x61, 0x69, 0x6e, 0x2f, 0x4c, 0x49, + 0x43, 0x45, 0x4e, 0x53, 0x45, 0x32, 0x05, 0x30, 0x2e, 0x32, 0x2e, 0x30, 0x1a, 0x0e, 0x31, 0x32, + 0x37, 0x2e, 0x30, 0x2e, 0x30, 0x2e, 0x31, 0x3a, 0x37, 0x34, 0x30, 0x30, 0x2a, 0x01, 0x01, 0x32, + 0x10, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x6a, 0x73, 0x6f, + 0x6e, 0x3a, 0x10, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x6a, + 0x73, 0x6f, 0x6e, 0x52, 0x3c, 0x0a, 0x03, 0x32, 0x30, 0x30, 0x12, 0x35, 0x0a, 0x1b, 0x4f, 0x4b, + 0x20, 0x2d, 0x20, 0x41, 0x20, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x66, 0x75, 0x6c, 0x20, + 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x12, 0x16, 0x0a, 0x14, 0x1a, 0x12, 0x2e, + 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, + 0x73, 0x52, 0x69, 0x0a, 0x03, 0x34, 0x30, 0x30, 0x12, 0x62, 0x0a, 0x48, 0x42, 0x61, 0x64, 0x20, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x20, 0x2d, 0x20, 0x54, 0x68, 0x65, 0x20, 0x72, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x20, 0x77, 0x61, 0x73, 0x20, 0x6d, 0x61, 0x6c, 0x66, 0x6f, 0x72, + 0x6d, 0x65, 0x64, 0x20, 0x6f, 0x72, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x64, + 0x20, 0x69, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x20, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, + 0x65, 0x72, 0x73, 0x2e, 0x12, 0x16, 0x0a, 0x14, 0x1a, 0x12, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, + 0x65, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x4a, 0x0a, 0x03, + 0x34, 0x30, 0x31, 0x12, 0x43, 0x0a, 0x29, 0x55, 0x6e, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, + 0x7a, 0x65, 0x64, 0x20, 0x2d, 0x20, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x69, 0x73, 0x20, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, + 0x12, 0x16, 0x0a, 0x14, 0x1a, 0x12, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x72, 0x70, + 0x63, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x61, 0x0a, 0x03, 0x34, 0x30, 0x33, 0x12, + 0x5a, 0x0a, 0x40, 0x46, 0x6f, 0x72, 0x62, 0x69, 0x64, 0x64, 0x65, 0x6e, 0x20, 0x2d, 0x20, 0x55, + 0x73, 0x65, 0x72, 0x20, 0x64, 0x6f, 0x65, 0x73, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x68, 0x61, 0x76, + 0x65, 0x20, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x74, 0x6f, 0x20, + 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, 0x72, 0x65, 0x73, 0x6f, 0x75, + 0x72, 0x63, 0x65, 0x12, 0x16, 0x0a, 0x14, 0x1a, 0x12, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, + 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x51, 0x0a, 0x03, 0x34, + 0x30, 0x34, 0x12, 0x4a, 0x0a, 0x30, 0x4e, 0x6f, 0x74, 0x20, 0x46, 0x6f, 0x75, 0x6e, 0x64, 0x20, + 0x2d, 0x20, 0x54, 0x68, 0x65, 0x20, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x65, 0x64, 0x20, + 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x20, 0x77, 0x61, 0x73, 0x20, 0x6e, 0x6f, 0x74, + 0x20, 0x66, 0x6f, 0x75, 0x6e, 0x64, 0x12, 0x16, 0x0a, 0x14, 0x1a, 0x12, 0x2e, 0x67, 0x6f, 0x6f, + 0x67, 0x6c, 0x65, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x75, + 0x0a, 0x03, 0x35, 0x30, 0x30, 0x12, 0x6e, 0x0a, 0x54, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, + 0x6c, 0x20, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x2e, 0x20, + 0x52, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x65, 0x64, 0x20, 0x77, 0x68, 0x65, 0x6e, 0x20, 0x74, 0x68, + 0x65, 0x72, 0x65, 0x73, 0x20, 0x69, 0x73, 0x20, 0x73, 0x6f, 0x6d, 0x65, 0x74, 0x68, 0x69, 0x6e, + 0x67, 0x20, 0x77, 0x72, 0x6f, 0x6e, 0x67, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x46, 0x72, 0x6f, + 0x6e, 0x74, 0x69, 0x65, 0x72, 0x20, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x12, 0x16, 0x0a, + 0x14, 0x1a, 0x12, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x53, + 0x74, 0x61, 0x74, 0x75, 0x73, 0x5a, 0xa8, 0x01, 0x0a, 0x4e, 0x0a, 0x05, 0x42, 0x61, 0x73, 0x69, + 0x63, 0x12, 0x45, 0x08, 0x01, 0x12, 0x37, 0x75, 0x73, 0x65, 0x20, 0x43, 0x6c, 0x69, 0x65, 0x6e, + 0x74, 0x20, 0x49, 0x44, 0x20, 0x61, 0x73, 0x20, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, + 0x20, 0x61, 0x6e, 0x64, 0x20, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x20, 0x53, 0x65, 0x63, 0x72, + 0x65, 0x74, 0x20, 0x61, 0x73, 0x20, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x1a, 0x06, + 0x42, 0x61, 0x73, 0x69, 0x63, 0x20, 0x20, 0x02, 0x0a, 0x56, 0x0a, 0x06, 0x42, 0x65, 0x61, 0x72, + 0x65, 0x72, 0x12, 0x4c, 0x08, 0x03, 0x12, 0x3d, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x20, 0x74, + 0x6f, 0x6b, 0x65, 0x6e, 0x20, 0x6f, 0x72, 0x20, 0x4a, 0x57, 0x54, 0x20, 0x74, 0x6f, 0x6b, 0x65, + 0x6e, 0x2c, 0x20, 0x70, 0x72, 0x65, 0x66, 0x69, 0x78, 0x65, 0x64, 0x20, 0x62, 0x79, 0x20, 0x42, + 0x65, 0x61, 0x72, 0x65, 0x72, 0x3a, 0x20, 0x42, 0x65, 0x61, 0x72, 0x65, 0x72, 0x20, 0x3c, 0x74, + 0x6f, 0x6b, 0x65, 0x6e, 0x3e, 0x1a, 0x07, 0x42, 0x65, 0x61, 0x72, 0x65, 0x72, 0x20, 0x20, 0x02, + 0x62, 0x0b, 0x0a, 0x09, 0x0a, 0x05, 0x42, 0x61, 0x73, 0x69, 0x63, 0x12, 0x00, 0x62, 0x0c, 0x0a, + 0x0a, 0x0a, 0x06, 0x42, 0x65, 0x61, 0x72, 0x65, 0x72, 0x12, 0x00, 0x6a, 0x06, 0x0a, 0x04, 0x55, + 0x73, 0x65, 0x72, 0x6a, 0x07, 0x0a, 0x05, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x6a, 0x0e, 0x0a, 0x0c, + 0x4f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x6a, 0x09, 0x0a, 0x07, + 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x6a, 0x0a, 0x0a, 0x08, 0x52, 0x65, 0x6c, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x6a, 0x0a, 0x0a, 0x08, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x6a, + 0x08, 0x0a, 0x06, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x6a, 0x06, 0x0a, 0x04, 0x52, 0x6f, 0x6c, + 0x65, 0x6a, 0x0c, 0x0a, 0x0a, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x0a, + 0x23, 0x69, 0x6f, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x6e, 0x2e, 0x66, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, + 0x65, 0x74, 0x61, 0x31, 0x42, 0x08, 0x46, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x5a, 0x3b, + 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x72, 0x61, 0x79, 0x73, 0x74, + 0x61, 0x63, 0x6b, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x6e, 0x2f, 0x66, 0x72, 0x6f, 0x6e, 0x74, + 0x69, 0x65, 0x72, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x3b, 0x66, 0x72, 0x6f, 0x6e, + 0x74, 0x69, 0x65, 0x72, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x33, } var ( @@ -3996,7 +4130,7 @@ func file_raystack_frontier_v1beta1_admin_proto_rawDescGZIP() []byte { return file_raystack_frontier_v1beta1_admin_proto_rawDescData } -var file_raystack_frontier_v1beta1_admin_proto_msgTypes = make([]protoimpl.MessageInfo, 55) +var file_raystack_frontier_v1beta1_admin_proto_msgTypes = make([]protoimpl.MessageInfo, 57) var file_raystack_frontier_v1beta1_admin_proto_goTypes = []interface{}{ (*ListAllUsersRequest)(nil), // 0: raystack.frontier.v1beta1.ListAllUsersRequest (*ListAllUsersResponse)(nil), // 1: raystack.frontier.v1beta1.ListAllUsersResponse @@ -4052,62 +4186,64 @@ var file_raystack_frontier_v1beta1_admin_proto_goTypes = []interface{}{ (*DeleteWebhookResponse)(nil), // 51: raystack.frontier.v1beta1.DeleteWebhookResponse (*ListWebhooksRequest)(nil), // 52: raystack.frontier.v1beta1.ListWebhooksRequest (*ListWebhooksResponse)(nil), // 53: raystack.frontier.v1beta1.ListWebhooksResponse - nil, // 54: raystack.frontier.v1beta1.WebhookRequestBody.HeadersEntry - (*User)(nil), // 55: raystack.frontier.v1beta1.User - (*Group)(nil), // 56: raystack.frontier.v1beta1.Group - (*Organization)(nil), // 57: raystack.frontier.v1beta1.Organization - (*Project)(nil), // 58: raystack.frontier.v1beta1.Project - (*Relation)(nil), // 59: raystack.frontier.v1beta1.Relation - (*Resource)(nil), // 60: raystack.frontier.v1beta1.Resource - (*RoleRequestBody)(nil), // 61: raystack.frontier.v1beta1.RoleRequestBody - (*Role)(nil), // 62: raystack.frontier.v1beta1.Role - (*structpb.Struct)(nil), // 63: google.protobuf.Struct - (*Permission)(nil), // 64: raystack.frontier.v1beta1.Permission - (*Preference)(nil), // 65: raystack.frontier.v1beta1.Preference - (*PreferenceRequestBody)(nil), // 66: raystack.frontier.v1beta1.PreferenceRequestBody - (*ServiceUser)(nil), // 67: raystack.frontier.v1beta1.ServiceUser - (*CheckoutSubscriptionBody)(nil), // 68: raystack.frontier.v1beta1.CheckoutSubscriptionBody - (*CheckoutProductBody)(nil), // 69: raystack.frontier.v1beta1.CheckoutProductBody - (*Subscription)(nil), // 70: raystack.frontier.v1beta1.Subscription - (*Product)(nil), // 71: raystack.frontier.v1beta1.Product - (*Invoice)(nil), // 72: raystack.frontier.v1beta1.Invoice - (*BillingAccount)(nil), // 73: raystack.frontier.v1beta1.BillingAccount - (*Webhook)(nil), // 74: raystack.frontier.v1beta1.Webhook + (*UpdateBillingAccountLimitsRequest)(nil), // 54: raystack.frontier.v1beta1.UpdateBillingAccountLimitsRequest + (*UpdateBillingAccountLimitsResponse)(nil), // 55: raystack.frontier.v1beta1.UpdateBillingAccountLimitsResponse + nil, // 56: raystack.frontier.v1beta1.WebhookRequestBody.HeadersEntry + (*User)(nil), // 57: raystack.frontier.v1beta1.User + (*Group)(nil), // 58: raystack.frontier.v1beta1.Group + (*Organization)(nil), // 59: raystack.frontier.v1beta1.Organization + (*Project)(nil), // 60: raystack.frontier.v1beta1.Project + (*Relation)(nil), // 61: raystack.frontier.v1beta1.Relation + (*Resource)(nil), // 62: raystack.frontier.v1beta1.Resource + (*RoleRequestBody)(nil), // 63: raystack.frontier.v1beta1.RoleRequestBody + (*Role)(nil), // 64: raystack.frontier.v1beta1.Role + (*structpb.Struct)(nil), // 65: google.protobuf.Struct + (*Permission)(nil), // 66: raystack.frontier.v1beta1.Permission + (*Preference)(nil), // 67: raystack.frontier.v1beta1.Preference + (*PreferenceRequestBody)(nil), // 68: raystack.frontier.v1beta1.PreferenceRequestBody + (*ServiceUser)(nil), // 69: raystack.frontier.v1beta1.ServiceUser + (*CheckoutSubscriptionBody)(nil), // 70: raystack.frontier.v1beta1.CheckoutSubscriptionBody + (*CheckoutProductBody)(nil), // 71: raystack.frontier.v1beta1.CheckoutProductBody + (*Subscription)(nil), // 72: raystack.frontier.v1beta1.Subscription + (*Product)(nil), // 73: raystack.frontier.v1beta1.Product + (*Invoice)(nil), // 74: raystack.frontier.v1beta1.Invoice + (*BillingAccount)(nil), // 75: raystack.frontier.v1beta1.BillingAccount + (*Webhook)(nil), // 76: raystack.frontier.v1beta1.Webhook } var file_raystack_frontier_v1beta1_admin_proto_depIdxs = []int32{ - 55, // 0: raystack.frontier.v1beta1.ListAllUsersResponse.users:type_name -> raystack.frontier.v1beta1.User - 56, // 1: raystack.frontier.v1beta1.ListGroupsResponse.groups:type_name -> raystack.frontier.v1beta1.Group - 57, // 2: raystack.frontier.v1beta1.ListAllOrganizationsResponse.organizations:type_name -> raystack.frontier.v1beta1.Organization - 58, // 3: raystack.frontier.v1beta1.ListProjectsResponse.projects:type_name -> raystack.frontier.v1beta1.Project - 59, // 4: raystack.frontier.v1beta1.ListRelationsResponse.relations:type_name -> raystack.frontier.v1beta1.Relation - 60, // 5: raystack.frontier.v1beta1.ListResourcesResponse.resources:type_name -> raystack.frontier.v1beta1.Resource - 61, // 6: raystack.frontier.v1beta1.CreateRoleRequest.body:type_name -> raystack.frontier.v1beta1.RoleRequestBody - 62, // 7: raystack.frontier.v1beta1.CreateRoleResponse.role:type_name -> raystack.frontier.v1beta1.Role - 61, // 8: raystack.frontier.v1beta1.UpdateRoleRequest.body:type_name -> raystack.frontier.v1beta1.RoleRequestBody - 62, // 9: raystack.frontier.v1beta1.UpdateRoleResponse.role:type_name -> raystack.frontier.v1beta1.Role - 63, // 10: raystack.frontier.v1beta1.PermissionRequestBody.metadata:type_name -> google.protobuf.Struct + 57, // 0: raystack.frontier.v1beta1.ListAllUsersResponse.users:type_name -> raystack.frontier.v1beta1.User + 58, // 1: raystack.frontier.v1beta1.ListGroupsResponse.groups:type_name -> raystack.frontier.v1beta1.Group + 59, // 2: raystack.frontier.v1beta1.ListAllOrganizationsResponse.organizations:type_name -> raystack.frontier.v1beta1.Organization + 60, // 3: raystack.frontier.v1beta1.ListProjectsResponse.projects:type_name -> raystack.frontier.v1beta1.Project + 61, // 4: raystack.frontier.v1beta1.ListRelationsResponse.relations:type_name -> raystack.frontier.v1beta1.Relation + 62, // 5: raystack.frontier.v1beta1.ListResourcesResponse.resources:type_name -> raystack.frontier.v1beta1.Resource + 63, // 6: raystack.frontier.v1beta1.CreateRoleRequest.body:type_name -> raystack.frontier.v1beta1.RoleRequestBody + 64, // 7: raystack.frontier.v1beta1.CreateRoleResponse.role:type_name -> raystack.frontier.v1beta1.Role + 63, // 8: raystack.frontier.v1beta1.UpdateRoleRequest.body:type_name -> raystack.frontier.v1beta1.RoleRequestBody + 64, // 9: raystack.frontier.v1beta1.UpdateRoleResponse.role:type_name -> raystack.frontier.v1beta1.Role + 65, // 10: raystack.frontier.v1beta1.PermissionRequestBody.metadata:type_name -> google.protobuf.Struct 18, // 11: raystack.frontier.v1beta1.CreatePermissionRequest.bodies:type_name -> raystack.frontier.v1beta1.PermissionRequestBody - 64, // 12: raystack.frontier.v1beta1.CreatePermissionResponse.permissions:type_name -> raystack.frontier.v1beta1.Permission + 66, // 12: raystack.frontier.v1beta1.CreatePermissionResponse.permissions:type_name -> raystack.frontier.v1beta1.Permission 18, // 13: raystack.frontier.v1beta1.UpdatePermissionRequest.body:type_name -> raystack.frontier.v1beta1.PermissionRequestBody - 64, // 14: raystack.frontier.v1beta1.UpdatePermissionResponse.permission:type_name -> raystack.frontier.v1beta1.Permission - 65, // 15: raystack.frontier.v1beta1.ListPreferencesResponse.preferences:type_name -> raystack.frontier.v1beta1.Preference - 66, // 16: raystack.frontier.v1beta1.CreatePreferencesRequest.preferences:type_name -> raystack.frontier.v1beta1.PreferenceRequestBody - 65, // 17: raystack.frontier.v1beta1.CreatePreferencesResponse.preference:type_name -> raystack.frontier.v1beta1.Preference - 55, // 18: raystack.frontier.v1beta1.ListPlatformUsersResponse.users:type_name -> raystack.frontier.v1beta1.User - 67, // 19: raystack.frontier.v1beta1.ListPlatformUsersResponse.serviceusers:type_name -> raystack.frontier.v1beta1.ServiceUser - 68, // 20: raystack.frontier.v1beta1.DelegatedCheckoutRequest.subscription_body:type_name -> raystack.frontier.v1beta1.CheckoutSubscriptionBody - 69, // 21: raystack.frontier.v1beta1.DelegatedCheckoutRequest.product_body:type_name -> raystack.frontier.v1beta1.CheckoutProductBody - 70, // 22: raystack.frontier.v1beta1.DelegatedCheckoutResponse.subscription:type_name -> raystack.frontier.v1beta1.Subscription - 71, // 23: raystack.frontier.v1beta1.DelegatedCheckoutResponse.product:type_name -> raystack.frontier.v1beta1.Product - 72, // 24: raystack.frontier.v1beta1.ListAllInvoicesResponse.invoices:type_name -> raystack.frontier.v1beta1.Invoice - 73, // 25: raystack.frontier.v1beta1.ListAllBillingAccountsResponse.billing_accounts:type_name -> raystack.frontier.v1beta1.BillingAccount - 54, // 26: raystack.frontier.v1beta1.WebhookRequestBody.headers:type_name -> raystack.frontier.v1beta1.WebhookRequestBody.HeadersEntry - 63, // 27: raystack.frontier.v1beta1.WebhookRequestBody.metadata:type_name -> google.protobuf.Struct + 66, // 14: raystack.frontier.v1beta1.UpdatePermissionResponse.permission:type_name -> raystack.frontier.v1beta1.Permission + 67, // 15: raystack.frontier.v1beta1.ListPreferencesResponse.preferences:type_name -> raystack.frontier.v1beta1.Preference + 68, // 16: raystack.frontier.v1beta1.CreatePreferencesRequest.preferences:type_name -> raystack.frontier.v1beta1.PreferenceRequestBody + 67, // 17: raystack.frontier.v1beta1.CreatePreferencesResponse.preference:type_name -> raystack.frontier.v1beta1.Preference + 57, // 18: raystack.frontier.v1beta1.ListPlatformUsersResponse.users:type_name -> raystack.frontier.v1beta1.User + 69, // 19: raystack.frontier.v1beta1.ListPlatformUsersResponse.serviceusers:type_name -> raystack.frontier.v1beta1.ServiceUser + 70, // 20: raystack.frontier.v1beta1.DelegatedCheckoutRequest.subscription_body:type_name -> raystack.frontier.v1beta1.CheckoutSubscriptionBody + 71, // 21: raystack.frontier.v1beta1.DelegatedCheckoutRequest.product_body:type_name -> raystack.frontier.v1beta1.CheckoutProductBody + 72, // 22: raystack.frontier.v1beta1.DelegatedCheckoutResponse.subscription:type_name -> raystack.frontier.v1beta1.Subscription + 73, // 23: raystack.frontier.v1beta1.DelegatedCheckoutResponse.product:type_name -> raystack.frontier.v1beta1.Product + 74, // 24: raystack.frontier.v1beta1.ListAllInvoicesResponse.invoices:type_name -> raystack.frontier.v1beta1.Invoice + 75, // 25: raystack.frontier.v1beta1.ListAllBillingAccountsResponse.billing_accounts:type_name -> raystack.frontier.v1beta1.BillingAccount + 56, // 26: raystack.frontier.v1beta1.WebhookRequestBody.headers:type_name -> raystack.frontier.v1beta1.WebhookRequestBody.HeadersEntry + 65, // 27: raystack.frontier.v1beta1.WebhookRequestBody.metadata:type_name -> google.protobuf.Struct 45, // 28: raystack.frontier.v1beta1.CreateWebhookRequest.body:type_name -> raystack.frontier.v1beta1.WebhookRequestBody - 74, // 29: raystack.frontier.v1beta1.CreateWebhookResponse.webhook:type_name -> raystack.frontier.v1beta1.Webhook + 76, // 29: raystack.frontier.v1beta1.CreateWebhookResponse.webhook:type_name -> raystack.frontier.v1beta1.Webhook 45, // 30: raystack.frontier.v1beta1.UpdateWebhookRequest.body:type_name -> raystack.frontier.v1beta1.WebhookRequestBody - 74, // 31: raystack.frontier.v1beta1.UpdateWebhookResponse.webhook:type_name -> raystack.frontier.v1beta1.Webhook - 74, // 32: raystack.frontier.v1beta1.ListWebhooksResponse.webhooks:type_name -> raystack.frontier.v1beta1.Webhook + 76, // 31: raystack.frontier.v1beta1.UpdateWebhookResponse.webhook:type_name -> raystack.frontier.v1beta1.Webhook + 76, // 32: raystack.frontier.v1beta1.ListWebhooksResponse.webhooks:type_name -> raystack.frontier.v1beta1.Webhook 0, // 33: raystack.frontier.v1beta1.AdminService.ListAllUsers:input_type -> raystack.frontier.v1beta1.ListAllUsersRequest 2, // 34: raystack.frontier.v1beta1.AdminService.ListGroups:input_type -> raystack.frontier.v1beta1.ListGroupsRequest 4, // 35: raystack.frontier.v1beta1.AdminService.ListAllOrganizations:input_type -> raystack.frontier.v1beta1.ListAllOrganizationsRequest @@ -4134,34 +4270,36 @@ var file_raystack_frontier_v1beta1_admin_proto_depIdxs = []int32{ 48, // 56: raystack.frontier.v1beta1.AdminService.UpdateWebhook:input_type -> raystack.frontier.v1beta1.UpdateWebhookRequest 50, // 57: raystack.frontier.v1beta1.AdminService.DeleteWebhook:input_type -> raystack.frontier.v1beta1.DeleteWebhookRequest 52, // 58: raystack.frontier.v1beta1.AdminService.ListWebhooks:input_type -> raystack.frontier.v1beta1.ListWebhooksRequest - 1, // 59: raystack.frontier.v1beta1.AdminService.ListAllUsers:output_type -> raystack.frontier.v1beta1.ListAllUsersResponse - 3, // 60: raystack.frontier.v1beta1.AdminService.ListGroups:output_type -> raystack.frontier.v1beta1.ListGroupsResponse - 5, // 61: raystack.frontier.v1beta1.AdminService.ListAllOrganizations:output_type -> raystack.frontier.v1beta1.ListAllOrganizationsResponse - 7, // 62: raystack.frontier.v1beta1.AdminService.ListProjects:output_type -> raystack.frontier.v1beta1.ListProjectsResponse - 9, // 63: raystack.frontier.v1beta1.AdminService.ListRelations:output_type -> raystack.frontier.v1beta1.ListRelationsResponse - 11, // 64: raystack.frontier.v1beta1.AdminService.ListResources:output_type -> raystack.frontier.v1beta1.ListResourcesResponse - 13, // 65: raystack.frontier.v1beta1.AdminService.CreateRole:output_type -> raystack.frontier.v1beta1.CreateRoleResponse - 15, // 66: raystack.frontier.v1beta1.AdminService.UpdateRole:output_type -> raystack.frontier.v1beta1.UpdateRoleResponse - 17, // 67: raystack.frontier.v1beta1.AdminService.DeleteRole:output_type -> raystack.frontier.v1beta1.DeleteRoleResponse - 20, // 68: raystack.frontier.v1beta1.AdminService.CreatePermission:output_type -> raystack.frontier.v1beta1.CreatePermissionResponse - 22, // 69: raystack.frontier.v1beta1.AdminService.UpdatePermission:output_type -> raystack.frontier.v1beta1.UpdatePermissionResponse - 24, // 70: raystack.frontier.v1beta1.AdminService.DeletePermission:output_type -> raystack.frontier.v1beta1.DeletePermissionResponse - 26, // 71: raystack.frontier.v1beta1.AdminService.ListPreferences:output_type -> raystack.frontier.v1beta1.ListPreferencesResponse - 28, // 72: raystack.frontier.v1beta1.AdminService.CreatePreferences:output_type -> raystack.frontier.v1beta1.CreatePreferencesResponse - 30, // 73: raystack.frontier.v1beta1.AdminService.CheckFederatedResourcePermission:output_type -> raystack.frontier.v1beta1.CheckFederatedResourcePermissionResponse - 32, // 74: raystack.frontier.v1beta1.AdminService.AddPlatformUser:output_type -> raystack.frontier.v1beta1.AddPlatformUserResponse - 34, // 75: raystack.frontier.v1beta1.AdminService.ListPlatformUsers:output_type -> raystack.frontier.v1beta1.ListPlatformUsersResponse - 36, // 76: raystack.frontier.v1beta1.AdminService.RemovePlatformUser:output_type -> raystack.frontier.v1beta1.RemovePlatformUserResponse - 38, // 77: raystack.frontier.v1beta1.AdminService.DelegatedCheckout:output_type -> raystack.frontier.v1beta1.DelegatedCheckoutResponse - 40, // 78: raystack.frontier.v1beta1.AdminService.ListAllInvoices:output_type -> raystack.frontier.v1beta1.ListAllInvoicesResponse - 42, // 79: raystack.frontier.v1beta1.AdminService.ListAllBillingAccounts:output_type -> raystack.frontier.v1beta1.ListAllBillingAccountsResponse - 44, // 80: raystack.frontier.v1beta1.AdminService.RevertBillingUsage:output_type -> raystack.frontier.v1beta1.RevertBillingUsageResponse - 47, // 81: raystack.frontier.v1beta1.AdminService.CreateWebhook:output_type -> raystack.frontier.v1beta1.CreateWebhookResponse - 49, // 82: raystack.frontier.v1beta1.AdminService.UpdateWebhook:output_type -> raystack.frontier.v1beta1.UpdateWebhookResponse - 51, // 83: raystack.frontier.v1beta1.AdminService.DeleteWebhook:output_type -> raystack.frontier.v1beta1.DeleteWebhookResponse - 53, // 84: raystack.frontier.v1beta1.AdminService.ListWebhooks:output_type -> raystack.frontier.v1beta1.ListWebhooksResponse - 59, // [59:85] is the sub-list for method output_type - 33, // [33:59] is the sub-list for method input_type + 54, // 59: raystack.frontier.v1beta1.AdminService.UpdateBillingAccountLimits:input_type -> raystack.frontier.v1beta1.UpdateBillingAccountLimitsRequest + 1, // 60: raystack.frontier.v1beta1.AdminService.ListAllUsers:output_type -> raystack.frontier.v1beta1.ListAllUsersResponse + 3, // 61: raystack.frontier.v1beta1.AdminService.ListGroups:output_type -> raystack.frontier.v1beta1.ListGroupsResponse + 5, // 62: raystack.frontier.v1beta1.AdminService.ListAllOrganizations:output_type -> raystack.frontier.v1beta1.ListAllOrganizationsResponse + 7, // 63: raystack.frontier.v1beta1.AdminService.ListProjects:output_type -> raystack.frontier.v1beta1.ListProjectsResponse + 9, // 64: raystack.frontier.v1beta1.AdminService.ListRelations:output_type -> raystack.frontier.v1beta1.ListRelationsResponse + 11, // 65: raystack.frontier.v1beta1.AdminService.ListResources:output_type -> raystack.frontier.v1beta1.ListResourcesResponse + 13, // 66: raystack.frontier.v1beta1.AdminService.CreateRole:output_type -> raystack.frontier.v1beta1.CreateRoleResponse + 15, // 67: raystack.frontier.v1beta1.AdminService.UpdateRole:output_type -> raystack.frontier.v1beta1.UpdateRoleResponse + 17, // 68: raystack.frontier.v1beta1.AdminService.DeleteRole:output_type -> raystack.frontier.v1beta1.DeleteRoleResponse + 20, // 69: raystack.frontier.v1beta1.AdminService.CreatePermission:output_type -> raystack.frontier.v1beta1.CreatePermissionResponse + 22, // 70: raystack.frontier.v1beta1.AdminService.UpdatePermission:output_type -> raystack.frontier.v1beta1.UpdatePermissionResponse + 24, // 71: raystack.frontier.v1beta1.AdminService.DeletePermission:output_type -> raystack.frontier.v1beta1.DeletePermissionResponse + 26, // 72: raystack.frontier.v1beta1.AdminService.ListPreferences:output_type -> raystack.frontier.v1beta1.ListPreferencesResponse + 28, // 73: raystack.frontier.v1beta1.AdminService.CreatePreferences:output_type -> raystack.frontier.v1beta1.CreatePreferencesResponse + 30, // 74: raystack.frontier.v1beta1.AdminService.CheckFederatedResourcePermission:output_type -> raystack.frontier.v1beta1.CheckFederatedResourcePermissionResponse + 32, // 75: raystack.frontier.v1beta1.AdminService.AddPlatformUser:output_type -> raystack.frontier.v1beta1.AddPlatformUserResponse + 34, // 76: raystack.frontier.v1beta1.AdminService.ListPlatformUsers:output_type -> raystack.frontier.v1beta1.ListPlatformUsersResponse + 36, // 77: raystack.frontier.v1beta1.AdminService.RemovePlatformUser:output_type -> raystack.frontier.v1beta1.RemovePlatformUserResponse + 38, // 78: raystack.frontier.v1beta1.AdminService.DelegatedCheckout:output_type -> raystack.frontier.v1beta1.DelegatedCheckoutResponse + 40, // 79: raystack.frontier.v1beta1.AdminService.ListAllInvoices:output_type -> raystack.frontier.v1beta1.ListAllInvoicesResponse + 42, // 80: raystack.frontier.v1beta1.AdminService.ListAllBillingAccounts:output_type -> raystack.frontier.v1beta1.ListAllBillingAccountsResponse + 44, // 81: raystack.frontier.v1beta1.AdminService.RevertBillingUsage:output_type -> raystack.frontier.v1beta1.RevertBillingUsageResponse + 47, // 82: raystack.frontier.v1beta1.AdminService.CreateWebhook:output_type -> raystack.frontier.v1beta1.CreateWebhookResponse + 49, // 83: raystack.frontier.v1beta1.AdminService.UpdateWebhook:output_type -> raystack.frontier.v1beta1.UpdateWebhookResponse + 51, // 84: raystack.frontier.v1beta1.AdminService.DeleteWebhook:output_type -> raystack.frontier.v1beta1.DeleteWebhookResponse + 53, // 85: raystack.frontier.v1beta1.AdminService.ListWebhooks:output_type -> raystack.frontier.v1beta1.ListWebhooksResponse + 55, // 86: raystack.frontier.v1beta1.AdminService.UpdateBillingAccountLimits:output_type -> raystack.frontier.v1beta1.UpdateBillingAccountLimitsResponse + 60, // [60:87] is the sub-list for method output_type + 33, // [33:60] is the sub-list for method input_type 33, // [33:33] is the sub-list for extension type_name 33, // [33:33] is the sub-list for extension extendee 0, // [0:33] is the sub-list for field type_name @@ -4822,6 +4960,30 @@ func file_raystack_frontier_v1beta1_admin_proto_init() { return nil } } + file_raystack_frontier_v1beta1_admin_proto_msgTypes[54].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*UpdateBillingAccountLimitsRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_raystack_frontier_v1beta1_admin_proto_msgTypes[55].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*UpdateBillingAccountLimitsResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } } type x struct{} out := protoimpl.TypeBuilder{ @@ -4829,7 +4991,7 @@ func file_raystack_frontier_v1beta1_admin_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_raystack_frontier_v1beta1_admin_proto_rawDesc, NumEnums: 0, - NumMessages: 55, + NumMessages: 57, NumExtensions: 0, NumServices: 1, }, diff --git a/proto/v1beta1/admin.pb.gw.go b/proto/v1beta1/admin.pb.gw.go index 573cad8b2..4f865527a 100644 --- a/proto/v1beta1/admin.pb.gw.go +++ b/proto/v1beta1/admin.pb.gw.go @@ -1269,6 +1269,94 @@ func local_request_AdminService_ListWebhooks_0(ctx context.Context, marshaler ru } +func request_AdminService_UpdateBillingAccountLimits_0(ctx context.Context, marshaler runtime.Marshaler, client AdminServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq UpdateBillingAccountLimitsRequest + var metadata runtime.ServerMetadata + + newReader, berr := utilities.IOReaderFactory(req.Body) + if berr != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr) + } + if err := marshaler.NewDecoder(newReader()).Decode(&protoReq); err != nil && err != io.EOF { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["org_id"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "org_id") + } + + protoReq.OrgId, err = runtime.String(val) + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "org_id", err) + } + + val, ok = pathParams["id"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "id") + } + + protoReq.Id, err = runtime.String(val) + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "id", err) + } + + msg, err := client.UpdateBillingAccountLimits(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_AdminService_UpdateBillingAccountLimits_0(ctx context.Context, marshaler runtime.Marshaler, server AdminServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq UpdateBillingAccountLimitsRequest + var metadata runtime.ServerMetadata + + newReader, berr := utilities.IOReaderFactory(req.Body) + if berr != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr) + } + if err := marshaler.NewDecoder(newReader()).Decode(&protoReq); err != nil && err != io.EOF { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["org_id"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "org_id") + } + + protoReq.OrgId, err = runtime.String(val) + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "org_id", err) + } + + val, ok = pathParams["id"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "id") + } + + protoReq.Id, err = runtime.String(val) + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "id", err) + } + + msg, err := server.UpdateBillingAccountLimits(ctx, &protoReq) + return msg, metadata, err + +} + // RegisterAdminServiceHandlerServer registers the http handlers for service AdminService to "mux". // UnaryRPC :call AdminServiceServer directly. // StreamingRPC :currently unsupported pending https://github.com/grpc/grpc-go/issues/906. @@ -1975,6 +2063,31 @@ func RegisterAdminServiceHandlerServer(ctx context.Context, mux *runtime.ServeMu }) + mux.Handle("PUT", pattern_AdminService_UpdateBillingAccountLimits_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/raystack.frontier.v1beta1.AdminService/UpdateBillingAccountLimits", runtime.WithHTTPPathPattern("/v1beta1/admin/organizations/{org_id}/billing/{id}/limits")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_AdminService_UpdateBillingAccountLimits_0(annotatedContext, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_AdminService_UpdateBillingAccountLimits_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + return nil } @@ -2632,6 +2745,28 @@ func RegisterAdminServiceHandlerClient(ctx context.Context, mux *runtime.ServeMu }) + mux.Handle("PUT", pattern_AdminService_UpdateBillingAccountLimits_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/raystack.frontier.v1beta1.AdminService/UpdateBillingAccountLimits", runtime.WithHTTPPathPattern("/v1beta1/admin/organizations/{org_id}/billing/{id}/limits")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_AdminService_UpdateBillingAccountLimits_0(annotatedContext, inboundMarshaler, client, req, pathParams) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_AdminService_UpdateBillingAccountLimits_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + return nil } @@ -2691,6 +2826,8 @@ var ( pattern_AdminService_DeleteWebhook_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3}, []string{"v1beta1", "admin", "webhooks", "id"}, "")) pattern_AdminService_ListWebhooks_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"v1beta1", "admin", "webhooks"}, "")) + + pattern_AdminService_UpdateBillingAccountLimits_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3, 2, 4, 1, 0, 4, 1, 5, 5, 2, 6}, []string{"v1beta1", "admin", "organizations", "org_id", "billing", "id", "limits"}, "")) ) var ( @@ -2749,4 +2886,6 @@ var ( forward_AdminService_DeleteWebhook_0 = runtime.ForwardResponseMessage forward_AdminService_ListWebhooks_0 = runtime.ForwardResponseMessage + + forward_AdminService_UpdateBillingAccountLimits_0 = runtime.ForwardResponseMessage ) diff --git a/proto/v1beta1/admin.pb.validate.go b/proto/v1beta1/admin.pb.validate.go index d47e72a3c..3e29eab34 100644 --- a/proto/v1beta1/admin.pb.validate.go +++ b/proto/v1beta1/admin.pb.validate.go @@ -6922,3 +6922,250 @@ var _ interface { Cause() error ErrorName() string } = ListWebhooksResponseValidationError{} + +// Validate checks the field values on UpdateBillingAccountLimitsRequest with +// the rules defined in the proto definition for this message. If any rules +// are violated, the first error encountered is returned, or nil if there are +// no violations. +func (m *UpdateBillingAccountLimitsRequest) Validate() error { + return m.validate(false) +} + +// ValidateAll checks the field values on UpdateBillingAccountLimitsRequest +// with the rules defined in the proto definition for this message. If any +// rules are violated, the result is a list of violation errors wrapped in +// UpdateBillingAccountLimitsRequestMultiError, or nil if none found. +func (m *UpdateBillingAccountLimitsRequest) ValidateAll() error { + return m.validate(true) +} + +func (m *UpdateBillingAccountLimitsRequest) validate(all bool) error { + if m == nil { + return nil + } + + var errors []error + + if utf8.RuneCountInString(m.GetOrgId()) < 3 { + err := UpdateBillingAccountLimitsRequestValidationError{ + field: "OrgId", + reason: "value length must be at least 3 runes", + } + if !all { + return err + } + errors = append(errors, err) + } + + if m.GetId() != "" { + + if err := m._validateUuid(m.GetId()); err != nil { + err = UpdateBillingAccountLimitsRequestValidationError{ + field: "Id", + reason: "value must be a valid UUID", + cause: err, + } + if !all { + return err + } + errors = append(errors, err) + } + + } + + // no validation rules for CreditMin + + if len(errors) > 0 { + return UpdateBillingAccountLimitsRequestMultiError(errors) + } + + return nil +} + +func (m *UpdateBillingAccountLimitsRequest) _validateUuid(uuid string) error { + if matched := _admin_uuidPattern.MatchString(uuid); !matched { + return errors.New("invalid uuid format") + } + + return nil +} + +// UpdateBillingAccountLimitsRequestMultiError is an error wrapping multiple +// validation errors returned by +// UpdateBillingAccountLimitsRequest.ValidateAll() if the designated +// constraints aren't met. +type UpdateBillingAccountLimitsRequestMultiError []error + +// Error returns a concatenation of all the error messages it wraps. +func (m UpdateBillingAccountLimitsRequestMultiError) Error() string { + var msgs []string + for _, err := range m { + msgs = append(msgs, err.Error()) + } + return strings.Join(msgs, "; ") +} + +// AllErrors returns a list of validation violation errors. +func (m UpdateBillingAccountLimitsRequestMultiError) AllErrors() []error { return m } + +// UpdateBillingAccountLimitsRequestValidationError is the validation error +// returned by UpdateBillingAccountLimitsRequest.Validate if the designated +// constraints aren't met. +type UpdateBillingAccountLimitsRequestValidationError struct { + field string + reason string + cause error + key bool +} + +// Field function returns field value. +func (e UpdateBillingAccountLimitsRequestValidationError) Field() string { return e.field } + +// Reason function returns reason value. +func (e UpdateBillingAccountLimitsRequestValidationError) Reason() string { return e.reason } + +// Cause function returns cause value. +func (e UpdateBillingAccountLimitsRequestValidationError) Cause() error { return e.cause } + +// Key function returns key value. +func (e UpdateBillingAccountLimitsRequestValidationError) Key() bool { return e.key } + +// ErrorName returns error name. +func (e UpdateBillingAccountLimitsRequestValidationError) ErrorName() string { + return "UpdateBillingAccountLimitsRequestValidationError" +} + +// Error satisfies the builtin error interface +func (e UpdateBillingAccountLimitsRequestValidationError) Error() string { + cause := "" + if e.cause != nil { + cause = fmt.Sprintf(" | caused by: %v", e.cause) + } + + key := "" + if e.key { + key = "key for " + } + + return fmt.Sprintf( + "invalid %sUpdateBillingAccountLimitsRequest.%s: %s%s", + key, + e.field, + e.reason, + cause) +} + +var _ error = UpdateBillingAccountLimitsRequestValidationError{} + +var _ interface { + Field() string + Reason() string + Key() bool + Cause() error + ErrorName() string +} = UpdateBillingAccountLimitsRequestValidationError{} + +// Validate checks the field values on UpdateBillingAccountLimitsResponse with +// the rules defined in the proto definition for this message. If any rules +// are violated, the first error encountered is returned, or nil if there are +// no violations. +func (m *UpdateBillingAccountLimitsResponse) Validate() error { + return m.validate(false) +} + +// ValidateAll checks the field values on UpdateBillingAccountLimitsResponse +// with the rules defined in the proto definition for this message. If any +// rules are violated, the result is a list of violation errors wrapped in +// UpdateBillingAccountLimitsResponseMultiError, or nil if none found. +func (m *UpdateBillingAccountLimitsResponse) ValidateAll() error { + return m.validate(true) +} + +func (m *UpdateBillingAccountLimitsResponse) validate(all bool) error { + if m == nil { + return nil + } + + var errors []error + + if len(errors) > 0 { + return UpdateBillingAccountLimitsResponseMultiError(errors) + } + + return nil +} + +// UpdateBillingAccountLimitsResponseMultiError is an error wrapping multiple +// validation errors returned by +// UpdateBillingAccountLimitsResponse.ValidateAll() if the designated +// constraints aren't met. +type UpdateBillingAccountLimitsResponseMultiError []error + +// Error returns a concatenation of all the error messages it wraps. +func (m UpdateBillingAccountLimitsResponseMultiError) Error() string { + var msgs []string + for _, err := range m { + msgs = append(msgs, err.Error()) + } + return strings.Join(msgs, "; ") +} + +// AllErrors returns a list of validation violation errors. +func (m UpdateBillingAccountLimitsResponseMultiError) AllErrors() []error { return m } + +// UpdateBillingAccountLimitsResponseValidationError is the validation error +// returned by UpdateBillingAccountLimitsResponse.Validate if the designated +// constraints aren't met. +type UpdateBillingAccountLimitsResponseValidationError struct { + field string + reason string + cause error + key bool +} + +// Field function returns field value. +func (e UpdateBillingAccountLimitsResponseValidationError) Field() string { return e.field } + +// Reason function returns reason value. +func (e UpdateBillingAccountLimitsResponseValidationError) Reason() string { return e.reason } + +// Cause function returns cause value. +func (e UpdateBillingAccountLimitsResponseValidationError) Cause() error { return e.cause } + +// Key function returns key value. +func (e UpdateBillingAccountLimitsResponseValidationError) Key() bool { return e.key } + +// ErrorName returns error name. +func (e UpdateBillingAccountLimitsResponseValidationError) ErrorName() string { + return "UpdateBillingAccountLimitsResponseValidationError" +} + +// Error satisfies the builtin error interface +func (e UpdateBillingAccountLimitsResponseValidationError) Error() string { + cause := "" + if e.cause != nil { + cause = fmt.Sprintf(" | caused by: %v", e.cause) + } + + key := "" + if e.key { + key = "key for " + } + + return fmt.Sprintf( + "invalid %sUpdateBillingAccountLimitsResponse.%s: %s%s", + key, + e.field, + e.reason, + cause) +} + +var _ error = UpdateBillingAccountLimitsResponseValidationError{} + +var _ interface { + Field() string + Reason() string + Key() bool + Cause() error + ErrorName() string +} = UpdateBillingAccountLimitsResponseValidationError{} diff --git a/proto/v1beta1/admin_grpc.pb.go b/proto/v1beta1/admin_grpc.pb.go index 36c83393e..3ae3e80fe 100644 --- a/proto/v1beta1/admin_grpc.pb.go +++ b/proto/v1beta1/admin_grpc.pb.go @@ -45,6 +45,7 @@ const ( AdminService_UpdateWebhook_FullMethodName = "/raystack.frontier.v1beta1.AdminService/UpdateWebhook" AdminService_DeleteWebhook_FullMethodName = "/raystack.frontier.v1beta1.AdminService/DeleteWebhook" AdminService_ListWebhooks_FullMethodName = "/raystack.frontier.v1beta1.AdminService/ListWebhooks" + AdminService_UpdateBillingAccountLimits_FullMethodName = "/raystack.frontier.v1beta1.AdminService/UpdateBillingAccountLimits" ) // AdminServiceClient is the client API for AdminService service. @@ -91,6 +92,8 @@ type AdminServiceClient interface { UpdateWebhook(ctx context.Context, in *UpdateWebhookRequest, opts ...grpc.CallOption) (*UpdateWebhookResponse, error) DeleteWebhook(ctx context.Context, in *DeleteWebhookRequest, opts ...grpc.CallOption) (*DeleteWebhookResponse, error) ListWebhooks(ctx context.Context, in *ListWebhooksRequest, opts ...grpc.CallOption) (*ListWebhooksResponse, error) + // Billing Account + UpdateBillingAccountLimits(ctx context.Context, in *UpdateBillingAccountLimitsRequest, opts ...grpc.CallOption) (*UpdateBillingAccountLimitsResponse, error) } type adminServiceClient struct { @@ -335,6 +338,15 @@ func (c *adminServiceClient) ListWebhooks(ctx context.Context, in *ListWebhooksR return out, nil } +func (c *adminServiceClient) UpdateBillingAccountLimits(ctx context.Context, in *UpdateBillingAccountLimitsRequest, opts ...grpc.CallOption) (*UpdateBillingAccountLimitsResponse, error) { + out := new(UpdateBillingAccountLimitsResponse) + err := c.cc.Invoke(ctx, AdminService_UpdateBillingAccountLimits_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + // AdminServiceServer is the server API for AdminService service. // All implementations must embed UnimplementedAdminServiceServer // for forward compatibility @@ -379,6 +391,8 @@ type AdminServiceServer interface { UpdateWebhook(context.Context, *UpdateWebhookRequest) (*UpdateWebhookResponse, error) DeleteWebhook(context.Context, *DeleteWebhookRequest) (*DeleteWebhookResponse, error) ListWebhooks(context.Context, *ListWebhooksRequest) (*ListWebhooksResponse, error) + // Billing Account + UpdateBillingAccountLimits(context.Context, *UpdateBillingAccountLimitsRequest) (*UpdateBillingAccountLimitsResponse, error) mustEmbedUnimplementedAdminServiceServer() } @@ -464,6 +478,9 @@ func (UnimplementedAdminServiceServer) DeleteWebhook(context.Context, *DeleteWeb func (UnimplementedAdminServiceServer) ListWebhooks(context.Context, *ListWebhooksRequest) (*ListWebhooksResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method ListWebhooks not implemented") } +func (UnimplementedAdminServiceServer) UpdateBillingAccountLimits(context.Context, *UpdateBillingAccountLimitsRequest) (*UpdateBillingAccountLimitsResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method UpdateBillingAccountLimits not implemented") +} func (UnimplementedAdminServiceServer) mustEmbedUnimplementedAdminServiceServer() {} // UnsafeAdminServiceServer may be embedded to opt out of forward compatibility for this service. @@ -945,6 +962,24 @@ func _AdminService_ListWebhooks_Handler(srv interface{}, ctx context.Context, de return interceptor(ctx, in, info, handler) } +func _AdminService_UpdateBillingAccountLimits_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(UpdateBillingAccountLimitsRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(AdminServiceServer).UpdateBillingAccountLimits(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: AdminService_UpdateBillingAccountLimits_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(AdminServiceServer).UpdateBillingAccountLimits(ctx, req.(*UpdateBillingAccountLimitsRequest)) + } + return interceptor(ctx, in, info, handler) +} + // AdminService_ServiceDesc is the grpc.ServiceDesc for AdminService service. // It's only intended for direct use with grpc.RegisterService, // and not to be introspected or modified (even as a copy) @@ -1056,6 +1091,10 @@ var AdminService_ServiceDesc = grpc.ServiceDesc{ MethodName: "ListWebhooks", Handler: _AdminService_ListWebhooks_Handler, }, + { + MethodName: "UpdateBillingAccountLimits", + Handler: _AdminService_UpdateBillingAccountLimits_Handler, + }, }, Streams: []grpc.StreamDesc{}, Metadata: "raystack/frontier/v1beta1/admin.proto", diff --git a/test/e2e/regression/billing_test.go b/test/e2e/regression/billing_test.go index 5d2724438..338d60730 100644 --- a/test/e2e/regression/billing_test.go +++ b/test/e2e/regression/billing_test.go @@ -8,6 +8,8 @@ import ( "testing" "time" + "github.com/raystack/frontier/billing/credit" + "github.com/stripe/stripe-go/v79" "github.com/raystack/frontier/billing/usage" @@ -1032,6 +1034,84 @@ func (s *BillingRegressionTestSuite) TestUsageAPI() { s.Assert().NoError(err) s.Assert().Equal(beforeBalance, getBalanceResp.GetBalance().GetAmount()) }) + s.Run("9. allow customer overdraft if set", func() { + // check balance + getBalanceResp, err := s.testBench.Client.GetBillingBalance(ctxOrgAdminAuth, &frontierv1beta1.GetBillingBalanceRequest{ + OrgId: createOrgResp.GetOrganization().GetId(), + Id: createBillingResp.GetBillingAccount().GetId(), + }) + s.Assert().NoError(err) + beforeBalance := getBalanceResp.GetBalance().GetAmount() + + // set limit to -20 + _, err = s.testBench.AdminClient.UpdateBillingAccountLimits(ctxOrgAdminAuth, &frontierv1beta1.UpdateBillingAccountLimitsRequest{ + OrgId: createOrgResp.GetOrganization().GetId(), + Id: createBillingResp.GetBillingAccount().GetId(), + CreditMin: -20, + }) + s.Assert().NoError(err) + + usageID := uuid.New().String() + // go overdraft + _, err = s.testBench.Client.CreateBillingUsage(ctxOrgAdminAuth, &frontierv1beta1.CreateBillingUsageRequest{ + ProjectId: creteProjectResp.GetProject().GetId(), + Usages: []*frontierv1beta1.Usage{ + { + Id: usageID, + Source: "billing.test", + Description: "billing test", + Amount: beforeBalance + 10, + UserId: testUserID, + Metadata: Must(structpb.NewStruct(map[string]interface{}{ + "key": "value", + })), + }, + }, + }) + s.Assert().NoError(err) + + // check balance + getBalanceResp, err = s.testBench.Client.GetBillingBalance(ctxOrgAdminAuth, &frontierv1beta1.GetBillingBalanceRequest{ + OrgId: createOrgResp.GetOrganization().GetId(), + Id: createBillingResp.GetBillingAccount().GetId(), + }) + s.Assert().NoError(err) + s.Assert().Equal(int64(-10), getBalanceResp.GetBalance().GetAmount()) + + // can't go over overdraft + _, err = s.testBench.Client.CreateBillingUsage(ctxOrgAdminAuth, &frontierv1beta1.CreateBillingUsageRequest{ + ProjectId: creteProjectResp.GetProject().GetId(), + Usages: []*frontierv1beta1.Usage{ + { + Id: uuid.NewString(), + Source: "billing.test", + Description: "billing test", + Amount: 50, + UserId: testUserID, + Metadata: Must(structpb.NewStruct(map[string]interface{}{ + "key": "value", + })), + }, + }, + }) + s.Assert().ErrorContains(err, credit.ErrInsufficientCredits.Error()) + + // revert usage + _, err = s.testBench.AdminClient.RevertBillingUsage(ctxOrgAdminAuth, &frontierv1beta1.RevertBillingUsageRequest{ + ProjectId: creteProjectResp.GetProject().GetId(), + UsageId: usageID, + Amount: beforeBalance + 10, + }) + s.Assert().NoError(err) + + // reset limit + _, err = s.testBench.AdminClient.UpdateBillingAccountLimits(ctxOrgAdminAuth, &frontierv1beta1.UpdateBillingAccountLimitsRequest{ + OrgId: createOrgResp.GetOrganization().GetId(), + Id: createBillingResp.GetBillingAccount().GetId(), + CreditMin: 0, + }) + s.Assert().NoError(err) + }) } func (s *BillingRegressionTestSuite) TestCheckFeatureEntitlementAPI() {