Support login with username and password (#15656) (#16341)

Signed-off-by: kejiang <ke.jiang@zilliz.com>

Co-authored-by: kejiang <ke.jiang@zilliz.com>
This commit is contained in:
codeman 2022-04-11 19:49:34 +08:00 committed by GitHub
parent 0fa4ec487d
commit 4e12271d79
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
53 changed files with 6440 additions and 771 deletions

1
go.mod
View File

@ -49,6 +49,7 @@ require (
go.uber.org/atomic v1.7.0
go.uber.org/automaxprocs v1.4.0
go.uber.org/zap v1.17.0
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519 // indirect
golang.org/x/exp v0.0.0-20211216164055-b2b84827b756
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c
google.golang.org/grpc v1.44.0

View File

@ -265,7 +265,7 @@ const char descriptor_table_protodef_common_2eproto[] PROTOBUF_SECTION_VARIABLE(
"ceID\030\004 \001(\003\"7\n\tMsgHeader\022*\n\004base\030\001 \001(\0132\034."
"milvus.proto.common.MsgBase\"M\n\014DMLMsgHea"
"der\022*\n\004base\030\001 \001(\0132\034.milvus.proto.common."
"MsgBase\022\021\n\tshardName\030\002 \001(\t*\363\004\n\tErrorCode"
"MsgBase\022\021\n\tshardName\030\002 \001(\t*\376\005\n\tErrorCode"
"\022\013\n\007Success\020\000\022\023\n\017UnexpectedError\020\001\022\021\n\rCo"
"nnectFailed\020\002\022\024\n\020PermissionDenied\020\003\022\027\n\023C"
"ollectionNotExists\020\004\022\023\n\017IllegalArgument\020"
@ -280,55 +280,61 @@ const char descriptor_table_protodef_common_2eproto[] PROTOBUF_SECTION_VARIABLE(
"\025\022\020\n\014IllegalNLIST\020\026\022\025\n\021IllegalMetricType"
"\020\027\022\017\n\013OutOfMemory\020\030\022\021\n\rIndexNotExist\020\031\022\023"
"\n\017EmptyCollection\020\032\022\033\n\027UpdateImportTaskF"
"ailure\020\033\022\032\n\026CollectionNameNotFound\020\034\022\022\n\r"
"DDRequestRace\020\350\007*X\n\nIndexState\022\022\n\016IndexS"
"tateNone\020\000\022\014\n\010Unissued\020\001\022\016\n\nInProgress\020\002"
"\022\014\n\010Finished\020\003\022\n\n\006Failed\020\004*s\n\014SegmentSta"
"te\022\024\n\020SegmentStateNone\020\000\022\014\n\010NotExist\020\001\022\013"
"\n\007Growing\020\002\022\n\n\006Sealed\020\003\022\013\n\007Flushed\020\004\022\014\n\010"
"Flushing\020\005\022\013\n\007Dropped\020\006*\300\t\n\007MsgType\022\r\n\tU"
"ndefined\020\000\022\024\n\020CreateCollection\020d\022\022\n\016Drop"
"Collection\020e\022\021\n\rHasCollection\020f\022\026\n\022Descr"
"ibeCollection\020g\022\023\n\017ShowCollections\020h\022\024\n\020"
"GetSystemConfigs\020i\022\022\n\016LoadCollection\020j\022\025"
"\n\021ReleaseCollection\020k\022\017\n\013CreateAlias\020l\022\r"
"\n\tDropAlias\020m\022\016\n\nAlterAlias\020n\022\024\n\017CreateP"
"artition\020\310\001\022\022\n\rDropPartition\020\311\001\022\021\n\014HasPa"
"rtition\020\312\001\022\026\n\021DescribePartition\020\313\001\022\023\n\016Sh"
"owPartitions\020\314\001\022\023\n\016LoadPartitions\020\315\001\022\026\n\021"
"ReleasePartitions\020\316\001\022\021\n\014ShowSegments\020\372\001\022"
"\024\n\017DescribeSegment\020\373\001\022\021\n\014LoadSegments\020\374\001"
"\022\024\n\017ReleaseSegments\020\375\001\022\024\n\017HandoffSegment"
"s\020\376\001\022\030\n\023LoadBalanceSegments\020\377\001\022\025\n\020Descri"
"beSegments\020\200\002\022\020\n\013CreateIndex\020\254\002\022\022\n\rDescr"
"ibeIndex\020\255\002\022\016\n\tDropIndex\020\256\002\022\013\n\006Insert\020\220\003"
"\022\013\n\006Delete\020\221\003\022\n\n\005Flush\020\222\003\022\013\n\006Search\020\364\003\022\021"
"\n\014SearchResult\020\365\003\022\022\n\rGetIndexState\020\366\003\022\032\n"
"\025GetIndexBuildProgress\020\367\003\022\034\n\027GetCollecti"
"onStatistics\020\370\003\022\033\n\026GetPartitionStatistic"
"s\020\371\003\022\r\n\010Retrieve\020\372\003\022\023\n\016RetrieveResult\020\373\003"
"\022\024\n\017WatchDmChannels\020\374\003\022\025\n\020RemoveDmChanne"
"ls\020\375\003\022\027\n\022WatchQueryChannels\020\376\003\022\030\n\023Remove"
"QueryChannels\020\377\003\022\035\n\030SealedSegmentsChange"
"Info\020\200\004\022\027\n\022WatchDeltaChannels\020\201\004\022\020\n\013Segm"
"entInfo\020\330\004\022\017\n\nSystemInfo\020\331\004\022\024\n\017GetRecove"
"ryInfo\020\332\004\022\024\n\017GetSegmentState\020\333\004\022\r\n\010TimeT"
"ick\020\260\t\022\023\n\016QueryNodeStats\020\261\t\022\016\n\tLoadIndex"
"\020\262\t\022\016\n\tRequestID\020\263\t\022\017\n\nRequestTSO\020\264\t\022\024\n\017"
"AllocateSegment\020\265\t\022\026\n\021SegmentStatistics\020"
"\266\t\022\025\n\020SegmentFlushDone\020\267\t\022\017\n\nDataNodeTt\020"
"\270\t*\"\n\007DslType\022\007\n\003Dsl\020\000\022\016\n\nBoolExprV1\020\001*B"
"\n\017CompactionState\022\021\n\rUndefiedState\020\000\022\r\n\t"
"Executing\020\001\022\r\n\tCompleted\020\002*X\n\020Consistenc"
"yLevel\022\n\n\006Strong\020\000\022\013\n\007Session\020\001\022\013\n\007Bound"
"ed\020\002\022\016\n\nEventually\020\003\022\016\n\nCustomized\020\004*\227\001\n"
"\013ImportState\022\021\n\rImportPending\020\000\022\020\n\014Impor"
"tFailed\020\001\022\021\n\rImportStarted\020\002\022\024\n\020ImportDo"
"wnloaded\020\003\022\020\n\014ImportParsed\020\004\022\023\n\017ImportPe"
"rsisted\020\005\022\023\n\017ImportCompleted\020\006BW\n\016io.mil"
"vus.grpcB\013CommonProtoP\001Z3github.com/milv"
"us-io/milvus/internal/proto/commonpb\240\001\001b"
"\006proto3"
"ailure\020\033\022\032\n\026CollectionNameNotFound\020\034\022\033\n\027"
"CreateCredentialFailure\020\035\022\033\n\027UpdateCrede"
"ntialFailure\020\036\022\033\n\027DeleteCredentialFailur"
"e\020\037\022\030\n\024GetCredentialFailure\020 \022\030\n\024ListCre"
"dUsersFailure\020!\022\022\n\rDDRequestRace\020\350\007*X\n\nI"
"ndexState\022\022\n\016IndexStateNone\020\000\022\014\n\010Unissue"
"d\020\001\022\016\n\nInProgress\020\002\022\014\n\010Finished\020\003\022\n\n\006Fai"
"led\020\004*s\n\014SegmentState\022\024\n\020SegmentStateNon"
"e\020\000\022\014\n\010NotExist\020\001\022\013\n\007Growing\020\002\022\n\n\006Sealed"
"\020\003\022\013\n\007Flushed\020\004\022\014\n\010Flushing\020\005\022\013\n\007Dropped"
"\020\006*\261\n\n\007MsgType\022\r\n\tUndefined\020\000\022\024\n\020CreateC"
"ollection\020d\022\022\n\016DropCollection\020e\022\021\n\rHasCo"
"llection\020f\022\026\n\022DescribeCollection\020g\022\023\n\017Sh"
"owCollections\020h\022\024\n\020GetSystemConfigs\020i\022\022\n"
"\016LoadCollection\020j\022\025\n\021ReleaseCollection\020k"
"\022\017\n\013CreateAlias\020l\022\r\n\tDropAlias\020m\022\016\n\nAlte"
"rAlias\020n\022\024\n\017CreatePartition\020\310\001\022\022\n\rDropPa"
"rtition\020\311\001\022\021\n\014HasPartition\020\312\001\022\026\n\021Describ"
"ePartition\020\313\001\022\023\n\016ShowPartitions\020\314\001\022\023\n\016Lo"
"adPartitions\020\315\001\022\026\n\021ReleasePartitions\020\316\001\022"
"\021\n\014ShowSegments\020\372\001\022\024\n\017DescribeSegment\020\373\001"
"\022\021\n\014LoadSegments\020\374\001\022\024\n\017ReleaseSegments\020\375"
"\001\022\024\n\017HandoffSegments\020\376\001\022\030\n\023LoadBalanceSe"
"gments\020\377\001\022\025\n\020DescribeSegments\020\200\002\022\020\n\013Crea"
"teIndex\020\254\002\022\022\n\rDescribeIndex\020\255\002\022\016\n\tDropIn"
"dex\020\256\002\022\013\n\006Insert\020\220\003\022\013\n\006Delete\020\221\003\022\n\n\005Flus"
"h\020\222\003\022\013\n\006Search\020\364\003\022\021\n\014SearchResult\020\365\003\022\022\n\r"
"GetIndexState\020\366\003\022\032\n\025GetIndexBuildProgres"
"s\020\367\003\022\034\n\027GetCollectionStatistics\020\370\003\022\033\n\026Ge"
"tPartitionStatistics\020\371\003\022\r\n\010Retrieve\020\372\003\022\023"
"\n\016RetrieveResult\020\373\003\022\024\n\017WatchDmChannels\020\374"
"\003\022\025\n\020RemoveDmChannels\020\375\003\022\027\n\022WatchQueryCh"
"annels\020\376\003\022\030\n\023RemoveQueryChannels\020\377\003\022\035\n\030S"
"ealedSegmentsChangeInfo\020\200\004\022\027\n\022WatchDelta"
"Channels\020\201\004\022\020\n\013SegmentInfo\020\330\004\022\017\n\nSystemI"
"nfo\020\331\004\022\024\n\017GetRecoveryInfo\020\332\004\022\024\n\017GetSegme"
"ntState\020\333\004\022\r\n\010TimeTick\020\260\t\022\023\n\016QueryNodeSt"
"ats\020\261\t\022\016\n\tLoadIndex\020\262\t\022\016\n\tRequestID\020\263\t\022\017"
"\n\nRequestTSO\020\264\t\022\024\n\017AllocateSegment\020\265\t\022\026\n"
"\021SegmentStatistics\020\266\t\022\025\n\020SegmentFlushDon"
"e\020\267\t\022\017\n\nDataNodeTt\020\270\t\022\025\n\020CreateCredentia"
"l\020\334\013\022\022\n\rGetCredential\020\335\013\022\025\n\020DeleteCreden"
"tial\020\336\013\022\025\n\020UpdateCredential\020\337\013\022\026\n\021ListCr"
"edUsernames\020\340\013*\"\n\007DslType\022\007\n\003Dsl\020\000\022\016\n\nBo"
"olExprV1\020\001*B\n\017CompactionState\022\021\n\rUndefie"
"dState\020\000\022\r\n\tExecuting\020\001\022\r\n\tCompleted\020\002*X"
"\n\020ConsistencyLevel\022\n\n\006Strong\020\000\022\013\n\007Sessio"
"n\020\001\022\013\n\007Bounded\020\002\022\016\n\nEventually\020\003\022\016\n\nCust"
"omized\020\004*\227\001\n\013ImportState\022\021\n\rImportPendin"
"g\020\000\022\020\n\014ImportFailed\020\001\022\021\n\rImportStarted\020\002"
"\022\024\n\020ImportDownloaded\020\003\022\020\n\014ImportParsed\020\004"
"\022\023\n\017ImportPersisted\020\005\022\023\n\017ImportCompleted"
"\020\006BW\n\016io.milvus.grpcB\013CommonProtoP\001Z3git"
"hub.com/milvus-io/milvus/internal/proto/"
"commonpb\240\001\001b\006proto3"
;
static const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable*const descriptor_table_common_2eproto_deps[1] = {
};
@ -345,7 +351,7 @@ static ::PROTOBUF_NAMESPACE_ID::internal::SCCInfoBase*const descriptor_table_com
static ::PROTOBUF_NAMESPACE_ID::internal::once_flag descriptor_table_common_2eproto_once;
static bool descriptor_table_common_2eproto_initialized = false;
const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable descriptor_table_common_2eproto = {
&descriptor_table_common_2eproto_initialized, descriptor_table_protodef_common_2eproto, "common.proto", 3007,
&descriptor_table_common_2eproto_initialized, descriptor_table_protodef_common_2eproto, "common.proto", 3259,
&descriptor_table_common_2eproto_once, descriptor_table_common_2eproto_sccs, descriptor_table_common_2eproto_deps, 8, 0,
schemas, file_default_instances, TableStruct_common_2eproto::offsets,
file_level_metadata_common_2eproto, 8, file_level_enum_descriptors_common_2eproto, file_level_service_descriptors_common_2eproto,
@ -390,6 +396,11 @@ bool ErrorCode_IsValid(int value) {
case 26:
case 27:
case 28:
case 29:
case 30:
case 31:
case 32:
case 33:
case 1000:
return true;
default:
@ -498,6 +509,11 @@ bool MsgType_IsValid(int value) {
case 1206:
case 1207:
case 1208:
case 1500:
case 1501:
case 1502:
case 1503:
case 1504:
return true;
default:
return false;

View File

@ -128,6 +128,11 @@ enum ErrorCode : int {
EmptyCollection = 26,
UpdateImportTaskFailure = 27,
CollectionNameNotFound = 28,
CreateCredentialFailure = 29,
UpdateCredentialFailure = 30,
DeleteCredentialFailure = 31,
GetCredentialFailure = 32,
ListCredUsersFailure = 33,
DDRequestRace = 1000,
ErrorCode_INT_MIN_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::PROTOBUF_NAMESPACE_ID::int32>::min(),
ErrorCode_INT_MAX_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::PROTOBUF_NAMESPACE_ID::int32>::max()
@ -269,12 +274,17 @@ enum MsgType : int {
SegmentStatistics = 1206,
SegmentFlushDone = 1207,
DataNodeTt = 1208,
CreateCredential = 1500,
GetCredential = 1501,
DeleteCredential = 1502,
UpdateCredential = 1503,
ListCredUsernames = 1504,
MsgType_INT_MIN_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::PROTOBUF_NAMESPACE_ID::int32>::min(),
MsgType_INT_MAX_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::PROTOBUF_NAMESPACE_ID::int32>::max()
};
bool MsgType_IsValid(int value);
constexpr MsgType MsgType_MIN = Undefined;
constexpr MsgType MsgType_MAX = DataNodeTt;
constexpr MsgType MsgType_MAX = ListCredUsernames;
constexpr int MsgType_ARRAYSIZE = MsgType_MAX + 1;
const ::PROTOBUF_NAMESPACE_ID::EnumDescriptor* MsgType_descriptor();

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -603,6 +603,26 @@ func (t *mockCompactionTrigger) stop() {
panic("not implemented")
}
func (m *mockRootCoordService) CreateCredential(ctx context.Context, req *internalpb.CredentialInfo) (*commonpb.Status, error) {
panic("implement me")
}
func (m *mockRootCoordService) UpdateCredential(ctx context.Context, req *internalpb.CredentialInfo) (*commonpb.Status, error) {
panic("implement me")
}
func (m *mockRootCoordService) DeleteCredential(ctx context.Context, req *milvuspb.DeleteCredentialRequest) (*commonpb.Status, error) {
panic("implement me")
}
func (m *mockRootCoordService) ListCredUsers(ctx context.Context, req *milvuspb.ListCredUsersRequest) (*milvuspb.ListCredUsersResponse, error) {
panic("implement me")
}
func (m *mockRootCoordService) GetCredential(ctx context.Context, req *rootcoordpb.GetCredentialRequest) (*rootcoordpb.GetCredentialResponse, error) {
panic("implement me")
}
type mockHandler struct {
}

View File

@ -167,3 +167,42 @@ func (c *Client) SendRetrieveResult(ctx context.Context, results *internalpb.Ret
}
return ret.(*commonpb.Status), err
}
func (c *Client) InvalidateCredentialCache(ctx context.Context, req *proxypb.InvalidateCredCacheRequest) (*commonpb.Status, error) {
ret, err := c.grpcClient.ReCall(ctx, func(client interface{}) (interface{}, error) {
if !funcutil.CheckCtxValid(ctx) {
return nil, ctx.Err()
}
return client.(proxypb.ProxyClient).InvalidateCredentialCache(ctx, req)
})
if err != nil || ret == nil {
return nil, err
}
return ret.(*commonpb.Status), err
}
func (c *Client) UpdateCredentialCache(ctx context.Context, req *proxypb.UpdateCredCacheRequest) (*commonpb.Status, error) {
ret, err := c.grpcClient.ReCall(ctx, func(client interface{}) (interface{}, error) {
if !funcutil.CheckCtxValid(ctx) {
return nil, ctx.Err()
}
return client.(proxypb.ProxyClient).UpdateCredentialCache(ctx, req)
})
if err != nil || ret == nil {
return nil, err
}
return ret.(*commonpb.Status), err
}
func (c *Client) ClearCredUsersCache(ctx context.Context, req *internalpb.ClearCredUsersCacheRequest) (*commonpb.Status, error) {
ret, err := c.grpcClient.ReCall(ctx, func(client interface{}) (interface{}, error) {
if !funcutil.CheckCtxValid(ctx) {
return nil, ctx.Err()
}
return client.(proxypb.ProxyClient).ClearCredUsersCache(ctx, req)
})
if err != nil || ret == nil {
return nil, err
}
return ret.(*commonpb.Status), err
}

View File

@ -20,6 +20,7 @@ import (
"context"
"errors"
"testing"
"time"
"github.com/milvus-io/milvus/internal/util/mock"
"google.golang.org/grpc"
@ -74,6 +75,15 @@ func Test_NewClient(t *testing.T) {
r6, err := client.SendRetrieveResult(ctx, nil)
retCheck(retNotNil, r6, err)
r7, err := client.InvalidateCredentialCache(ctx, nil)
retCheck(retNotNil, r7, err)
r8, err := client.UpdateCredentialCache(ctx, nil)
retCheck(retNotNil, r8, err)
r9, err := client.ClearCredUsersCache(ctx, nil)
retCheck(retNotNil, r9, err)
}
client.grpcClient = &mock.ClientBase{
@ -108,6 +118,45 @@ func Test_NewClient(t *testing.T) {
checkFunc(true)
// timeout
timeout := time.Nanosecond
shortCtx, shortCancel := context.WithTimeout(ctx, timeout)
defer shortCancel()
time.Sleep(timeout)
retCheck := func(ret interface{}, err error) {
assert.Nil(t, ret)
assert.NotNil(t, err)
}
r1Timeout, err := client.GetComponentStates(shortCtx)
retCheck(r1Timeout, err)
r2Timeout, err := client.GetStatisticsChannel(shortCtx)
retCheck(r2Timeout, err)
r3Timeout, err := client.InvalidateCollectionMetaCache(shortCtx, nil)
retCheck(r3Timeout, err)
r4Timeout, err := client.ReleaseDQLMessageStream(shortCtx, nil)
retCheck(r4Timeout, err)
r5Timeout, err := client.SendSearchResult(shortCtx, nil)
retCheck(r5Timeout, err)
r6Timeout, err := client.SendRetrieveResult(shortCtx, nil)
retCheck(r6Timeout, err)
r7Timeout, err := client.InvalidateCredentialCache(shortCtx, nil)
retCheck(r7Timeout, err)
r8Timeout, err := client.UpdateCredentialCache(shortCtx, nil)
retCheck(r8Timeout, err)
r9Timeout, err := client.ClearCredUsersCache(shortCtx, nil)
retCheck(r9Timeout, err)
// cleanup
err = client.Stop()
assert.Nil(t, err)
}

View File

@ -26,6 +26,13 @@ import (
"sync"
"time"
grpc_auth "github.com/grpc-ecosystem/go-grpc-middleware/auth"
grpc_middleware "github.com/grpc-ecosystem/go-grpc-middleware"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
"github.com/gin-gonic/gin"
ot "github.com/grpc-ecosystem/go-grpc-middleware/tracing/opentracing"
"github.com/opentracing/opentracing-go"
@ -58,6 +65,11 @@ import (
var Params paramtable.GrpcServerConfig
var HTTPParams paramtable.HTTPConfig
var (
errMissingMetadata = status.Errorf(codes.InvalidArgument, "missing metadata")
errInvalidToken = status.Errorf(codes.Unauthenticated, "invalid token")
)
// Server is the Proxy Server
type Server struct {
ctx context.Context
@ -155,8 +167,15 @@ func (s *Server) startGrpcLoop(grpcPort int) {
grpc.KeepaliveParams(kasp),
grpc.MaxRecvMsgSize(Params.ServerMaxRecvSize),
grpc.MaxSendMsgSize(Params.ServerMaxSendSize),
grpc.UnaryInterceptor(ot.UnaryServerInterceptor(opts...)),
grpc.StreamInterceptor(ot.StreamServerInterceptor(opts...)))
grpc.UnaryInterceptor(grpc_middleware.ChainUnaryServer(
ot.UnaryServerInterceptor(opts...),
grpc_auth.UnaryServerInterceptor(proxy.AuthenticationInterceptor),
)),
grpc.StreamInterceptor(grpc_middleware.ChainStreamServer(
ot.StreamServerInterceptor(opts...),
grpc_auth.StreamServerInterceptor(proxy.AuthenticationInterceptor),
)),
)
proxypb.RegisterProxyServer(s.grpcServer, s)
milvuspb.RegisterMilvusServiceServer(s.grpcServer, s)
grpc_health_v1.RegisterHealthServer(s.grpcServer, s)
@ -689,3 +708,31 @@ func (s *Server) Watch(req *grpc_health_v1.HealthCheckRequest, server grpc_healt
ret.Status = grpc_health_v1.HealthCheckResponse_SERVING
return server.Send(ret)
}
func (s *Server) InvalidateCredentialCache(ctx context.Context, request *proxypb.InvalidateCredCacheRequest) (*commonpb.Status, error) {
return s.proxy.InvalidateCredentialCache(ctx, request)
}
func (s *Server) UpdateCredentialCache(ctx context.Context, request *proxypb.UpdateCredCacheRequest) (*commonpb.Status, error) {
return s.proxy.UpdateCredentialCache(ctx, request)
}
func (s *Server) ClearCredUsersCache(ctx context.Context, request *internalpb.ClearCredUsersCacheRequest) (*commonpb.Status, error) {
return s.proxy.ClearCredUsersCache(ctx, request)
}
func (s *Server) CreateCredential(ctx context.Context, req *milvuspb.CreateCredentialRequest) (*commonpb.Status, error) {
return s.proxy.CreateCredential(ctx, req)
}
func (s *Server) UpdateCredential(ctx context.Context, req *milvuspb.CreateCredentialRequest) (*commonpb.Status, error) {
return s.proxy.UpdateCredential(ctx, req)
}
func (s *Server) DeleteCredential(ctx context.Context, req *milvuspb.DeleteCredentialRequest) (*commonpb.Status, error) {
return s.proxy.DeleteCredential(ctx, req)
}
func (s *Server) ListCredUsers(ctx context.Context, req *milvuspb.ListCredUsersRequest) (*milvuspb.ListCredUsersResponse, error) {
return s.proxy.ListCredUsers(ctx, req)
}

View File

@ -214,6 +214,26 @@ func (m *MockRootCoord) ReportImport(ctx context.Context, req *rootcoordpb.Impor
return nil, nil
}
func (m *MockRootCoord) CreateCredential(ctx context.Context, req *internalpb.CredentialInfo) (*commonpb.Status, error) {
return nil, nil
}
func (m *MockRootCoord) UpdateCredential(ctx context.Context, req *internalpb.CredentialInfo) (*commonpb.Status, error) {
return nil, nil
}
func (m *MockRootCoord) DeleteCredential(ctx context.Context, req *milvuspb.DeleteCredentialRequest) (*commonpb.Status, error) {
return nil, nil
}
func (m *MockRootCoord) ListCredUsers(ctx context.Context, req *milvuspb.ListCredUsersRequest) (*milvuspb.ListCredUsersResponse, error) {
return nil, nil
}
func (m *MockRootCoord) GetCredential(ctx context.Context, req *rootcoordpb.GetCredentialRequest) (*rootcoordpb.GetCredentialResponse, error) {
return nil, nil
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
type MockIndexCoord struct {
MockBase
@ -716,6 +736,34 @@ func (m *MockProxy) GetReplicas(ctx context.Context, req *milvuspb.GetReplicasRe
return nil, nil
}
func (m *MockProxy) InvalidateCredentialCache(ctx context.Context, request *proxypb.InvalidateCredCacheRequest) (*commonpb.Status, error) {
return nil, nil
}
func (m *MockProxy) UpdateCredentialCache(ctx context.Context, request *proxypb.UpdateCredCacheRequest) (*commonpb.Status, error) {
return nil, nil
}
func (m *MockProxy) ClearCredUsersCache(ctx context.Context, request *internalpb.ClearCredUsersCacheRequest) (*commonpb.Status, error) {
return nil, nil
}
func (m *MockProxy) CreateCredential(ctx context.Context, req *milvuspb.CreateCredentialRequest) (*commonpb.Status, error) {
return nil, nil
}
func (m *MockProxy) UpdateCredential(ctx context.Context, req *milvuspb.CreateCredentialRequest) (*commonpb.Status, error) {
return nil, nil
}
func (m *MockProxy) DeleteCredential(ctx context.Context, req *milvuspb.DeleteCredentialRequest) (*commonpb.Status, error) {
return nil, nil
}
func (m *MockProxy) ListCredUsers(ctx context.Context, req *milvuspb.ListCredUsersRequest) (*milvuspb.ListCredUsersResponse, error) {
return nil, nil
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
func Test_NewServer(t *testing.T) {
ctx := context.Background()
@ -949,6 +997,41 @@ func Test_NewServer(t *testing.T) {
assert.Nil(t, err)
})
t.Run("CreateCredential", func(t *testing.T) {
_, err := server.CreateCredential(ctx, nil)
assert.Nil(t, err)
})
t.Run("UpdateCredential", func(t *testing.T) {
_, err := server.UpdateCredential(ctx, nil)
assert.Nil(t, err)
})
t.Run("DeleteCredential", func(t *testing.T) {
_, err := server.DeleteCredential(ctx, nil)
assert.Nil(t, err)
})
t.Run("ListCredUsers", func(t *testing.T) {
_, err := server.ListCredUsers(ctx, nil)
assert.Nil(t, err)
})
t.Run("InvalidateCredentialCache", func(t *testing.T) {
_, err := server.InvalidateCredentialCache(ctx, nil)
assert.Nil(t, err)
})
t.Run("UpdateCredentialCache", func(t *testing.T) {
_, err := server.UpdateCredentialCache(ctx, nil)
assert.Nil(t, err)
})
t.Run("ClearCredUsersCache", func(t *testing.T) {
_, err := server.ClearCredUsersCache(ctx, nil)
assert.Nil(t, err)
})
err = server.Stop()
assert.Nil(t, err)

View File

@ -530,3 +530,68 @@ func (c *Client) ReportImport(ctx context.Context, req *rootcoordpb.ImportResult
}
return ret.(*commonpb.Status), err
}
func (c *Client) CreateCredential(ctx context.Context, req *internalpb.CredentialInfo) (*commonpb.Status, error) {
ret, err := c.grpcClient.ReCall(ctx, func(client interface{}) (interface{}, error) {
if !funcutil.CheckCtxValid(ctx) {
return nil, ctx.Err()
}
return client.(rootcoordpb.RootCoordClient).CreateCredential(ctx, req)
})
if err != nil || ret == nil {
return nil, err
}
return ret.(*commonpb.Status), err
}
func (c *Client) GetCredential(ctx context.Context, req *rootcoordpb.GetCredentialRequest) (*rootcoordpb.GetCredentialResponse, error) {
ret, err := c.grpcClient.ReCall(ctx, func(client interface{}) (interface{}, error) {
if !funcutil.CheckCtxValid(ctx) {
return nil, ctx.Err()
}
return client.(rootcoordpb.RootCoordClient).GetCredential(ctx, req)
})
if err != nil || ret == nil {
return nil, err
}
return ret.(*rootcoordpb.GetCredentialResponse), err
}
func (c *Client) UpdateCredential(ctx context.Context, req *internalpb.CredentialInfo) (*commonpb.Status, error) {
ret, err := c.grpcClient.ReCall(ctx, func(client interface{}) (interface{}, error) {
if !funcutil.CheckCtxValid(ctx) {
return nil, ctx.Err()
}
return client.(rootcoordpb.RootCoordClient).UpdateCredential(ctx, req)
})
if err != nil || ret == nil {
return nil, err
}
return ret.(*commonpb.Status), err
}
func (c *Client) DeleteCredential(ctx context.Context, req *milvuspb.DeleteCredentialRequest) (*commonpb.Status, error) {
ret, err := c.grpcClient.ReCall(ctx, func(client interface{}) (interface{}, error) {
if !funcutil.CheckCtxValid(ctx) {
return nil, ctx.Err()
}
return client.(rootcoordpb.RootCoordClient).DeleteCredential(ctx, req)
})
if err != nil || ret == nil {
return nil, err
}
return ret.(*commonpb.Status), err
}
func (c *Client) ListCredUsers(ctx context.Context, req *milvuspb.ListCredUsersRequest) (*milvuspb.ListCredUsersResponse, error) {
ret, err := c.grpcClient.ReCall(ctx, func(client interface{}) (interface{}, error) {
if !funcutil.CheckCtxValid(ctx) {
return nil, ctx.Err()
}
return client.(rootcoordpb.RootCoordClient).ListCredUsers(ctx, req)
})
if err != nil || ret == nil {
return nil, err
}
return ret.(*milvuspb.ListCredUsersResponse), err
}

View File

@ -20,6 +20,7 @@ import (
"context"
"errors"
"testing"
"time"
"github.com/milvus-io/milvus/internal/util/mock"
"google.golang.org/grpc"
@ -145,6 +146,21 @@ func Test_NewClient(t *testing.T) {
r29, err := client.ReportImport(ctx, nil)
retCheck(retNotNil, r29, err)
r30, err := client.CreateCredential(ctx, nil)
retCheck(retNotNil, r30, err)
r31, err := client.GetCredential(ctx, nil)
retCheck(retNotNil, r31, err)
r32, err := client.UpdateCredential(ctx, nil)
retCheck(retNotNil, r32, err)
r33, err := client.DeleteCredential(ctx, nil)
retCheck(retNotNil, r33, err)
r34, err := client.ListCredUsers(ctx, nil)
retCheck(retNotNil, r34, err)
}
client.grpcClient = &mock.ClientBase{
@ -181,6 +197,120 @@ func Test_NewClient(t *testing.T) {
checkFunc(true)
// timeout
timeout := time.Nanosecond
shortCtx, shortCancel := context.WithTimeout(ctx, timeout)
defer shortCancel()
time.Sleep(timeout)
retCheck := func(ret interface{}, err error) {
assert.Nil(t, ret)
assert.NotNil(t, err)
}
r1Timeout, err := client.GetComponentStates(shortCtx)
retCheck(r1Timeout, err)
r2Timeout, err := client.GetTimeTickChannel(shortCtx)
retCheck(r2Timeout, err)
r3Timeout, err := client.GetStatisticsChannel(shortCtx)
retCheck(r3Timeout, err)
r4Timeout, err := client.CreateCollection(shortCtx, nil)
retCheck(r4Timeout, err)
r5Timeout, err := client.DropCollection(shortCtx, nil)
retCheck(r5Timeout, err)
r6Timeout, err := client.HasCollection(shortCtx, nil)
retCheck(r6Timeout, err)
r7Timeout, err := client.DescribeCollection(shortCtx, nil)
retCheck(r7Timeout, err)
r8Timeout, err := client.ShowCollections(shortCtx, nil)
retCheck(r8Timeout, err)
r9Timeout, err := client.CreatePartition(shortCtx, nil)
retCheck(r9Timeout, err)
r10Timeout, err := client.DropPartition(shortCtx, nil)
retCheck(r10Timeout, err)
r11Timeout, err := client.HasPartition(shortCtx, nil)
retCheck(r11Timeout, err)
r12Timeout, err := client.ShowPartitions(shortCtx, nil)
retCheck(r12Timeout, err)
r13Timeout, err := client.CreateIndex(shortCtx, nil)
retCheck(r13Timeout, err)
r14Timeout, err := client.DropIndex(shortCtx, nil)
retCheck(r14Timeout, err)
r15Timeout, err := client.DescribeIndex(shortCtx, nil)
retCheck(r15Timeout, err)
r16Timeout, err := client.AllocTimestamp(shortCtx, nil)
retCheck(r16Timeout, err)
r17Timeout, err := client.AllocID(shortCtx, nil)
retCheck(r17Timeout, err)
r18Timeout, err := client.UpdateChannelTimeTick(shortCtx, nil)
retCheck(r18Timeout, err)
r19Timeout, err := client.DescribeSegment(shortCtx, nil)
retCheck(r19Timeout, err)
r20Timeout, err := client.ShowSegments(shortCtx, nil)
retCheck(r20Timeout, err)
r21Timeout, err := client.ReleaseDQLMessageStream(shortCtx, nil)
retCheck(r21Timeout, err)
r22Timeout, err := client.SegmentFlushCompleted(shortCtx, nil)
retCheck(r22Timeout, err)
r23Timeout, err := client.GetMetrics(shortCtx, nil)
retCheck(r23Timeout, err)
r24Timeout, err := client.CreateAlias(shortCtx, nil)
retCheck(r24Timeout, err)
r25Timeout, err := client.DropAlias(shortCtx, nil)
retCheck(r25Timeout, err)
r26Timeout, err := client.AlterAlias(shortCtx, nil)
retCheck(r26Timeout, err)
r27Timeout, err := client.Import(shortCtx, nil)
retCheck(r27Timeout, err)
r28Timeout, err := client.GetImportState(shortCtx, nil)
retCheck(r28Timeout, err)
r29Timeout, err := client.ReportImport(shortCtx, nil)
retCheck(r29Timeout, err)
r30Timeout, err := client.CreateCredential(shortCtx, nil)
retCheck(r30Timeout, err)
r31Timeout, err := client.GetCredential(shortCtx, nil)
retCheck(r31Timeout, err)
r32Timeout, err := client.UpdateCredential(shortCtx, nil)
retCheck(r32Timeout, err)
r33Timeout, err := client.DeleteCredential(shortCtx, nil)
retCheck(r33Timeout, err)
r34Timeout, err := client.ListCredUsers(shortCtx, nil)
retCheck(r34Timeout, err)
// clean up
err = client.Stop()
assert.Nil(t, err)
}

View File

@ -453,3 +453,23 @@ func (s *Server) GetImportState(ctx context.Context, in *milvuspb.GetImportState
func (s *Server) ReportImport(ctx context.Context, in *rootcoordpb.ImportResult) (*commonpb.Status, error) {
return s.rootCoord.ReportImport(ctx, in)
}
func (s *Server) CreateCredential(ctx context.Context, request *internalpb.CredentialInfo) (*commonpb.Status, error) {
return s.rootCoord.CreateCredential(ctx, request)
}
func (s *Server) GetCredential(ctx context.Context, request *rootcoordpb.GetCredentialRequest) (*rootcoordpb.GetCredentialResponse, error) {
return s.rootCoord.GetCredential(ctx, request)
}
func (s *Server) UpdateCredential(ctx context.Context, request *internalpb.CredentialInfo) (*commonpb.Status, error) {
return s.rootCoord.UpdateCredential(ctx, request)
}
func (s *Server) DeleteCredential(ctx context.Context, request *milvuspb.DeleteCredentialRequest) (*commonpb.Status, error) {
return s.rootCoord.DeleteCredential(ctx, request)
}
func (s *Server) ListCredUsers(ctx context.Context, request *milvuspb.ListCredUsersRequest) (*milvuspb.ListCredUsersResponse, error) {
return s.rootCoord.ListCredUsers(ctx, request)
}

View File

@ -64,6 +64,7 @@ const (
functionLabelName = "function_name"
queryTypeLabelName = "query_type"
segmentTypeLabelName = "segment_type"
usernameLabelName = "username"
)
var (

View File

@ -270,6 +270,16 @@ var (
Help: "The latency for searching",
Buckets: buckets,
}, []string{nodeIDLabelName})
// ProxyCredentialReqLatency record the latency that for credential request, like "CreateCredential".
ProxyCredentialReqLatency = prometheus.NewHistogramVec(
prometheus.HistogramOpts{
Namespace: milvusNamespace,
Subsystem: typeutil.ProxyRole,
Name: "credential_call_latency",
Help: "The latency that for credential request",
Buckets: buckets, // unit: ms
}, []string{nodeIDLabelName, functionLabelName, usernameLabelName})
)
//RegisterProxy registers Proxy metrics
@ -305,4 +315,7 @@ func RegisterProxy(registry *prometheus.Registry) {
registry.MustRegister(ProxyDDLReqLatency)
registry.MustRegister(ProxyDMLReqLatency)
registry.MustRegister(ProxyDQLReqLatency)
// for credential
registry.MustRegister(ProxyCredentialReqLatency)
}

View File

@ -153,6 +153,51 @@ var (
Help: "Counter of describe segments",
}, []string{statusLabelName})
// RootCoordCreateCredentialCounter counts the num of calls of CreateCredential
RootCoordCreateCredentialCounter = prometheus.NewCounterVec(
prometheus.CounterOpts{
Namespace: milvusNamespace,
Subsystem: typeutil.RootCoordRole,
Name: "create_credential_total",
Help: "Counter of create credential",
}, []string{statusLabelName})
// RootCoordGetCredentialCounter counts the num of calls of GetCredential
RootCoordGetCredentialCounter = prometheus.NewCounterVec(
prometheus.CounterOpts{
Namespace: milvusNamespace,
Subsystem: typeutil.RootCoordRole,
Name: "get_credential_total",
Help: "Counter of get credential",
}, []string{statusLabelName})
// RootCoordDeleteCredentialCounter counts the num of calls of DeleteCredential
RootCoordDeleteCredentialCounter = prometheus.NewCounterVec(
prometheus.CounterOpts{
Namespace: milvusNamespace,
Subsystem: typeutil.RootCoordRole,
Name: "delete_credential_total",
Help: "Counter of delete credential",
}, []string{statusLabelName})
// RootCoordUpdateCredentialCounter counts the num of calls of UpdateCredential
RootCoordUpdateCredentialCounter = prometheus.NewCounterVec(
prometheus.CounterOpts{
Namespace: milvusNamespace,
Subsystem: typeutil.RootCoordRole,
Name: "update_credential_total",
Help: "Counter of update credential",
}, []string{statusLabelName})
// RootCoordListCredUsersCounter counts the num of calls of ListCredUsers
RootCoordListCredUsersCounter = prometheus.NewCounterVec(
prometheus.CounterOpts{
Namespace: milvusNamespace,
Subsystem: typeutil.RootCoordRole,
Name: "list_cred_users_total",
Help: "Counter of list cred users",
}, []string{statusLabelName})
////////////////////////////////////////////////////////////////////////////
// for time tick
@ -192,6 +237,24 @@ var (
Help: "The latency of sync time tick",
})
// RootCoordCredentialWriteTypeLatency records the latency for write type of credential operations.
RootCoordCredentialWriteTypeLatency = prometheus.NewHistogramVec(
prometheus.HistogramOpts{
Namespace: milvusNamespace,
Subsystem: typeutil.RootCoordRole,
Name: "credential_write_type_latency",
Help: "The latency for write type of credential operations",
}, []string{functionLabelName})
// RootCoordCredentialReadTypeLatency records the latency for read type of credential operations.
RootCoordCredentialReadTypeLatency = prometheus.NewHistogramVec(
prometheus.HistogramOpts{
Namespace: milvusNamespace,
Subsystem: typeutil.RootCoordRole,
Name: "credential_read_type_latency",
Help: "The latency for read type of credential operations",
}, []string{functionLabelName, usernameLabelName})
// RootCoordIDAllocCounter records the number of global ID allocations.
RootCoordIDAllocCounter = prometheus.NewCounter(
prometheus.CounterOpts{
@ -272,6 +335,15 @@ var (
Name: "num_of_msg_stream",
Help: "The number of message streams",
})
// RootCoordNumOfCredentials counts the number of credentials.
RootCoordNumOfCredentials = prometheus.NewGauge(
prometheus.GaugeOpts{
Namespace: milvusNamespace,
Subsystem: typeutil.RootCoordRole,
Name: "num_of_credentials",
Help: "The number of credentials",
})
)
//RegisterRootCoord registers RootCoord metrics
@ -317,4 +389,14 @@ func RegisterRootCoord(registry *prometheus.Registry) {
registry.MustRegister(RootCoordNumOfDMLChannel)
registry.MustRegister(RootCoordNumOfMsgStream)
// for credential
registry.MustRegister(RootCoordCreateCredentialCounter)
registry.MustRegister(RootCoordGetCredentialCounter)
registry.MustRegister(RootCoordDeleteCredentialCounter)
registry.MustRegister(RootCoordUpdateCredentialCounter)
registry.MustRegister(RootCoordListCredUsersCounter)
registry.MustRegister(RootCoordCredentialWriteTypeLatency)
registry.MustRegister(RootCoordCredentialReadTypeLatency)
registry.MustRegister(RootCoordNumOfCredentials)
}

View File

@ -37,6 +37,11 @@ enum ErrorCode {
EmptyCollection = 26;
UpdateImportTaskFailure = 27;
CollectionNameNotFound = 28;
CreateCredentialFailure = 29;
UpdateCredentialFailure = 30;
DeleteCredentialFailure = 31;
GetCredentialFailure = 32;
ListCredUsersFailure = 33;
// internal error code.
DDRequestRace = 1000;
@ -161,6 +166,13 @@ enum MsgType {
SegmentFlushDone = 1207;
DataNodeTt = 1208;
/* Credential */
CreateCredential = 1500;
GetCredential = 1501;
DeleteCredential = 1502;
UpdateCredential = 1503;
ListCredUsernames = 1504;
}
message MsgBase {

View File

@ -51,6 +51,11 @@ const (
ErrorCode_EmptyCollection ErrorCode = 26
ErrorCode_UpdateImportTaskFailure ErrorCode = 27
ErrorCode_CollectionNameNotFound ErrorCode = 28
ErrorCode_CreateCredentialFailure ErrorCode = 29
ErrorCode_UpdateCredentialFailure ErrorCode = 30
ErrorCode_DeleteCredentialFailure ErrorCode = 31
ErrorCode_GetCredentialFailure ErrorCode = 32
ErrorCode_ListCredUsersFailure ErrorCode = 33
// internal error code.
ErrorCode_DDRequestRace ErrorCode = 1000
)
@ -84,6 +89,11 @@ var ErrorCode_name = map[int32]string{
26: "EmptyCollection",
27: "UpdateImportTaskFailure",
28: "CollectionNameNotFound",
29: "CreateCredentialFailure",
30: "UpdateCredentialFailure",
31: "DeleteCredentialFailure",
32: "GetCredentialFailure",
33: "ListCredUsersFailure",
1000: "DDRequestRace",
}
@ -116,6 +126,11 @@ var ErrorCode_value = map[string]int32{
"EmptyCollection": 26,
"UpdateImportTaskFailure": 27,
"CollectionNameNotFound": 28,
"CreateCredentialFailure": 29,
"UpdateCredentialFailure": 30,
"DeleteCredentialFailure": 31,
"GetCredentialFailure": 32,
"ListCredUsersFailure": 33,
"DDRequestRace": 1000,
}
@ -271,6 +286,12 @@ const (
MsgType_SegmentStatistics MsgType = 1206
MsgType_SegmentFlushDone MsgType = 1207
MsgType_DataNodeTt MsgType = 1208
// Credential
MsgType_CreateCredential MsgType = 1500
MsgType_GetCredential MsgType = 1501
MsgType_DeleteCredential MsgType = 1502
MsgType_UpdateCredential MsgType = 1503
MsgType_ListCredUsernames MsgType = 1504
)
var MsgType_name = map[int32]string{
@ -333,6 +354,11 @@ var MsgType_name = map[int32]string{
1206: "SegmentStatistics",
1207: "SegmentFlushDone",
1208: "DataNodeTt",
1500: "CreateCredential",
1501: "GetCredential",
1502: "DeleteCredential",
1503: "UpdateCredential",
1504: "ListCredUsernames",
}
var MsgType_value = map[string]int32{
@ -395,6 +421,11 @@ var MsgType_value = map[string]int32{
"SegmentStatistics": 1206,
"SegmentFlushDone": 1207,
"DataNodeTt": 1208,
"CreateCredential": 1500,
"GetCredential": 1501,
"DeleteCredential": 1502,
"UpdateCredential": 1503,
"ListCredUsernames": 1504,
}
func (x MsgType) String() string {
@ -932,107 +963,113 @@ func init() {
func init() { proto.RegisterFile("common.proto", fileDescriptor_555bd8c177793206) }
var fileDescriptor_555bd8c177793206 = []byte{
// 1630 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x56, 0x4b, 0x73, 0x1b, 0xb9,
0x11, 0xd6, 0x90, 0xd4, 0x83, 0x2d, 0x89, 0x82, 0xa1, 0x87, 0xb5, 0xb6, 0x92, 0x72, 0xe9, 0xe4,
0x52, 0xd5, 0xda, 0x49, 0x5c, 0x95, 0x9c, 0xf6, 0x20, 0x72, 0x24, 0x99, 0x65, 0x4b, 0x66, 0x48,
0xd9, 0xbb, 0x95, 0x43, 0x5c, 0xd0, 0x4c, 0x8b, 0x44, 0x3c, 0x03, 0x30, 0x00, 0x46, 0x16, 0x73,
0xda, 0xfc, 0x83, 0x64, 0x2f, 0xb9, 0xe6, 0x07, 0x24, 0xa9, 0xbc, 0x93, 0x63, 0x8e, 0x79, 0x9f,
0xf3, 0xf8, 0x03, 0xb9, 0xe7, 0xbd, 0xcf, 0x54, 0x63, 0x86, 0x33, 0xe3, 0xd4, 0xee, 0x69, 0x6f,
0xe8, 0x0f, 0xdd, 0x5f, 0x37, 0xba, 0x1b, 0x0d, 0xc0, 0x5a, 0xa4, 0xd3, 0x54, 0xab, 0x7b, 0x53,
0xa3, 0x9d, 0xe6, 0x9b, 0xa9, 0x4c, 0xae, 0x32, 0x9b, 0x4b, 0xf7, 0xf2, 0xad, 0xfd, 0xe7, 0xb0,
0x34, 0x72, 0xc2, 0x65, 0x96, 0xbf, 0x01, 0x80, 0xc6, 0x68, 0xf3, 0x3c, 0xd2, 0x31, 0xee, 0x06,
0x77, 0x82, 0xbb, 0x9d, 0x2f, 0x7c, 0xf6, 0xde, 0xc7, 0xd8, 0xdc, 0x3b, 0x22, 0xb5, 0x9e, 0x8e,
0x71, 0xd8, 0xc6, 0xf9, 0x92, 0xef, 0xc0, 0x92, 0x41, 0x61, 0xb5, 0xda, 0x6d, 0xdc, 0x09, 0xee,
0xb6, 0x87, 0x85, 0xb4, 0xff, 0x45, 0x58, 0x7b, 0x84, 0xb3, 0x67, 0x22, 0xc9, 0x70, 0x20, 0xa4,
0xe1, 0x0c, 0x9a, 0x2f, 0x70, 0xe6, 0xf9, 0xdb, 0x43, 0x5a, 0xf2, 0x2d, 0x58, 0xbc, 0xa2, 0xed,
0xc2, 0x30, 0x17, 0xf6, 0x1f, 0xc0, 0xea, 0x23, 0x9c, 0x85, 0xc2, 0x89, 0x4f, 0x30, 0xe3, 0xd0,
0x8a, 0x85, 0x13, 0xde, 0x6a, 0x6d, 0xe8, 0xd7, 0xfb, 0x7b, 0xd0, 0xea, 0x26, 0xfa, 0xa2, 0xa2,
0x0c, 0xfc, 0x66, 0x41, 0xf9, 0x3a, 0x2c, 0x1f, 0xc6, 0xb1, 0x41, 0x6b, 0x79, 0x07, 0x1a, 0x72,
0x5a, 0xb0, 0x35, 0xe4, 0x94, 0xc8, 0xa6, 0xda, 0x38, 0x4f, 0xd6, 0x1c, 0xfa, 0xf5, 0xfe, 0x3b,
0x01, 0x2c, 0x9f, 0xda, 0x71, 0x57, 0x58, 0xe4, 0x5f, 0x82, 0x95, 0xd4, 0x8e, 0x9f, 0xbb, 0xd9,
0x74, 0x9e, 0x9a, 0xbd, 0x8f, 0x4d, 0xcd, 0xa9, 0x1d, 0x9f, 0xcf, 0xa6, 0x38, 0x5c, 0x4e, 0xf3,
0x05, 0x45, 0x92, 0xda, 0x71, 0x3f, 0x2c, 0x98, 0x73, 0x81, 0xef, 0x41, 0xdb, 0xc9, 0x14, 0xad,
0x13, 0xe9, 0x74, 0xb7, 0x79, 0x27, 0xb8, 0xdb, 0x1a, 0x56, 0x00, 0xbf, 0x05, 0x2b, 0x56, 0x67,
0x26, 0xc2, 0x7e, 0xb8, 0xdb, 0xf2, 0x66, 0xa5, 0xbc, 0xff, 0x06, 0xb4, 0x4f, 0xed, 0xf8, 0x21,
0x8a, 0x18, 0x0d, 0xff, 0x1c, 0xb4, 0x2e, 0x84, 0xcd, 0x23, 0x5a, 0xfd, 0xe4, 0x88, 0xe8, 0x04,
0x43, 0xaf, 0xb9, 0xff, 0x55, 0x58, 0x0b, 0x4f, 0x1f, 0x7f, 0x0a, 0x06, 0x0a, 0xdd, 0x4e, 0x84,
0x89, 0xcf, 0x44, 0x3a, 0xaf, 0x58, 0x05, 0x1c, 0xfc, 0xbd, 0x05, 0xed, 0xb2, 0x3d, 0xf8, 0x2a,
0x2c, 0x8f, 0xb2, 0x28, 0x42, 0x6b, 0xd9, 0x02, 0xdf, 0x84, 0x8d, 0xa7, 0x0a, 0xaf, 0xa7, 0x18,
0x39, 0x8c, 0xbd, 0x0e, 0x0b, 0xf8, 0x0d, 0x58, 0xef, 0x69, 0xa5, 0x30, 0x72, 0xc7, 0x42, 0x26,
0x18, 0xb3, 0x06, 0xdf, 0x02, 0x36, 0x40, 0x93, 0x4a, 0x6b, 0xa5, 0x56, 0x21, 0x2a, 0x89, 0x31,
0x6b, 0xf2, 0x9b, 0xb0, 0xd9, 0xd3, 0x49, 0x82, 0x91, 0x93, 0x5a, 0x9d, 0x69, 0x77, 0x74, 0x2d,
0xad, 0xb3, 0xac, 0x45, 0xb4, 0xfd, 0x24, 0xc1, 0xb1, 0x48, 0x0e, 0xcd, 0x38, 0x4b, 0x51, 0x39,
0xb6, 0x48, 0x1c, 0x05, 0x18, 0xca, 0x14, 0x15, 0x31, 0xb1, 0xe5, 0x1a, 0xda, 0x57, 0x31, 0x5e,
0x53, 0x7d, 0xd8, 0x0a, 0x7f, 0x0d, 0xb6, 0x0b, 0xb4, 0xe6, 0x40, 0xa4, 0xc8, 0xda, 0x7c, 0x03,
0x56, 0x8b, 0xad, 0xf3, 0x27, 0x83, 0x47, 0x0c, 0x6a, 0x0c, 0x43, 0xfd, 0x72, 0x88, 0x91, 0x36,
0x31, 0x5b, 0xad, 0x85, 0xf0, 0x0c, 0x23, 0xa7, 0x4d, 0x3f, 0x64, 0x6b, 0x14, 0x70, 0x01, 0x8e,
0x50, 0x98, 0x68, 0x32, 0x44, 0x9b, 0x25, 0x8e, 0xad, 0x73, 0x06, 0x6b, 0xc7, 0x32, 0xc1, 0x33,
0xed, 0x8e, 0x75, 0xa6, 0x62, 0xd6, 0xe1, 0x1d, 0x80, 0x53, 0x74, 0xa2, 0xc8, 0xc0, 0x06, 0xb9,
0xed, 0x89, 0x68, 0x82, 0x05, 0xc0, 0xf8, 0x0e, 0xf0, 0x9e, 0x50, 0x4a, 0xbb, 0x9e, 0x41, 0xe1,
0xf0, 0x58, 0x27, 0x31, 0x1a, 0x76, 0x83, 0xc2, 0x79, 0x05, 0x97, 0x09, 0x32, 0x5e, 0x69, 0x87,
0x98, 0x60, 0xa9, 0xbd, 0x59, 0x69, 0x17, 0x38, 0x69, 0x6f, 0x51, 0xf0, 0xdd, 0x4c, 0x26, 0xb1,
0x4f, 0x49, 0x5e, 0x96, 0x6d, 0x8a, 0xb1, 0x08, 0xfe, 0xec, 0x71, 0x7f, 0x74, 0xce, 0x76, 0xf8,
0x36, 0xdc, 0x28, 0x90, 0x53, 0x74, 0x46, 0x46, 0x3e, 0x79, 0x37, 0x29, 0xd4, 0x27, 0x99, 0x7b,
0x72, 0x79, 0x8a, 0xa9, 0x36, 0x33, 0xb6, 0x4b, 0x05, 0xf5, 0x4c, 0xf3, 0x12, 0xb1, 0xd7, 0xc8,
0xc3, 0x51, 0x3a, 0x75, 0xb3, 0x2a, 0xbd, 0xec, 0x16, 0xbf, 0x0d, 0x37, 0x9f, 0x4e, 0x63, 0xe1,
0xb0, 0x9f, 0xd2, 0x65, 0x3b, 0x17, 0xf6, 0x05, 0x1d, 0x37, 0x33, 0xc8, 0x6e, 0xf3, 0x5b, 0xb0,
0xf3, 0x6a, 0x2d, 0xca, 0x64, 0xed, 0x71, 0x0e, 0xeb, 0x61, 0x38, 0xc4, 0xaf, 0x67, 0x68, 0xdd,
0x50, 0x44, 0xc8, 0xfe, 0xb6, 0x7c, 0xf0, 0x16, 0x80, 0x77, 0x4a, 0x93, 0x0c, 0x39, 0x87, 0x4e,
0x25, 0x9d, 0x69, 0x85, 0x6c, 0x81, 0xaf, 0xc1, 0xca, 0x53, 0x25, 0xad, 0xcd, 0x30, 0x66, 0x01,
0x25, 0xbc, 0xaf, 0x06, 0x46, 0x8f, 0x69, 0x16, 0xb0, 0x06, 0xed, 0x1e, 0x4b, 0x25, 0xed, 0xc4,
0xb7, 0x1a, 0xc0, 0x52, 0x91, 0xf9, 0xd6, 0x81, 0x85, 0xb5, 0x11, 0x8e, 0xa9, 0xab, 0x72, 0xee,
0x2d, 0x60, 0x75, 0xb9, 0x62, 0x2f, 0xcf, 0x1b, 0x50, 0xd7, 0x9f, 0x18, 0xfd, 0x52, 0xaa, 0x31,
0x6b, 0x10, 0xd9, 0x08, 0x45, 0xe2, 0x89, 0x57, 0x61, 0xf9, 0x38, 0xc9, 0xbc, 0x97, 0x96, 0xf7,
0x49, 0x02, 0xa9, 0x2d, 0xd2, 0x56, 0x68, 0xf4, 0x74, 0x8a, 0x31, 0x5b, 0x3a, 0xf8, 0x55, 0xdb,
0x0f, 0x1e, 0x3f, 0x3f, 0xd6, 0xa1, 0xfd, 0x54, 0xc5, 0x78, 0x29, 0x15, 0xc6, 0x6c, 0xc1, 0xd7,
0xd0, 0xd7, 0xba, 0x96, 0xcc, 0x98, 0x4e, 0x4c, 0xd6, 0x35, 0x0c, 0xa9, 0x10, 0x0f, 0x85, 0xad,
0x41, 0x97, 0xd4, 0x18, 0x21, 0xda, 0xc8, 0xc8, 0x8b, 0xba, 0xf9, 0x98, 0x0a, 0x34, 0x9a, 0xe8,
0x97, 0x15, 0x66, 0xd9, 0x84, 0x3c, 0x9d, 0xa0, 0x1b, 0xcd, 0xac, 0xc3, 0xb4, 0xa7, 0xd5, 0xa5,
0x1c, 0x5b, 0x26, 0xc9, 0xd3, 0x63, 0x2d, 0xe2, 0x9a, 0xf9, 0xd7, 0xa8, 0x35, 0x86, 0x98, 0xa0,
0xb0, 0x75, 0xd6, 0x17, 0xbe, 0x8b, 0x7d, 0xa8, 0x87, 0x89, 0x14, 0x96, 0x25, 0x74, 0x14, 0x8a,
0x32, 0x17, 0x53, 0x2a, 0xc2, 0x61, 0xe2, 0xd0, 0xe4, 0xb2, 0xe2, 0x5b, 0xb0, 0x91, 0xeb, 0x0f,
0x84, 0x71, 0xd2, 0x93, 0xfc, 0x3a, 0xf0, 0xe5, 0x36, 0x7a, 0x5a, 0x61, 0xbf, 0xa1, 0xa1, 0xb1,
0xf6, 0x50, 0xd8, 0x0a, 0xfa, 0x6d, 0xc0, 0x77, 0xe0, 0xc6, 0xfc, 0x68, 0x15, 0xfe, 0xbb, 0x80,
0x6f, 0x42, 0x87, 0x8e, 0x56, 0x62, 0x96, 0xfd, 0xde, 0x83, 0x74, 0x88, 0x1a, 0xf8, 0x07, 0xcf,
0x50, 0x9c, 0xa2, 0x86, 0xff, 0xd1, 0x3b, 0x23, 0x86, 0xa2, 0xea, 0x96, 0xbd, 0x1b, 0x50, 0xa4,
0x73, 0x67, 0x05, 0xcc, 0xde, 0xf3, 0x8a, 0xc4, 0x5a, 0x2a, 0xbe, 0xef, 0x15, 0x0b, 0xce, 0x12,
0xfd, 0xc0, 0xa3, 0x0f, 0x85, 0x8a, 0xf5, 0xe5, 0x65, 0x89, 0x7e, 0x18, 0xf0, 0x5d, 0xd8, 0x24,
0xf3, 0xae, 0x48, 0x84, 0x8a, 0x2a, 0xfd, 0x8f, 0x02, 0xbe, 0x0d, 0xec, 0xff, 0xdc, 0x59, 0xf6,
0x76, 0x83, 0xb3, 0x79, 0x7e, 0x7d, 0xb3, 0xb3, 0xef, 0x35, 0x7c, 0xae, 0x0a, 0xc5, 0x1c, 0xfb,
0x7e, 0x83, 0x77, 0xf2, 0xa4, 0xe7, 0xf2, 0x0f, 0x1a, 0x7c, 0x15, 0x96, 0xfa, 0xca, 0xa2, 0x71,
0xec, 0x5b, 0xd4, 0x90, 0x4b, 0xf9, 0x2c, 0x60, 0xdf, 0xa6, 0xb6, 0x5f, 0xf4, 0x0d, 0xc9, 0xde,
0xf1, 0x1b, 0xf9, 0xd4, 0x62, 0xff, 0x68, 0xfa, 0x0c, 0xd4, 0x47, 0xd8, 0x3f, 0x9b, 0xe4, 0xe9,
0x04, 0x5d, 0x75, 0xcb, 0xd8, 0xbf, 0x9a, 0xfc, 0x16, 0x6c, 0xcf, 0x31, 0x3f, 0x50, 0xca, 0xfb,
0xf5, 0xef, 0x26, 0xdf, 0x83, 0x9b, 0x27, 0xe8, 0xaa, 0xf6, 0x20, 0x23, 0x69, 0x9d, 0x8c, 0x2c,
0xfb, 0x4f, 0x93, 0xdf, 0x86, 0x9d, 0x13, 0x74, 0x65, 0xda, 0x6b, 0x9b, 0xff, 0x6d, 0xf2, 0x75,
0x58, 0x19, 0xd2, 0xc4, 0xc1, 0x2b, 0x64, 0xef, 0x36, 0xa9, 0x76, 0x73, 0xb1, 0x08, 0xe7, 0xbd,
0x26, 0x65, 0xf4, 0x4d, 0xe1, 0xa2, 0x49, 0x98, 0xf6, 0x26, 0x42, 0x29, 0x4c, 0x2c, 0x7b, 0xbf,
0x49, 0x79, 0x1b, 0x62, 0xaa, 0xaf, 0xb0, 0x06, 0x7f, 0x40, 0x2f, 0x09, 0xf7, 0xca, 0x5f, 0xce,
0xd0, 0xcc, 0xca, 0x8d, 0x0f, 0x9b, 0x54, 0x81, 0x5c, 0xff, 0xd5, 0x9d, 0x8f, 0x9a, 0xfc, 0x33,
0xb0, 0x9b, 0x5f, 0xe2, 0x79, 0xfe, 0x69, 0x73, 0x8c, 0x7d, 0x75, 0xa9, 0xd9, 0xdb, 0xad, 0x92,
0x31, 0xc4, 0xc4, 0x89, 0xd2, 0xee, 0x9b, 0x2d, 0x2a, 0x51, 0x61, 0xe1, 0x55, 0xff, 0xd4, 0xe2,
0x1b, 0x00, 0xf9, 0x95, 0xf2, 0xc0, 0x9f, 0x5b, 0x14, 0xfa, 0x09, 0x3a, 0x7a, 0x4a, 0xae, 0xd0,
0xcc, 0x3c, 0xfa, 0x97, 0x39, 0x5a, 0x9f, 0x34, 0xec, 0xaf, 0x2d, 0x4a, 0xc5, 0xb9, 0x4c, 0xf1,
0x5c, 0x46, 0x2f, 0xd8, 0x0f, 0xdb, 0x94, 0x0a, 0x1f, 0xe9, 0x99, 0x8e, 0x91, 0x74, 0x2c, 0xfb,
0x51, 0x9b, 0xea, 0x4d, 0x6d, 0x94, 0xd7, 0xfb, 0xc7, 0x5e, 0x2e, 0x86, 0x65, 0x3f, 0x64, 0x3f,
0xa1, 0x27, 0x0d, 0x0a, 0xf9, 0x7c, 0xf4, 0x84, 0xfd, 0xb4, 0x4d, 0xae, 0x0e, 0x93, 0x44, 0x47,
0xc2, 0x95, 0xcd, 0xfc, 0xb3, 0x36, 0xdd, 0x86, 0x9a, 0xf7, 0xa2, 0x1a, 0x3f, 0x6f, 0x53, 0x4e,
0x0b, 0xdc, 0xf7, 0x4a, 0x48, 0xf3, 0xef, 0x17, 0x9e, 0x95, 0x7e, 0x6a, 0x14, 0xc9, 0xb9, 0x63,
0xbf, 0x6c, 0x1f, 0xec, 0xc3, 0x72, 0x68, 0x13, 0x3f, 0xc1, 0x96, 0xa1, 0x19, 0xda, 0x84, 0x2d,
0xd0, 0x85, 0xef, 0x6a, 0x9d, 0x1c, 0x5d, 0x4f, 0xcd, 0xb3, 0xcf, 0xb3, 0xe0, 0xa0, 0x0b, 0x1b,
0x3d, 0x9d, 0x4e, 0x45, 0xd9, 0x11, 0x7e, 0x68, 0xe5, 0xd3, 0x0e, 0xe3, 0xfc, 0xd4, 0x0b, 0x34,
0x35, 0x8e, 0xae, 0x31, 0xca, 0x1c, 0x0d, 0xca, 0x80, 0x44, 0x32, 0xa2, 0xa6, 0x8d, 0x59, 0xe3,
0xe0, 0x2d, 0x60, 0x3d, 0xad, 0xac, 0xb4, 0x0e, 0x55, 0x34, 0x7b, 0x8c, 0x57, 0x98, 0xf8, 0x91,
0xeb, 0x8c, 0x56, 0x63, 0xb6, 0xe0, 0x7f, 0x20, 0xe8, 0x7f, 0x12, 0xf9, 0x60, 0xee, 0xd2, 0x2b,
0xe2, 0xbf, 0x19, 0x1d, 0x80, 0xa3, 0x2b, 0x54, 0x2e, 0x13, 0x49, 0x32, 0x63, 0x4d, 0x92, 0x7b,
0x99, 0x75, 0x3a, 0x95, 0xdf, 0xf0, 0x93, 0xff, 0x3b, 0x01, 0xac, 0xe6, 0x6f, 0x53, 0x19, 0x5a,
0x2e, 0x0e, 0x50, 0xc5, 0xd2, 0x93, 0xd3, 0x2b, 0xe9, 0xa1, 0xe2, 0xb9, 0x08, 0x2a, 0xa5, 0x91,
0x13, 0xc6, 0xcd, 0xbf, 0x33, 0x39, 0x14, 0xea, 0x97, 0x2a, 0xd1, 0x22, 0xf6, 0x4f, 0x41, 0x69,
0x3a, 0x10, 0xc6, 0xfa, 0xf7, 0x80, 0x3e, 0x11, 0x05, 0xbf, 0xf1, 0xe7, 0x89, 0xd9, 0x62, 0x05,
0x56, 0x67, 0x5e, 0xea, 0xbe, 0x09, 0x1d, 0xa9, 0xe7, 0x3f, 0xb5, 0xb1, 0x99, 0x46, 0xdd, 0xd5,
0x9e, 0xff, 0xa9, 0x0d, 0xe8, 0xd7, 0x36, 0x08, 0xbe, 0xf2, 0x60, 0x2c, 0xdd, 0x24, 0xbb, 0xa0,
0xff, 0xdb, 0xfd, 0x5c, 0xed, 0x75, 0xa9, 0x8b, 0xd5, 0x7d, 0xa9, 0x1c, 0x1a, 0x25, 0x92, 0xfb,
0xfe, 0x8f, 0x77, 0x3f, 0xff, 0xe3, 0x4d, 0x2f, 0xbe, 0x1b, 0x04, 0x17, 0x4b, 0x1e, 0x7a, 0xf0,
0xbf, 0x00, 0x00, 0x00, 0xff, 0xff, 0x4e, 0x2a, 0xbb, 0x0b, 0x37, 0x0c, 0x00, 0x00,
// 1715 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x56, 0x4b, 0x73, 0x1c, 0x49,
0x11, 0x56, 0xcf, 0x8c, 0x1e, 0x93, 0xa3, 0x47, 0xb9, 0xf4, 0xb0, 0xd6, 0xd6, 0x2e, 0x46, 0x27,
0x87, 0x22, 0xd6, 0x06, 0x1c, 0x01, 0xa7, 0x3d, 0x48, 0xd3, 0x92, 0x3c, 0x61, 0x49, 0x16, 0x33,
0x92, 0x77, 0x83, 0x03, 0x8e, 0x52, 0x77, 0x6a, 0x54, 0xb8, 0xbb, 0x6a, 0xa8, 0xaa, 0x96, 0x35,
0x9c, 0x96, 0x7f, 0x00, 0x7b, 0xe1, 0xca, 0x0f, 0x00, 0x82, 0xe5, 0xfd, 0x13, 0x78, 0x9f, 0x79,
0xc3, 0x91, 0x1f, 0xc0, 0x73, 0x1f, 0x5e, 0x22, 0xab, 0x7b, 0xba, 0xdb, 0xf6, 0xee, 0x89, 0x5b,
0xe5, 0x97, 0x99, 0x5f, 0x65, 0x65, 0x66, 0x65, 0x15, 0xcc, 0x47, 0x3a, 0x4d, 0xb5, 0xba, 0x33,
0x32, 0xda, 0x69, 0xbe, 0x9c, 0xca, 0xe4, 0x32, 0xb3, 0xb9, 0x74, 0x27, 0x57, 0x6d, 0x3e, 0x86,
0x99, 0x81, 0x13, 0x2e, 0xb3, 0xfc, 0x0d, 0x00, 0x34, 0x46, 0x9b, 0xc7, 0x91, 0x8e, 0x71, 0x3d,
0xb8, 0x15, 0xdc, 0x5e, 0xfc, 0xdc, 0x6b, 0x77, 0x3e, 0xc6, 0xe7, 0xce, 0x2e, 0x99, 0x75, 0x75,
0x8c, 0xfd, 0x36, 0x4e, 0x96, 0x7c, 0x0d, 0x66, 0x0c, 0x0a, 0xab, 0xd5, 0x7a, 0xe3, 0x56, 0x70,
0xbb, 0xdd, 0x2f, 0xa4, 0xcd, 0xcf, 0xc3, 0xfc, 0x03, 0x1c, 0x3f, 0x12, 0x49, 0x86, 0xc7, 0x42,
0x1a, 0xce, 0xa0, 0xf9, 0x04, 0xc7, 0x9e, 0xbf, 0xdd, 0xa7, 0x25, 0x5f, 0x81, 0xe9, 0x4b, 0x52,
0x17, 0x8e, 0xb9, 0xb0, 0x79, 0x0f, 0x3a, 0x0f, 0x70, 0x1c, 0x0a, 0x27, 0x3e, 0xc1, 0x8d, 0x43,
0x2b, 0x16, 0x4e, 0x78, 0xaf, 0xf9, 0xbe, 0x5f, 0x6f, 0x6e, 0x40, 0x6b, 0x27, 0xd1, 0x67, 0x15,
0x65, 0xe0, 0x95, 0x05, 0xe5, 0xeb, 0x30, 0xbb, 0x1d, 0xc7, 0x06, 0xad, 0xe5, 0x8b, 0xd0, 0x90,
0xa3, 0x82, 0xad, 0x21, 0x47, 0x44, 0x36, 0xd2, 0xc6, 0x79, 0xb2, 0x66, 0xdf, 0xaf, 0x37, 0xdf,
0x09, 0x60, 0xf6, 0xd0, 0x0e, 0x77, 0x84, 0x45, 0xfe, 0x05, 0x98, 0x4b, 0xed, 0xf0, 0xb1, 0x1b,
0x8f, 0x26, 0xa9, 0xd9, 0xf8, 0xd8, 0xd4, 0x1c, 0xda, 0xe1, 0xc9, 0x78, 0x84, 0xfd, 0xd9, 0x34,
0x5f, 0x50, 0x24, 0xa9, 0x1d, 0xf6, 0xc2, 0x82, 0x39, 0x17, 0xf8, 0x06, 0xb4, 0x9d, 0x4c, 0xd1,
0x3a, 0x91, 0x8e, 0xd6, 0x9b, 0xb7, 0x82, 0xdb, 0xad, 0x7e, 0x05, 0xf0, 0x1b, 0x30, 0x67, 0x75,
0x66, 0x22, 0xec, 0x85, 0xeb, 0x2d, 0xef, 0x56, 0xca, 0x9b, 0x6f, 0x40, 0xfb, 0xd0, 0x0e, 0xef,
0xa3, 0x88, 0xd1, 0xf0, 0xcf, 0x40, 0xeb, 0x4c, 0xd8, 0x3c, 0xa2, 0xce, 0x27, 0x47, 0x44, 0x27,
0xe8, 0x7b, 0xcb, 0xcd, 0x2f, 0xc3, 0x7c, 0x78, 0x78, 0xf0, 0x7f, 0x30, 0x50, 0xe8, 0xf6, 0x42,
0x98, 0xf8, 0x48, 0xa4, 0x93, 0x8a, 0x55, 0xc0, 0xd6, 0xb3, 0x69, 0x68, 0x97, 0xed, 0xc1, 0x3b,
0x30, 0x3b, 0xc8, 0xa2, 0x08, 0xad, 0x65, 0x53, 0x7c, 0x19, 0x96, 0x4e, 0x15, 0x5e, 0x8d, 0x30,
0x72, 0x18, 0x7b, 0x1b, 0x16, 0xf0, 0x6b, 0xb0, 0xd0, 0xd5, 0x4a, 0x61, 0xe4, 0xf6, 0x84, 0x4c,
0x30, 0x66, 0x0d, 0xbe, 0x02, 0xec, 0x18, 0x4d, 0x2a, 0xad, 0x95, 0x5a, 0x85, 0xa8, 0x24, 0xc6,
0xac, 0xc9, 0xaf, 0xc3, 0x72, 0x57, 0x27, 0x09, 0x46, 0x4e, 0x6a, 0x75, 0xa4, 0xdd, 0xee, 0x95,
0xb4, 0xce, 0xb2, 0x16, 0xd1, 0xf6, 0x92, 0x04, 0x87, 0x22, 0xd9, 0x36, 0xc3, 0x2c, 0x45, 0xe5,
0xd8, 0x34, 0x71, 0x14, 0x60, 0x28, 0x53, 0x54, 0xc4, 0xc4, 0x66, 0x6b, 0x68, 0x4f, 0xc5, 0x78,
0x45, 0xf5, 0x61, 0x73, 0xfc, 0x15, 0x58, 0x2d, 0xd0, 0xda, 0x06, 0x22, 0x45, 0xd6, 0xe6, 0x4b,
0xd0, 0x29, 0x54, 0x27, 0x0f, 0x8f, 0x1f, 0x30, 0xa8, 0x31, 0xf4, 0xf5, 0xd3, 0x3e, 0x46, 0xda,
0xc4, 0xac, 0x53, 0x0b, 0xe1, 0x11, 0x46, 0x4e, 0x9b, 0x5e, 0xc8, 0xe6, 0x29, 0xe0, 0x02, 0x1c,
0xa0, 0x30, 0xd1, 0x45, 0x1f, 0x6d, 0x96, 0x38, 0xb6, 0xc0, 0x19, 0xcc, 0xef, 0xc9, 0x04, 0x8f,
0xb4, 0xdb, 0xd3, 0x99, 0x8a, 0xd9, 0x22, 0x5f, 0x04, 0x38, 0x44, 0x27, 0x8a, 0x0c, 0x2c, 0xd1,
0xb6, 0x5d, 0x11, 0x5d, 0x60, 0x01, 0x30, 0xbe, 0x06, 0xbc, 0x2b, 0x94, 0xd2, 0xae, 0x6b, 0x50,
0x38, 0xdc, 0xd3, 0x49, 0x8c, 0x86, 0x5d, 0xa3, 0x70, 0x9e, 0xc3, 0x65, 0x82, 0x8c, 0x57, 0xd6,
0x21, 0x26, 0x58, 0x5a, 0x2f, 0x57, 0xd6, 0x05, 0x4e, 0xd6, 0x2b, 0x14, 0xfc, 0x4e, 0x26, 0x93,
0xd8, 0xa7, 0x24, 0x2f, 0xcb, 0x2a, 0xc5, 0x58, 0x04, 0x7f, 0x74, 0xd0, 0x1b, 0x9c, 0xb0, 0x35,
0xbe, 0x0a, 0xd7, 0x0a, 0xe4, 0x10, 0x9d, 0x91, 0x91, 0x4f, 0xde, 0x75, 0x0a, 0xf5, 0x61, 0xe6,
0x1e, 0x9e, 0x1f, 0x62, 0xaa, 0xcd, 0x98, 0xad, 0x53, 0x41, 0x3d, 0xd3, 0xa4, 0x44, 0xec, 0x15,
0xda, 0x61, 0x37, 0x1d, 0xb9, 0x71, 0x95, 0x5e, 0x76, 0x83, 0xdf, 0x84, 0xeb, 0xa7, 0xa3, 0x58,
0x38, 0xec, 0xa5, 0x74, 0xd9, 0x4e, 0x84, 0x7d, 0x42, 0xc7, 0xcd, 0x0c, 0xb2, 0x9b, 0xfc, 0x06,
0xac, 0x3d, 0x5f, 0x8b, 0x32, 0x59, 0x1b, 0xe4, 0x98, 0x9f, 0xb6, 0x6b, 0x30, 0x46, 0xe5, 0xa4,
0x48, 0x26, 0x8e, 0xaf, 0x56, 0xac, 0x2f, 0x2b, 0x5f, 0x23, 0x65, 0x7e, 0xf2, 0x97, 0x95, 0x9f,
0xe2, 0xeb, 0xb0, 0xb2, 0x8f, 0xee, 0x65, 0xcd, 0x2d, 0xd2, 0x1c, 0x48, 0xeb, 0x55, 0xa7, 0x16,
0x8d, 0x9d, 0x68, 0x3e, 0xcd, 0x39, 0x2c, 0x84, 0x61, 0x1f, 0xbf, 0x9a, 0xa1, 0x75, 0x7d, 0x11,
0x21, 0xfb, 0xfb, 0xec, 0xd6, 0x5b, 0x00, 0xfe, 0xfc, 0x34, 0x54, 0x91, 0x73, 0x58, 0xac, 0xa4,
0x23, 0xad, 0x90, 0x4d, 0xf1, 0x79, 0x98, 0x3b, 0x55, 0xd2, 0xda, 0x0c, 0x63, 0x16, 0x50, 0xed,
0x7b, 0xea, 0xd8, 0xe8, 0x21, 0x8d, 0x25, 0xd6, 0x20, 0xed, 0x9e, 0x54, 0xd2, 0x5e, 0xf8, 0xae,
0x07, 0x98, 0x29, 0x9a, 0xa0, 0xb5, 0x65, 0x61, 0x7e, 0x80, 0x43, 0x6a, 0xf0, 0x9c, 0x7b, 0x05,
0x58, 0x5d, 0xae, 0xd8, 0xcb, 0xd4, 0x07, 0x74, 0x01, 0xf7, 0x8d, 0x7e, 0x2a, 0xd5, 0x90, 0x35,
0x88, 0x6c, 0x80, 0x22, 0xf1, 0xc4, 0x1d, 0x98, 0xdd, 0x4b, 0x32, 0xbf, 0x4b, 0xcb, 0xef, 0x49,
0x02, 0x99, 0x4d, 0x93, 0x2a, 0x34, 0x7a, 0x34, 0xc2, 0x98, 0xcd, 0x6c, 0xbd, 0x0b, 0x7e, 0x06,
0xfa, 0x51, 0xb6, 0x00, 0xed, 0x53, 0x15, 0xe3, 0xb9, 0x54, 0x18, 0xb3, 0x29, 0xdf, 0x4e, 0x79,
0x21, 0xaa, 0xba, 0xc6, 0x74, 0x62, 0xf2, 0xae, 0x61, 0x48, 0x3d, 0x71, 0x5f, 0xd8, 0x1a, 0x74,
0x4e, 0x3d, 0x1a, 0xa2, 0x8d, 0x8c, 0x3c, 0xab, 0xbb, 0x0f, 0xa9, 0x57, 0x06, 0x17, 0xfa, 0x69,
0x85, 0x59, 0x76, 0x41, 0x3b, 0xed, 0xa3, 0x1b, 0x8c, 0xad, 0xc3, 0xb4, 0xab, 0xd5, 0xb9, 0x1c,
0x5a, 0x26, 0x69, 0xa7, 0x03, 0x2d, 0xe2, 0x9a, 0xfb, 0x57, 0xa8, 0x4b, 0xfb, 0x98, 0xa0, 0xb0,
0x75, 0xd6, 0x27, 0xfe, 0x42, 0xf9, 0x50, 0xb7, 0x13, 0x29, 0x2c, 0x4b, 0xe8, 0x28, 0x14, 0x65,
0x2e, 0xa6, 0x54, 0x84, 0xed, 0xc4, 0xa1, 0xc9, 0x65, 0xc5, 0x57, 0x60, 0x29, 0xb7, 0x3f, 0x16,
0xc6, 0x49, 0x4f, 0xf2, 0xf3, 0xc0, 0x97, 0xdb, 0xe8, 0x51, 0x85, 0xfd, 0x82, 0xe6, 0xd7, 0xfc,
0x7d, 0x61, 0x2b, 0xe8, 0x97, 0x01, 0x5f, 0x83, 0x6b, 0x93, 0xa3, 0x55, 0xf8, 0xaf, 0x02, 0xbe,
0x0c, 0x8b, 0x74, 0xb4, 0x12, 0xb3, 0xec, 0xd7, 0x1e, 0xa4, 0x43, 0xd4, 0xc0, 0xdf, 0x78, 0x86,
0xe2, 0x14, 0x35, 0xfc, 0xb7, 0x7e, 0x33, 0x62, 0x28, 0xaa, 0x6e, 0xd9, 0x7b, 0x01, 0x45, 0x3a,
0xd9, 0xac, 0x80, 0xd9, 0xfb, 0xde, 0x90, 0x58, 0x4b, 0xc3, 0x0f, 0xbc, 0x61, 0xc1, 0x59, 0xa2,
0x1f, 0x7a, 0xf4, 0xbe, 0x50, 0xb1, 0x3e, 0x3f, 0x2f, 0xd1, 0x67, 0x01, 0x5f, 0x87, 0x65, 0x72,
0xdf, 0x11, 0x89, 0x50, 0x51, 0x65, 0xff, 0x51, 0xc0, 0x57, 0x81, 0xbd, 0xb0, 0x9d, 0x65, 0x6f,
0x37, 0x38, 0x9b, 0xe4, 0xd7, 0x37, 0x3b, 0xfb, 0x4e, 0xc3, 0xe7, 0xaa, 0x30, 0xcc, 0xb1, 0xef,
0x36, 0xf8, 0x62, 0x9e, 0xf4, 0x5c, 0xfe, 0x5e, 0x83, 0x77, 0x60, 0xa6, 0xa7, 0x2c, 0x1a, 0xc7,
0xbe, 0x41, 0x0d, 0x39, 0x93, 0x5f, 0x4e, 0xf6, 0x4d, 0x6a, 0xfb, 0x69, 0xdf, 0x90, 0xec, 0x1d,
0xaf, 0xc8, 0x07, 0x28, 0xfb, 0x47, 0xd3, 0x67, 0xa0, 0x3e, 0x4d, 0xff, 0xd9, 0xa4, 0x9d, 0xf6,
0xd1, 0x55, 0xb7, 0x8c, 0xfd, 0xab, 0xc9, 0x6f, 0xc0, 0xea, 0x04, 0xf3, 0xb3, 0xad, 0xbc, 0x5f,
0xff, 0x6e, 0xf2, 0x0d, 0xb8, 0x4e, 0x17, 0xbd, 0x6c, 0x0f, 0x72, 0x92, 0xd6, 0xc9, 0xc8, 0xb2,
0xff, 0x34, 0xf9, 0x4d, 0x58, 0xdb, 0x47, 0x57, 0xa6, 0xbd, 0xa6, 0xfc, 0x6f, 0x93, 0x2f, 0xc0,
0x5c, 0x9f, 0x86, 0x1f, 0x5e, 0x22, 0x7b, 0xaf, 0x49, 0xb5, 0x9b, 0x88, 0x45, 0x38, 0xef, 0x37,
0x29, 0xa3, 0x6f, 0x0a, 0x17, 0x5d, 0x84, 0x69, 0xf7, 0x42, 0x28, 0x85, 0x89, 0x65, 0x1f, 0x34,
0x29, 0x6f, 0x7d, 0x4c, 0xf5, 0x25, 0xd6, 0xe0, 0x0f, 0xe9, 0x51, 0xe3, 0xde, 0xf8, 0x8b, 0x19,
0x9a, 0x71, 0xa9, 0x78, 0xd6, 0xa4, 0x0a, 0xe4, 0xf6, 0xcf, 0x6b, 0x3e, 0x6a, 0xf2, 0x57, 0x61,
0x3d, 0xbf, 0xc4, 0x93, 0xfc, 0x93, 0x72, 0x88, 0x3d, 0x75, 0xae, 0xd9, 0xdb, 0xad, 0x92, 0x31,
0xc4, 0xc4, 0x89, 0xd2, 0xef, 0xeb, 0x2d, 0x2a, 0x51, 0xe1, 0xe1, 0x4d, 0x7f, 0xd7, 0xe2, 0x4b,
0x00, 0xf9, 0x95, 0xf2, 0xc0, 0xef, 0x5b, 0x14, 0xfa, 0x3e, 0x3a, 0x7a, 0xd5, 0x2e, 0xd1, 0x8c,
0x3d, 0xfa, 0x87, 0x09, 0x5a, 0x9f, 0x34, 0xec, 0x8f, 0x2d, 0x4a, 0xc5, 0x89, 0x4c, 0xf1, 0x44,
0x46, 0x4f, 0xd8, 0xf7, 0xdb, 0x94, 0x0a, 0x1f, 0xe9, 0x91, 0x8e, 0x91, 0x6c, 0x2c, 0x7b, 0xb7,
0x4d, 0xf5, 0xa6, 0x36, 0xca, 0xeb, 0xfd, 0x03, 0x2f, 0x17, 0xc3, 0xb2, 0x17, 0xb2, 0x1f, 0xd2,
0xeb, 0x0a, 0x85, 0x7c, 0x32, 0x78, 0xc8, 0x7e, 0xd4, 0xa6, 0xad, 0xb6, 0x93, 0x44, 0x47, 0xc2,
0x95, 0xcd, 0xfc, 0xe3, 0x36, 0xdd, 0x86, 0xda, 0xee, 0x45, 0x35, 0x7e, 0xd2, 0xa6, 0x9c, 0x16,
0xb8, 0xef, 0x95, 0x90, 0xe6, 0xdf, 0x4f, 0x3d, 0x2b, 0x7d, 0x1a, 0x29, 0x92, 0x13, 0xc7, 0x7e,
0xe6, 0xed, 0x5e, 0x7c, 0x30, 0xd8, 0x9f, 0x3a, 0x45, 0xdf, 0xd4, 0xb0, 0x3f, 0x77, 0xf2, 0xf6,
0x7e, 0xfe, 0x85, 0x60, 0x7f, 0xf1, 0xf0, 0x8b, 0xaf, 0x0a, 0xfb, 0x6b, 0x87, 0x02, 0xab, 0x3f,
0x0c, 0x4a, 0xa4, 0x68, 0xd9, 0xdf, 0x3a, 0x5b, 0x9b, 0x30, 0x1b, 0xda, 0xc4, 0x8f, 0xcc, 0x59,
0x68, 0x86, 0x36, 0x61, 0x53, 0x34, 0x61, 0x76, 0xb4, 0x4e, 0x76, 0xaf, 0x46, 0xe6, 0xd1, 0x67,
0x59, 0xb0, 0xb5, 0x03, 0x4b, 0x5d, 0x9d, 0x8e, 0x44, 0xd9, 0x82, 0x7e, 0x4a, 0xe6, 0xe3, 0x15,
0xe3, 0x3c, 0xcd, 0x53, 0x34, 0xa6, 0x76, 0xaf, 0x30, 0xca, 0x1c, 0x4d, 0xe6, 0x80, 0x44, 0x72,
0xa2, 0x00, 0x63, 0xd6, 0xd8, 0x7a, 0x0b, 0x58, 0x57, 0x2b, 0x2b, 0xad, 0x43, 0x15, 0x8d, 0x0f,
0xf0, 0x12, 0x13, 0x3f, 0xe3, 0x9d, 0xd1, 0x6a, 0xc8, 0xa6, 0xfc, 0xef, 0x0b, 0xfd, 0x2f, 0x2a,
0x7f, 0x09, 0x76, 0xe8, 0x05, 0xf5, 0x5f, 0xac, 0x45, 0x80, 0xdd, 0x4b, 0x54, 0x2e, 0x13, 0x49,
0x32, 0x66, 0x4d, 0x92, 0xbb, 0x99, 0x75, 0x3a, 0x95, 0x5f, 0xf3, 0x4f, 0xcd, 0xb7, 0x02, 0xe8,
0xe4, 0xef, 0x72, 0x19, 0x5a, 0x2e, 0x1e, 0xa3, 0x8a, 0xa5, 0x27, 0xa7, 0x1f, 0x82, 0x87, 0x8a,
0xf7, 0x29, 0xa8, 0x8c, 0x06, 0x4e, 0x18, 0x37, 0xf9, 0xca, 0xe5, 0x50, 0xa8, 0x9f, 0xaa, 0x44,
0x8b, 0xd8, 0xbf, 0x3d, 0xa5, 0xeb, 0xb1, 0x30, 0xd6, 0x3f, 0x40, 0xf4, 0x81, 0x2a, 0xf8, 0x8d,
0x3f, 0x4f, 0xcc, 0xa6, 0x2b, 0xb0, 0x3a, 0xf3, 0xcc, 0xce, 0x9b, 0xb0, 0x28, 0xf5, 0xe4, 0x97,
0x3a, 0x34, 0xa3, 0x68, 0xa7, 0xd3, 0xf5, 0xbf, 0xd4, 0x63, 0xfa, 0xb1, 0x1e, 0x07, 0x5f, 0xba,
0x37, 0x94, 0xee, 0x22, 0x3b, 0xa3, 0xbf, 0xeb, 0xdd, 0xdc, 0xec, 0x75, 0xa9, 0x8b, 0xd5, 0x5d,
0xa9, 0x1c, 0xd5, 0x29, 0xb9, 0xeb, 0xff, 0xb7, 0x77, 0xf3, 0xff, 0xed, 0xe8, 0xec, 0xdb, 0x41,
0x70, 0x36, 0xe3, 0xa1, 0x7b, 0xff, 0x0b, 0x00, 0x00, 0xff, 0xff, 0x51, 0xd5, 0x43, 0x23, 0x33,
0x0d, 0x00, 0x00,
}

View File

@ -271,3 +271,11 @@ message ChannelTimeTickMsg {
repeated uint64 timestamps = 3;
uint64 default_timestamp = 4;
}
message ClearCredUsersCacheRequest {
}
message CredentialInfo {
string username = 1;
string encrypted_password = 2;
}

View File

@ -2305,6 +2305,84 @@ func (m *ChannelTimeTickMsg) GetDefaultTimestamp() uint64 {
return 0
}
type ClearCredUsersCacheRequest struct {
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *ClearCredUsersCacheRequest) Reset() { *m = ClearCredUsersCacheRequest{} }
func (m *ClearCredUsersCacheRequest) String() string { return proto.CompactTextString(m) }
func (*ClearCredUsersCacheRequest) ProtoMessage() {}
func (*ClearCredUsersCacheRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_41f4a519b878ee3b, []int{31}
}
func (m *ClearCredUsersCacheRequest) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_ClearCredUsersCacheRequest.Unmarshal(m, b)
}
func (m *ClearCredUsersCacheRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_ClearCredUsersCacheRequest.Marshal(b, m, deterministic)
}
func (m *ClearCredUsersCacheRequest) XXX_Merge(src proto.Message) {
xxx_messageInfo_ClearCredUsersCacheRequest.Merge(m, src)
}
func (m *ClearCredUsersCacheRequest) XXX_Size() int {
return xxx_messageInfo_ClearCredUsersCacheRequest.Size(m)
}
func (m *ClearCredUsersCacheRequest) XXX_DiscardUnknown() {
xxx_messageInfo_ClearCredUsersCacheRequest.DiscardUnknown(m)
}
var xxx_messageInfo_ClearCredUsersCacheRequest proto.InternalMessageInfo
type CredentialInfo struct {
Username string `protobuf:"bytes,1,opt,name=username,proto3" json:"username,omitempty"`
EncryptedPassword string `protobuf:"bytes,2,opt,name=encrypted_password,json=encryptedPassword,proto3" json:"encrypted_password,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *CredentialInfo) Reset() { *m = CredentialInfo{} }
func (m *CredentialInfo) String() string { return proto.CompactTextString(m) }
func (*CredentialInfo) ProtoMessage() {}
func (*CredentialInfo) Descriptor() ([]byte, []int) {
return fileDescriptor_41f4a519b878ee3b, []int{32}
}
func (m *CredentialInfo) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_CredentialInfo.Unmarshal(m, b)
}
func (m *CredentialInfo) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_CredentialInfo.Marshal(b, m, deterministic)
}
func (m *CredentialInfo) XXX_Merge(src proto.Message) {
xxx_messageInfo_CredentialInfo.Merge(m, src)
}
func (m *CredentialInfo) XXX_Size() int {
return xxx_messageInfo_CredentialInfo.Size(m)
}
func (m *CredentialInfo) XXX_DiscardUnknown() {
xxx_messageInfo_CredentialInfo.DiscardUnknown(m)
}
var xxx_messageInfo_CredentialInfo proto.InternalMessageInfo
func (m *CredentialInfo) GetUsername() string {
if m != nil {
return m.Username
}
return ""
}
func (m *CredentialInfo) GetEncryptedPassword() string {
if m != nil {
return m.EncryptedPassword
}
return ""
}
func init() {
proto.RegisterEnum("milvus.proto.internal.StateCode", StateCode_name, StateCode_value)
proto.RegisterEnum("milvus.proto.internal.InsertDataVersion", InsertDataVersion_name, InsertDataVersion_value)
@ -2339,134 +2417,140 @@ func init() {
proto.RegisterType((*QueryNodeStats)(nil), "milvus.proto.internal.QueryNodeStats")
proto.RegisterType((*MsgPosition)(nil), "milvus.proto.internal.MsgPosition")
proto.RegisterType((*ChannelTimeTickMsg)(nil), "milvus.proto.internal.ChannelTimeTickMsg")
proto.RegisterType((*ClearCredUsersCacheRequest)(nil), "milvus.proto.internal.ClearCredUsersCacheRequest")
proto.RegisterType((*CredentialInfo)(nil), "milvus.proto.internal.CredentialInfo")
}
func init() { proto.RegisterFile("internal.proto", fileDescriptor_41f4a519b878ee3b) }
var fileDescriptor_41f4a519b878ee3b = []byte{
// 1979 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xec, 0x59, 0xcd, 0x73, 0x1c, 0x47,
0x15, 0xcf, 0xec, 0xac, 0xb4, 0xbb, 0x6f, 0x57, 0xd2, 0xaa, 0x25, 0x3b, 0xe3, 0x8f, 0xc4, 0xca,
0x24, 0x80, 0xb0, 0xc1, 0x36, 0x4a, 0x48, 0x52, 0x40, 0xe1, 0x58, 0x5a, 0x30, 0x5b, 0x8e, 0x8d,
0x18, 0x19, 0x57, 0xc1, 0x65, 0xaa, 0x77, 0xa7, 0xb5, 0x6a, 0x3c, 0x33, 0x3d, 0xe9, 0xee, 0x91,
0xbc, 0x3e, 0x71, 0xe0, 0x04, 0x05, 0x55, 0x1c, 0x38, 0xc2, 0x8d, 0x33, 0x47, 0x4e, 0x40, 0x15,
0xa7, 0x9c, 0xb8, 0xf3, 0xaf, 0x70, 0xa2, 0xfa, 0x63, 0x66, 0x67, 0x57, 0x2b, 0x59, 0x52, 0x2a,
0xc4, 0x54, 0xe5, 0x36, 0xfd, 0xde, 0xeb, 0xee, 0xd7, 0xbf, 0xf7, 0xeb, 0xd7, 0xef, 0xed, 0xc2,
0x32, 0x4d, 0x25, 0xe1, 0x29, 0x8e, 0x6f, 0x67, 0x9c, 0x49, 0x86, 0x2e, 0x25, 0x34, 0x3e, 0xcc,
0x85, 0x19, 0xdd, 0x2e, 0x94, 0x57, 0x3b, 0x43, 0x96, 0x24, 0x2c, 0x35, 0xe2, 0xab, 0x1d, 0x31,
0x3c, 0x20, 0x09, 0x36, 0x23, 0xff, 0xef, 0x0e, 0x2c, 0xed, 0xb0, 0x24, 0x63, 0x29, 0x49, 0x65,
0x3f, 0xdd, 0x67, 0xe8, 0x32, 0x2c, 0xa6, 0x2c, 0x22, 0xfd, 0x9e, 0xe7, 0x6c, 0x38, 0x9b, 0x6e,
0x60, 0x47, 0x08, 0x41, 0x9d, 0xb3, 0x98, 0x78, 0xb5, 0x0d, 0x67, 0xb3, 0x15, 0xe8, 0x6f, 0x74,
0x0f, 0x40, 0x48, 0x2c, 0x49, 0x38, 0x64, 0x11, 0xf1, 0xdc, 0x0d, 0x67, 0x73, 0x79, 0x6b, 0xe3,
0xf6, 0x5c, 0x2f, 0x6e, 0xef, 0x29, 0xc3, 0x1d, 0x16, 0x91, 0xa0, 0x25, 0x8a, 0x4f, 0xf4, 0x11,
0x00, 0x79, 0x2e, 0x39, 0x0e, 0x69, 0xba, 0xcf, 0xbc, 0xfa, 0x86, 0xbb, 0xd9, 0xde, 0x7a, 0x6b,
0x7a, 0x01, 0xeb, 0xfc, 0x43, 0x32, 0x7e, 0x8a, 0xe3, 0x9c, 0xec, 0x62, 0xca, 0x83, 0x96, 0x9e,
0xa4, 0xdc, 0xf5, 0xff, 0xed, 0xc0, 0x4a, 0x79, 0x00, 0xbd, 0x87, 0x40, 0xdf, 0x81, 0x05, 0xbd,
0x85, 0x3e, 0x41, 0x7b, 0xeb, 0x9d, 0x13, 0x3c, 0x9a, 0x3a, 0x77, 0x60, 0xa6, 0xa0, 0x9f, 0xc2,
0x9a, 0xc8, 0x07, 0xc3, 0x42, 0x15, 0x6a, 0xa9, 0xf0, 0x6a, 0xda, 0xb5, 0xb3, 0xad, 0x84, 0xaa,
0x0b, 0x58, 0x97, 0xde, 0x85, 0x45, 0xb5, 0x52, 0x2e, 0x34, 0x4a, 0xed, 0xad, 0x6b, 0x73, 0x0f,
0xb9, 0xa7, 0x4d, 0x02, 0x6b, 0xea, 0x5f, 0x83, 0x2b, 0x0f, 0x88, 0x9c, 0x39, 0x5d, 0x40, 0x3e,
0xc9, 0x89, 0x90, 0x56, 0xf9, 0x84, 0x26, 0xe4, 0x09, 0x1d, 0x3e, 0xdb, 0x39, 0xc0, 0x69, 0x4a,
0xe2, 0x42, 0xf9, 0x06, 0x5c, 0x7b, 0x40, 0xf4, 0x04, 0x2a, 0x24, 0x1d, 0x8a, 0x19, 0xf5, 0x25,
0x58, 0x7b, 0x40, 0x64, 0x2f, 0x9a, 0x11, 0x3f, 0x85, 0xe6, 0x63, 0x15, 0x6c, 0x45, 0x83, 0xf7,
0xa1, 0x81, 0xa3, 0x88, 0x13, 0x21, 0x2c, 0x8a, 0xd7, 0xe7, 0x7a, 0x7c, 0xdf, 0xd8, 0x04, 0x85,
0xf1, 0x3c, 0x9a, 0xf8, 0xbf, 0x00, 0xe8, 0xa7, 0x54, 0xee, 0x62, 0x8e, 0x13, 0x71, 0x22, 0xc1,
0x7a, 0xd0, 0x11, 0x12, 0x73, 0x19, 0x66, 0xda, 0xce, 0x42, 0x7e, 0x06, 0x36, 0xb4, 0xf5, 0x34,
0xb3, 0xba, 0xff, 0x33, 0x80, 0x3d, 0xc9, 0x69, 0x3a, 0xfa, 0x98, 0x0a, 0xa9, 0xf6, 0x3a, 0x54,
0x76, 0xea, 0x10, 0xee, 0x66, 0x2b, 0xb0, 0xa3, 0x4a, 0x38, 0x6a, 0x67, 0x0f, 0xc7, 0x3d, 0x68,
0x17, 0x70, 0x3f, 0x12, 0x23, 0x74, 0x17, 0xea, 0x03, 0x2c, 0xc8, 0xa9, 0xf0, 0x3c, 0x12, 0xa3,
0x6d, 0x2c, 0x48, 0xa0, 0x2d, 0xfd, 0x5f, 0xbb, 0xf0, 0xfa, 0x0e, 0x27, 0x9a, 0xfc, 0x71, 0x4c,
0x86, 0x92, 0xb2, 0xd4, 0x62, 0x7f, 0xfe, 0xd5, 0xd0, 0xeb, 0xd0, 0x88, 0x06, 0x61, 0x8a, 0x93,
0x02, 0xec, 0xc5, 0x68, 0xf0, 0x18, 0x27, 0x04, 0x7d, 0x15, 0x96, 0x87, 0xe5, 0xfa, 0x4a, 0xa2,
0x39, 0xd7, 0x0a, 0x66, 0xa4, 0xe8, 0x1d, 0x58, 0xca, 0x30, 0x97, 0xb4, 0x34, 0xab, 0x6b, 0xb3,
0x69, 0xa1, 0x0a, 0x68, 0x34, 0xe8, 0xf7, 0xbc, 0x05, 0x1d, 0x2c, 0xfd, 0x8d, 0x7c, 0xe8, 0x4c,
0xd6, 0xea, 0xf7, 0xbc, 0x45, 0xad, 0x9b, 0x92, 0xa1, 0x0d, 0x68, 0x97, 0x0b, 0xf5, 0x7b, 0x5e,
0x43, 0x9b, 0x54, 0x45, 0x2a, 0x38, 0x26, 0x17, 0x79, 0xcd, 0x0d, 0x67, 0xb3, 0x13, 0xd8, 0x11,
0xba, 0x0b, 0x6b, 0x87, 0x94, 0xcb, 0x1c, 0xc7, 0x96, 0x9f, 0xca, 0x0f, 0xe1, 0xb5, 0x74, 0x04,
0xe7, 0xa9, 0xd0, 0x16, 0xac, 0x67, 0x07, 0x63, 0x41, 0x87, 0x33, 0x53, 0x40, 0x4f, 0x99, 0xab,
0xf3, 0xff, 0xe9, 0xc0, 0xa5, 0x1e, 0x67, 0xd9, 0x2b, 0x11, 0x8a, 0x02, 0xe4, 0xfa, 0x29, 0x20,
0x2f, 0x1c, 0x07, 0xd9, 0xff, 0x6d, 0x0d, 0x2e, 0x1b, 0x46, 0xed, 0x16, 0xc0, 0x7e, 0x0e, 0xa7,
0xf8, 0x1a, 0xac, 0x4c, 0x76, 0x35, 0x06, 0xf3, 0x8f, 0xf1, 0x15, 0x58, 0x2e, 0x03, 0x6c, 0xec,
0xfe, 0xb7, 0x94, 0xf2, 0x7f, 0x53, 0x83, 0x75, 0x15, 0xd4, 0x2f, 0xd1, 0x50, 0x68, 0xfc, 0xc9,
0x01, 0x64, 0xd8, 0x71, 0x3f, 0xa6, 0x58, 0x7c, 0x91, 0x58, 0xac, 0xc3, 0x02, 0x56, 0x3e, 0x58,
0x08, 0xcc, 0xc0, 0x17, 0xd0, 0x55, 0xd1, 0xfa, 0xbc, 0xbc, 0x2b, 0x37, 0x75, 0xab, 0x9b, 0xfe,
0xd1, 0x81, 0xd5, 0xfb, 0xb1, 0x24, 0xfc, 0x15, 0x05, 0xe5, 0x1f, 0xb5, 0x22, 0x6a, 0xfd, 0x34,
0x22, 0xcf, 0xbf, 0x48, 0x07, 0xdf, 0x00, 0xd8, 0xa7, 0x24, 0x8e, 0xaa, 0xec, 0x6d, 0x69, 0xc9,
0x67, 0x62, 0xae, 0x07, 0x0d, 0xbd, 0x48, 0xc9, 0xda, 0x62, 0xa8, 0x6a, 0x00, 0x53, 0x0f, 0xda,
0x1a, 0xa0, 0x79, 0xe6, 0x1a, 0x40, 0x4f, 0xb3, 0x35, 0xc0, 0xbf, 0xea, 0xb0, 0xd4, 0x4f, 0x05,
0xe1, 0xf2, 0xe2, 0xe0, 0x5d, 0x87, 0x96, 0x38, 0xc0, 0x5c, 0x1f, 0xd4, 0xc2, 0x37, 0x11, 0x54,
0xa1, 0x75, 0x5f, 0x06, 0x6d, 0xfd, 0x8c, 0xc9, 0x61, 0xe1, 0xb4, 0xe4, 0xb0, 0x78, 0x0a, 0xc4,
0x8d, 0x97, 0x27, 0x87, 0xe6, 0xf1, 0xd7, 0x57, 0x1d, 0x90, 0x8c, 0x12, 0x55, 0xb4, 0xf6, 0xbc,
0x96, 0xd6, 0x4f, 0x04, 0xe8, 0x4d, 0x00, 0x49, 0x13, 0x22, 0x24, 0x4e, 0x32, 0xf3, 0x8e, 0xd6,
0x83, 0x8a, 0x44, 0xbd, 0xdd, 0x9c, 0x1d, 0xf5, 0x7b, 0xc2, 0x6b, 0x6f, 0xb8, 0xaa, 0x88, 0x33,
0x23, 0xf4, 0x1e, 0x34, 0x39, 0x3b, 0x0a, 0x23, 0x2c, 0xb1, 0xd7, 0xd1, 0xc1, 0xbb, 0x32, 0x17,
0xec, 0xed, 0x98, 0x0d, 0x82, 0x06, 0x67, 0x47, 0x3d, 0x2c, 0x31, 0xba, 0x07, 0x6d, 0xcd, 0x00,
0x61, 0x26, 0x2e, 0xe9, 0x89, 0x6f, 0x4e, 0x4f, 0xb4, 0x6d, 0xcb, 0x0f, 0x95, 0x9d, 0x9a, 0x14,
0x18, 0x6a, 0x0a, 0xbd, 0xc0, 0x15, 0x68, 0xa6, 0x79, 0x12, 0x72, 0x76, 0x24, 0xbc, 0xe5, 0x0d,
0x67, 0xb3, 0x1e, 0x34, 0xd2, 0x3c, 0x09, 0xd8, 0x91, 0x40, 0xdb, 0xd0, 0x38, 0x24, 0x5c, 0x50,
0x96, 0x7a, 0x2b, 0xba, 0x41, 0xd9, 0x3c, 0xa1, 0x88, 0x37, 0x8c, 0x51, 0xcb, 0x3d, 0x35, 0xf6,
0x41, 0x31, 0xd1, 0xff, 0x73, 0x1d, 0x96, 0xf6, 0x08, 0xe6, 0xc3, 0x83, 0x8b, 0x13, 0xea, 0xeb,
0xd0, 0xe5, 0x44, 0xe4, 0xb1, 0x0c, 0x87, 0xa6, 0x0c, 0xe9, 0xf7, 0x2c, 0xaf, 0x56, 0x8c, 0x7c,
0xa7, 0x10, 0x97, 0x41, 0x77, 0x4f, 0x09, 0x7a, 0x7d, 0x4e, 0xd0, 0x7d, 0xe8, 0x54, 0x22, 0x2c,
0xbc, 0x05, 0x1d, 0x9a, 0x29, 0x19, 0xea, 0x82, 0x1b, 0x89, 0x58, 0xf3, 0xa9, 0x15, 0xa8, 0x4f,
0x74, 0x0b, 0x56, 0xb3, 0x18, 0x0f, 0xc9, 0x01, 0x8b, 0x23, 0xc2, 0xc3, 0x11, 0x67, 0x79, 0xa6,
0x39, 0xd5, 0x09, 0xba, 0x15, 0xc5, 0x03, 0x25, 0x47, 0x1f, 0x40, 0x33, 0x12, 0x71, 0x28, 0xc7,
0x19, 0xd1, 0xa4, 0x5a, 0x3e, 0xe1, 0xec, 0x3d, 0x11, 0x3f, 0x19, 0x67, 0x24, 0x68, 0x44, 0xe6,
0x03, 0xdd, 0x85, 0x75, 0x41, 0x38, 0xc5, 0x31, 0x7d, 0x41, 0xa2, 0x90, 0x3c, 0xcf, 0x78, 0x98,
0xc5, 0x38, 0xd5, 0xcc, 0xeb, 0x04, 0x68, 0xa2, 0xfb, 0xc1, 0xf3, 0x8c, 0xef, 0xc6, 0x38, 0x45,
0x9b, 0xd0, 0x65, 0xb9, 0xcc, 0x72, 0x19, 0x5a, 0x6e, 0xd0, 0x48, 0x13, 0xd1, 0x0d, 0x96, 0x8d,
0x5c, 0x53, 0x41, 0xf4, 0x23, 0x05, 0xad, 0xe4, 0xf8, 0x90, 0xc4, 0x61, 0xc9, 0x50, 0xaf, 0xad,
0x59, 0xb0, 0x62, 0xe4, 0x4f, 0x0a, 0x31, 0xba, 0x03, 0x6b, 0xa3, 0x1c, 0x73, 0x9c, 0x4a, 0x42,
0x2a, 0xd6, 0x1d, 0x6d, 0x8d, 0x4a, 0xd5, 0x64, 0xc2, 0x2d, 0x58, 0x55, 0x66, 0x2c, 0x97, 0x15,
0xf3, 0x25, 0x6d, 0xde, 0xb5, 0x8a, 0xd2, 0xd8, 0xff, 0x7d, 0x85, 0x27, 0x2a, 0xa4, 0xe2, 0x02,
0x3c, 0xb9, 0x48, 0x6b, 0x32, 0x97, 0x5c, 0xee, 0x7c, 0x72, 0xdd, 0x80, 0x76, 0x42, 0x24, 0xa7,
0x43, 0x13, 0x44, 0x93, 0x9d, 0xc0, 0x88, 0x74, 0xa4, 0x6e, 0x40, 0x5b, 0xdd, 0xa5, 0x4f, 0x72,
0xc2, 0x29, 0x11, 0x36, 0xb9, 0x43, 0x9a, 0x27, 0x3f, 0x31, 0x12, 0xb4, 0x06, 0x0b, 0x92, 0x65,
0xe1, 0xb3, 0x22, 0x29, 0x49, 0x96, 0x3d, 0x44, 0xdf, 0x83, 0xab, 0x82, 0xe0, 0x98, 0x44, 0x61,
0x99, 0x44, 0x44, 0x28, 0x34, 0x16, 0x24, 0xf2, 0x1a, 0x3a, 0x6e, 0x9e, 0xb1, 0xd8, 0x2b, 0x0d,
0xf6, 0xac, 0x5e, 0x85, 0xa5, 0x74, 0xbc, 0x32, 0xad, 0xa9, 0xeb, 0x77, 0x34, 0x51, 0x95, 0x13,
0x3e, 0x04, 0x6f, 0x14, 0xb3, 0x01, 0x8e, 0xc3, 0x63, 0xbb, 0xea, 0x46, 0xc1, 0x0d, 0x2e, 0x1b,
0xfd, 0xde, 0xcc, 0x96, 0xea, 0x78, 0x22, 0xa6, 0x43, 0x12, 0x85, 0x83, 0x98, 0x0d, 0x3c, 0xd0,
0xfc, 0x03, 0x23, 0x52, 0x59, 0x49, 0xf1, 0xce, 0x1a, 0x28, 0x18, 0x86, 0x2c, 0x4f, 0xa5, 0x66,
0x93, 0x1b, 0x2c, 0x1b, 0xf9, 0xe3, 0x3c, 0xd9, 0x51, 0x52, 0xf4, 0x36, 0x2c, 0x59, 0x4b, 0xb6,
0xbf, 0x2f, 0x88, 0xd4, 0x34, 0x72, 0x83, 0x8e, 0x11, 0xfe, 0x58, 0xcb, 0xfc, 0xbf, 0xb8, 0xb0,
0x12, 0x28, 0x74, 0xc9, 0x21, 0xf9, 0xbf, 0xcf, 0x1e, 0x27, 0xdd, 0xe2, 0xc5, 0x73, 0xdd, 0xe2,
0xc6, 0x99, 0x6f, 0x71, 0xf3, 0x5c, 0xb7, 0xb8, 0x75, 0xbe, 0x5b, 0x0c, 0x27, 0xdc, 0xe2, 0xbf,
0x4d, 0x45, 0xec, 0x55, 0xbd, 0xc7, 0x37, 0xc1, 0xa5, 0x91, 0x29, 0x1d, 0xdb, 0x5b, 0xde, 0xdc,
0xb7, 0xb2, 0xdf, 0x13, 0x81, 0x32, 0x9a, 0x7d, 0x5f, 0x17, 0xce, 0xfd, 0xbe, 0x7e, 0x1f, 0xae,
0x1d, 0xbf, 0xdd, 0xdc, 0x62, 0x14, 0x79, 0x8b, 0x3a, 0xa0, 0x57, 0x66, 0xaf, 0x77, 0x01, 0x62,
0x84, 0xbe, 0x05, 0xeb, 0x95, 0xfb, 0x3d, 0x99, 0xd8, 0x30, 0x3d, 0xfd, 0x44, 0x37, 0x99, 0x72,
0xda, 0x0d, 0x6f, 0x9e, 0x76, 0xc3, 0xfd, 0x4f, 0x5d, 0x58, 0xea, 0x91, 0x98, 0x48, 0xf2, 0x65,
0xf9, 0x77, 0x62, 0xf9, 0xf7, 0x0d, 0x40, 0x34, 0x95, 0xef, 0xbf, 0x17, 0x66, 0x9c, 0x26, 0x98,
0x8f, 0xc3, 0x67, 0x64, 0x5c, 0xa4, 0xce, 0xae, 0xd6, 0xec, 0x1a, 0xc5, 0x43, 0x32, 0x16, 0x2f,
0x2d, 0x07, 0xab, 0xf5, 0x97, 0xc9, 0x95, 0x65, 0xfd, 0xf5, 0x5d, 0xe8, 0x4c, 0x6d, 0xd1, 0x79,
0x09, 0x61, 0xdb, 0xd9, 0x64, 0x5f, 0xff, 0x3f, 0x0e, 0xb4, 0x3e, 0x66, 0x38, 0xd2, 0x9d, 0xd0,
0x05, 0xc3, 0x58, 0x16, 0xb9, 0xb5, 0xd9, 0x22, 0xf7, 0x3a, 0x4c, 0x9a, 0x19, 0x1b, 0xc8, 0x4a,
0x77, 0x53, 0xe9, 0x52, 0xea, 0xd3, 0x5d, 0xca, 0x0d, 0x68, 0x53, 0xe5, 0x50, 0x98, 0x61, 0x79,
0x60, 0x12, 0x65, 0x2b, 0x00, 0x2d, 0xda, 0x55, 0x12, 0xd5, 0xc6, 0x14, 0x06, 0xba, 0x8d, 0x59,
0x3c, 0x73, 0x1b, 0x63, 0x17, 0xd1, 0x6d, 0xcc, 0xaf, 0x1c, 0x00, 0x7d, 0x70, 0x95, 0x24, 0x8e,
0x2f, 0xea, 0x5c, 0x64, 0x51, 0x95, 0xc1, 0x75, 0xa4, 0x48, 0x8c, 0xe5, 0xe4, 0x52, 0x09, 0x0b,
0x0e, 0x52, 0x51, 0x33, 0x2a, 0x7b, 0xa1, 0x84, 0xff, 0x3b, 0x07, 0x40, 0x67, 0x05, 0xe3, 0xc6,
0x2c, 0xfd, 0x9c, 0xd3, 0x1b, 0xbc, 0xda, 0x34, 0x74, 0xdb, 0x05, 0x74, 0x2a, 0xe1, 0xa9, 0xc6,
0x7c, 0xce, 0x19, 0x2a, 0x15, 0x79, 0x71, 0x78, 0x8b, 0xae, 0xfe, 0xf6, 0xff, 0xe0, 0x40, 0xc7,
0x7a, 0x67, 0x5c, 0x9a, 0x8a, 0xb2, 0x33, 0x1b, 0x65, 0x5d, 0xf0, 0x24, 0x8c, 0x8f, 0x43, 0x41,
0x5f, 0x10, 0xeb, 0x10, 0x18, 0xd1, 0x1e, 0x7d, 0x41, 0xa6, 0xc8, 0xeb, 0x4e, 0x93, 0xf7, 0x16,
0xac, 0x72, 0x32, 0x24, 0xa9, 0x8c, 0xc7, 0x61, 0xc2, 0x22, 0xba, 0x4f, 0x49, 0xa4, 0xd9, 0xd0,
0x0c, 0xba, 0x85, 0xe2, 0x91, 0x95, 0xfb, 0x9f, 0x3a, 0xb0, 0xac, 0x6a, 0xa4, 0xf1, 0x63, 0x16,
0x11, 0xe3, 0xd9, 0xf9, 0x19, 0xfb, 0x91, 0x3e, 0x8b, 0x85, 0xc7, 0xfc, 0x04, 0xfe, 0xf6, 0x49,
0xff, 0xa8, 0x54, 0x30, 0x08, 0x9a, 0x82, 0x8c, 0xcc, 0x9e, 0xdb, 0x36, 0xd9, 0x9f, 0x09, 0xe2,
0x49, 0x60, 0x6d, 0xbe, 0x37, 0x10, 0xff, 0xd2, 0x81, 0xf6, 0x23, 0x31, 0xda, 0x65, 0x42, 0xe7,
0x0b, 0xf4, 0x16, 0x74, 0x6c, 0x8e, 0x36, 0xc9, 0xca, 0xd1, 0x97, 0xa5, 0x3d, 0x9c, 0xfc, 0xa0,
0x8a, 0xd6, 0x61, 0x21, 0x11, 0x23, 0x1b, 0xf1, 0x4e, 0x60, 0x06, 0xe8, 0x2a, 0x34, 0x13, 0x31,
0xd2, 0xbd, 0x83, 0xbd, 0x61, 0xe5, 0x58, 0x85, 0x6d, 0xf2, 0x18, 0xd7, 0xf5, 0x63, 0x3c, 0x11,
0xf8, 0x7f, 0x75, 0x00, 0xd9, 0xd7, 0xee, 0x33, 0xfd, 0xea, 0xae, 0x09, 0x5b, 0xfd, 0x51, 0xb8,
0xa6, 0xaf, 0xeb, 0x94, 0x6c, 0x26, 0xbf, 0xb9, 0xc7, 0xf2, 0xdb, 0x2d, 0x58, 0x8d, 0xc8, 0x3e,
0x56, 0x0f, 0xf3, 0xac, 0xcb, 0x5d, 0xab, 0x28, 0xeb, 0x87, 0x9b, 0x1f, 0x42, 0xab, 0xfc, 0xb3,
0x0b, 0x75, 0xa1, 0xd3, 0x4f, 0xa9, 0xd4, 0x65, 0x11, 0x4d, 0x47, 0xdd, 0xd7, 0x50, 0x1b, 0x1a,
0x3f, 0x22, 0x38, 0x96, 0x07, 0xe3, 0xae, 0x83, 0x3a, 0xd0, 0xbc, 0x3f, 0x48, 0x19, 0x4f, 0x70,
0xdc, 0xad, 0xdd, 0xdc, 0x82, 0xd5, 0x63, 0x5d, 0xa8, 0x32, 0x09, 0xd8, 0x91, 0x3a, 0x50, 0xd4,
0x7d, 0x0d, 0xad, 0x40, 0x7b, 0x87, 0xc5, 0x79, 0x92, 0x1a, 0x81, 0xb3, 0xfd, 0xc1, 0xcf, 0xbf,
0x3d, 0xa2, 0xf2, 0x20, 0x1f, 0xa8, 0xd3, 0xdf, 0x31, 0x70, 0x7c, 0x93, 0x32, 0xfb, 0x75, 0xa7,
0x88, 0xf4, 0x1d, 0x8d, 0x50, 0x39, 0xcc, 0x06, 0x83, 0x45, 0x2d, 0x79, 0xf7, 0xbf, 0x01, 0x00,
0x00, 0xff, 0xff, 0x66, 0xd1, 0x46, 0x17, 0x46, 0x1c, 0x00, 0x00,
// 2043 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xec, 0x59, 0xcf, 0x73, 0x1c, 0x47,
0x15, 0xce, 0xec, 0xac, 0xb4, 0xbb, 0x6f, 0x57, 0xab, 0x55, 0x4b, 0x76, 0xc6, 0xb2, 0x13, 0x2b,
0x93, 0x00, 0xc2, 0x26, 0xb6, 0x51, 0x42, 0x92, 0x02, 0x0a, 0xc7, 0xda, 0x05, 0xb3, 0xe5, 0xd8,
0x88, 0x91, 0xe3, 0x2a, 0xe0, 0x30, 0xd5, 0xbb, 0xd3, 0xda, 0x1d, 0x3c, 0x33, 0x3d, 0xe9, 0xee,
0x91, 0xbc, 0x3e, 0x71, 0xe0, 0x04, 0x05, 0x55, 0x1c, 0x38, 0xc2, 0x8d, 0x33, 0x47, 0x4e, 0x40,
0x15, 0xa7, 0x9c, 0xb8, 0xf3, 0xaf, 0x70, 0xa2, 0xfa, 0xc7, 0xcc, 0xce, 0xae, 0x56, 0xb2, 0xa4,
0x54, 0x88, 0x53, 0x95, 0xdb, 0xf4, 0x7b, 0xaf, 0xbb, 0x5f, 0x7f, 0xef, 0x7b, 0xaf, 0x5f, 0xef,
0x42, 0x3b, 0x4c, 0x04, 0x61, 0x09, 0x8e, 0x6e, 0xa5, 0x8c, 0x0a, 0x8a, 0x2e, 0xc5, 0x61, 0x74,
0x98, 0x71, 0x3d, 0xba, 0x95, 0x2b, 0x37, 0x5b, 0x43, 0x1a, 0xc7, 0x34, 0xd1, 0xe2, 0xcd, 0x16,
0x1f, 0x8e, 0x49, 0x8c, 0xf5, 0xc8, 0xfd, 0x87, 0x05, 0x2b, 0x5d, 0x1a, 0xa7, 0x34, 0x21, 0x89,
0xe8, 0x27, 0x07, 0x14, 0x5d, 0x86, 0xe5, 0x84, 0x06, 0xa4, 0xdf, 0x73, 0xac, 0x2d, 0x6b, 0xdb,
0xf6, 0xcc, 0x08, 0x21, 0xa8, 0x32, 0x1a, 0x11, 0xa7, 0xb2, 0x65, 0x6d, 0x37, 0x3c, 0xf5, 0x8d,
0xee, 0x02, 0x70, 0x81, 0x05, 0xf1, 0x87, 0x34, 0x20, 0x8e, 0xbd, 0x65, 0x6d, 0xb7, 0x77, 0xb6,
0x6e, 0x2d, 0xf4, 0xe2, 0xd6, 0xbe, 0x34, 0xec, 0xd2, 0x80, 0x78, 0x0d, 0x9e, 0x7f, 0xa2, 0x0f,
0x01, 0xc8, 0x33, 0xc1, 0xb0, 0x1f, 0x26, 0x07, 0xd4, 0xa9, 0x6e, 0xd9, 0xdb, 0xcd, 0x9d, 0x37,
0x66, 0x17, 0x30, 0xce, 0x3f, 0x20, 0x93, 0x27, 0x38, 0xca, 0xc8, 0x1e, 0x0e, 0x99, 0xd7, 0x50,
0x93, 0xa4, 0xbb, 0xee, 0x7f, 0x2c, 0x58, 0x2d, 0x0e, 0xa0, 0xf6, 0xe0, 0xe8, 0xbb, 0xb0, 0xa4,
0xb6, 0x50, 0x27, 0x68, 0xee, 0xbc, 0x75, 0x82, 0x47, 0x33, 0xe7, 0xf6, 0xf4, 0x14, 0xf4, 0x31,
0xac, 0xf3, 0x6c, 0x30, 0xcc, 0x55, 0xbe, 0x92, 0x72, 0xa7, 0xa2, 0x5c, 0x3b, 0xdb, 0x4a, 0xa8,
0xbc, 0x80, 0x71, 0xe9, 0x1d, 0x58, 0x96, 0x2b, 0x65, 0x5c, 0xa1, 0xd4, 0xdc, 0xb9, 0xba, 0xf0,
0x90, 0xfb, 0xca, 0xc4, 0x33, 0xa6, 0xee, 0x55, 0xb8, 0x72, 0x9f, 0x88, 0xb9, 0xd3, 0x79, 0xe4,
0x93, 0x8c, 0x70, 0x61, 0x94, 0x8f, 0xc3, 0x98, 0x3c, 0x0e, 0x87, 0x4f, 0xbb, 0x63, 0x9c, 0x24,
0x24, 0xca, 0x95, 0xaf, 0xc1, 0xd5, 0xfb, 0x44, 0x4d, 0x08, 0xb9, 0x08, 0x87, 0x7c, 0x4e, 0x7d,
0x09, 0xd6, 0xef, 0x13, 0xd1, 0x0b, 0xe6, 0xc4, 0x4f, 0xa0, 0xfe, 0x48, 0x06, 0x5b, 0xd2, 0xe0,
0x3d, 0xa8, 0xe1, 0x20, 0x60, 0x84, 0x73, 0x83, 0xe2, 0xb5, 0x85, 0x1e, 0xdf, 0xd3, 0x36, 0x5e,
0x6e, 0xbc, 0x88, 0x26, 0xee, 0x2f, 0x01, 0xfa, 0x49, 0x28, 0xf6, 0x30, 0xc3, 0x31, 0x3f, 0x91,
0x60, 0x3d, 0x68, 0x71, 0x81, 0x99, 0xf0, 0x53, 0x65, 0x67, 0x20, 0x3f, 0x03, 0x1b, 0x9a, 0x6a,
0x9a, 0x5e, 0xdd, 0xfd, 0x19, 0xc0, 0xbe, 0x60, 0x61, 0x32, 0xfa, 0x28, 0xe4, 0x42, 0xee, 0x75,
0x28, 0xed, 0xe4, 0x21, 0xec, 0xed, 0x86, 0x67, 0x46, 0xa5, 0x70, 0x54, 0xce, 0x1e, 0x8e, 0xbb,
0xd0, 0xcc, 0xe1, 0x7e, 0xc8, 0x47, 0xe8, 0x0e, 0x54, 0x07, 0x98, 0x93, 0x53, 0xe1, 0x79, 0xc8,
0x47, 0xbb, 0x98, 0x13, 0x4f, 0x59, 0xba, 0xbf, 0xb1, 0xe1, 0xd5, 0x2e, 0x23, 0x8a, 0xfc, 0x51,
0x44, 0x86, 0x22, 0xa4, 0x89, 0xc1, 0xfe, 0xfc, 0xab, 0xa1, 0x57, 0xa1, 0x16, 0x0c, 0xfc, 0x04,
0xc7, 0x39, 0xd8, 0xcb, 0xc1, 0xe0, 0x11, 0x8e, 0x09, 0xfa, 0x3a, 0xb4, 0x87, 0xc5, 0xfa, 0x52,
0xa2, 0x38, 0xd7, 0xf0, 0xe6, 0xa4, 0xe8, 0x2d, 0x58, 0x49, 0x31, 0x13, 0x61, 0x61, 0x56, 0x55,
0x66, 0xb3, 0x42, 0x19, 0xd0, 0x60, 0xd0, 0xef, 0x39, 0x4b, 0x2a, 0x58, 0xea, 0x1b, 0xb9, 0xd0,
0x9a, 0xae, 0xd5, 0xef, 0x39, 0xcb, 0x4a, 0x37, 0x23, 0x43, 0x5b, 0xd0, 0x2c, 0x16, 0xea, 0xf7,
0x9c, 0x9a, 0x32, 0x29, 0x8b, 0x64, 0x70, 0x74, 0x2d, 0x72, 0xea, 0x5b, 0xd6, 0x76, 0xcb, 0x33,
0x23, 0x74, 0x07, 0xd6, 0x0f, 0x43, 0x26, 0x32, 0x1c, 0x19, 0x7e, 0x4a, 0x3f, 0xb8, 0xd3, 0x50,
0x11, 0x5c, 0xa4, 0x42, 0x3b, 0xb0, 0x91, 0x8e, 0x27, 0x3c, 0x1c, 0xce, 0x4d, 0x01, 0x35, 0x65,
0xa1, 0xce, 0xfd, 0x97, 0x05, 0x97, 0x7a, 0x8c, 0xa6, 0x2f, 0x45, 0x28, 0x72, 0x90, 0xab, 0xa7,
0x80, 0xbc, 0x74, 0x1c, 0x64, 0xf7, 0x77, 0x15, 0xb8, 0xac, 0x19, 0xb5, 0x97, 0x03, 0xfb, 0x39,
0x9c, 0xe2, 0x1b, 0xb0, 0x3a, 0xdd, 0x55, 0x1b, 0x2c, 0x3e, 0xc6, 0xd7, 0xa0, 0x5d, 0x04, 0x58,
0xdb, 0xfd, 0x7f, 0x29, 0xe5, 0xfe, 0xb6, 0x02, 0x1b, 0x32, 0xa8, 0x5f, 0xa1, 0x21, 0xd1, 0xf8,
0xb3, 0x05, 0x48, 0xb3, 0xe3, 0x5e, 0x14, 0x62, 0xfe, 0x45, 0x62, 0xb1, 0x01, 0x4b, 0x58, 0xfa,
0x60, 0x20, 0xd0, 0x03, 0x97, 0x43, 0x47, 0x46, 0xeb, 0xf3, 0xf2, 0xae, 0xd8, 0xd4, 0x2e, 0x6f,
0xfa, 0x27, 0x0b, 0xd6, 0xee, 0x45, 0x82, 0xb0, 0x97, 0x14, 0x94, 0x7f, 0x56, 0xf2, 0xa8, 0xf5,
0x93, 0x80, 0x3c, 0xfb, 0x22, 0x1d, 0x7c, 0x0d, 0xe0, 0x20, 0x24, 0x51, 0x50, 0x66, 0x6f, 0x43,
0x49, 0x3e, 0x13, 0x73, 0x1d, 0xa8, 0xa9, 0x45, 0x0a, 0xd6, 0xe6, 0x43, 0xd9, 0x03, 0xe8, 0x7e,
0xd0, 0xf4, 0x00, 0xf5, 0x33, 0xf7, 0x00, 0x6a, 0x9a, 0xe9, 0x01, 0xfe, 0x5d, 0x85, 0x95, 0x7e,
0xc2, 0x09, 0x13, 0x17, 0x07, 0xef, 0x1a, 0x34, 0xf8, 0x18, 0x33, 0x75, 0x50, 0x03, 0xdf, 0x54,
0x50, 0x86, 0xd6, 0x7e, 0x11, 0xb4, 0xd5, 0x33, 0x16, 0x87, 0xa5, 0xd3, 0x8a, 0xc3, 0xf2, 0x29,
0x10, 0xd7, 0x5e, 0x5c, 0x1c, 0xea, 0xc7, 0x6f, 0x5f, 0x79, 0x40, 0x32, 0x8a, 0x65, 0xd3, 0xda,
0x73, 0x1a, 0x4a, 0x3f, 0x15, 0xa0, 0xd7, 0x01, 0x44, 0x18, 0x13, 0x2e, 0x70, 0x9c, 0xea, 0x7b,
0xb4, 0xea, 0x95, 0x24, 0xf2, 0xee, 0x66, 0xf4, 0xa8, 0xdf, 0xe3, 0x4e, 0x73, 0xcb, 0x96, 0x4d,
0x9c, 0x1e, 0xa1, 0x77, 0xa1, 0xce, 0xe8, 0x91, 0x1f, 0x60, 0x81, 0x9d, 0x96, 0x0a, 0xde, 0x95,
0x85, 0x60, 0xef, 0x46, 0x74, 0xe0, 0xd5, 0x18, 0x3d, 0xea, 0x61, 0x81, 0xd1, 0x5d, 0x68, 0x2a,
0x06, 0x70, 0x3d, 0x71, 0x45, 0x4d, 0x7c, 0x7d, 0x76, 0xa2, 0x79, 0xb6, 0xfc, 0x48, 0xda, 0xc9,
0x49, 0x9e, 0xa6, 0x26, 0x57, 0x0b, 0x5c, 0x81, 0x7a, 0x92, 0xc5, 0x3e, 0xa3, 0x47, 0xdc, 0x69,
0x6f, 0x59, 0xdb, 0x55, 0xaf, 0x96, 0x64, 0xb1, 0x47, 0x8f, 0x38, 0xda, 0x85, 0xda, 0x21, 0x61,
0x3c, 0xa4, 0x89, 0xb3, 0xaa, 0x1e, 0x28, 0xdb, 0x27, 0x34, 0xf1, 0x9a, 0x31, 0x72, 0xb9, 0x27,
0xda, 0xde, 0xcb, 0x27, 0xba, 0x7f, 0xa9, 0xc2, 0xca, 0x3e, 0xc1, 0x6c, 0x38, 0xbe, 0x38, 0xa1,
0xbe, 0x09, 0x1d, 0x46, 0x78, 0x16, 0x09, 0x7f, 0xa8, 0xdb, 0x90, 0x7e, 0xcf, 0xf0, 0x6a, 0x55,
0xcb, 0xbb, 0xb9, 0xb8, 0x08, 0xba, 0x7d, 0x4a, 0xd0, 0xab, 0x0b, 0x82, 0xee, 0x42, 0xab, 0x14,
0x61, 0xee, 0x2c, 0xa9, 0xd0, 0xcc, 0xc8, 0x50, 0x07, 0xec, 0x80, 0x47, 0x8a, 0x4f, 0x0d, 0x4f,
0x7e, 0xa2, 0x9b, 0xb0, 0x96, 0x46, 0x78, 0x48, 0xc6, 0x34, 0x0a, 0x08, 0xf3, 0x47, 0x8c, 0x66,
0xa9, 0xe2, 0x54, 0xcb, 0xeb, 0x94, 0x14, 0xf7, 0xa5, 0x1c, 0xbd, 0x0f, 0xf5, 0x80, 0x47, 0xbe,
0x98, 0xa4, 0x44, 0x91, 0xaa, 0x7d, 0xc2, 0xd9, 0x7b, 0x3c, 0x7a, 0x3c, 0x49, 0x89, 0x57, 0x0b,
0xf4, 0x07, 0xba, 0x03, 0x1b, 0x9c, 0xb0, 0x10, 0x47, 0xe1, 0x73, 0x12, 0xf8, 0xe4, 0x59, 0xca,
0xfc, 0x34, 0xc2, 0x89, 0x62, 0x5e, 0xcb, 0x43, 0x53, 0xdd, 0x0f, 0x9f, 0xa5, 0x6c, 0x2f, 0xc2,
0x09, 0xda, 0x86, 0x0e, 0xcd, 0x44, 0x9a, 0x09, 0xdf, 0x70, 0x23, 0x0c, 0x14, 0x11, 0x6d, 0xaf,
0xad, 0xe5, 0x8a, 0x0a, 0xbc, 0x1f, 0x48, 0x68, 0x05, 0xc3, 0x87, 0x24, 0xf2, 0x0b, 0x86, 0x3a,
0x4d, 0xc5, 0x82, 0x55, 0x2d, 0x7f, 0x9c, 0x8b, 0xd1, 0x6d, 0x58, 0x1f, 0x65, 0x98, 0xe1, 0x44,
0x10, 0x52, 0xb2, 0x6e, 0x29, 0x6b, 0x54, 0xa8, 0xa6, 0x13, 0x6e, 0xc2, 0x9a, 0x34, 0xa3, 0x99,
0x28, 0x99, 0xaf, 0x28, 0xf3, 0x8e, 0x51, 0x14, 0xc6, 0xee, 0x1f, 0x4a, 0x3c, 0x91, 0x21, 0xe5,
0x17, 0xe0, 0xc9, 0x45, 0x9e, 0x26, 0x0b, 0xc9, 0x65, 0x2f, 0x26, 0xd7, 0x75, 0x68, 0xc6, 0x44,
0xb0, 0x70, 0xa8, 0x83, 0xa8, 0xab, 0x13, 0x68, 0x91, 0x8a, 0xd4, 0x75, 0x68, 0xca, 0x5c, 0xfa,
0x24, 0x23, 0x2c, 0x24, 0xdc, 0x14, 0x77, 0x48, 0xb2, 0xf8, 0xa7, 0x5a, 0x82, 0xd6, 0x61, 0x49,
0xd0, 0xd4, 0x7f, 0x9a, 0x17, 0x25, 0x41, 0xd3, 0x07, 0xe8, 0xfb, 0xb0, 0xc9, 0x09, 0x8e, 0x48,
0xe0, 0x17, 0x45, 0x84, 0xfb, 0x5c, 0x61, 0x41, 0x02, 0xa7, 0xa6, 0xe2, 0xe6, 0x68, 0x8b, 0xfd,
0xc2, 0x60, 0xdf, 0xe8, 0x65, 0x58, 0x0a, 0xc7, 0x4b, 0xd3, 0xea, 0xaa, 0x7f, 0x47, 0x53, 0x55,
0x31, 0xe1, 0x03, 0x70, 0x46, 0x11, 0x1d, 0xe0, 0xc8, 0x3f, 0xb6, 0xab, 0x7a, 0x28, 0xd8, 0xde,
0x65, 0xad, 0xdf, 0x9f, 0xdb, 0x52, 0x1e, 0x8f, 0x47, 0xe1, 0x90, 0x04, 0xfe, 0x20, 0xa2, 0x03,
0x07, 0x14, 0xff, 0x40, 0x8b, 0x64, 0x55, 0x92, 0xbc, 0x33, 0x06, 0x12, 0x86, 0x21, 0xcd, 0x12,
0xa1, 0xd8, 0x64, 0x7b, 0x6d, 0x2d, 0x7f, 0x94, 0xc5, 0x5d, 0x29, 0x45, 0x6f, 0xc2, 0x8a, 0xb1,
0xa4, 0x07, 0x07, 0x9c, 0x08, 0x45, 0x23, 0xdb, 0x6b, 0x69, 0xe1, 0x4f, 0x94, 0xcc, 0xfd, 0xab,
0x0d, 0xab, 0x9e, 0x44, 0x97, 0x1c, 0x92, 0x2f, 0x7d, 0xf5, 0x38, 0x29, 0x8b, 0x97, 0xcf, 0x95,
0xc5, 0xb5, 0x33, 0x67, 0x71, 0xfd, 0x5c, 0x59, 0xdc, 0x38, 0x5f, 0x16, 0xc3, 0x09, 0x59, 0xfc,
0xf7, 0x99, 0x88, 0xbd, 0xac, 0x79, 0x7c, 0x03, 0xec, 0x30, 0xd0, 0xad, 0x63, 0x73, 0xc7, 0x59,
0x78, 0x57, 0xf6, 0x7b, 0xdc, 0x93, 0x46, 0xf3, 0xf7, 0xeb, 0xd2, 0xb9, 0xef, 0xd7, 0x1f, 0xc0,
0xd5, 0xe3, 0xd9, 0xcd, 0x0c, 0x46, 0x81, 0xb3, 0xac, 0x02, 0x7a, 0x65, 0x3e, 0xbd, 0x73, 0x10,
0x03, 0xf4, 0x6d, 0xd8, 0x28, 0xe5, 0xf7, 0x74, 0x62, 0x4d, 0xbf, 0xe9, 0xa7, 0xba, 0xe9, 0x94,
0xd3, 0x32, 0xbc, 0x7e, 0x5a, 0x86, 0xbb, 0x9f, 0xda, 0xb0, 0xd2, 0x23, 0x11, 0x11, 0xe4, 0xab,
0xf6, 0xef, 0xc4, 0xf6, 0xef, 0x5b, 0x80, 0xc2, 0x44, 0xbc, 0xf7, 0xae, 0x9f, 0xb2, 0x30, 0xc6,
0x6c, 0xe2, 0x3f, 0x25, 0x93, 0xbc, 0x74, 0x76, 0x94, 0x66, 0x4f, 0x2b, 0x1e, 0x90, 0x09, 0x7f,
0x61, 0x3b, 0x58, 0xee, 0xbf, 0x74, 0xad, 0x2c, 0xfa, 0xaf, 0xef, 0x41, 0x6b, 0x66, 0x8b, 0xd6,
0x0b, 0x08, 0xdb, 0x4c, 0xa7, 0xfb, 0xba, 0xff, 0xb5, 0xa0, 0xf1, 0x11, 0xc5, 0x81, 0x7a, 0x09,
0x5d, 0x30, 0x8c, 0x45, 0x93, 0x5b, 0x99, 0x6f, 0x72, 0xaf, 0xc1, 0xf4, 0x31, 0x63, 0x02, 0x59,
0x7a, 0xdd, 0x94, 0x5e, 0x29, 0xd5, 0xd9, 0x57, 0xca, 0x75, 0x68, 0x86, 0xd2, 0x21, 0x3f, 0xc5,
0x62, 0xac, 0x0b, 0x65, 0xc3, 0x03, 0x25, 0xda, 0x93, 0x12, 0xf9, 0x8c, 0xc9, 0x0d, 0xd4, 0x33,
0x66, 0xf9, 0xcc, 0xcf, 0x18, 0xb3, 0x88, 0x7a, 0xc6, 0xfc, 0xda, 0x02, 0x50, 0x07, 0x97, 0x45,
0xe2, 0xf8, 0xa2, 0xd6, 0x45, 0x16, 0x95, 0x15, 0x5c, 0x45, 0x8a, 0x44, 0x58, 0x4c, 0x93, 0x8a,
0x1b, 0x70, 0x90, 0x8c, 0x9a, 0x56, 0x99, 0x84, 0xe2, 0xee, 0xef, 0x2d, 0x00, 0x55, 0x15, 0xb4,
0x1b, 0xf3, 0xf4, 0xb3, 0x4e, 0x7f, 0xe0, 0x55, 0x66, 0xa1, 0xdb, 0xcd, 0xa1, 0x93, 0x05, 0x4f,
0x3e, 0xcc, 0x17, 0x9c, 0xa1, 0xd4, 0x91, 0xe7, 0x87, 0x37, 0xe8, 0xaa, 0x6f, 0xf7, 0x8f, 0x16,
0xb4, 0x8c, 0x77, 0xda, 0xa5, 0x99, 0x28, 0x5b, 0xf3, 0x51, 0x56, 0x0d, 0x4f, 0x4c, 0xd9, 0xc4,
0xe7, 0xe1, 0x73, 0x62, 0x1c, 0x02, 0x2d, 0xda, 0x0f, 0x9f, 0x93, 0x19, 0xf2, 0xda, 0xb3, 0xe4,
0xbd, 0x09, 0x6b, 0x8c, 0x0c, 0x49, 0x22, 0xa2, 0x89, 0x1f, 0xd3, 0x20, 0x3c, 0x08, 0x49, 0xa0,
0xd8, 0x50, 0xf7, 0x3a, 0xb9, 0xe2, 0xa1, 0x91, 0xbb, 0x9f, 0x5a, 0xd0, 0x96, 0x3d, 0xd2, 0xe4,
0x11, 0x0d, 0x88, 0xf6, 0xec, 0xfc, 0x8c, 0xfd, 0x50, 0x9d, 0xc5, 0xc0, 0xa3, 0x7f, 0x02, 0x7f,
0xf3, 0xa4, 0x7f, 0x54, 0x4a, 0x18, 0x78, 0x75, 0x4e, 0x46, 0x7a, 0xcf, 0x5d, 0x53, 0xec, 0xcf,
0x04, 0xf1, 0x34, 0xb0, 0xa6, 0xde, 0x6b, 0x88, 0x7f, 0x65, 0x41, 0xf3, 0x21, 0x1f, 0xed, 0x51,
0xae, 0xea, 0x05, 0x7a, 0x03, 0x5a, 0xa6, 0x46, 0xeb, 0x62, 0x65, 0xa9, 0x64, 0x69, 0x0e, 0xa7,
0x3f, 0xa8, 0xa2, 0x0d, 0x58, 0x8a, 0xf9, 0xc8, 0x44, 0xbc, 0xe5, 0xe9, 0x01, 0xda, 0x84, 0x7a,
0xcc, 0x47, 0xea, 0xed, 0x60, 0x32, 0xac, 0x18, 0xcb, 0xb0, 0x4d, 0x2f, 0xe3, 0xaa, 0xba, 0x8c,
0xa7, 0x02, 0xf7, 0x6f, 0x16, 0x20, 0x73, 0xdb, 0x7d, 0xa6, 0x5f, 0xdd, 0x15, 0x61, 0xcb, 0x3f,
0x0a, 0x57, 0x54, 0xba, 0xce, 0xc8, 0xe6, 0xea, 0x9b, 0x7d, 0xac, 0xbe, 0xdd, 0x84, 0xb5, 0x80,
0x1c, 0x60, 0x79, 0x31, 0xcf, 0xbb, 0xdc, 0x31, 0x8a, 0x69, 0xff, 0x70, 0x0d, 0x36, 0xbb, 0x11,
0xc1, 0xac, 0xcb, 0x48, 0xf0, 0x31, 0x27, 0x8c, 0x77, 0xf1, 0x70, 0x9c, 0xdf, 0x45, 0xee, 0x2f,
0xa0, 0x2d, 0x15, 0x24, 0x11, 0x21, 0x8e, 0xd4, 0x5f, 0x2d, 0x9b, 0x50, 0xcf, 0xb8, 0x0c, 0x47,
0x01, 0x6c, 0x31, 0x46, 0x6f, 0x03, 0x22, 0xc9, 0x90, 0x4d, 0x52, 0x99, 0xac, 0x29, 0xe6, 0xfc,
0x88, 0xb2, 0xc0, 0x5c, 0x48, 0x6b, 0x85, 0x66, 0xcf, 0x28, 0x6e, 0x7c, 0x00, 0x8d, 0xe2, 0x7f,
0x36, 0xd4, 0x81, 0x56, 0x3f, 0x09, 0x85, 0xea, 0xc8, 0xc2, 0x64, 0xd4, 0x79, 0x05, 0x35, 0xa1,
0xf6, 0x63, 0x82, 0x23, 0x31, 0x9e, 0x74, 0x2c, 0xd4, 0x82, 0xfa, 0xbd, 0x41, 0x42, 0x59, 0x8c,
0xa3, 0x4e, 0xe5, 0xc6, 0x0e, 0xac, 0x1d, 0x7b, 0x00, 0x4b, 0x13, 0x8f, 0x1e, 0x49, 0x2c, 0x83,
0xce, 0x2b, 0x68, 0x15, 0x9a, 0x5d, 0x1a, 0x65, 0x71, 0xa2, 0x05, 0xd6, 0xee, 0xfb, 0x3f, 0xff,
0xce, 0x28, 0x14, 0xe3, 0x6c, 0x20, 0x81, 0xbf, 0xad, 0x23, 0xf1, 0x76, 0x48, 0xcd, 0xd7, 0xed,
0x9c, 0x64, 0xb7, 0x55, 0x70, 0x8a, 0x61, 0x3a, 0x18, 0x2c, 0x2b, 0xc9, 0x3b, 0xff, 0x0b, 0x00,
0x00, 0xff, 0xff, 0x48, 0x13, 0x23, 0xf5, 0xc1, 0x1c, 0x00, 0x00,
}

View File

@ -66,6 +66,12 @@ service MilvusService {
// https://wiki.lfaidata.foundation/display/MIL/MEP+24+--+Support+bulk+load
rpc Import(ImportRequest) returns (ImportResponse) {}
rpc GetImportState(GetImportStateRequest) returns (GetImportStateResponse) {}
// https://wiki.lfaidata.foundation/display/MIL/MEP+27+--+Support+Basic+Authentication
rpc CreateCredential(CreateCredentialRequest) returns (common.Status) {}
rpc UpdateCredential(CreateCredentialRequest) returns (common.Status) {}
rpc DeleteCredential(DeleteCredentialRequest) returns (common.Status) {}
rpc ListCredUsers(ListCredUsersRequest) returns (ListCredUsersResponse) {}
}
message CreateAliasRequest {
@ -847,7 +853,7 @@ message ShardReplica {
string dm_channel_name = 3;
// optional, DO NOT save it in meta, set it only for GetReplicas()
// if with_shard_nodes is true
repeated int64 node_ids = 4;
repeated int64 node_ids = 4;
}
@ -856,3 +862,36 @@ service ProxyService {
rpc RegisterLink(RegisterLinkRequest) returns (RegisterLinkResponse) {}
}
// https://wiki.lfaidata.foundation/display/MIL/MEP+27+--+Support+Basic+Authentication
message CreateCredentialRequest {
// Not useful for now
common.MsgBase base = 1;
// username
string username = 2;
// ciphertext password
string password = 3;
// create time
uint64 created_utc_timestamps = 4;
// modify time
uint64 modified_utc_timestamps = 5;
}
message DeleteCredentialRequest {
// Not useful for now
common.MsgBase base = 1;
// Not useful for now
string username = 2;
}
message ListCredUsersResponse {
// Contain error_code and reason
common.Status status = 1;
// username array
repeated string usernames = 2;
}
message ListCredUsersRequest {
// Not useful for now
common.MsgBase base = 1;
}

View File

@ -5429,6 +5429,220 @@ func (m *ShardReplica) GetNodeIds() []int64 {
return nil
}
type CreateCredentialRequest struct {
// Not useful for now
Base *commonpb.MsgBase `protobuf:"bytes,1,opt,name=base,proto3" json:"base,omitempty"`
// username
Username string `protobuf:"bytes,2,opt,name=username,proto3" json:"username,omitempty"`
// ciphertext password
Password string `protobuf:"bytes,3,opt,name=password,proto3" json:"password,omitempty"`
// create time
CreatedUtcTimestamps uint64 `protobuf:"varint,4,opt,name=created_utc_timestamps,json=createdUtcTimestamps,proto3" json:"created_utc_timestamps,omitempty"`
// modify time
ModifiedUtcTimestamps uint64 `protobuf:"varint,5,opt,name=modified_utc_timestamps,json=modifiedUtcTimestamps,proto3" json:"modified_utc_timestamps,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *CreateCredentialRequest) Reset() { *m = CreateCredentialRequest{} }
func (m *CreateCredentialRequest) String() string { return proto.CompactTextString(m) }
func (*CreateCredentialRequest) ProtoMessage() {}
func (*CreateCredentialRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_02345ba45cc0e303, []int{84}
}
func (m *CreateCredentialRequest) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_CreateCredentialRequest.Unmarshal(m, b)
}
func (m *CreateCredentialRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_CreateCredentialRequest.Marshal(b, m, deterministic)
}
func (m *CreateCredentialRequest) XXX_Merge(src proto.Message) {
xxx_messageInfo_CreateCredentialRequest.Merge(m, src)
}
func (m *CreateCredentialRequest) XXX_Size() int {
return xxx_messageInfo_CreateCredentialRequest.Size(m)
}
func (m *CreateCredentialRequest) XXX_DiscardUnknown() {
xxx_messageInfo_CreateCredentialRequest.DiscardUnknown(m)
}
var xxx_messageInfo_CreateCredentialRequest proto.InternalMessageInfo
func (m *CreateCredentialRequest) GetBase() *commonpb.MsgBase {
if m != nil {
return m.Base
}
return nil
}
func (m *CreateCredentialRequest) GetUsername() string {
if m != nil {
return m.Username
}
return ""
}
func (m *CreateCredentialRequest) GetPassword() string {
if m != nil {
return m.Password
}
return ""
}
func (m *CreateCredentialRequest) GetCreatedUtcTimestamps() uint64 {
if m != nil {
return m.CreatedUtcTimestamps
}
return 0
}
func (m *CreateCredentialRequest) GetModifiedUtcTimestamps() uint64 {
if m != nil {
return m.ModifiedUtcTimestamps
}
return 0
}
type DeleteCredentialRequest struct {
// Not useful for now
Base *commonpb.MsgBase `protobuf:"bytes,1,opt,name=base,proto3" json:"base,omitempty"`
// Not useful for now
Username string `protobuf:"bytes,2,opt,name=username,proto3" json:"username,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *DeleteCredentialRequest) Reset() { *m = DeleteCredentialRequest{} }
func (m *DeleteCredentialRequest) String() string { return proto.CompactTextString(m) }
func (*DeleteCredentialRequest) ProtoMessage() {}
func (*DeleteCredentialRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_02345ba45cc0e303, []int{85}
}
func (m *DeleteCredentialRequest) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_DeleteCredentialRequest.Unmarshal(m, b)
}
func (m *DeleteCredentialRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_DeleteCredentialRequest.Marshal(b, m, deterministic)
}
func (m *DeleteCredentialRequest) XXX_Merge(src proto.Message) {
xxx_messageInfo_DeleteCredentialRequest.Merge(m, src)
}
func (m *DeleteCredentialRequest) XXX_Size() int {
return xxx_messageInfo_DeleteCredentialRequest.Size(m)
}
func (m *DeleteCredentialRequest) XXX_DiscardUnknown() {
xxx_messageInfo_DeleteCredentialRequest.DiscardUnknown(m)
}
var xxx_messageInfo_DeleteCredentialRequest proto.InternalMessageInfo
func (m *DeleteCredentialRequest) GetBase() *commonpb.MsgBase {
if m != nil {
return m.Base
}
return nil
}
func (m *DeleteCredentialRequest) GetUsername() string {
if m != nil {
return m.Username
}
return ""
}
type ListCredUsersResponse struct {
// Contain error_code and reason
Status *commonpb.Status `protobuf:"bytes,1,opt,name=status,proto3" json:"status,omitempty"`
// username array
Usernames []string `protobuf:"bytes,2,rep,name=usernames,proto3" json:"usernames,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *ListCredUsersResponse) Reset() { *m = ListCredUsersResponse{} }
func (m *ListCredUsersResponse) String() string { return proto.CompactTextString(m) }
func (*ListCredUsersResponse) ProtoMessage() {}
func (*ListCredUsersResponse) Descriptor() ([]byte, []int) {
return fileDescriptor_02345ba45cc0e303, []int{86}
}
func (m *ListCredUsersResponse) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_ListCredUsersResponse.Unmarshal(m, b)
}
func (m *ListCredUsersResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_ListCredUsersResponse.Marshal(b, m, deterministic)
}
func (m *ListCredUsersResponse) XXX_Merge(src proto.Message) {
xxx_messageInfo_ListCredUsersResponse.Merge(m, src)
}
func (m *ListCredUsersResponse) XXX_Size() int {
return xxx_messageInfo_ListCredUsersResponse.Size(m)
}
func (m *ListCredUsersResponse) XXX_DiscardUnknown() {
xxx_messageInfo_ListCredUsersResponse.DiscardUnknown(m)
}
var xxx_messageInfo_ListCredUsersResponse proto.InternalMessageInfo
func (m *ListCredUsersResponse) GetStatus() *commonpb.Status {
if m != nil {
return m.Status
}
return nil
}
func (m *ListCredUsersResponse) GetUsernames() []string {
if m != nil {
return m.Usernames
}
return nil
}
type ListCredUsersRequest struct {
// Not useful for now
Base *commonpb.MsgBase `protobuf:"bytes,1,opt,name=base,proto3" json:"base,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *ListCredUsersRequest) Reset() { *m = ListCredUsersRequest{} }
func (m *ListCredUsersRequest) String() string { return proto.CompactTextString(m) }
func (*ListCredUsersRequest) ProtoMessage() {}
func (*ListCredUsersRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_02345ba45cc0e303, []int{87}
}
func (m *ListCredUsersRequest) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_ListCredUsersRequest.Unmarshal(m, b)
}
func (m *ListCredUsersRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_ListCredUsersRequest.Marshal(b, m, deterministic)
}
func (m *ListCredUsersRequest) XXX_Merge(src proto.Message) {
xxx_messageInfo_ListCredUsersRequest.Merge(m, src)
}
func (m *ListCredUsersRequest) XXX_Size() int {
return xxx_messageInfo_ListCredUsersRequest.Size(m)
}
func (m *ListCredUsersRequest) XXX_DiscardUnknown() {
xxx_messageInfo_ListCredUsersRequest.DiscardUnknown(m)
}
var xxx_messageInfo_ListCredUsersRequest proto.InternalMessageInfo
func (m *ListCredUsersRequest) GetBase() *commonpb.MsgBase {
if m != nil {
return m.Base
}
return nil
}
func init() {
proto.RegisterEnum("milvus.proto.milvus.ShowType", ShowType_name, ShowType_value)
proto.RegisterEnum("milvus.proto.milvus.PlaceholderType", PlaceholderType_name, PlaceholderType_value)
@ -5517,265 +5731,278 @@ func init() {
proto.RegisterType((*GetReplicasResponse)(nil), "milvus.proto.milvus.GetReplicasResponse")
proto.RegisterType((*ReplicaInfo)(nil), "milvus.proto.milvus.ReplicaInfo")
proto.RegisterType((*ShardReplica)(nil), "milvus.proto.milvus.ShardReplica")
proto.RegisterType((*CreateCredentialRequest)(nil), "milvus.proto.milvus.CreateCredentialRequest")
proto.RegisterType((*DeleteCredentialRequest)(nil), "milvus.proto.milvus.DeleteCredentialRequest")
proto.RegisterType((*ListCredUsersResponse)(nil), "milvus.proto.milvus.ListCredUsersResponse")
proto.RegisterType((*ListCredUsersRequest)(nil), "milvus.proto.milvus.ListCredUsersRequest")
}
func init() { proto.RegisterFile("milvus.proto", fileDescriptor_02345ba45cc0e303) }
var fileDescriptor_02345ba45cc0e303 = []byte{
// 4041 bytes of a gzipped FileDescriptorProto
// 4187 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xd4, 0x3c, 0x4d, 0x6f, 0x1c, 0xc9,
0x75, 0xec, 0x19, 0xce, 0xd7, 0x9b, 0x19, 0x72, 0x54, 0xa4, 0xa8, 0xd9, 0xd1, 0x6a, 0x97, 0xea,
0xfd, 0xe2, 0x4a, 0x5e, 0xc9, 0x4b, 0xad, 0x77, 0x9d, 0x5d, 0x27, 0x6b, 0x49, 0xcc, 0x4a, 0xc4,
0x4a, 0x0a, 0xdd, 0x5c, 0xdb, 0x70, 0x16, 0x42, 0xa3, 0xd8, 0x5d, 0x1c, 0x36, 0xd4, 0xd3, 0x3d,
0xee, 0xaa, 0x11, 0xc5, 0x3d, 0x19, 0x70, 0x90, 0x0f, 0x78, 0xb3, 0x46, 0x10, 0x23, 0x1f, 0x87,
0x04, 0x41, 0x3e, 0x0e, 0x41, 0x90, 0x20, 0xb6, 0x83, 0x24, 0xc8, 0x25, 0x39, 0xe4, 0x90, 0x43,
0x80, 0x7c, 0x5c, 0x82, 0x20, 0x97, 0xfc, 0x81, 0xdc, 0x72, 0xcc, 0x21, 0xa8, 0x8f, 0xee, 0xe9,
0xee, 0xa9, 0x1e, 0x0e, 0x77, 0x2c, 0x93, 0xba, 0x4d, 0xbf, 0x7a, 0xaf, 0xea, 0xd5, 0xab, 0x57,
0xaf, 0x5e, 0xbd, 0xf7, 0x6a, 0xa0, 0x35, 0xf0, 0xfc, 0xc7, 0x23, 0x7a, 0x6d, 0x18, 0x85, 0x2c,
0x44, 0x2b, 0xe9, 0xaf, 0x6b, 0xf2, 0xa3, 0xd7, 0x72, 0xc2, 0xc1, 0x20, 0x0c, 0x24, 0xb0, 0xd7,
0xa2, 0xce, 0x01, 0x19, 0x60, 0xf9, 0x65, 0xfe, 0xbe, 0x01, 0xe8, 0x76, 0x44, 0x30, 0x23, 0x37,
0x7d, 0x0f, 0x53, 0x8b, 0x7c, 0x7b, 0x44, 0x28, 0x43, 0x5f, 0x84, 0xc5, 0x3d, 0x4c, 0x49, 0xd7,
0x58, 0x37, 0x36, 0x9a, 0x9b, 0xcf, 0x5f, 0xcb, 0x74, 0xab, 0xba, 0xbb, 0x4f, 0xfb, 0xb7, 0x30,
0x25, 0x96, 0xc0, 0x44, 0x17, 0xa0, 0xe6, 0xee, 0xd9, 0x01, 0x1e, 0x90, 0x6e, 0x69, 0xdd, 0xd8,
0x68, 0x58, 0x55, 0x77, 0xef, 0x01, 0x1e, 0x10, 0xf4, 0x1a, 0x2c, 0x3b, 0xa1, 0xef, 0x13, 0x87,
0x79, 0x61, 0x20, 0x11, 0xca, 0x02, 0x61, 0x69, 0x0c, 0x16, 0x88, 0xab, 0x50, 0xc1, 0x9c, 0x87,
0xee, 0xa2, 0x68, 0x96, 0x1f, 0x26, 0x85, 0xce, 0x56, 0x14, 0x0e, 0x9f, 0x16, 0x77, 0xc9, 0xa0,
0xe5, 0xf4, 0xa0, 0xbf, 0x67, 0xc0, 0xb9, 0x9b, 0x3e, 0x23, 0xd1, 0x19, 0x15, 0xca, 0xef, 0x94,
0xe0, 0x82, 0x5c, 0xb5, 0xdb, 0x09, 0xfa, 0x69, 0x72, 0xb9, 0x06, 0x55, 0xa9, 0x55, 0x82, 0xcd,
0x96, 0xa5, 0xbe, 0xd0, 0x25, 0x00, 0x7a, 0x80, 0x23, 0x97, 0xda, 0xc1, 0x68, 0xd0, 0xad, 0xac,
0x1b, 0x1b, 0x15, 0xab, 0x21, 0x21, 0x0f, 0x46, 0x03, 0x64, 0xc1, 0x39, 0x27, 0x0c, 0xa8, 0x47,
0x19, 0x09, 0x9c, 0x23, 0xdb, 0x27, 0x8f, 0x89, 0xdf, 0xad, 0xae, 0x1b, 0x1b, 0x4b, 0x9b, 0xaf,
0x68, 0xf9, 0xbe, 0x3d, 0xc6, 0xbe, 0xc7, 0x91, 0xad, 0x8e, 0x93, 0x83, 0x98, 0xdf, 0x33, 0xe0,
0x3c, 0x57, 0x98, 0x33, 0x21, 0x18, 0xf3, 0x4f, 0x0d, 0x58, 0xbd, 0x8b, 0xe9, 0xd9, 0x58, 0xa5,
0x4b, 0x00, 0xcc, 0x1b, 0x10, 0x9b, 0x32, 0x3c, 0x18, 0x8a, 0x95, 0x5a, 0xb4, 0x1a, 0x1c, 0xb2,
0xcb, 0x01, 0xe6, 0xb7, 0xa0, 0x75, 0x2b, 0x0c, 0x7d, 0x8b, 0xd0, 0x61, 0x18, 0x50, 0x82, 0x6e,
0x40, 0x95, 0x32, 0xcc, 0x46, 0x54, 0x31, 0x79, 0x51, 0xcb, 0xe4, 0xae, 0x40, 0xb1, 0x14, 0x2a,
0xd7, 0xd7, 0xc7, 0xd8, 0x1f, 0x49, 0x1e, 0xeb, 0x96, 0xfc, 0x30, 0x3f, 0x86, 0xa5, 0x5d, 0x16,
0x79, 0x41, 0xff, 0x27, 0xd8, 0x79, 0x23, 0xee, 0xfc, 0xdf, 0x0d, 0x78, 0x6e, 0x8b, 0x50, 0x27,
0xf2, 0xf6, 0xce, 0xc8, 0x76, 0x30, 0xa1, 0x35, 0x86, 0x6c, 0x6f, 0x09, 0x51, 0x97, 0xad, 0x0c,
0x2c, 0xb7, 0x18, 0x95, 0xfc, 0x62, 0x7c, 0xa7, 0x02, 0x3d, 0xdd, 0xa4, 0xe6, 0x11, 0xdf, 0xcf,
0x26, 0xbb, 0xb4, 0x24, 0x88, 0x72, 0x7b, 0x4c, 0x9d, 0x0b, 0xe3, 0xd1, 0x76, 0x05, 0x20, 0xd9,
0xcc, 0xf9, 0x59, 0x95, 0x35, 0xb3, 0xda, 0x84, 0xf3, 0x8f, 0xbd, 0x88, 0x8d, 0xb0, 0x6f, 0x3b,
0x07, 0x38, 0x08, 0x88, 0x2f, 0xe4, 0xc4, 0xcd, 0x57, 0x79, 0xa3, 0x61, 0xad, 0xa8, 0xc6, 0xdb,
0xb2, 0x8d, 0x0b, 0x8b, 0xa2, 0xb7, 0x60, 0x6d, 0x78, 0x70, 0x44, 0x3d, 0x67, 0x82, 0xa8, 0x22,
0x88, 0x56, 0xe3, 0xd6, 0x0c, 0xd5, 0x55, 0x38, 0xe7, 0x08, 0x0b, 0xe8, 0xda, 0x5c, 0x6a, 0x52,
0x8c, 0x55, 0x21, 0xc6, 0x8e, 0x6a, 0xf8, 0x28, 0x86, 0x73, 0xb6, 0x62, 0xe4, 0x11, 0x73, 0x52,
0x04, 0x35, 0x41, 0xb0, 0xa2, 0x1a, 0xbf, 0xce, 0x9c, 0x31, 0x4d, 0xd6, 0x76, 0xd5, 0xf3, 0xb6,
0xab, 0x0b, 0x35, 0x61, 0x8b, 0x09, 0xed, 0x36, 0x04, 0x9b, 0xf1, 0x27, 0xda, 0x86, 0x65, 0xca,
0x70, 0xc4, 0xec, 0x61, 0x48, 0x3d, 0x2e, 0x17, 0xda, 0x85, 0xf5, 0xf2, 0x46, 0x73, 0x73, 0x5d,
0xbb, 0x48, 0x1f, 0x92, 0xa3, 0x2d, 0xcc, 0xf0, 0x0e, 0xf6, 0x22, 0x6b, 0x49, 0x10, 0xee, 0xc4,
0x74, 0x7a, 0x03, 0xd9, 0x9c, 0xcb, 0x40, 0xea, 0xb4, 0xb8, 0xa5, 0xb5, 0x5d, 0x3f, 0x32, 0xe0,
0xfc, 0xbd, 0x10, 0xbb, 0x67, 0x63, 0x4f, 0xbd, 0x02, 0x4b, 0x11, 0x19, 0xfa, 0x9e, 0x83, 0xf9,
0x7a, 0xec, 0x91, 0x48, 0xec, 0xaa, 0x8a, 0xd5, 0x56, 0xd0, 0x07, 0x02, 0x68, 0x7e, 0x66, 0x40,
0xd7, 0x22, 0x3e, 0xc1, 0xf4, 0x6c, 0xd8, 0x02, 0xf3, 0x07, 0x06, 0xbc, 0x70, 0x87, 0xb0, 0xd4,
0xae, 0x62, 0x98, 0x79, 0x94, 0x79, 0xce, 0x69, 0xfa, 0x15, 0xe6, 0xf7, 0x0d, 0x78, 0xb1, 0x90,
0xad, 0x79, 0x8c, 0xcc, 0x3b, 0x50, 0xe1, 0xbf, 0x68, 0xb7, 0x24, 0x74, 0xfe, 0x72, 0x91, 0xce,
0x7f, 0x83, 0xdb, 0x6e, 0xa1, 0xf4, 0x12, 0xdf, 0xfc, 0x6f, 0x03, 0xd6, 0x76, 0x0f, 0xc2, 0xc3,
0x31, 0x4b, 0x4f, 0x43, 0x40, 0x59, 0xb3, 0x5b, 0xce, 0x99, 0x5d, 0xf4, 0x26, 0x2c, 0xb2, 0xa3,
0x21, 0x11, 0xba, 0xb5, 0xb4, 0x79, 0xe9, 0x9a, 0xc6, 0x9d, 0xbe, 0xc6, 0x99, 0xfc, 0xe8, 0x68,
0x48, 0x2c, 0x81, 0x8a, 0x5e, 0x87, 0x4e, 0x4e, 0xe4, 0xb1, 0xe1, 0x5a, 0xce, 0xca, 0x9c, 0x9a,
0x7f, 0x5b, 0x82, 0x0b, 0x13, 0x53, 0x9c, 0x47, 0xd8, 0xba, 0xb1, 0x4b, 0xda, 0xb1, 0xf9, 0xfe,
0x49, 0xa1, 0x7a, 0x2e, 0xf7, 0x78, 0xcb, 0x1b, 0x65, 0xab, 0x9d, 0xb2, 0xdf, 0x2e, 0x45, 0x6f,
0x00, 0x9a, 0x30, 0xab, 0xd2, 0x7a, 0x2f, 0x5a, 0xe7, 0xf2, 0x76, 0x55, 0xd8, 0x6e, 0xad, 0x61,
0x95, 0x22, 0x58, 0xb4, 0x56, 0x35, 0x96, 0x95, 0xa2, 0x37, 0x61, 0xd5, 0x0b, 0xee, 0x93, 0x41,
0x18, 0x1d, 0xd9, 0x43, 0x12, 0x39, 0x24, 0x60, 0xb8, 0x4f, 0x68, 0xb7, 0x2a, 0x38, 0x5a, 0x89,
0xdb, 0x76, 0xc6, 0x4d, 0xe6, 0x8f, 0x0d, 0x58, 0x93, 0x1e, 0xef, 0x0e, 0x8e, 0x98, 0x77, 0x06,
0xac, 0xd1, 0x30, 0xe6, 0x43, 0xe2, 0x49, 0xff, 0xbc, 0x9d, 0x40, 0xc5, 0x2e, 0xfb, 0xa1, 0x01,
0xab, 0xdc, 0x19, 0x7d, 0x96, 0x78, 0xfe, 0x4b, 0x03, 0x56, 0xee, 0x62, 0xfa, 0x2c, 0xb1, 0xfc,
0x57, 0xea, 0xa4, 0x4a, 0x78, 0x3e, 0xd5, 0x2b, 0xdb, 0x6b, 0xb0, 0x9c, 0x65, 0x3a, 0xf6, 0x7e,
0x96, 0x32, 0x5c, 0x53, 0xf3, 0x6f, 0xc6, 0x67, 0xd5, 0x33, 0xc6, 0xf9, 0xdf, 0x19, 0x70, 0xe9,
0x0e, 0x61, 0x09, 0xd7, 0x67, 0xe2, 0x4c, 0x9b, 0x55, 0x5b, 0x3e, 0x93, 0x27, 0xb2, 0x96, 0xf9,
0x53, 0x39, 0xf9, 0xbe, 0x57, 0x82, 0xf3, 0xfc, 0x58, 0x38, 0x1b, 0x4a, 0x30, 0xcb, 0xe5, 0x45,
0xa3, 0x28, 0x15, 0x9d, 0xa2, 0x24, 0xe7, 0x69, 0x75, 0xe6, 0xf3, 0xd4, 0xfc, 0x51, 0x49, 0xfa,
0x01, 0x69, 0x69, 0xcc, 0xb3, 0x2c, 0x1a, 0x5e, 0x4b, 0x5a, 0x5e, 0x4d, 0x68, 0x25, 0x90, 0xed,
0xad, 0xf8, 0x7c, 0xcc, 0xc0, 0xce, 0xec, 0xf1, 0xf8, 0xa9, 0x01, 0x6b, 0xf1, 0x75, 0x71, 0x97,
0xf4, 0x07, 0x24, 0x60, 0x9f, 0x5f, 0x87, 0xf2, 0x1a, 0x50, 0xd2, 0x68, 0xc0, 0xf3, 0xd0, 0xa0,
0x72, 0x9c, 0xe4, 0x26, 0x38, 0x06, 0x98, 0x7f, 0x6f, 0xc0, 0x85, 0x09, 0x76, 0xe6, 0x59, 0xc4,
0x2e, 0xd4, 0xbc, 0xc0, 0x25, 0x4f, 0x12, 0x6e, 0xe2, 0x4f, 0xde, 0xb2, 0x37, 0xf2, 0x7c, 0x37,
0x61, 0x23, 0xfe, 0x44, 0x97, 0xa1, 0x45, 0x02, 0xbc, 0xe7, 0x13, 0x5b, 0xe0, 0x0a, 0x45, 0xae,
0x5b, 0x4d, 0x09, 0xdb, 0xe6, 0x20, 0x4e, 0xbc, 0xef, 0x11, 0x41, 0x5c, 0x91, 0xc4, 0xea, 0xd3,
0xfc, 0x75, 0x03, 0x56, 0xb8, 0x16, 0x2a, 0xee, 0xe9, 0xd3, 0x95, 0xe6, 0x3a, 0x34, 0x53, 0x6a,
0xa6, 0x26, 0x92, 0x06, 0x99, 0x8f, 0x60, 0x35, 0xcb, 0xce, 0x3c, 0xd2, 0x7c, 0x01, 0x20, 0x59,
0x2b, 0xb9, 0x1b, 0xca, 0x56, 0x0a, 0x62, 0x7e, 0x5a, 0x8a, 0x83, 0xc2, 0x42, 0x4c, 0xa7, 0x1c,
0xb3, 0x12, 0x4b, 0x92, 0xb6, 0xe7, 0x0d, 0x01, 0x11, 0xcd, 0x5b, 0xd0, 0x22, 0x4f, 0x58, 0x84,
0xed, 0x21, 0x8e, 0xf0, 0x40, 0x6e, 0xab, 0x99, 0x4c, 0x6f, 0x53, 0x90, 0xed, 0x08, 0x2a, 0x3e,
0x88, 0x50, 0x11, 0x39, 0x48, 0x55, 0x0e, 0x22, 0x20, 0xe2, 0xc0, 0xf8, 0x27, 0xee, 0xc5, 0x29,
0x6d, 0x3e, 0xeb, 0x02, 0xc9, 0x4e, 0xa5, 0x92, 0x9f, 0xca, 0x9f, 0x18, 0xd0, 0x11, 0x53, 0x90,
0xf3, 0x19, 0xf2, 0x6e, 0x73, 0x34, 0x46, 0x8e, 0x66, 0xca, 0xde, 0xfb, 0x19, 0xa8, 0x2a, 0xb9,
0x97, 0x67, 0x95, 0xbb, 0x22, 0x38, 0x66, 0x1a, 0xe6, 0x1f, 0x1a, 0x70, 0x3e, 0x27, 0xf2, 0x79,
0x14, 0xfe, 0x23, 0x40, 0x72, 0x86, 0xee, 0x78, 0xda, 0xf1, 0x39, 0xfd, 0x8a, 0xf6, 0x50, 0xca,
0x0b, 0xc9, 0x3a, 0xe7, 0xe5, 0x20, 0xd4, 0xfc, 0x57, 0x03, 0x9e, 0xbf, 0x43, 0x98, 0x40, 0xbd,
0xc5, 0x8d, 0xce, 0x4e, 0x14, 0xf6, 0x23, 0x42, 0xe9, 0xb3, 0xab, 0x1f, 0xbf, 0x25, 0x1d, 0x3b,
0xdd, 0x94, 0xe6, 0x91, 0xff, 0x65, 0x68, 0x89, 0x31, 0x88, 0x6b, 0x47, 0xe1, 0x21, 0x55, 0x7a,
0xd4, 0x54, 0x30, 0x2b, 0x3c, 0x14, 0x0a, 0xc1, 0x42, 0x86, 0x7d, 0x89, 0xa0, 0x4e, 0x14, 0x01,
0xe1, 0xcd, 0x62, 0x0f, 0xc6, 0x8c, 0xf1, 0xce, 0xc9, 0xb3, 0x2b, 0xe3, 0x3f, 0x36, 0xe0, 0x7c,
0x6e, 0x2a, 0xf3, 0xc8, 0xf6, 0x4b, 0xd2, 0xed, 0x94, 0x93, 0x59, 0xda, 0x7c, 0x51, 0x4b, 0x93,
0x1a, 0x4c, 0x62, 0xa3, 0x17, 0xa1, 0xb9, 0x8f, 0x3d, 0xdf, 0x8e, 0x08, 0xa6, 0x61, 0xa0, 0x26,
0x0a, 0x1c, 0x64, 0x09, 0x88, 0xf9, 0x8f, 0x86, 0xcc, 0xbc, 0x3d, 0xe3, 0x16, 0xef, 0x8f, 0x4a,
0xd0, 0xde, 0x0e, 0x28, 0x89, 0xd8, 0xd9, 0xbf, 0x9a, 0xa0, 0xf7, 0xa1, 0x29, 0x26, 0x46, 0x6d,
0x17, 0x33, 0xac, 0x4e, 0xb3, 0x17, 0xb4, 0x61, 0xfa, 0x0f, 0x38, 0xde, 0x16, 0x66, 0xd8, 0x92,
0xd2, 0xa1, 0xfc, 0x37, 0xba, 0x08, 0x8d, 0x03, 0x4c, 0x0f, 0xec, 0x47, 0xe4, 0x48, 0xfa, 0x8b,
0x6d, 0xab, 0xce, 0x01, 0x1f, 0x92, 0x23, 0x8a, 0x9e, 0x83, 0x7a, 0x30, 0x1a, 0xc8, 0x0d, 0x56,
0x5b, 0x37, 0x36, 0xda, 0x56, 0x2d, 0x18, 0x0d, 0xc4, 0xf6, 0xfa, 0xe7, 0x12, 0x2c, 0xdd, 0x1f,
0xf1, 0x8b, 0x90, 0x48, 0x32, 0x8c, 0x7c, 0xf6, 0xf9, 0x94, 0xf1, 0x0a, 0x94, 0xa5, 0x4b, 0xc1,
0x29, 0xba, 0x5a, 0xc6, 0xb7, 0xb7, 0xa8, 0xc5, 0x91, 0x44, 0x80, 0x7d, 0xe4, 0x38, 0xca, 0x3b,
0x2b, 0x0b, 0x66, 0x1b, 0x1c, 0x22, 0x7d, 0xb3, 0x8b, 0xd0, 0x20, 0x51, 0x94, 0xf8, 0x6e, 0x62,
0x2a, 0x24, 0x8a, 0x64, 0xa3, 0x09, 0x2d, 0xec, 0x3c, 0x0a, 0xc2, 0x43, 0x9f, 0xb8, 0x7d, 0xe2,
0x8a, 0x65, 0xaf, 0x5b, 0x19, 0x98, 0x54, 0x0c, 0xbe, 0xf0, 0xb6, 0x13, 0x30, 0x71, 0xaa, 0x97,
0xb9, 0x62, 0x70, 0xc8, 0xed, 0x80, 0xf1, 0x66, 0x97, 0xf8, 0x84, 0x11, 0xd1, 0x5c, 0x93, 0xcd,
0x12, 0xa2, 0x9a, 0x47, 0xc3, 0x84, 0xba, 0x2e, 0x9b, 0x25, 0x84, 0x37, 0x3f, 0x0f, 0x8d, 0x71,
0x16, 0xa1, 0x31, 0x0e, 0x23, 0x0a, 0x80, 0xf9, 0x5f, 0x06, 0xb4, 0xb7, 0x44, 0x57, 0xcf, 0x80,
0xd2, 0x21, 0x58, 0x24, 0x4f, 0x86, 0x91, 0xda, 0x3a, 0xe2, 0xf7, 0x54, 0x3d, 0x32, 0x1f, 0x43,
0x67, 0xc7, 0xc7, 0x0e, 0x39, 0x08, 0x7d, 0x97, 0x44, 0xe2, 0x6c, 0x47, 0x1d, 0x28, 0x33, 0xdc,
0x57, 0xce, 0x03, 0xff, 0x89, 0xbe, 0xac, 0xae, 0x7e, 0xd2, 0x2c, 0xbd, 0xac, 0x3d, 0x65, 0x53,
0xdd, 0xa4, 0x22, 0xaa, 0x6b, 0x50, 0x15, 0x99, 0x3d, 0xe9, 0x56, 0xb4, 0x2c, 0xf5, 0x65, 0x3e,
0xcc, 0x8c, 0x7b, 0x27, 0x0a, 0x47, 0x43, 0xb4, 0x0d, 0xad, 0xe1, 0x18, 0xc6, 0x75, 0xb5, 0xf8,
0x4c, 0xcf, 0x33, 0x6d, 0x65, 0x48, 0xcd, 0xff, 0x29, 0x43, 0x7b, 0x97, 0xe0, 0xc8, 0x39, 0x78,
0x16, 0x62, 0x30, 0x5c, 0xe2, 0x2e, 0xf5, 0xd5, 0xaa, 0xf1, 0x9f, 0xe8, 0x2a, 0x9c, 0x4b, 0x4d,
0xc8, 0xee, 0x73, 0x01, 0x09, 0xbd, 0x6f, 0x59, 0x9d, 0x61, 0x5e, 0x70, 0xef, 0x40, 0xdd, 0xa5,
0xbe, 0x2d, 0x96, 0xa8, 0x26, 0x96, 0x48, 0x3f, 0xbf, 0x2d, 0xea, 0x8b, 0xa5, 0xa9, 0xb9, 0xf2,
0x07, 0x7a, 0x09, 0xda, 0xe1, 0x88, 0x0d, 0x47, 0xcc, 0x96, 0x76, 0xa7, 0x5b, 0x17, 0xec, 0xb5,
0x24, 0x50, 0x98, 0x25, 0x8a, 0x3e, 0x80, 0x36, 0x15, 0xa2, 0x8c, 0x1d, 0xf3, 0xc6, 0xac, 0x0e,
0x62, 0x4b, 0xd2, 0x29, 0xcf, 0xfc, 0x75, 0xe8, 0xb0, 0x08, 0x3f, 0x26, 0x7e, 0x2a, 0x67, 0x07,
0x62, 0xb7, 0x2d, 0x4b, 0xf8, 0x38, 0x5f, 0x77, 0x1d, 0x56, 0xfa, 0x23, 0x1c, 0xe1, 0x80, 0x11,
0x92, 0xc2, 0x6e, 0x0a, 0x6c, 0x94, 0x34, 0x25, 0x04, 0xe6, 0x87, 0xb0, 0x78, 0xd7, 0x63, 0x42,
0x90, 0xdc, 0x66, 0x19, 0xe2, 0x1a, 0x24, 0x2c, 0xd3, 0x73, 0x50, 0x8f, 0xc2, 0x43, 0x69, 0x83,
0x4b, 0x42, 0x05, 0x6b, 0x51, 0x78, 0x28, 0x0c, 0xac, 0xa8, 0x74, 0x08, 0x23, 0xa5, 0x9b, 0x25,
0x4b, 0x7d, 0x99, 0x7f, 0x61, 0x8c, 0x95, 0x87, 0x9b, 0x4f, 0xfa, 0xf9, 0xec, 0xe7, 0xfb, 0x50,
0x8b, 0x24, 0xfd, 0xd4, 0x1c, 0x6d, 0x7a, 0x24, 0x71, 0x06, 0xc4, 0x54, 0xb3, 0x27, 0x80, 0x7e,
0xc9, 0x80, 0xd6, 0x07, 0xfe, 0x88, 0x3e, 0x0d, 0x65, 0xd7, 0xa5, 0x25, 0xca, 0xfa, 0x94, 0xc8,
0x6f, 0x94, 0xa0, 0xad, 0xd8, 0x98, 0xc7, 0x09, 0x2a, 0x64, 0x65, 0x17, 0x9a, 0x7c, 0x48, 0x9b,
0x92, 0x7e, 0x1c, 0xd3, 0x69, 0x6e, 0x6e, 0x6a, 0xcd, 0x43, 0x86, 0x0d, 0x91, 0x06, 0xdf, 0x15,
0x44, 0x3f, 0x1f, 0xb0, 0xe8, 0xc8, 0x02, 0x27, 0x01, 0xf4, 0x1e, 0xc2, 0x72, 0xae, 0x99, 0x2b,
0xd1, 0x23, 0x72, 0x14, 0xdb, 0xbf, 0x47, 0xe4, 0x08, 0xbd, 0x95, 0x2e, 0x56, 0x28, 0x3a, 0xc5,
0xef, 0x85, 0x41, 0xff, 0x66, 0x14, 0xe1, 0x23, 0x55, 0xcc, 0xf0, 0x6e, 0xe9, 0xcb, 0x86, 0xf9,
0x0f, 0x25, 0x68, 0x7d, 0x6d, 0x44, 0xa2, 0xa3, 0xd3, 0xb4, 0x43, 0xf1, 0xa9, 0xb0, 0x98, 0x3a,
0x15, 0x26, 0xb6, 0x7e, 0x45, 0xb3, 0xf5, 0x35, 0x06, 0xac, 0xaa, 0x35, 0x60, 0xba, 0xbd, 0x5d,
0x3b, 0xd1, 0xde, 0xae, 0x17, 0xee, 0xed, 0x3f, 0x37, 0x12, 0x11, 0xce, 0xb5, 0x1b, 0x33, 0xee,
0x58, 0xe9, 0xc4, 0xee, 0xd8, 0xcc, 0xbb, 0xf1, 0x87, 0x06, 0x34, 0xbe, 0x41, 0x1c, 0x16, 0x46,
0xdc, 0xfe, 0x68, 0xc8, 0x8c, 0x19, 0x5c, 0xe3, 0x52, 0xde, 0x35, 0xbe, 0x01, 0x75, 0xcf, 0xb5,
0x31, 0xd7, 0x2f, 0x31, 0xee, 0x34, 0x97, 0xac, 0xe6, 0xb9, 0x42, 0x11, 0x67, 0x4f, 0x02, 0xfc,
0xb6, 0x01, 0x2d, 0xc9, 0x33, 0x95, 0x94, 0xef, 0xa5, 0x86, 0x33, 0x74, 0x4a, 0xaf, 0x3e, 0x92,
0x89, 0xde, 0x5d, 0x18, 0x0f, 0x7b, 0x13, 0x80, 0x0b, 0x59, 0x91, 0xcb, 0x3d, 0xb3, 0xae, 0xe5,
0x56, 0x92, 0x0b, 0x81, 0xdf, 0x5d, 0xb0, 0x1a, 0x9c, 0x4a, 0x74, 0x71, 0xab, 0x06, 0x15, 0x41,
0x6d, 0xfe, 0x9f, 0x01, 0x2b, 0xb7, 0xb1, 0xef, 0x6c, 0x79, 0x94, 0xe1, 0xc0, 0x99, 0xc3, 0x09,
0x7b, 0x17, 0x6a, 0xe1, 0xd0, 0xf6, 0xc9, 0x3e, 0x53, 0x2c, 0x5d, 0x9e, 0x32, 0x23, 0x29, 0x06,
0xab, 0x1a, 0x0e, 0xef, 0x91, 0x7d, 0x86, 0xbe, 0x02, 0xf5, 0x70, 0x68, 0x47, 0x5e, 0xff, 0x80,
0x29, 0xe9, 0xcf, 0x40, 0x5c, 0x0b, 0x87, 0x16, 0xa7, 0x48, 0xc5, 0x56, 0x16, 0x4f, 0x18, 0x5b,
0x31, 0xff, 0x6d, 0x62, 0xfa, 0x73, 0xec, 0x81, 0x77, 0xa1, 0xee, 0x05, 0xcc, 0x76, 0x3d, 0x1a,
0x8b, 0xe0, 0x92, 0x5e, 0x87, 0x02, 0x26, 0x66, 0x20, 0xd6, 0x34, 0x60, 0x7c, 0x6c, 0xf4, 0x55,
0x80, 0x7d, 0x3f, 0xc4, 0x8a, 0x5a, 0xca, 0xe0, 0x45, 0xfd, 0xf6, 0xe1, 0x68, 0x31, 0x7d, 0x43,
0x10, 0xf1, 0x1e, 0xc6, 0x4b, 0xfa, 0x2f, 0x06, 0x9c, 0xdf, 0x21, 0x91, 0x2c, 0x65, 0x61, 0x2a,
0x0c, 0xba, 0x1d, 0xec, 0x87, 0xd9, 0x48, 0xb4, 0x91, 0x8b, 0x44, 0xff, 0x64, 0xa2, 0xaf, 0x99,
0x9b, 0x93, 0xcc, 0x87, 0xc4, 0x37, 0xa7, 0x38, 0xeb, 0x23, 0x6f, 0x9e, 0x4b, 0x05, 0xcb, 0xa4,
0xf8, 0x4d, 0x5f, 0xc0, 0xcd, 0xdf, 0x94, 0x15, 0x18, 0xda, 0x49, 0x7d, 0x7e, 0x85, 0x5d, 0x03,
0x65, 0xe9, 0x73, 0x76, 0xff, 0x55, 0xc8, 0xd9, 0x8e, 0x02, 0x43, 0xf4, 0xbb, 0x06, 0xac, 0x17,
0x73, 0x35, 0xcf, 0x11, 0xfd, 0x55, 0xa8, 0x78, 0xc1, 0x7e, 0x18, 0x87, 0xdd, 0xae, 0xe8, 0x5d,
0x74, 0xed, 0xb8, 0x92, 0xd0, 0xfc, 0xeb, 0x12, 0x74, 0x84, 0x51, 0x3f, 0x85, 0xe5, 0x1f, 0x90,
0x81, 0x4d, 0xbd, 0x4f, 0x48, 0xbc, 0xfc, 0x03, 0x32, 0xd8, 0xf5, 0x3e, 0x21, 0x19, 0xcd, 0xa8,
0x64, 0x35, 0x63, 0x7a, 0x54, 0x39, 0x1d, 0x56, 0xad, 0x65, 0xc3, 0xaa, 0x6b, 0x50, 0x0d, 0x42,
0x97, 0x6c, 0x6f, 0xa9, 0x6b, 0xa7, 0xfa, 0x1a, 0xab, 0x5a, 0xe3, 0x84, 0xaa, 0xf6, 0x99, 0x01,
0xbd, 0x3b, 0x84, 0xe5, 0x65, 0x77, 0x7a, 0x5a, 0xf6, 0x7d, 0x03, 0x2e, 0x6a, 0x19, 0x9a, 0x47,
0xc1, 0xde, 0xcb, 0x2a, 0x98, 0xfe, 0x0e, 0x38, 0x31, 0xa4, 0xd2, 0xad, 0x37, 0xa1, 0xb5, 0x35,
0x1a, 0x0c, 0x12, 0x97, 0xeb, 0x32, 0xb4, 0x22, 0xf9, 0x53, 0x5e, 0x91, 0xe4, 0xf9, 0xdb, 0x54,
0x30, 0x7e, 0x11, 0x32, 0xaf, 0x42, 0x5b, 0x91, 0x28, 0xae, 0x7b, 0x50, 0x8f, 0xd4, 0x6f, 0x85,
0x9f, 0x7c, 0x9b, 0xe7, 0x61, 0xc5, 0x22, 0x7d, 0xae, 0xda, 0xd1, 0x3d, 0x2f, 0x78, 0xa4, 0x86,
0x31, 0xbf, 0x6b, 0xc0, 0x6a, 0x16, 0xae, 0xfa, 0x7a, 0x1b, 0x6a, 0xd8, 0x75, 0x23, 0x42, 0xe9,
0xd4, 0x65, 0xb9, 0x29, 0x71, 0xac, 0x18, 0x39, 0x25, 0xb9, 0xd2, 0xcc, 0x92, 0x33, 0x6d, 0x38,
0x77, 0x87, 0xb0, 0xfb, 0x84, 0x45, 0x73, 0x65, 0xf0, 0xbb, 0xfc, 0xf2, 0x22, 0x88, 0x95, 0x5a,
0xc4, 0x9f, 0xe6, 0xa7, 0x06, 0xa0, 0xf4, 0x08, 0xf3, 0x2c, 0x73, 0x5a, 0xca, 0xa5, 0xac, 0x94,
0x65, 0x91, 0xd3, 0x60, 0x18, 0x06, 0x24, 0x60, 0x69, 0x77, 0xab, 0x9d, 0x40, 0x85, 0xfa, 0xfd,
0xd8, 0x00, 0x74, 0x2f, 0xc4, 0xee, 0x2d, 0xec, 0xcf, 0xe7, 0x1e, 0x5c, 0x02, 0xa0, 0x91, 0x63,
0xab, 0xdd, 0x5a, 0x52, 0xd6, 0x27, 0x72, 0x1e, 0xc8, 0x0d, 0xfb, 0x22, 0x34, 0x5d, 0xca, 0x54,
0x73, 0x9c, 0x50, 0x06, 0x97, 0x32, 0xd9, 0x2e, 0x8a, 0x58, 0x29, 0xc1, 0x3e, 0x71, 0xed, 0x54,
0x3e, 0x6e, 0x51, 0xa0, 0x75, 0x64, 0xc3, 0xee, 0x38, 0x2b, 0xf7, 0x10, 0x2e, 0xdc, 0xc7, 0xc1,
0x08, 0xfb, 0xb7, 0xc3, 0xc1, 0x10, 0x67, 0x0a, 0x1b, 0xf3, 0x66, 0xce, 0xd0, 0x98, 0xb9, 0x17,
0x64, 0xe5, 0x9b, 0x74, 0xad, 0x05, 0xaf, 0x8b, 0x56, 0x0a, 0x62, 0x52, 0xe8, 0x4e, 0x76, 0x3f,
0xcf, 0x42, 0x09, 0xa6, 0xe2, 0xae, 0xd2, 0xb6, 0x77, 0x0c, 0x33, 0xdf, 0x87, 0xe7, 0x44, 0x15,
0x62, 0x0c, 0xca, 0x84, 0xf6, 0xf3, 0x1d, 0x18, 0x9a, 0x0e, 0x7e, 0xa5, 0x24, 0x4c, 0xdb, 0x44,
0x0f, 0xf3, 0x30, 0xfe, 0x6e, 0x36, 0xa2, 0xfe, 0x72, 0x41, 0xa5, 0x6d, 0x76, 0x44, 0x15, 0x56,
0xdf, 0x80, 0x65, 0xf2, 0x84, 0x38, 0x23, 0xe6, 0x05, 0xfd, 0x1d, 0x1f, 0x07, 0x0f, 0x42, 0x75,
0xa0, 0xe4, 0xc1, 0xe8, 0x65, 0x68, 0x73, 0xe9, 0x87, 0x23, 0xa6, 0xf0, 0xe4, 0xc9, 0x92, 0x05,
0xf2, 0xfe, 0xf8, 0x7c, 0x7d, 0xc2, 0x88, 0xab, 0xf0, 0xe4, 0x31, 0x93, 0x07, 0x4f, 0x88, 0x92,
0x83, 0xe9, 0x49, 0x44, 0xf9, 0x1f, 0x46, 0x4e, 0x94, 0xaa, 0x87, 0xd3, 0x12, 0xe5, 0x5d, 0x80,
0x01, 0x89, 0xfa, 0x64, 0x5b, 0x18, 0x75, 0x79, 0x73, 0xdf, 0xd0, 0x1a, 0xf5, 0x71, 0x07, 0xf7,
0x63, 0x02, 0x2b, 0x45, 0x6b, 0xde, 0x81, 0x15, 0x0d, 0x0a, 0xb7, 0x57, 0x34, 0x1c, 0x45, 0x0e,
0x89, 0x83, 0x3f, 0xf1, 0x27, 0x3f, 0xdf, 0x18, 0x8e, 0xfa, 0x84, 0x29, 0xa5, 0x55, 0x5f, 0xe6,
0xdb, 0x22, 0x09, 0x25, 0x02, 0x05, 0x19, 0x4d, 0xcd, 0x26, 0xd4, 0x8d, 0x89, 0x84, 0xfa, 0xbe,
0xc8, 0xf8, 0xa4, 0xe9, 0xe6, 0x2c, 0x86, 0xd8, 0xe7, 0x5d, 0x11, 0x57, 0xbd, 0xb2, 0x88, 0x3f,
0xb9, 0x97, 0xdc, 0xde, 0x1e, 0x0c, 0xc3, 0x71, 0xb2, 0x63, 0xe6, 0xab, 0xe4, 0x64, 0xb0, 0xb8,
0xa4, 0x0b, 0x16, 0x5f, 0x84, 0x46, 0x14, 0x1e, 0xda, 0xdc, 0xfa, 0xb9, 0x42, 0xb3, 0xeb, 0x56,
0x3d, 0x0a, 0x0f, 0xb9, 0x4d, 0x74, 0xd1, 0x2a, 0x54, 0xf6, 0x3d, 0x3f, 0xb9, 0x30, 0xca, 0x0f,
0xf4, 0x1e, 0xbf, 0x43, 0xc9, 0x8c, 0xeb, 0xcc, 0xe9, 0xf9, 0x98, 0xc2, 0xfc, 0x18, 0x96, 0xe2,
0x09, 0xcd, 0xf9, 0x72, 0x84, 0x61, 0xfa, 0x28, 0x2e, 0x76, 0x90, 0x1f, 0xe6, 0x55, 0x99, 0x88,
0x13, 0xfd, 0x67, 0xd6, 0x13, 0xc1, 0x22, 0xc7, 0x50, 0xdb, 0x44, 0xfc, 0x36, 0xff, 0xd7, 0x80,
0xb5, 0x3c, 0xf6, 0x3c, 0x2c, 0xbd, 0x9d, 0xdd, 0x1a, 0xfa, 0xc7, 0x01, 0xe9, 0xd1, 0xd4, 0xb6,
0x50, 0x2b, 0xe0, 0x84, 0xa3, 0x80, 0x29, 0xdb, 0xc2, 0x57, 0xe0, 0x36, 0xff, 0x46, 0x17, 0xa0,
0xe6, 0xb9, 0xb6, 0xcf, 0xaf, 0x5b, 0xf2, 0x18, 0xa9, 0x7a, 0xee, 0x3d, 0x7e, 0x15, 0x7b, 0x27,
0x76, 0x8e, 0x66, 0x5e, 0x02, 0xe5, 0x18, 0xfd, 0x40, 0x1e, 0xdd, 0x96, 0xac, 0xb2, 0x7f, 0xca,
0x75, 0x30, 0x1b, 0xd0, 0x39, 0xf4, 0xd8, 0x81, 0x2d, 0x9e, 0x59, 0x88, 0x73, 0x93, 0x2a, 0x25,
0x5b, 0xe2, 0xf0, 0x5d, 0x0e, 0xe6, 0x67, 0x27, 0x35, 0x7f, 0xd5, 0x80, 0x95, 0x0c, 0x5b, 0xf3,
0x2c, 0xc5, 0x57, 0xb8, 0x4b, 0x21, 0x3b, 0x52, 0xce, 0xe3, 0xba, 0xd6, 0xce, 0xa8, 0xd1, 0x84,
0x7d, 0x49, 0x28, 0xcc, 0xff, 0x34, 0xa0, 0x99, 0x6a, 0xe1, 0x37, 0x12, 0xd5, 0x36, 0xbe, 0x91,
0x24, 0x80, 0x99, 0xc4, 0xf0, 0x12, 0x8c, 0x77, 0x5d, 0xaa, 0x54, 0x3b, 0x55, 0x8a, 0xe6, 0x52,
0x74, 0x17, 0x96, 0xa4, 0x98, 0x12, 0xd6, 0xb5, 0x81, 0x82, 0xa4, 0xc8, 0x0e, 0x47, 0xae, 0xe2,
0xd2, 0x6a, 0xd3, 0xd4, 0x97, 0xcc, 0x0b, 0x86, 0x2e, 0x11, 0x23, 0x55, 0xa4, 0x21, 0x14, 0x2e,
0x8b, 0x4b, 0xf9, 0xcd, 0xa1, 0x95, 0x26, 0xe5, 0xde, 0x97, 0x4f, 0xb0, 0x4b, 0xa2, 0x64, 0x6e,
0xc9, 0x37, 0x77, 0x77, 0xe4, 0x6f, 0x9b, 0x7b, 0xa3, 0xca, 0x7e, 0x80, 0x04, 0x71, 0x47, 0x15,
0xbd, 0x0a, 0xcb, 0xee, 0x20, 0xf3, 0xc6, 0x27, 0xf6, 0xcf, 0xdc, 0x41, 0xea, 0x71, 0x4f, 0x86,
0xa1, 0xc5, 0x0c, 0x43, 0x57, 0x2e, 0x43, 0x3d, 0xae, 0x17, 0x44, 0x35, 0x28, 0xdf, 0xf4, 0xfd,
0xce, 0x02, 0x6a, 0x41, 0x7d, 0x5b, 0x15, 0xc5, 0x75, 0x8c, 0x2b, 0x3f, 0x07, 0xcb, 0xb9, 0xbc,
0x12, 0xaa, 0xc3, 0xe2, 0x83, 0x30, 0x20, 0x9d, 0x05, 0xd4, 0x81, 0xd6, 0x2d, 0x2f, 0xc0, 0xd1,
0x91, 0x8c, 0xba, 0x74, 0x5c, 0xb4, 0x0c, 0x4d, 0x11, 0x7d, 0x50, 0x00, 0xb2, 0xf9, 0x67, 0x97,
0xa1, 0x7d, 0x5f, 0x48, 0x6d, 0x97, 0x44, 0x8f, 0x3d, 0x87, 0x20, 0x1b, 0x3a, 0xf9, 0xd7, 0x96,
0xe8, 0x0b, 0xfa, 0x93, 0x48, 0xff, 0x28, 0xb3, 0x37, 0x4d, 0x0d, 0xcd, 0x05, 0xf4, 0x31, 0x2c,
0x65, 0xdf, 0x2c, 0x22, 0xfd, 0xf5, 0x58, 0xfb, 0xb0, 0xf1, 0xb8, 0xce, 0x6d, 0x68, 0x67, 0x9e,
0x20, 0xa2, 0xd7, 0xb5, 0x7d, 0xeb, 0x9e, 0x29, 0xf6, 0xf4, 0xca, 0x94, 0x7e, 0x26, 0x28, 0xb9,
0xcf, 0xbe, 0x13, 0x2a, 0xe0, 0x5e, 0xfb, 0x98, 0xe8, 0x38, 0xee, 0x31, 0x9c, 0x9b, 0x78, 0xcf,
0x83, 0xde, 0x28, 0xd8, 0x9e, 0xfa, 0x77, 0x3f, 0xc7, 0x0d, 0x71, 0x08, 0x68, 0xf2, 0xa9, 0x1d,
0xba, 0xa6, 0x5f, 0x81, 0xa2, 0x87, 0x86, 0xbd, 0xeb, 0x33, 0xe3, 0x27, 0x82, 0xfb, 0x65, 0x03,
0x2e, 0x14, 0x3c, 0xc2, 0x41, 0x37, 0xb4, 0xdd, 0x4d, 0x7f, 0x49, 0xd4, 0x7b, 0xeb, 0x64, 0x44,
0x09, 0x23, 0x01, 0x2c, 0xe7, 0xde, 0xa5, 0xa0, 0xab, 0x85, 0xb5, 0xba, 0x93, 0x0f, 0x74, 0x7a,
0x5f, 0x98, 0x0d, 0x39, 0x19, 0xef, 0x21, 0x2c, 0xe7, 0x1e, 0x73, 0x14, 0x8c, 0xa7, 0x7f, 0xf2,
0x71, 0xdc, 0x82, 0x7e, 0x0b, 0xda, 0x99, 0x57, 0x17, 0x05, 0x1a, 0xaf, 0x7b, 0x99, 0x71, 0x5c,
0xd7, 0x0f, 0xa1, 0x95, 0x7e, 0x1c, 0x81, 0x36, 0x8a, 0xf6, 0xd2, 0x44, 0xc7, 0x27, 0xd9, 0x4a,
0xe3, 0xda, 0xe7, 0x29, 0x5b, 0x69, 0xa2, 0x5c, 0x7c, 0xf6, 0xad, 0x94, 0xea, 0x7f, 0xea, 0x56,
0x3a, 0xf1, 0x10, 0xdf, 0x95, 0x4e, 0x92, 0xa6, 0xb6, 0x1e, 0x6d, 0x16, 0xe9, 0x66, 0xf1, 0x2b,
0x82, 0xde, 0x8d, 0x13, 0xd1, 0x24, 0x52, 0x7c, 0x04, 0x4b, 0xd9, 0x0a, 0xf2, 0x02, 0x29, 0x6a,
0x8b, 0xee, 0x7b, 0x57, 0x67, 0xc2, 0x4d, 0x06, 0xfb, 0x3a, 0x34, 0x53, 0x7f, 0xa0, 0x80, 0x5e,
0x9b, 0xa2, 0xc7, 0xe9, 0x7f, 0x13, 0x38, 0x4e, 0x92, 0x5f, 0x83, 0x46, 0xf2, 0xbf, 0x07, 0xe8,
0x95, 0x42, 0xfd, 0x3d, 0x49, 0x97, 0xbb, 0x00, 0xe3, 0x3f, 0x35, 0x40, 0xaf, 0x6a, 0xfb, 0x9c,
0xf8, 0xd7, 0x83, 0xe3, 0x3a, 0x4d, 0xa6, 0x2f, 0x0b, 0x73, 0xa6, 0x4d, 0x3f, 0x5d, 0x49, 0x76,
0x5c, 0xb7, 0x07, 0xd0, 0xce, 0xd4, 0x7f, 0x16, 0x6d, 0x61, 0x4d, 0x59, 0x6e, 0xef, 0xca, 0x2c,
0xa8, 0xc9, 0xfa, 0x1d, 0x40, 0x3b, 0x53, 0x8d, 0x57, 0x30, 0x92, 0xae, 0xf8, 0xb0, 0x60, 0x24,
0x6d, 0x71, 0x9f, 0xb9, 0x80, 0xbe, 0x93, 0x2a, 0xfc, 0xcb, 0x14, 0x57, 0xa2, 0x37, 0xa7, 0xf6,
0xa3, 0xab, 0x2d, 0xed, 0x6d, 0x9e, 0x84, 0x24, 0x61, 0x41, 0x69, 0x95, 0x14, 0x69, 0xb1, 0x56,
0x9d, 0x64, 0xa5, 0x76, 0xa1, 0x2a, 0xeb, 0xeb, 0x90, 0x59, 0x50, 0x49, 0x9b, 0x2a, 0xbe, 0xeb,
0xbd, 0xa4, 0xc5, 0xc9, 0x96, 0x9e, 0xc9, 0x4e, 0x65, 0xfd, 0x54, 0x41, 0xa7, 0x99, 0xe2, 0xaa,
0x59, 0x3b, 0xb5, 0xa0, 0x2a, 0x0b, 0x27, 0x0a, 0x3a, 0xcd, 0x14, 0xff, 0xf4, 0xa6, 0xe3, 0x88,
0x8c, 0x9a, 0xb9, 0x80, 0x76, 0xa0, 0x22, 0xae, 0xf5, 0xe8, 0xf2, 0xb4, 0x9a, 0x82, 0x69, 0x3d,
0x66, 0xca, 0x0e, 0xcc, 0x05, 0xf4, 0x0b, 0x50, 0x11, 0x41, 0xea, 0x82, 0x1e, 0xd3, 0x85, 0x01,
0xbd, 0xa9, 0x28, 0x31, 0x8b, 0x2e, 0xb4, 0xd2, 0xd9, 0xc0, 0x82, 0x23, 0x4b, 0x93, 0x2f, 0xed,
0xcd, 0x82, 0x19, 0x8f, 0x22, 0xb7, 0xd1, 0x38, 0xc4, 0x51, 0xbc, 0x8d, 0x26, 0xc2, 0x27, 0xc5,
0xdb, 0x68, 0x32, 0x62, 0x62, 0x2e, 0xa0, 0x5f, 0x33, 0xa0, 0x5b, 0x94, 0xa2, 0x42, 0x85, 0x1e,
0xd0, 0xb4, 0x3c, 0x5b, 0xef, 0x4b, 0x27, 0xa4, 0x4a, 0x78, 0xf9, 0x44, 0xdc, 0x42, 0x27, 0x92,
0x52, 0xd7, 0x8b, 0xfa, 0x2b, 0x48, 0xc1, 0xf4, 0xbe, 0x38, 0x3b, 0x41, 0x32, 0xf6, 0x1e, 0x34,
0x53, 0x37, 0xe0, 0x02, 0xcb, 0x3b, 0x79, 0x75, 0x2f, 0x58, 0x55, 0xcd, 0x65, 0x5a, 0xaa, 0xb7,
0xc8, 0x71, 0x14, 0x28, 0x63, 0x3a, 0x65, 0x52, 0xa0, 0xde, 0x99, 0x14, 0x89, 0xb9, 0x80, 0x08,
0xb4, 0xd2, 0x09, 0x8f, 0x02, 0x6d, 0xd4, 0xe4, 0x4a, 0x7a, 0xaf, 0xcf, 0x80, 0x99, 0x0c, 0x63,
0x03, 0x8c, 0x13, 0x0e, 0x05, 0x67, 0xdd, 0x44, 0xce, 0xa3, 0xf7, 0xda, 0xb1, 0x78, 0xe9, 0x63,
0x3f, 0x95, 0x42, 0x28, 0x90, 0xfe, 0x64, 0x92, 0x61, 0x86, 0xbb, 0xc8, 0x64, 0x38, 0xbb, 0xe0,
0x2e, 0x52, 0x18, 0x39, 0xef, 0x5d, 0x9f, 0x19, 0x3f, 0x99, 0xcf, 0xb7, 0xa1, 0x93, 0x0f, 0xff,
0x17, 0xdc, 0x71, 0x0b, 0x92, 0x10, 0xbd, 0x37, 0x66, 0xc4, 0x4e, 0x9f, 0x87, 0x17, 0x27, 0x79,
0xfa, 0xa6, 0xc7, 0x0e, 0x44, 0xe4, 0x79, 0x96, 0x59, 0xa7, 0x83, 0xdc, 0xb3, 0xcc, 0x3a, 0x13,
0xd2, 0x56, 0x87, 0x97, 0x08, 0xb1, 0x15, 0x1d, 0x5e, 0xe9, 0x60, 0x6a, 0xc1, 0x39, 0x93, 0x8d,
0x4f, 0x4a, 0xf7, 0x33, 0x1b, 0x28, 0x44, 0xc5, 0x7e, 0xc2, 0x44, 0xec, 0xb1, 0xc0, 0xfd, 0xd4,
0x47, 0x1e, 0xcd, 0x85, 0xcd, 0x11, 0xb4, 0x76, 0xa2, 0xf0, 0xc9, 0x51, 0x1c, 0xab, 0xf8, 0xe9,
0xec, 0xaf, 0x5b, 0xdf, 0x84, 0x25, 0x2f, 0xc1, 0xe9, 0x47, 0x43, 0xe7, 0x56, 0x53, 0xc6, 0x4c,
0x76, 0x38, 0xf1, 0x8e, 0xf1, 0x8b, 0x37, 0xfa, 0x1e, 0x3b, 0x18, 0xed, 0x71, 0x05, 0xbf, 0x2e,
0xd1, 0xde, 0xf0, 0x42, 0xf5, 0xeb, 0xba, 0x17, 0x30, 0x12, 0x05, 0xd8, 0xbf, 0x2e, 0x86, 0x52,
0xd0, 0xe1, 0xde, 0x1f, 0x18, 0xc6, 0x5e, 0x55, 0x80, 0x6e, 0xfc, 0x7f, 0x00, 0x00, 0x00, 0xff,
0xff, 0x8a, 0x5f, 0xf0, 0xa5, 0xd8, 0x4c, 0x00, 0x00,
0x75, 0xec, 0x19, 0xce, 0xd7, 0x9b, 0x19, 0x72, 0x54, 0xfc, 0x9a, 0x1d, 0x49, 0x2b, 0xaa, 0xf7,
0x8b, 0x2b, 0x79, 0x25, 0x2f, 0xb5, 0xde, 0x75, 0x76, 0x9d, 0xac, 0x25, 0x31, 0x2b, 0x11, 0x2b,
0x29, 0x74, 0x73, 0xd7, 0x86, 0xb3, 0x10, 0x1a, 0xc5, 0xe9, 0xe2, 0xb0, 0xa3, 0x9e, 0xee, 0x71,
0x57, 0x8d, 0x28, 0xee, 0xc9, 0x80, 0x83, 0x7c, 0xc0, 0x9b, 0x35, 0x82, 0x18, 0xf9, 0x38, 0x24,
0x08, 0xf2, 0x71, 0xc8, 0x21, 0x41, 0x6c, 0x07, 0x89, 0x91, 0x4b, 0x72, 0xc8, 0x21, 0x87, 0x00,
0xf9, 0xb8, 0x04, 0x41, 0x2e, 0xf9, 0x03, 0x39, 0x04, 0xc8, 0x31, 0x87, 0xa0, 0x3e, 0xba, 0xa7,
0xbb, 0xa7, 0x7a, 0x38, 0xd4, 0x58, 0x26, 0x75, 0x9b, 0x7e, 0xf5, 0x5e, 0xd5, 0xab, 0x57, 0xaf,
0x5e, 0xbd, 0x7a, 0xef, 0xd5, 0x40, 0xa3, 0xef, 0x7a, 0x8f, 0x87, 0xf4, 0xda, 0x20, 0x0c, 0x58,
0x80, 0x96, 0x92, 0x5f, 0xd7, 0xe4, 0x47, 0xa7, 0xd1, 0x0d, 0xfa, 0xfd, 0xc0, 0x97, 0xc0, 0x4e,
0x83, 0x76, 0x0f, 0x48, 0x1f, 0xcb, 0x2f, 0xf3, 0x0f, 0x0c, 0x40, 0xb7, 0x43, 0x82, 0x19, 0xb9,
0xe9, 0xb9, 0x98, 0x5a, 0xe4, 0x5b, 0x43, 0x42, 0x19, 0xfa, 0x22, 0xcc, 0xef, 0x61, 0x4a, 0xda,
0xc6, 0xba, 0xb1, 0x51, 0xdf, 0xbc, 0x70, 0x2d, 0xd5, 0xad, 0xea, 0xee, 0x3e, 0xed, 0xdd, 0xc2,
0x94, 0x58, 0x02, 0x13, 0xad, 0x41, 0xc5, 0xd9, 0xb3, 0x7d, 0xdc, 0x27, 0xed, 0xc2, 0xba, 0xb1,
0x51, 0xb3, 0xca, 0xce, 0xde, 0x03, 0xdc, 0x27, 0xe8, 0x35, 0x58, 0xec, 0x06, 0x9e, 0x47, 0xba,
0xcc, 0x0d, 0x7c, 0x89, 0x50, 0x14, 0x08, 0x0b, 0x23, 0xb0, 0x40, 0x5c, 0x86, 0x12, 0xe6, 0x3c,
0xb4, 0xe7, 0x45, 0xb3, 0xfc, 0x30, 0x29, 0xb4, 0xb6, 0xc2, 0x60, 0xf0, 0xac, 0xb8, 0x8b, 0x07,
0x2d, 0x26, 0x07, 0xfd, 0x7d, 0x03, 0xce, 0xdd, 0xf4, 0x18, 0x09, 0xcf, 0xa8, 0x50, 0x7e, 0xb7,
0x00, 0x6b, 0x72, 0xd5, 0x6e, 0xc7, 0xe8, 0xa7, 0xc9, 0xe5, 0x2a, 0x94, 0xa5, 0x56, 0x09, 0x36,
0x1b, 0x96, 0xfa, 0x42, 0x17, 0x01, 0xe8, 0x01, 0x0e, 0x1d, 0x6a, 0xfb, 0xc3, 0x7e, 0xbb, 0xb4,
0x6e, 0x6c, 0x94, 0xac, 0x9a, 0x84, 0x3c, 0x18, 0xf6, 0x91, 0x05, 0xe7, 0xba, 0x81, 0x4f, 0x5d,
0xca, 0x88, 0xdf, 0x3d, 0xb2, 0x3d, 0xf2, 0x98, 0x78, 0xed, 0xf2, 0xba, 0xb1, 0xb1, 0xb0, 0xf9,
0x8a, 0x96, 0xef, 0xdb, 0x23, 0xec, 0x7b, 0x1c, 0xd9, 0x6a, 0x75, 0x33, 0x10, 0xf3, 0xbb, 0x06,
0xac, 0x70, 0x85, 0x39, 0x13, 0x82, 0x31, 0xff, 0xcc, 0x80, 0xe5, 0xbb, 0x98, 0x9e, 0x8d, 0x55,
0xba, 0x08, 0xc0, 0xdc, 0x3e, 0xb1, 0x29, 0xc3, 0xfd, 0x81, 0x58, 0xa9, 0x79, 0xab, 0xc6, 0x21,
0xbb, 0x1c, 0x60, 0x7e, 0x13, 0x1a, 0xb7, 0x82, 0xc0, 0xb3, 0x08, 0x1d, 0x04, 0x3e, 0x25, 0xe8,
0x06, 0x94, 0x29, 0xc3, 0x6c, 0x48, 0x15, 0x93, 0xe7, 0xb5, 0x4c, 0xee, 0x0a, 0x14, 0x4b, 0xa1,
0x72, 0x7d, 0x7d, 0x8c, 0xbd, 0xa1, 0xe4, 0xb1, 0x6a, 0xc9, 0x0f, 0xf3, 0x13, 0x58, 0xd8, 0x65,
0xa1, 0xeb, 0xf7, 0x7e, 0x82, 0x9d, 0xd7, 0xa2, 0xce, 0xff, 0xcd, 0x80, 0x17, 0xb6, 0x08, 0xed,
0x86, 0xee, 0xde, 0x19, 0xd9, 0x0e, 0x26, 0x34, 0x46, 0x90, 0xed, 0x2d, 0x21, 0xea, 0xa2, 0x95,
0x82, 0x65, 0x16, 0xa3, 0x94, 0x5d, 0x8c, 0x6f, 0x97, 0xa0, 0xa3, 0x9b, 0xd4, 0x2c, 0xe2, 0xfb,
0xd9, 0x78, 0x97, 0x16, 0x04, 0x51, 0x66, 0x8f, 0xa9, 0x73, 0x61, 0x34, 0xda, 0xae, 0x00, 0xc4,
0x9b, 0x39, 0x3b, 0xab, 0xa2, 0x66, 0x56, 0x9b, 0xb0, 0xf2, 0xd8, 0x0d, 0xd9, 0x10, 0x7b, 0x76,
0xf7, 0x00, 0xfb, 0x3e, 0xf1, 0x84, 0x9c, 0xb8, 0xf9, 0x2a, 0x6e, 0xd4, 0xac, 0x25, 0xd5, 0x78,
0x5b, 0xb6, 0x71, 0x61, 0x51, 0xf4, 0x16, 0xac, 0x0e, 0x0e, 0x8e, 0xa8, 0xdb, 0x1d, 0x23, 0x2a,
0x09, 0xa2, 0xe5, 0xa8, 0x35, 0x45, 0x75, 0x15, 0xce, 0x75, 0x85, 0x05, 0x74, 0x6c, 0x2e, 0x35,
0x29, 0xc6, 0xb2, 0x10, 0x63, 0x4b, 0x35, 0x7c, 0x14, 0xc1, 0x39, 0x5b, 0x11, 0xf2, 0x90, 0x75,
0x13, 0x04, 0x15, 0x41, 0xb0, 0xa4, 0x1a, 0x3f, 0x66, 0xdd, 0x11, 0x4d, 0xda, 0x76, 0x55, 0xb3,
0xb6, 0xab, 0x0d, 0x15, 0x61, 0x8b, 0x09, 0x6d, 0xd7, 0x04, 0x9b, 0xd1, 0x27, 0xda, 0x86, 0x45,
0xca, 0x70, 0xc8, 0xec, 0x41, 0x40, 0x5d, 0x2e, 0x17, 0xda, 0x86, 0xf5, 0xe2, 0x46, 0x7d, 0x73,
0x5d, 0xbb, 0x48, 0x1f, 0x92, 0xa3, 0x2d, 0xcc, 0xf0, 0x0e, 0x76, 0x43, 0x6b, 0x41, 0x10, 0xee,
0x44, 0x74, 0x7a, 0x03, 0x59, 0x9f, 0xc9, 0x40, 0xea, 0xb4, 0xb8, 0xa1, 0xb5, 0x5d, 0x3f, 0x34,
0x60, 0xe5, 0x5e, 0x80, 0x9d, 0xb3, 0xb1, 0xa7, 0x5e, 0x81, 0x85, 0x90, 0x0c, 0x3c, 0xb7, 0x8b,
0xf9, 0x7a, 0xec, 0x91, 0x50, 0xec, 0xaa, 0x92, 0xd5, 0x54, 0xd0, 0x07, 0x02, 0x68, 0x7e, 0x6e,
0x40, 0xdb, 0x22, 0x1e, 0xc1, 0xf4, 0x6c, 0xd8, 0x02, 0xf3, 0xfb, 0x06, 0xbc, 0x78, 0x87, 0xb0,
0xc4, 0xae, 0x62, 0x98, 0xb9, 0x94, 0xb9, 0xdd, 0xd3, 0xf4, 0x2b, 0xcc, 0xef, 0x19, 0x70, 0x29,
0x97, 0xad, 0x59, 0x8c, 0xcc, 0x3b, 0x50, 0xe2, 0xbf, 0x68, 0xbb, 0x20, 0x74, 0xfe, 0x72, 0x9e,
0xce, 0x7f, 0x9d, 0xdb, 0x6e, 0xa1, 0xf4, 0x12, 0xdf, 0xfc, 0x2f, 0x03, 0x56, 0x77, 0x0f, 0x82,
0xc3, 0x11, 0x4b, 0xcf, 0x42, 0x40, 0x69, 0xb3, 0x5b, 0xcc, 0x98, 0x5d, 0xf4, 0x26, 0xcc, 0xb3,
0xa3, 0x01, 0x11, 0xba, 0xb5, 0xb0, 0x79, 0xf1, 0x9a, 0xc6, 0x9d, 0xbe, 0xc6, 0x99, 0xfc, 0xe8,
0x68, 0x40, 0x2c, 0x81, 0x8a, 0x5e, 0x87, 0x56, 0x46, 0xe4, 0x91, 0xe1, 0x5a, 0x4c, 0xcb, 0x9c,
0x9a, 0x3f, 0x2e, 0xc0, 0xda, 0xd8, 0x14, 0x67, 0x11, 0xb6, 0x6e, 0xec, 0x82, 0x76, 0x6c, 0xbe,
0x7f, 0x12, 0xa8, 0xae, 0xc3, 0x3d, 0xde, 0xe2, 0x46, 0xd1, 0x6a, 0x26, 0xec, 0xb7, 0x43, 0xd1,
0x1b, 0x80, 0xc6, 0xcc, 0xaa, 0xb4, 0xde, 0xf3, 0xd6, 0xb9, 0xac, 0x5d, 0x15, 0xb6, 0x5b, 0x6b,
0x58, 0xa5, 0x08, 0xe6, 0xad, 0x65, 0x8d, 0x65, 0xa5, 0xe8, 0x4d, 0x58, 0x76, 0xfd, 0xfb, 0xa4,
0x1f, 0x84, 0x47, 0xf6, 0x80, 0x84, 0x5d, 0xe2, 0x33, 0xdc, 0x23, 0xb4, 0x5d, 0x16, 0x1c, 0x2d,
0x45, 0x6d, 0x3b, 0xa3, 0x26, 0xf3, 0x47, 0x06, 0xac, 0x4a, 0x8f, 0x77, 0x07, 0x87, 0xcc, 0x3d,
0x03, 0xd6, 0x68, 0x10, 0xf1, 0x21, 0xf1, 0xa4, 0x7f, 0xde, 0x8c, 0xa1, 0x62, 0x97, 0xfd, 0xc0,
0x80, 0x65, 0xee, 0x8c, 0x3e, 0x4f, 0x3c, 0xff, 0xa5, 0x01, 0x4b, 0x77, 0x31, 0x7d, 0x9e, 0x58,
0xfe, 0x2b, 0x75, 0x52, 0xc5, 0x3c, 0x9f, 0xea, 0x95, 0xed, 0x35, 0x58, 0x4c, 0x33, 0x1d, 0x79,
0x3f, 0x0b, 0x29, 0xae, 0xa9, 0xf9, 0x37, 0xa3, 0xb3, 0xea, 0x39, 0xe3, 0xfc, 0x6f, 0x0d, 0xb8,
0x78, 0x87, 0xb0, 0x98, 0xeb, 0x33, 0x71, 0xa6, 0x4d, 0xab, 0x2d, 0x9f, 0xcb, 0x13, 0x59, 0xcb,
0xfc, 0xa9, 0x9c, 0x7c, 0xdf, 0x2d, 0xc0, 0x0a, 0x3f, 0x16, 0xce, 0x86, 0x12, 0x4c, 0x73, 0x79,
0xd1, 0x28, 0x4a, 0x49, 0xa7, 0x28, 0xf1, 0x79, 0x5a, 0x9e, 0xfa, 0x3c, 0x35, 0x7f, 0x58, 0x90,
0x7e, 0x40, 0x52, 0x1a, 0xb3, 0x2c, 0x8b, 0x86, 0xd7, 0x82, 0x96, 0x57, 0x13, 0x1a, 0x31, 0x64,
0x7b, 0x2b, 0x3a, 0x1f, 0x53, 0xb0, 0x33, 0x7b, 0x3c, 0x7e, 0x66, 0xc0, 0x6a, 0x74, 0x5d, 0xdc,
0x25, 0xbd, 0x3e, 0xf1, 0xd9, 0xd3, 0xeb, 0x50, 0x56, 0x03, 0x0a, 0x1a, 0x0d, 0xb8, 0x00, 0x35,
0x2a, 0xc7, 0x89, 0x6f, 0x82, 0x23, 0x80, 0xf9, 0x77, 0x06, 0xac, 0x8d, 0xb1, 0x33, 0xcb, 0x22,
0xb6, 0xa1, 0xe2, 0xfa, 0x0e, 0x79, 0x12, 0x73, 0x13, 0x7d, 0xf2, 0x96, 0xbd, 0xa1, 0xeb, 0x39,
0x31, 0x1b, 0xd1, 0x27, 0xba, 0x0c, 0x0d, 0xe2, 0xe3, 0x3d, 0x8f, 0xd8, 0x02, 0x57, 0x28, 0x72,
0xd5, 0xaa, 0x4b, 0xd8, 0x36, 0x07, 0x71, 0xe2, 0x7d, 0x97, 0x08, 0xe2, 0x92, 0x24, 0x56, 0x9f,
0xe6, 0x6f, 0x18, 0xb0, 0xc4, 0xb5, 0x50, 0x71, 0x4f, 0x9f, 0xad, 0x34, 0xd7, 0xa1, 0x9e, 0x50,
0x33, 0x35, 0x91, 0x24, 0xc8, 0x7c, 0x04, 0xcb, 0x69, 0x76, 0x66, 0x91, 0xe6, 0x8b, 0x00, 0xf1,
0x5a, 0xc9, 0xdd, 0x50, 0xb4, 0x12, 0x10, 0xf3, 0xb3, 0x42, 0x14, 0x14, 0x16, 0x62, 0x3a, 0xe5,
0x98, 0x95, 0x58, 0x92, 0xa4, 0x3d, 0xaf, 0x09, 0x88, 0x68, 0xde, 0x82, 0x06, 0x79, 0xc2, 0x42,
0x6c, 0x0f, 0x70, 0x88, 0xfb, 0x72, 0x5b, 0x4d, 0x65, 0x7a, 0xeb, 0x82, 0x6c, 0x47, 0x50, 0xf1,
0x41, 0x84, 0x8a, 0xc8, 0x41, 0xca, 0x72, 0x10, 0x01, 0x11, 0x07, 0xc6, 0x3f, 0x72, 0x2f, 0x4e,
0x69, 0xf3, 0x59, 0x17, 0x48, 0x7a, 0x2a, 0xa5, 0xec, 0x54, 0xfe, 0xd4, 0x80, 0x96, 0x98, 0x82,
0x9c, 0xcf, 0x80, 0x77, 0x9b, 0xa1, 0x31, 0x32, 0x34, 0x13, 0xf6, 0xde, 0xcf, 0x40, 0x59, 0xc9,
0xbd, 0x38, 0xad, 0xdc, 0x15, 0xc1, 0x31, 0xd3, 0x30, 0xff, 0xc8, 0x80, 0x95, 0x8c, 0xc8, 0x67,
0x51, 0xf8, 0x8f, 0x00, 0xc9, 0x19, 0x3a, 0xa3, 0x69, 0x47, 0xe7, 0xf4, 0x2b, 0xda, 0x43, 0x29,
0x2b, 0x24, 0xeb, 0x9c, 0x9b, 0x81, 0x50, 0xf3, 0x5f, 0x0c, 0xb8, 0x70, 0x87, 0x30, 0x81, 0x7a,
0x8b, 0x1b, 0x9d, 0x9d, 0x30, 0xe8, 0x85, 0x84, 0xd2, 0xe7, 0x57, 0x3f, 0x7e, 0x5b, 0x3a, 0x76,
0xba, 0x29, 0xcd, 0x22, 0xff, 0xcb, 0xd0, 0x10, 0x63, 0x10, 0xc7, 0x0e, 0x83, 0x43, 0xaa, 0xf4,
0xa8, 0xae, 0x60, 0x56, 0x70, 0x28, 0x14, 0x82, 0x05, 0x0c, 0x7b, 0x12, 0x41, 0x9d, 0x28, 0x02,
0xc2, 0x9b, 0xc5, 0x1e, 0x8c, 0x18, 0xe3, 0x9d, 0x93, 0xe7, 0x57, 0xc6, 0x7f, 0x62, 0xc0, 0x4a,
0x66, 0x2a, 0xb3, 0xc8, 0xf6, 0x4b, 0xd2, 0xed, 0x94, 0x93, 0x59, 0xd8, 0xbc, 0xa4, 0xa5, 0x49,
0x0c, 0x26, 0xb1, 0xd1, 0x25, 0xa8, 0xef, 0x63, 0xd7, 0xb3, 0x43, 0x82, 0x69, 0xe0, 0xab, 0x89,
0x02, 0x07, 0x59, 0x02, 0x62, 0xfe, 0x83, 0x21, 0x33, 0x6f, 0xcf, 0xb9, 0xc5, 0xfb, 0xe3, 0x02,
0x34, 0xb7, 0x7d, 0x4a, 0x42, 0x76, 0xf6, 0xaf, 0x26, 0xe8, 0x7d, 0xa8, 0x8b, 0x89, 0x51, 0xdb,
0xc1, 0x0c, 0xab, 0xd3, 0xec, 0x45, 0x6d, 0x98, 0xfe, 0x03, 0x8e, 0xb7, 0x85, 0x19, 0xb6, 0xa4,
0x74, 0x28, 0xff, 0x8d, 0xce, 0x43, 0xed, 0x00, 0xd3, 0x03, 0xfb, 0x11, 0x39, 0x92, 0xfe, 0x62,
0xd3, 0xaa, 0x72, 0xc0, 0x87, 0xe4, 0x88, 0xa2, 0x17, 0xa0, 0xea, 0x0f, 0xfb, 0x72, 0x83, 0x55,
0xd6, 0x8d, 0x8d, 0xa6, 0x55, 0xf1, 0x87, 0x7d, 0xb1, 0xbd, 0xfe, 0xa9, 0x00, 0x0b, 0xf7, 0x87,
0xfc, 0x22, 0x24, 0x92, 0x0c, 0x43, 0x8f, 0x3d, 0x9d, 0x32, 0x5e, 0x81, 0xa2, 0x74, 0x29, 0x38,
0x45, 0x5b, 0xcb, 0xf8, 0xf6, 0x16, 0xb5, 0x38, 0x92, 0x08, 0xb0, 0x0f, 0xbb, 0x5d, 0xe5, 0x9d,
0x15, 0x05, 0xb3, 0x35, 0x0e, 0x91, 0xbe, 0xd9, 0x79, 0xa8, 0x91, 0x30, 0x8c, 0x7d, 0x37, 0x31,
0x15, 0x12, 0x86, 0xb2, 0xd1, 0x84, 0x06, 0xee, 0x3e, 0xf2, 0x83, 0x43, 0x8f, 0x38, 0x3d, 0xe2,
0x88, 0x65, 0xaf, 0x5a, 0x29, 0x98, 0x54, 0x0c, 0xbe, 0xf0, 0x76, 0xd7, 0x67, 0xe2, 0x54, 0x2f,
0x72, 0xc5, 0xe0, 0x90, 0xdb, 0x3e, 0xe3, 0xcd, 0x0e, 0xf1, 0x08, 0x23, 0xa2, 0xb9, 0x22, 0x9b,
0x25, 0x44, 0x35, 0x0f, 0x07, 0x31, 0x75, 0x55, 0x36, 0x4b, 0x08, 0x6f, 0xbe, 0x00, 0xb5, 0x51,
0x16, 0xa1, 0x36, 0x0a, 0x23, 0x0a, 0x80, 0xf9, 0x9f, 0x06, 0x34, 0xb7, 0x44, 0x57, 0xcf, 0x81,
0xd2, 0x21, 0x98, 0x27, 0x4f, 0x06, 0xa1, 0xda, 0x3a, 0xe2, 0xf7, 0x44, 0x3d, 0x32, 0x1f, 0x43,
0x6b, 0xc7, 0xc3, 0x5d, 0x72, 0x10, 0x78, 0x0e, 0x09, 0xc5, 0xd9, 0x8e, 0x5a, 0x50, 0x64, 0xb8,
0xa7, 0x9c, 0x07, 0xfe, 0x13, 0x7d, 0x59, 0x5d, 0xfd, 0xa4, 0x59, 0x7a, 0x59, 0x7b, 0xca, 0x26,
0xba, 0x49, 0x44, 0x54, 0x57, 0xa1, 0x2c, 0x32, 0x7b, 0xd2, 0xad, 0x68, 0x58, 0xea, 0xcb, 0x7c,
0x98, 0x1a, 0xf7, 0x4e, 0x18, 0x0c, 0x07, 0x68, 0x1b, 0x1a, 0x83, 0x11, 0x8c, 0xeb, 0x6a, 0xfe,
0x99, 0x9e, 0x65, 0xda, 0x4a, 0x91, 0x9a, 0xff, 0x5d, 0x84, 0xe6, 0x2e, 0xc1, 0x61, 0xf7, 0xe0,
0x79, 0x88, 0xc1, 0x70, 0x89, 0x3b, 0xd4, 0x53, 0xab, 0xc6, 0x7f, 0xa2, 0xab, 0x70, 0x2e, 0x31,
0x21, 0xbb, 0xc7, 0x05, 0x24, 0xf4, 0xbe, 0x61, 0xb5, 0x06, 0x59, 0xc1, 0xbd, 0x03, 0x55, 0x87,
0x7a, 0xb6, 0x58, 0xa2, 0x8a, 0x58, 0x22, 0xfd, 0xfc, 0xb6, 0xa8, 0x27, 0x96, 0xa6, 0xe2, 0xc8,
0x1f, 0xe8, 0x25, 0x68, 0x06, 0x43, 0x36, 0x18, 0x32, 0x5b, 0xda, 0x9d, 0x76, 0x55, 0xb0, 0xd7,
0x90, 0x40, 0x61, 0x96, 0x28, 0xfa, 0x00, 0x9a, 0x54, 0x88, 0x32, 0x72, 0xcc, 0x6b, 0xd3, 0x3a,
0x88, 0x0d, 0x49, 0xa7, 0x3c, 0xf3, 0xd7, 0xa1, 0xc5, 0x42, 0xfc, 0x98, 0x78, 0x89, 0x9c, 0x1d,
0x88, 0xdd, 0xb6, 0x28, 0xe1, 0xa3, 0x7c, 0xdd, 0x75, 0x58, 0xea, 0x0d, 0x71, 0x88, 0x7d, 0x46,
0x48, 0x02, 0xbb, 0x2e, 0xb0, 0x51, 0xdc, 0x14, 0x13, 0x98, 0x1f, 0xc2, 0xfc, 0x5d, 0x97, 0x09,
0x41, 0x72, 0x9b, 0x65, 0x88, 0x6b, 0x90, 0xb0, 0x4c, 0x2f, 0x40, 0x35, 0x0c, 0x0e, 0xa5, 0x0d,
0x2e, 0x08, 0x15, 0xac, 0x84, 0xc1, 0xa1, 0x30, 0xb0, 0xa2, 0xd2, 0x21, 0x08, 0x95, 0x6e, 0x16,
0x2c, 0xf5, 0x65, 0xfe, 0x85, 0x31, 0x52, 0x1e, 0x6e, 0x3e, 0xe9, 0xd3, 0xd9, 0xcf, 0xf7, 0xa1,
0x12, 0x4a, 0xfa, 0x89, 0x39, 0xda, 0xe4, 0x48, 0xe2, 0x0c, 0x88, 0xa8, 0xa6, 0x4f, 0x00, 0xfd,
0xb2, 0x01, 0x8d, 0x0f, 0xbc, 0x21, 0x7d, 0x16, 0xca, 0xae, 0x4b, 0x4b, 0x14, 0xf5, 0x29, 0x91,
0xdf, 0x2c, 0x40, 0x53, 0xb1, 0x31, 0x8b, 0x13, 0x94, 0xcb, 0xca, 0x2e, 0xd4, 0xf9, 0x90, 0x36,
0x25, 0xbd, 0x28, 0xa6, 0x53, 0xdf, 0xdc, 0xd4, 0x9a, 0x87, 0x14, 0x1b, 0x22, 0x0d, 0xbe, 0x2b,
0x88, 0x7e, 0xde, 0x67, 0xe1, 0x91, 0x05, 0xdd, 0x18, 0xd0, 0x79, 0x08, 0x8b, 0x99, 0x66, 0xae,
0x44, 0x8f, 0xc8, 0x51, 0x64, 0xff, 0x1e, 0x91, 0x23, 0xf4, 0x56, 0xb2, 0x58, 0x21, 0xef, 0x14,
0xbf, 0x17, 0xf8, 0xbd, 0x9b, 0x61, 0x88, 0x8f, 0x54, 0x31, 0xc3, 0xbb, 0x85, 0x2f, 0x1b, 0xe6,
0xdf, 0x17, 0xa0, 0xf1, 0xb5, 0x21, 0x09, 0x8f, 0x4e, 0xd3, 0x0e, 0x45, 0xa7, 0xc2, 0x7c, 0xe2,
0x54, 0x18, 0xdb, 0xfa, 0x25, 0xcd, 0xd6, 0xd7, 0x18, 0xb0, 0xb2, 0xd6, 0x80, 0xe9, 0xf6, 0x76,
0xe5, 0x44, 0x7b, 0xbb, 0x9a, 0xbb, 0xb7, 0xff, 0xdc, 0x88, 0x45, 0x38, 0xd3, 0x6e, 0x4c, 0xb9,
0x63, 0x85, 0x13, 0xbb, 0x63, 0x53, 0xef, 0xc6, 0x1f, 0x18, 0x50, 0xfb, 0x3a, 0xe9, 0xb2, 0x20,
0xe4, 0xf6, 0x47, 0x43, 0x66, 0x4c, 0xe1, 0x1a, 0x17, 0xb2, 0xae, 0xf1, 0x0d, 0xa8, 0xba, 0x8e,
0x8d, 0xb9, 0x7e, 0x89, 0x71, 0x27, 0xb9, 0x64, 0x15, 0xd7, 0x11, 0x8a, 0x38, 0x7d, 0x12, 0xe0,
0x77, 0x0c, 0x68, 0x48, 0x9e, 0xa9, 0xa4, 0x7c, 0x2f, 0x31, 0x9c, 0xa1, 0x53, 0x7a, 0xf5, 0x11,
0x4f, 0xf4, 0xee, 0xdc, 0x68, 0xd8, 0x9b, 0x00, 0x5c, 0xc8, 0x8a, 0x5c, 0xee, 0x99, 0x75, 0x2d,
0xb7, 0x92, 0x5c, 0x08, 0xfc, 0xee, 0x9c, 0x55, 0xe3, 0x54, 0xa2, 0x8b, 0x5b, 0x15, 0x28, 0x09,
0x6a, 0xf3, 0xff, 0x0c, 0x58, 0xba, 0x8d, 0xbd, 0xee, 0x96, 0x4b, 0x19, 0xf6, 0xbb, 0x33, 0x38,
0x61, 0xef, 0x42, 0x25, 0x18, 0xd8, 0x1e, 0xd9, 0x67, 0x8a, 0xa5, 0xcb, 0x13, 0x66, 0x24, 0xc5,
0x60, 0x95, 0x83, 0xc1, 0x3d, 0xb2, 0xcf, 0xd0, 0x57, 0xa0, 0x1a, 0x0c, 0xec, 0xd0, 0xed, 0x1d,
0x30, 0x25, 0xfd, 0x29, 0x88, 0x2b, 0xc1, 0xc0, 0xe2, 0x14, 0x89, 0xd8, 0xca, 0xfc, 0x09, 0x63,
0x2b, 0xe6, 0xbf, 0x8e, 0x4d, 0x7f, 0x86, 0x3d, 0xf0, 0x2e, 0x54, 0x5d, 0x9f, 0xd9, 0x8e, 0x4b,
0x23, 0x11, 0x5c, 0xd4, 0xeb, 0x90, 0xcf, 0xc4, 0x0c, 0xc4, 0x9a, 0xfa, 0x8c, 0x8f, 0x8d, 0xbe,
0x0a, 0xb0, 0xef, 0x05, 0x58, 0x51, 0x4b, 0x19, 0x5c, 0xd2, 0x6f, 0x1f, 0x8e, 0x16, 0xd1, 0xd7,
0x04, 0x11, 0xef, 0x61, 0xb4, 0xa4, 0xff, 0x6c, 0xc0, 0xca, 0x0e, 0x09, 0x65, 0x29, 0x0b, 0x53,
0x61, 0xd0, 0x6d, 0x7f, 0x3f, 0x48, 0x47, 0xa2, 0x8d, 0x4c, 0x24, 0xfa, 0x27, 0x13, 0x7d, 0x4d,
0xdd, 0x9c, 0x64, 0x3e, 0x24, 0xba, 0x39, 0x45, 0x59, 0x1f, 0x79, 0xf3, 0x5c, 0xc8, 0x59, 0x26,
0xc5, 0x6f, 0xf2, 0x02, 0x6e, 0xfe, 0x96, 0xac, 0xc0, 0xd0, 0x4e, 0xea, 0xe9, 0x15, 0x76, 0x15,
0x94, 0xa5, 0xcf, 0xd8, 0xfd, 0x57, 0x21, 0x63, 0x3b, 0x72, 0x0c, 0xd1, 0xef, 0x19, 0xb0, 0x9e,
0xcf, 0xd5, 0x2c, 0x47, 0xf4, 0x57, 0xa1, 0xe4, 0xfa, 0xfb, 0x41, 0x14, 0x76, 0xbb, 0xa2, 0x77,
0xd1, 0xb5, 0xe3, 0x4a, 0x42, 0xf3, 0xaf, 0x0b, 0xd0, 0x12, 0x46, 0xfd, 0x14, 0x96, 0xbf, 0x4f,
0xfa, 0x36, 0x75, 0x3f, 0x25, 0xd1, 0xf2, 0xf7, 0x49, 0x7f, 0xd7, 0xfd, 0x94, 0xa4, 0x34, 0xa3,
0x94, 0xd6, 0x8c, 0xc9, 0x51, 0xe5, 0x64, 0x58, 0xb5, 0x92, 0x0e, 0xab, 0xae, 0x42, 0xd9, 0x0f,
0x1c, 0xb2, 0xbd, 0xa5, 0xae, 0x9d, 0xea, 0x6b, 0xa4, 0x6a, 0xb5, 0x13, 0xaa, 0xda, 0xe7, 0x06,
0x74, 0xee, 0x10, 0x96, 0x95, 0xdd, 0xe9, 0x69, 0xd9, 0xf7, 0x0c, 0x38, 0xaf, 0x65, 0x68, 0x16,
0x05, 0x7b, 0x2f, 0xad, 0x60, 0xfa, 0x3b, 0xe0, 0xd8, 0x90, 0x4a, 0xb7, 0xde, 0x84, 0xc6, 0xd6,
0xb0, 0xdf, 0x8f, 0x5d, 0xae, 0xcb, 0xd0, 0x08, 0xe5, 0x4f, 0x79, 0x45, 0x92, 0xe7, 0x6f, 0x5d,
0xc1, 0xf8, 0x45, 0xc8, 0xbc, 0x0a, 0x4d, 0x45, 0xa2, 0xb8, 0xee, 0x40, 0x35, 0x54, 0xbf, 0x15,
0x7e, 0xfc, 0x6d, 0xae, 0xc0, 0x92, 0x45, 0x7a, 0x5c, 0xb5, 0xc3, 0x7b, 0xae, 0xff, 0x48, 0x0d,
0x63, 0x7e, 0xc7, 0x80, 0xe5, 0x34, 0x5c, 0xf5, 0xf5, 0x36, 0x54, 0xb0, 0xe3, 0x84, 0x84, 0xd2,
0x89, 0xcb, 0x72, 0x53, 0xe2, 0x58, 0x11, 0x72, 0x42, 0x72, 0x85, 0xa9, 0x25, 0x67, 0xda, 0x70,
0xee, 0x0e, 0x61, 0xf7, 0x09, 0x0b, 0x67, 0xca, 0xe0, 0xb7, 0xf9, 0xe5, 0x45, 0x10, 0x2b, 0xb5,
0x88, 0x3e, 0xcd, 0xcf, 0x0c, 0x40, 0xc9, 0x11, 0x66, 0x59, 0xe6, 0xa4, 0x94, 0x0b, 0x69, 0x29,
0xcb, 0x22, 0xa7, 0xfe, 0x20, 0xf0, 0x89, 0xcf, 0x92, 0xee, 0x56, 0x33, 0x86, 0x0a, 0xf5, 0xfb,
0x91, 0x01, 0xe8, 0x5e, 0x80, 0x9d, 0x5b, 0xd8, 0x9b, 0xcd, 0x3d, 0xb8, 0x08, 0x40, 0xc3, 0xae,
0xad, 0x76, 0x6b, 0x41, 0x59, 0x9f, 0xb0, 0xfb, 0x40, 0x6e, 0xd8, 0x4b, 0x50, 0x77, 0x28, 0x53,
0xcd, 0x51, 0x42, 0x19, 0x1c, 0xca, 0x64, 0xbb, 0x28, 0x62, 0xa5, 0x04, 0x7b, 0xc4, 0xb1, 0x13,
0xf9, 0xb8, 0x79, 0x81, 0xd6, 0x92, 0x0d, 0xbb, 0xa3, 0xac, 0xdc, 0x43, 0x58, 0xbb, 0x8f, 0xfd,
0x21, 0xf6, 0x6e, 0x07, 0xfd, 0x01, 0x4e, 0x15, 0x36, 0x66, 0xcd, 0x9c, 0xa1, 0x31, 0x73, 0x2f,
0xca, 0xca, 0x37, 0xe9, 0x5a, 0x0b, 0x5e, 0xe7, 0xad, 0x04, 0xc4, 0xa4, 0xd0, 0x1e, 0xef, 0x7e,
0x96, 0x85, 0x12, 0x4c, 0x45, 0x5d, 0x25, 0x6d, 0xef, 0x08, 0x66, 0xbe, 0x0f, 0x2f, 0x88, 0x2a,
0xc4, 0x08, 0x94, 0x0a, 0xed, 0x67, 0x3b, 0x30, 0x34, 0x1d, 0xfc, 0x6a, 0x41, 0x98, 0xb6, 0xb1,
0x1e, 0x66, 0x61, 0xfc, 0xdd, 0x74, 0x44, 0xfd, 0xe5, 0x9c, 0x4a, 0xdb, 0xf4, 0x88, 0x2a, 0xac,
0xbe, 0x01, 0x8b, 0xe4, 0x09, 0xe9, 0x0e, 0x99, 0xeb, 0xf7, 0x76, 0x3c, 0xec, 0x3f, 0x08, 0xd4,
0x81, 0x92, 0x05, 0xa3, 0x97, 0xa1, 0xc9, 0xa5, 0x1f, 0x0c, 0x99, 0xc2, 0x93, 0x27, 0x4b, 0x1a,
0xc8, 0xfb, 0xe3, 0xf3, 0xf5, 0x08, 0x23, 0x8e, 0xc2, 0x93, 0xc7, 0x4c, 0x16, 0x3c, 0x26, 0x4a,
0x0e, 0xa6, 0x27, 0x11, 0xe5, 0xbf, 0x1b, 0x19, 0x51, 0xaa, 0x1e, 0x4e, 0x4b, 0x94, 0x77, 0x01,
0xfa, 0x24, 0xec, 0x91, 0x6d, 0x61, 0xd4, 0xe5, 0xcd, 0x7d, 0x43, 0x6b, 0xd4, 0x47, 0x1d, 0xdc,
0x8f, 0x08, 0xac, 0x04, 0xad, 0x79, 0x07, 0x96, 0x34, 0x28, 0xdc, 0x5e, 0xd1, 0x60, 0x18, 0x76,
0x49, 0x14, 0xfc, 0x89, 0x3e, 0xf9, 0xf9, 0xc6, 0x70, 0xd8, 0x23, 0x4c, 0x29, 0xad, 0xfa, 0x32,
0xdf, 0x16, 0x49, 0x28, 0x11, 0x28, 0x48, 0x69, 0x6a, 0x3a, 0xa1, 0x6e, 0x8c, 0x25, 0xd4, 0xf7,
0x45, 0xc6, 0x27, 0x49, 0x37, 0x63, 0x31, 0xc4, 0x3e, 0xef, 0x8a, 0x38, 0xea, 0x95, 0x45, 0xf4,
0xc9, 0xbd, 0xe4, 0xe6, 0x76, 0x7f, 0x10, 0x8c, 0x92, 0x1d, 0x53, 0x5f, 0x25, 0xc7, 0x83, 0xc5,
0x05, 0x5d, 0xb0, 0xf8, 0x3c, 0xd4, 0xc2, 0xe0, 0xd0, 0xe6, 0xd6, 0xcf, 0x11, 0x9a, 0x5d, 0xb5,
0xaa, 0x61, 0x70, 0xc8, 0x6d, 0xa2, 0x83, 0x96, 0xa1, 0xb4, 0xef, 0x7a, 0xf1, 0x85, 0x51, 0x7e,
0xa0, 0xf7, 0xf8, 0x1d, 0x4a, 0x66, 0x5c, 0xa7, 0x4e, 0xcf, 0x47, 0x14, 0xe6, 0x27, 0xb0, 0x10,
0x4d, 0x68, 0xc6, 0x97, 0x23, 0x0c, 0xd3, 0x47, 0x51, 0xb1, 0x83, 0xfc, 0x30, 0xaf, 0xca, 0x44,
0x9c, 0xe8, 0x3f, 0xb5, 0x9e, 0x08, 0xe6, 0x39, 0x86, 0xda, 0x26, 0xe2, 0xb7, 0xf9, 0xbf, 0x06,
0xac, 0x66, 0xb1, 0x67, 0x61, 0xe9, 0xed, 0xf4, 0xd6, 0xd0, 0x3f, 0x0e, 0x48, 0x8e, 0xa6, 0xb6,
0x85, 0x5a, 0x81, 0x6e, 0x30, 0xf4, 0x99, 0xb2, 0x2d, 0x7c, 0x05, 0x6e, 0xf3, 0x6f, 0xb4, 0x06,
0x15, 0xd7, 0xb1, 0x3d, 0x7e, 0xdd, 0x92, 0xc7, 0x48, 0xd9, 0x75, 0xee, 0xf1, 0xab, 0xd8, 0x3b,
0x91, 0x73, 0x34, 0xf5, 0x12, 0x28, 0xc7, 0xe8, 0xfb, 0xf2, 0xe8, 0xb6, 0x64, 0x95, 0xfd, 0x33,
0xae, 0x83, 0xd9, 0x80, 0xd6, 0xa1, 0xcb, 0x0e, 0x6c, 0xf1, 0xcc, 0x42, 0x9c, 0x9b, 0x54, 0x29,
0xd9, 0x02, 0x87, 0xef, 0x72, 0x30, 0x3f, 0x3b, 0xa9, 0xf9, 0x6b, 0x06, 0x2c, 0xa5, 0xd8, 0x9a,
0x65, 0x29, 0xbe, 0xc2, 0x5d, 0x0a, 0xd9, 0x91, 0x72, 0x1e, 0xd7, 0xb5, 0x76, 0x46, 0x8d, 0x26,
0xec, 0x4b, 0x4c, 0x61, 0xfe, 0x87, 0x01, 0xf5, 0x44, 0x0b, 0xbf, 0x91, 0xa8, 0xb6, 0xd1, 0x8d,
0x24, 0x06, 0x4c, 0x25, 0x86, 0x97, 0x60, 0xb4, 0xeb, 0x12, 0xa5, 0xda, 0x89, 0x52, 0x34, 0x87,
0xa2, 0xbb, 0xb0, 0x20, 0xc5, 0x14, 0xb3, 0xae, 0x0d, 0x14, 0xc4, 0x45, 0x76, 0x38, 0x74, 0x14,
0x97, 0x56, 0x93, 0x26, 0xbe, 0x64, 0x5e, 0x30, 0x70, 0x88, 0x18, 0xa9, 0x24, 0x0d, 0xa1, 0x70,
0x59, 0x1c, 0xca, 0x6f, 0x0e, 0x8d, 0x24, 0x29, 0xf7, 0xbe, 0x3c, 0x82, 0x1d, 0x12, 0xc6, 0x73,
0x8b, 0xbf, 0xb9, 0xbb, 0x23, 0x7f, 0xdb, 0xdc, 0x1b, 0x55, 0xf6, 0x03, 0x24, 0x88, 0x3b, 0xaa,
0xe8, 0x55, 0x58, 0x74, 0xfa, 0xa9, 0x37, 0x3e, 0x91, 0x7f, 0xe6, 0xf4, 0x13, 0x8f, 0x7b, 0x52,
0x0c, 0xcd, 0xa7, 0x19, 0xfa, 0x1f, 0x23, 0x7e, 0xf9, 0x18, 0x12, 0x87, 0xf8, 0xcc, 0xc5, 0xde,
0xd3, 0xeb, 0x64, 0x07, 0xaa, 0x43, 0x4a, 0xc2, 0x84, 0xb9, 0x8b, 0xbf, 0x79, 0xdb, 0x00, 0x53,
0x7a, 0x18, 0x84, 0x8e, 0xe2, 0x32, 0xfe, 0x9e, 0x50, 0xd7, 0x27, 0x5f, 0xd5, 0xe9, 0xeb, 0xfa,
0xde, 0x86, 0xb5, 0x7e, 0xe0, 0xb8, 0xfb, 0xae, 0xae, 0x1c, 0x90, 0x93, 0xad, 0x44, 0xcd, 0x29,
0x3a, 0xb3, 0x07, 0x6b, 0x32, 0x99, 0xf8, 0x8c, 0xa7, 0x6c, 0xfe, 0x12, 0xac, 0x70, 0x63, 0xc1,
0x87, 0xf9, 0x98, 0x92, 0x70, 0xc6, 0x5d, 0x75, 0x01, 0x6a, 0x51, 0xcf, 0x51, 0xc9, 0xe5, 0x08,
0x60, 0xde, 0x85, 0xe5, 0xcc, 0x58, 0x4f, 0x39, 0xa3, 0x2b, 0x97, 0xa1, 0x1a, 0x95, 0x90, 0xa2,
0x0a, 0x14, 0x6f, 0x7a, 0x5e, 0x6b, 0x0e, 0x35, 0xa0, 0xba, 0xad, 0xea, 0x24, 0x5b, 0xc6, 0x95,
0x9f, 0x83, 0xc5, 0x4c, 0xaa, 0x11, 0x55, 0x61, 0xfe, 0x41, 0xe0, 0x93, 0xd6, 0x1c, 0x6a, 0x41,
0xe3, 0x96, 0xeb, 0xe3, 0xf0, 0x48, 0x06, 0xe2, 0x5a, 0x0e, 0x5a, 0x84, 0xba, 0x08, 0x48, 0x29,
0x00, 0xd9, 0xfc, 0xf1, 0xcb, 0xd0, 0xbc, 0x2f, 0x18, 0xd9, 0x25, 0xe1, 0x63, 0xb7, 0x4b, 0x90,
0x0d, 0xad, 0xec, 0x03, 0x5c, 0xf4, 0x05, 0xbd, 0x73, 0xa2, 0x7f, 0xa7, 0xdb, 0x99, 0x24, 0x43,
0x73, 0x0e, 0x7d, 0x02, 0x0b, 0xe9, 0x67, 0xac, 0x48, 0x1f, 0x31, 0xd1, 0xbe, 0x75, 0x3d, 0xae,
0x73, 0x1b, 0x9a, 0xa9, 0x57, 0xa9, 0xe8, 0x75, 0x6d, 0xdf, 0xba, 0x97, 0xab, 0x1d, 0xbd, 0x7d,
0x49, 0xbe, 0x1c, 0x95, 0xdc, 0xa7, 0x9f, 0x8e, 0xe5, 0x70, 0xaf, 0x7d, 0x5f, 0x76, 0x1c, 0xf7,
0x18, 0xce, 0x8d, 0x3d, 0xf1, 0x42, 0x6f, 0xe4, 0x58, 0x6c, 0xfd, 0x53, 0xb0, 0xe3, 0x86, 0x38,
0x04, 0x34, 0xfe, 0xfa, 0x12, 0x5d, 0xd3, 0xaf, 0x40, 0xde, 0xdb, 0xd3, 0xce, 0xf5, 0xa9, 0xf1,
0x63, 0xc1, 0xfd, 0x8a, 0x01, 0x6b, 0x39, 0xef, 0xb2, 0xd0, 0x0d, 0x6d, 0x77, 0x93, 0x1f, 0x97,
0x75, 0xde, 0x3a, 0x19, 0x51, 0xcc, 0x88, 0x0f, 0x8b, 0x99, 0xa7, 0x4a, 0xe8, 0x6a, 0x6e, 0xf9,
0xf6, 0xf8, 0x9b, 0xad, 0xce, 0x17, 0xa6, 0x43, 0x8e, 0xc7, 0x7b, 0x08, 0x8b, 0x99, 0xf7, 0x3d,
0x39, 0xe3, 0xe9, 0x5f, 0x01, 0x1d, 0xb7, 0xa0, 0xdf, 0x84, 0x66, 0xea, 0x21, 0x4e, 0x8e, 0xc6,
0xeb, 0x1e, 0xeb, 0x1c, 0xd7, 0xf5, 0x43, 0x68, 0x24, 0xdf, 0xcb, 0xa0, 0x8d, 0xbc, 0xbd, 0x34,
0xd6, 0xf1, 0x49, 0xb6, 0xd2, 0xa8, 0x1c, 0x7e, 0xc2, 0x56, 0x1a, 0x7b, 0x41, 0x30, 0xfd, 0x56,
0x4a, 0xf4, 0x3f, 0x71, 0x2b, 0x9d, 0x78, 0x88, 0xef, 0x48, 0xbf, 0x59, 0xf3, 0xdc, 0x02, 0x6d,
0xe6, 0xe9, 0x66, 0xfe, 0xc3, 0x92, 0xce, 0x8d, 0x13, 0xd1, 0xc4, 0x52, 0x7c, 0x04, 0x0b, 0xe9,
0x47, 0x05, 0x39, 0x52, 0xd4, 0xbe, 0xc3, 0xe8, 0x5c, 0x9d, 0x0a, 0x37, 0x1e, 0xec, 0x63, 0xa8,
0x27, 0xfe, 0x53, 0x03, 0xbd, 0x36, 0x41, 0x8f, 0x93, 0x7f, 0x30, 0x71, 0x9c, 0x24, 0xbf, 0x06,
0xb5, 0xf8, 0xaf, 0x30, 0xd0, 0x2b, 0xb9, 0xfa, 0x7b, 0x92, 0x2e, 0x77, 0x01, 0x46, 0xff, 0x73,
0x81, 0x5e, 0xd5, 0xf6, 0x39, 0xf6, 0x47, 0x18, 0xc7, 0x75, 0x1a, 0x4f, 0x5f, 0xd6, 0x6a, 0x4d,
0x9a, 0x7e, 0xb2, 0xb8, 0xf0, 0xb8, 0x6e, 0x0f, 0xa0, 0x99, 0x2a, 0x09, 0xce, 0xdb, 0xc2, 0x9a,
0x4a, 0xed, 0xce, 0x95, 0x69, 0x50, 0xe3, 0xf5, 0x3b, 0x80, 0x66, 0xaa, 0x40, 0x33, 0x67, 0x24,
0x5d, 0x3d, 0x6a, 0xce, 0x48, 0xda, 0x7a, 0x4f, 0x73, 0x0e, 0x7d, 0x3b, 0x51, 0x0b, 0x9a, 0xaa,
0xb7, 0x45, 0x6f, 0x4e, 0xec, 0x47, 0x57, 0x6e, 0xdc, 0xd9, 0x3c, 0x09, 0x49, 0xcc, 0x82, 0xd2,
0x2a, 0x29, 0xd2, 0x7c, 0xad, 0x3a, 0xc9, 0x4a, 0xed, 0x42, 0x59, 0x96, 0x5c, 0x22, 0x33, 0xa7,
0xb8, 0x3a, 0x51, 0x8f, 0xd9, 0x79, 0x49, 0x8b, 0x93, 0xae, 0x46, 0x94, 0x9d, 0x4a, 0x2f, 0x38,
0xa7, 0xd3, 0x54, 0xbd, 0xdd, 0xb4, 0x9d, 0x5a, 0x50, 0x96, 0xb5, 0x34, 0x39, 0x9d, 0xa6, 0xea,
0xc1, 0x3a, 0x93, 0x71, 0x44, 0x92, 0xd5, 0x9c, 0x43, 0x3b, 0x50, 0x12, 0x91, 0x1e, 0x74, 0x79,
0x52, 0x99, 0xc9, 0xa4, 0x1e, 0x53, 0x95, 0x28, 0xe6, 0x1c, 0xfa, 0x05, 0x28, 0x89, 0xbc, 0x45,
0x4e, 0x8f, 0xc9, 0x5a, 0x91, 0xce, 0x44, 0x94, 0x88, 0x45, 0x07, 0x1a, 0xc9, 0x04, 0x71, 0xce,
0x91, 0xa5, 0x49, 0xa1, 0x77, 0xa6, 0xc1, 0x8c, 0x46, 0x91, 0xdb, 0x68, 0x14, 0xf5, 0xca, 0xdf,
0x46, 0x63, 0x11, 0xb5, 0xfc, 0x6d, 0x34, 0x1e, 0x44, 0x33, 0xe7, 0xd0, 0xaf, 0x1b, 0xd0, 0xce,
0xcb, 0x5a, 0xa2, 0x5c, 0x0f, 0x68, 0x52, 0xea, 0xb5, 0xf3, 0xa5, 0x13, 0x52, 0xc5, 0xbc, 0x7c,
0x2a, 0x02, 0x13, 0x63, 0x79, 0xca, 0xeb, 0x79, 0xfd, 0xe5, 0x64, 0xe5, 0x3a, 0x5f, 0x9c, 0x9e,
0x20, 0x1e, 0x7b, 0x0f, 0xea, 0x89, 0xa0, 0x48, 0x8e, 0xe5, 0x1d, 0x8f, 0xe6, 0xe4, 0xac, 0xaa,
0x26, 0xbe, 0x22, 0xd5, 0x5b, 0xa4, 0xbd, 0x72, 0x94, 0x31, 0x99, 0x45, 0xcb, 0x51, 0xef, 0x54,
0xd6, 0xcc, 0x9c, 0x43, 0x04, 0x1a, 0xc9, 0x1c, 0x58, 0x8e, 0x36, 0x6a, 0xd2, 0x67, 0x9d, 0xd7,
0xa7, 0xc0, 0x8c, 0x87, 0xb1, 0x01, 0x46, 0x39, 0xa8, 0x9c, 0xb3, 0x6e, 0x2c, 0x0d, 0xd6, 0x79,
0xed, 0x58, 0xbc, 0xe4, 0xb1, 0x9f, 0xc8, 0x2a, 0xe5, 0x48, 0x7f, 0x3c, 0xef, 0x34, 0xc5, 0x5d,
0x64, 0x3c, 0xc3, 0x91, 0x73, 0x17, 0xc9, 0x4d, 0xa6, 0x74, 0xae, 0x4f, 0x8d, 0x1f, 0xcf, 0xe7,
0x5b, 0xd0, 0xca, 0x66, 0x84, 0x72, 0xee, 0xb8, 0x39, 0x79, 0xa9, 0xce, 0x1b, 0x53, 0x62, 0x27,
0xcf, 0xc3, 0xf3, 0xe3, 0x3c, 0x7d, 0xc3, 0x65, 0x07, 0x22, 0x19, 0x31, 0xcd, 0xac, 0x93, 0x79,
0x8f, 0x69, 0x66, 0x9d, 0xca, 0x72, 0xa8, 0xc3, 0x4b, 0x44, 0x5d, 0xf3, 0x0e, 0xaf, 0x64, 0x7c,
0x3d, 0xe7, 0x9c, 0x49, 0x87, 0xac, 0xa5, 0xfb, 0x99, 0x8e, 0x1d, 0xa3, 0x7c, 0x3f, 0x61, 0x2c,
0x1c, 0x9d, 0xe3, 0x7e, 0xea, 0x83, 0xd1, 0x42, 0xd1, 0x5b, 0xd9, 0x10, 0xd9, 0xe4, 0xd8, 0x44,
0x36, 0xac, 0x74, 0x7c, 0xf8, 0xa0, 0xf5, 0xf1, 0xc0, 0x79, 0xb6, 0x03, 0x64, 0x23, 0x5e, 0x39,
0x03, 0xe4, 0x04, 0xc6, 0xa6, 0xf0, 0x25, 0x53, 0xd1, 0xa7, 0x9c, 0xa3, 0x49, 0x17, 0xa1, 0xca,
0x39, 0x9a, 0xb4, 0x81, 0x33, 0x73, 0x6e, 0x73, 0x08, 0x8d, 0x9d, 0x30, 0x78, 0x72, 0x14, 0x05,
0x8e, 0x7e, 0x3a, 0xc6, 0xee, 0xd6, 0x37, 0x60, 0xc1, 0x8d, 0x71, 0x7a, 0xe1, 0xa0, 0x7b, 0xab,
0x2e, 0x03, 0x58, 0x3b, 0x9c, 0x78, 0xc7, 0xf8, 0xc5, 0x1b, 0x3d, 0x97, 0x1d, 0x0c, 0xf7, 0xb8,
0x64, 0xae, 0x4b, 0xb4, 0x37, 0xdc, 0x40, 0xfd, 0xba, 0xee, 0xfa, 0x8c, 0x84, 0x3e, 0xf6, 0xae,
0x8b, 0xa1, 0x14, 0x74, 0xb0, 0xf7, 0x87, 0x86, 0xb1, 0x57, 0x16, 0xa0, 0x1b, 0xff, 0x1f, 0x00,
0x00, 0xff, 0xff, 0x30, 0xd9, 0x29, 0x9e, 0x78, 0x50, 0x00, 0x00,
}
// Reference imports to suppress errors if they are not otherwise used.
@ -5835,6 +6062,11 @@ type MilvusServiceClient interface {
// https://wiki.lfaidata.foundation/display/MIL/MEP+24+--+Support+bulk+load
Import(ctx context.Context, in *ImportRequest, opts ...grpc.CallOption) (*ImportResponse, error)
GetImportState(ctx context.Context, in *GetImportStateRequest, opts ...grpc.CallOption) (*GetImportStateResponse, error)
// https://wiki.lfaidata.foundation/display/MIL/MEP+27+--+Support+Basic+Authentication
CreateCredential(ctx context.Context, in *CreateCredentialRequest, opts ...grpc.CallOption) (*commonpb.Status, error)
UpdateCredential(ctx context.Context, in *CreateCredentialRequest, opts ...grpc.CallOption) (*commonpb.Status, error)
DeleteCredential(ctx context.Context, in *DeleteCredentialRequest, opts ...grpc.CallOption) (*commonpb.Status, error)
ListCredUsers(ctx context.Context, in *ListCredUsersRequest, opts ...grpc.CallOption) (*ListCredUsersResponse, error)
}
type milvusServiceClient struct {
@ -6223,6 +6455,42 @@ func (c *milvusServiceClient) GetImportState(ctx context.Context, in *GetImportS
return out, nil
}
func (c *milvusServiceClient) CreateCredential(ctx context.Context, in *CreateCredentialRequest, opts ...grpc.CallOption) (*commonpb.Status, error) {
out := new(commonpb.Status)
err := c.cc.Invoke(ctx, "/milvus.proto.milvus.MilvusService/CreateCredential", in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *milvusServiceClient) UpdateCredential(ctx context.Context, in *CreateCredentialRequest, opts ...grpc.CallOption) (*commonpb.Status, error) {
out := new(commonpb.Status)
err := c.cc.Invoke(ctx, "/milvus.proto.milvus.MilvusService/UpdateCredential", in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *milvusServiceClient) DeleteCredential(ctx context.Context, in *DeleteCredentialRequest, opts ...grpc.CallOption) (*commonpb.Status, error) {
out := new(commonpb.Status)
err := c.cc.Invoke(ctx, "/milvus.proto.milvus.MilvusService/DeleteCredential", in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *milvusServiceClient) ListCredUsers(ctx context.Context, in *ListCredUsersRequest, opts ...grpc.CallOption) (*ListCredUsersResponse, error) {
out := new(ListCredUsersResponse)
err := c.cc.Invoke(ctx, "/milvus.proto.milvus.MilvusService/ListCredUsers", in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
// MilvusServiceServer is the server API for MilvusService service.
type MilvusServiceServer interface {
CreateCollection(context.Context, *CreateCollectionRequest) (*commonpb.Status, error)
@ -6270,6 +6538,11 @@ type MilvusServiceServer interface {
// https://wiki.lfaidata.foundation/display/MIL/MEP+24+--+Support+bulk+load
Import(context.Context, *ImportRequest) (*ImportResponse, error)
GetImportState(context.Context, *GetImportStateRequest) (*GetImportStateResponse, error)
// https://wiki.lfaidata.foundation/display/MIL/MEP+27+--+Support+Basic+Authentication
CreateCredential(context.Context, *CreateCredentialRequest) (*commonpb.Status, error)
UpdateCredential(context.Context, *CreateCredentialRequest) (*commonpb.Status, error)
DeleteCredential(context.Context, *DeleteCredentialRequest) (*commonpb.Status, error)
ListCredUsers(context.Context, *ListCredUsersRequest) (*ListCredUsersResponse, error)
}
// UnimplementedMilvusServiceServer can be embedded to have forward compatible implementations.
@ -6402,6 +6675,18 @@ func (*UnimplementedMilvusServiceServer) Import(ctx context.Context, req *Import
func (*UnimplementedMilvusServiceServer) GetImportState(ctx context.Context, req *GetImportStateRequest) (*GetImportStateResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method GetImportState not implemented")
}
func (*UnimplementedMilvusServiceServer) CreateCredential(ctx context.Context, req *CreateCredentialRequest) (*commonpb.Status, error) {
return nil, status.Errorf(codes.Unimplemented, "method CreateCredential not implemented")
}
func (*UnimplementedMilvusServiceServer) UpdateCredential(ctx context.Context, req *CreateCredentialRequest) (*commonpb.Status, error) {
return nil, status.Errorf(codes.Unimplemented, "method UpdateCredential not implemented")
}
func (*UnimplementedMilvusServiceServer) DeleteCredential(ctx context.Context, req *DeleteCredentialRequest) (*commonpb.Status, error) {
return nil, status.Errorf(codes.Unimplemented, "method DeleteCredential not implemented")
}
func (*UnimplementedMilvusServiceServer) ListCredUsers(ctx context.Context, req *ListCredUsersRequest) (*ListCredUsersResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method ListCredUsers not implemented")
}
func RegisterMilvusServiceServer(s *grpc.Server, srv MilvusServiceServer) {
s.RegisterService(&_MilvusService_serviceDesc, srv)
@ -7163,6 +7448,78 @@ func _MilvusService_GetImportState_Handler(srv interface{}, ctx context.Context,
return interceptor(ctx, in, info, handler)
}
func _MilvusService_CreateCredential_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(CreateCredentialRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(MilvusServiceServer).CreateCredential(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/milvus.proto.milvus.MilvusService/CreateCredential",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(MilvusServiceServer).CreateCredential(ctx, req.(*CreateCredentialRequest))
}
return interceptor(ctx, in, info, handler)
}
func _MilvusService_UpdateCredential_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(CreateCredentialRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(MilvusServiceServer).UpdateCredential(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/milvus.proto.milvus.MilvusService/UpdateCredential",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(MilvusServiceServer).UpdateCredential(ctx, req.(*CreateCredentialRequest))
}
return interceptor(ctx, in, info, handler)
}
func _MilvusService_DeleteCredential_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(DeleteCredentialRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(MilvusServiceServer).DeleteCredential(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/milvus.proto.milvus.MilvusService/DeleteCredential",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(MilvusServiceServer).DeleteCredential(ctx, req.(*DeleteCredentialRequest))
}
return interceptor(ctx, in, info, handler)
}
func _MilvusService_ListCredUsers_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(ListCredUsersRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(MilvusServiceServer).ListCredUsers(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/milvus.proto.milvus.MilvusService/ListCredUsers",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(MilvusServiceServer).ListCredUsers(ctx, req.(*ListCredUsersRequest))
}
return interceptor(ctx, in, info, handler)
}
var _MilvusService_serviceDesc = grpc.ServiceDesc{
ServiceName: "milvus.proto.milvus.MilvusService",
HandlerType: (*MilvusServiceServer)(nil),
@ -7335,6 +7692,22 @@ var _MilvusService_serviceDesc = grpc.ServiceDesc{
MethodName: "GetImportState",
Handler: _MilvusService_GetImportState_Handler,
},
{
MethodName: "CreateCredential",
Handler: _MilvusService_CreateCredential_Handler,
},
{
MethodName: "UpdateCredential",
Handler: _MilvusService_UpdateCredential_Handler,
},
{
MethodName: "DeleteCredential",
Handler: _MilvusService_DeleteCredential_Handler,
},
{
MethodName: "ListCredUsers",
Handler: _MilvusService_ListCredUsers_Handler,
},
},
Streams: []grpc.StreamDesc{},
Metadata: "milvus.proto",

View File

@ -18,6 +18,10 @@ service Proxy {
rpc SendSearchResult(internal.SearchResults) returns (common.Status) {}
rpc SendRetrieveResult(internal.RetrieveResults) returns (common.Status) {}
rpc InvalidateCredentialCache(InvalidateCredCacheRequest) returns (common.Status) {}
rpc UpdateCredentialCache(UpdateCredCacheRequest) returns (common.Status) {}
rpc ClearCredUsersCache(internal.ClearCredUsersCacheRequest) returns (common.Status) {}
}
message InvalidateCollMetaCacheRequest {
@ -31,3 +35,14 @@ message ReleaseDQLMessageStreamRequest {
int64 dbID = 2;
int64 collectionID = 3;
}
message InvalidateCredCacheRequest {
common.MsgBase base = 1;
string username = 2;
}
message UpdateCredCacheRequest {
common.MsgBase base = 1;
string username = 2;
string password = 3;
}

View File

@ -137,44 +137,154 @@ func (m *ReleaseDQLMessageStreamRequest) GetCollectionID() int64 {
return 0
}
type InvalidateCredCacheRequest struct {
Base *commonpb.MsgBase `protobuf:"bytes,1,opt,name=base,proto3" json:"base,omitempty"`
Username string `protobuf:"bytes,2,opt,name=username,proto3" json:"username,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *InvalidateCredCacheRequest) Reset() { *m = InvalidateCredCacheRequest{} }
func (m *InvalidateCredCacheRequest) String() string { return proto.CompactTextString(m) }
func (*InvalidateCredCacheRequest) ProtoMessage() {}
func (*InvalidateCredCacheRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_700b50b08ed8dbaf, []int{2}
}
func (m *InvalidateCredCacheRequest) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_InvalidateCredCacheRequest.Unmarshal(m, b)
}
func (m *InvalidateCredCacheRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_InvalidateCredCacheRequest.Marshal(b, m, deterministic)
}
func (m *InvalidateCredCacheRequest) XXX_Merge(src proto.Message) {
xxx_messageInfo_InvalidateCredCacheRequest.Merge(m, src)
}
func (m *InvalidateCredCacheRequest) XXX_Size() int {
return xxx_messageInfo_InvalidateCredCacheRequest.Size(m)
}
func (m *InvalidateCredCacheRequest) XXX_DiscardUnknown() {
xxx_messageInfo_InvalidateCredCacheRequest.DiscardUnknown(m)
}
var xxx_messageInfo_InvalidateCredCacheRequest proto.InternalMessageInfo
func (m *InvalidateCredCacheRequest) GetBase() *commonpb.MsgBase {
if m != nil {
return m.Base
}
return nil
}
func (m *InvalidateCredCacheRequest) GetUsername() string {
if m != nil {
return m.Username
}
return ""
}
type UpdateCredCacheRequest struct {
Base *commonpb.MsgBase `protobuf:"bytes,1,opt,name=base,proto3" json:"base,omitempty"`
Username string `protobuf:"bytes,2,opt,name=username,proto3" json:"username,omitempty"`
Password string `protobuf:"bytes,3,opt,name=password,proto3" json:"password,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *UpdateCredCacheRequest) Reset() { *m = UpdateCredCacheRequest{} }
func (m *UpdateCredCacheRequest) String() string { return proto.CompactTextString(m) }
func (*UpdateCredCacheRequest) ProtoMessage() {}
func (*UpdateCredCacheRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_700b50b08ed8dbaf, []int{3}
}
func (m *UpdateCredCacheRequest) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_UpdateCredCacheRequest.Unmarshal(m, b)
}
func (m *UpdateCredCacheRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_UpdateCredCacheRequest.Marshal(b, m, deterministic)
}
func (m *UpdateCredCacheRequest) XXX_Merge(src proto.Message) {
xxx_messageInfo_UpdateCredCacheRequest.Merge(m, src)
}
func (m *UpdateCredCacheRequest) XXX_Size() int {
return xxx_messageInfo_UpdateCredCacheRequest.Size(m)
}
func (m *UpdateCredCacheRequest) XXX_DiscardUnknown() {
xxx_messageInfo_UpdateCredCacheRequest.DiscardUnknown(m)
}
var xxx_messageInfo_UpdateCredCacheRequest proto.InternalMessageInfo
func (m *UpdateCredCacheRequest) GetBase() *commonpb.MsgBase {
if m != nil {
return m.Base
}
return nil
}
func (m *UpdateCredCacheRequest) GetUsername() string {
if m != nil {
return m.Username
}
return ""
}
func (m *UpdateCredCacheRequest) GetPassword() string {
if m != nil {
return m.Password
}
return ""
}
func init() {
proto.RegisterType((*InvalidateCollMetaCacheRequest)(nil), "milvus.proto.proxy.InvalidateCollMetaCacheRequest")
proto.RegisterType((*ReleaseDQLMessageStreamRequest)(nil), "milvus.proto.proxy.ReleaseDQLMessageStreamRequest")
proto.RegisterType((*InvalidateCredCacheRequest)(nil), "milvus.proto.proxy.InvalidateCredCacheRequest")
proto.RegisterType((*UpdateCredCacheRequest)(nil), "milvus.proto.proxy.UpdateCredCacheRequest")
}
func init() { proto.RegisterFile("proxy.proto", fileDescriptor_700b50b08ed8dbaf) }
var fileDescriptor_700b50b08ed8dbaf = []byte{
// 460 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x52, 0x61, 0x6b, 0x13, 0x41,
0x10, 0xed, 0x99, 0xb6, 0xe2, 0x36, 0x54, 0x59, 0x84, 0x96, 0xa8, 0xa5, 0x9c, 0xa2, 0x45, 0x30,
0x29, 0xd1, 0x5f, 0xd0, 0x04, 0x42, 0xc0, 0x88, 0xee, 0x7d, 0x10, 0xf4, 0x83, 0xcc, 0xdd, 0x0d,
0xc9, 0xc2, 0xde, 0xee, 0x75, 0x77, 0x2e, 0xe8, 0x5f, 0xf0, 0xb3, 0xff, 0xd1, 0xbf, 0x21, 0xb7,
0x77, 0x49, 0x7b, 0x6d, 0x2f, 0xc1, 0x7e, 0xbb, 0x99, 0x7d, 0x33, 0xef, 0xbd, 0xb9, 0xc7, 0x0e,
0x72, 0x6b, 0x7e, 0xfe, 0xea, 0xe7, 0xd6, 0x90, 0xe1, 0x3c, 0x93, 0x6a, 0x59, 0xb8, 0xaa, 0xea,
0xfb, 0x97, 0x5e, 0x37, 0x31, 0x59, 0x66, 0x74, 0xd5, 0xeb, 0x1d, 0x4a, 0x4d, 0x68, 0x35, 0xa8,
0xba, 0xee, 0x5e, 0x9f, 0x08, 0xff, 0x04, 0xec, 0x64, 0xaa, 0x97, 0xa0, 0x64, 0x0a, 0x84, 0x23,
0xa3, 0xd4, 0x0c, 0x09, 0x46, 0x90, 0x2c, 0x50, 0xe0, 0x65, 0x81, 0x8e, 0xf8, 0x39, 0xdb, 0x8d,
0xc1, 0xe1, 0x71, 0x70, 0x1a, 0x9c, 0x1d, 0x0c, 0x9f, 0xf7, 0x1b, 0x8c, 0x35, 0xd5, 0xcc, 0xcd,
0x2f, 0xc0, 0xa1, 0xf0, 0x48, 0x7e, 0xc4, 0x1e, 0xa6, 0xf1, 0x0f, 0x0d, 0x19, 0x1e, 0x3f, 0x38,
0x0d, 0xce, 0x1e, 0x89, 0xfd, 0x34, 0xfe, 0x04, 0x19, 0xf2, 0x37, 0xec, 0x71, 0x62, 0x94, 0xc2,
0x84, 0xa4, 0xd1, 0x15, 0xa0, 0xe3, 0x01, 0x87, 0x57, 0xed, 0x12, 0x18, 0xfe, 0x0e, 0xd8, 0x89,
0x40, 0x85, 0xe0, 0x70, 0xfc, 0xe5, 0xe3, 0x0c, 0x9d, 0x83, 0x39, 0x46, 0x64, 0x11, 0xb2, 0xfb,
0xcb, 0xe2, 0x6c, 0x37, 0x8d, 0xa7, 0x63, 0xaf, 0xa9, 0x23, 0xfc, 0x37, 0x0f, 0x59, 0xf7, 0x8a,
0x7a, 0x3a, 0xf6, 0x72, 0x3a, 0xa2, 0xd1, 0x1b, 0xfe, 0xdd, 0x63, 0x7b, 0x9f, 0xcb, 0xcb, 0xf2,
0x9c, 0xf1, 0x09, 0xd2, 0xc8, 0x64, 0xb9, 0xd1, 0xa8, 0x29, 0x22, 0x20, 0x74, 0xfc, 0xbc, 0xc9,
0xbd, 0xbe, 0xf7, 0x6d, 0x68, 0xad, 0xbd, 0xf7, 0xba, 0x65, 0xe2, 0x06, 0x3c, 0xdc, 0xe1, 0x97,
0xec, 0xe9, 0x04, 0x7d, 0x29, 0x1d, 0xc9, 0xc4, 0x8d, 0x16, 0xa0, 0x35, 0x2a, 0x3e, 0x6c, 0xe7,
0xbc, 0x05, 0x5e, 0xb1, 0xbe, 0x6c, 0xce, 0xd4, 0x45, 0x44, 0x56, 0xea, 0xb9, 0x40, 0x97, 0x1b,
0xed, 0x30, 0xdc, 0xe1, 0x96, 0xbd, 0x68, 0x26, 0xa2, 0x3a, 0xc4, 0x3a, 0x17, 0x37, 0xb9, 0xab,
0x38, 0x6e, 0x0e, 0x51, 0xef, 0xd9, 0x9d, 0xff, 0xa7, 0x94, 0x5a, 0x94, 0x36, 0x81, 0x75, 0x27,
0x48, 0xe3, 0x74, 0x65, 0xef, 0x6d, 0xbb, 0xbd, 0x35, 0xe8, 0x3f, 0x6d, 0x29, 0x76, 0xd4, 0x92,
0xa8, 0xbb, 0x0d, 0x6d, 0x8e, 0xdf, 0x36, 0x43, 0x5f, 0xd9, 0x93, 0x08, 0x75, 0x1a, 0x21, 0xd8,
0x64, 0x21, 0xd0, 0x15, 0x8a, 0xf8, 0xab, 0x16, 0x53, 0xd7, 0x41, 0x6e, 0xdb, 0xe2, 0xef, 0x8c,
0x97, 0x8b, 0x05, 0x92, 0x95, 0xb8, 0xc4, 0x7a, 0x75, 0x5b, 0xa0, 0x9a, 0xb0, 0x6d, 0xcb, 0x2f,
0x3e, 0x7c, 0x1b, 0xce, 0x25, 0x2d, 0x8a, 0xb8, 0x7c, 0x19, 0x54, 0xd0, 0x77, 0xd2, 0xd4, 0x5f,
0x83, 0xd5, 0xda, 0x81, 0x9f, 0x1e, 0xf8, 0x3b, 0xe5, 0x71, 0xbc, 0xef, 0xcb, 0xf7, 0xff, 0x02,
0x00, 0x00, 0xff, 0xff, 0x48, 0x84, 0x3c, 0x39, 0x99, 0x04, 0x00, 0x00,
// 560 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x94, 0xdd, 0x6e, 0xd3, 0x30,
0x14, 0xc7, 0x17, 0x3a, 0xc6, 0x38, 0xab, 0x06, 0x32, 0x1f, 0x1b, 0x01, 0xa6, 0x29, 0x20, 0x98,
0x26, 0xd1, 0x8e, 0xc2, 0x13, 0xac, 0x95, 0xaa, 0x4a, 0x14, 0x41, 0xaa, 0x09, 0x09, 0x2e, 0x90,
0x93, 0x1c, 0xb5, 0x9e, 0x1c, 0x3b, 0xb3, 0x9d, 0x02, 0xb7, 0x5c, 0x72, 0xcd, 0x03, 0xf0, 0xa8,
0x28, 0x1f, 0x4d, 0x9b, 0xb6, 0x59, 0xf8, 0xd0, 0xee, 0x72, 0xec, 0xff, 0xf1, 0xef, 0x1c, 0x1f,
0xff, 0x03, 0x3b, 0x91, 0x92, 0x5f, 0xbf, 0xb5, 0x22, 0x25, 0x8d, 0x24, 0x24, 0x64, 0x7c, 0x1a,
0xeb, 0x2c, 0x6a, 0xa5, 0x3b, 0x76, 0xd3, 0x97, 0x61, 0x28, 0x45, 0xb6, 0x66, 0xef, 0x32, 0x61,
0x50, 0x09, 0xca, 0xf3, 0xb8, 0xb9, 0x98, 0xe1, 0xfc, 0xb4, 0xe0, 0x60, 0x20, 0xa6, 0x94, 0xb3,
0x80, 0x1a, 0xec, 0x4a, 0xce, 0x87, 0x68, 0x68, 0x97, 0xfa, 0x13, 0x74, 0xf1, 0x22, 0x46, 0x6d,
0xc8, 0x09, 0x6c, 0x7a, 0x54, 0xe3, 0xbe, 0x75, 0x68, 0x1d, 0xed, 0x74, 0x1e, 0xb5, 0x4a, 0xc4,
0x1c, 0x35, 0xd4, 0xe3, 0x53, 0xaa, 0xd1, 0x4d, 0x95, 0x64, 0x0f, 0x6e, 0x04, 0xde, 0x67, 0x41,
0x43, 0xdc, 0xbf, 0x76, 0x68, 0x1d, 0xdd, 0x74, 0xb7, 0x02, 0xef, 0x2d, 0x0d, 0x91, 0x3c, 0x87,
0x5b, 0xbe, 0xe4, 0x1c, 0x7d, 0xc3, 0xa4, 0xc8, 0x04, 0x8d, 0x54, 0xb0, 0x3b, 0x5f, 0x4e, 0x84,
0xce, 0x0f, 0x0b, 0x0e, 0x5c, 0xe4, 0x48, 0x35, 0xf6, 0xde, 0xbf, 0x19, 0xa2, 0xd6, 0x74, 0x8c,
0x23, 0xa3, 0x90, 0x86, 0xff, 0x5e, 0x16, 0x81, 0xcd, 0xc0, 0x1b, 0xf4, 0xd2, 0x9a, 0x1a, 0x6e,
0xfa, 0x4d, 0x1c, 0x68, 0xce, 0xd1, 0x83, 0x5e, 0x5a, 0x4e, 0xc3, 0x2d, 0xad, 0x39, 0xe7, 0x60,
0x2f, 0x5c, 0x91, 0xc2, 0xe0, 0x3f, 0xaf, 0xc7, 0x86, 0xed, 0x58, 0x27, 0x23, 0x29, 0xee, 0xa7,
0x88, 0x9d, 0xef, 0x16, 0xdc, 0x3f, 0x8b, 0xae, 0x1e, 0x94, 0xec, 0x45, 0x54, 0xeb, 0x2f, 0x52,
0x05, 0xf9, 0x0c, 0x8a, 0xb8, 0xf3, 0x6b, 0x1b, 0xae, 0xbf, 0x4b, 0x9e, 0x12, 0x89, 0x80, 0xf4,
0xd1, 0x74, 0x65, 0x18, 0x49, 0x81, 0xc2, 0x8c, 0x0c, 0x35, 0xa8, 0xc9, 0x49, 0x99, 0x5d, 0x3c,
0xb0, 0x55, 0x69, 0x5e, 0xbb, 0xfd, 0xac, 0x22, 0x63, 0x49, 0xee, 0x6c, 0x90, 0x0b, 0xb8, 0xdb,
0xc7, 0x34, 0x64, 0xda, 0x30, 0x5f, 0x77, 0x27, 0x54, 0x08, 0xe4, 0xa4, 0x53, 0xcd, 0x5c, 0x11,
0xcf, 0xa8, 0x4f, 0xca, 0x39, 0x79, 0x30, 0x32, 0x8a, 0x89, 0xb1, 0x8b, 0x3a, 0x92, 0x42, 0xa3,
0xb3, 0x41, 0x14, 0x3c, 0x2e, 0x5b, 0x20, 0x9b, 0x7c, 0x61, 0x84, 0x65, 0x76, 0xe6, 0xbf, 0xcb,
0x5d, 0x63, 0x3f, 0x5c, 0x3b, 0x9f, 0xa4, 0xd4, 0x38, 0x69, 0x93, 0x42, 0xb3, 0x8f, 0xa6, 0x17,
0xcc, 0xda, 0x3b, 0xae, 0x6e, 0xaf, 0x10, 0xfd, 0x65, 0x5b, 0x1c, 0xf6, 0x2a, 0x2c, 0xb4, 0xbe,
0xa1, 0xcb, 0xfd, 0x56, 0xd7, 0xd0, 0x07, 0xb8, 0x3d, 0x42, 0x11, 0x8c, 0x90, 0x2a, 0x7f, 0xe2,
0xa2, 0x8e, 0xb9, 0x21, 0x4f, 0x2b, 0x9a, 0x5a, 0x14, 0xe9, 0xba, 0x83, 0x3f, 0x01, 0x49, 0x0e,
0x76, 0xd1, 0x28, 0x86, 0x53, 0xcc, 0x8f, 0xae, 0x7a, 0x50, 0x65, 0x59, 0xed, 0xe1, 0xe7, 0xf0,
0xa0, 0x6c, 0x6d, 0x14, 0x86, 0x51, 0x9e, 0x8d, 0xbd, 0x55, 0x33, 0xf6, 0x25, 0x83, 0xd6, 0xb1,
0x3c, 0xb8, 0x37, 0x77, 0xf6, 0x22, 0xe7, 0x78, 0x1d, 0x67, 0xfd, 0x4f, 0xa0, 0x8e, 0x31, 0x86,
0x3b, 0x5d, 0x8e, 0x54, 0x25, 0x79, 0x67, 0x1a, 0x95, 0xce, 0x08, 0x2f, 0xab, 0xec, 0xb7, 0xaa,
0xfd, 0x33, 0xd0, 0xe9, 0xeb, 0x8f, 0x9d, 0x31, 0x33, 0x93, 0xd8, 0x4b, 0x76, 0xda, 0x99, 0xf4,
0x05, 0x93, 0xf9, 0x57, 0x7b, 0x46, 0x68, 0xa7, 0xd9, 0xed, 0xb4, 0xa5, 0xc8, 0xf3, 0xb6, 0xd2,
0xf0, 0xd5, 0xef, 0x00, 0x00, 0x00, 0xff, 0xff, 0xf2, 0x58, 0x7c, 0x7f, 0xc3, 0x06, 0x00, 0x00,
}
// Reference imports to suppress errors if they are not otherwise used.
@ -196,6 +306,9 @@ type ProxyClient interface {
ReleaseDQLMessageStream(ctx context.Context, in *ReleaseDQLMessageStreamRequest, opts ...grpc.CallOption) (*commonpb.Status, error)
SendSearchResult(ctx context.Context, in *internalpb.SearchResults, opts ...grpc.CallOption) (*commonpb.Status, error)
SendRetrieveResult(ctx context.Context, in *internalpb.RetrieveResults, opts ...grpc.CallOption) (*commonpb.Status, error)
InvalidateCredentialCache(ctx context.Context, in *InvalidateCredCacheRequest, opts ...grpc.CallOption) (*commonpb.Status, error)
UpdateCredentialCache(ctx context.Context, in *UpdateCredCacheRequest, opts ...grpc.CallOption) (*commonpb.Status, error)
ClearCredUsersCache(ctx context.Context, in *internalpb.ClearCredUsersCacheRequest, opts ...grpc.CallOption) (*commonpb.Status, error)
}
type proxyClient struct {
@ -269,6 +382,33 @@ func (c *proxyClient) SendRetrieveResult(ctx context.Context, in *internalpb.Ret
return out, nil
}
func (c *proxyClient) InvalidateCredentialCache(ctx context.Context, in *InvalidateCredCacheRequest, opts ...grpc.CallOption) (*commonpb.Status, error) {
out := new(commonpb.Status)
err := c.cc.Invoke(ctx, "/milvus.proto.proxy.Proxy/InvalidateCredentialCache", in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *proxyClient) UpdateCredentialCache(ctx context.Context, in *UpdateCredCacheRequest, opts ...grpc.CallOption) (*commonpb.Status, error) {
out := new(commonpb.Status)
err := c.cc.Invoke(ctx, "/milvus.proto.proxy.Proxy/UpdateCredentialCache", in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *proxyClient) ClearCredUsersCache(ctx context.Context, in *internalpb.ClearCredUsersCacheRequest, opts ...grpc.CallOption) (*commonpb.Status, error) {
out := new(commonpb.Status)
err := c.cc.Invoke(ctx, "/milvus.proto.proxy.Proxy/ClearCredUsersCache", in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
// ProxyServer is the server API for Proxy service.
type ProxyServer interface {
GetComponentStates(context.Context, *internalpb.GetComponentStatesRequest) (*internalpb.ComponentStates, error)
@ -278,6 +418,9 @@ type ProxyServer interface {
ReleaseDQLMessageStream(context.Context, *ReleaseDQLMessageStreamRequest) (*commonpb.Status, error)
SendSearchResult(context.Context, *internalpb.SearchResults) (*commonpb.Status, error)
SendRetrieveResult(context.Context, *internalpb.RetrieveResults) (*commonpb.Status, error)
InvalidateCredentialCache(context.Context, *InvalidateCredCacheRequest) (*commonpb.Status, error)
UpdateCredentialCache(context.Context, *UpdateCredCacheRequest) (*commonpb.Status, error)
ClearCredUsersCache(context.Context, *internalpb.ClearCredUsersCacheRequest) (*commonpb.Status, error)
}
// UnimplementedProxyServer can be embedded to have forward compatible implementations.
@ -305,6 +448,15 @@ func (*UnimplementedProxyServer) SendSearchResult(ctx context.Context, req *inte
func (*UnimplementedProxyServer) SendRetrieveResult(ctx context.Context, req *internalpb.RetrieveResults) (*commonpb.Status, error) {
return nil, status.Errorf(codes.Unimplemented, "method SendRetrieveResult not implemented")
}
func (*UnimplementedProxyServer) InvalidateCredentialCache(ctx context.Context, req *InvalidateCredCacheRequest) (*commonpb.Status, error) {
return nil, status.Errorf(codes.Unimplemented, "method InvalidateCredentialCache not implemented")
}
func (*UnimplementedProxyServer) UpdateCredentialCache(ctx context.Context, req *UpdateCredCacheRequest) (*commonpb.Status, error) {
return nil, status.Errorf(codes.Unimplemented, "method UpdateCredentialCache not implemented")
}
func (*UnimplementedProxyServer) ClearCredUsersCache(ctx context.Context, req *internalpb.ClearCredUsersCacheRequest) (*commonpb.Status, error) {
return nil, status.Errorf(codes.Unimplemented, "method ClearCredUsersCache not implemented")
}
func RegisterProxyServer(s *grpc.Server, srv ProxyServer) {
s.RegisterService(&_Proxy_serviceDesc, srv)
@ -436,6 +588,60 @@ func _Proxy_SendRetrieveResult_Handler(srv interface{}, ctx context.Context, dec
return interceptor(ctx, in, info, handler)
}
func _Proxy_InvalidateCredentialCache_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(InvalidateCredCacheRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(ProxyServer).InvalidateCredentialCache(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/milvus.proto.proxy.Proxy/InvalidateCredentialCache",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(ProxyServer).InvalidateCredentialCache(ctx, req.(*InvalidateCredCacheRequest))
}
return interceptor(ctx, in, info, handler)
}
func _Proxy_UpdateCredentialCache_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(UpdateCredCacheRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(ProxyServer).UpdateCredentialCache(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/milvus.proto.proxy.Proxy/UpdateCredentialCache",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(ProxyServer).UpdateCredentialCache(ctx, req.(*UpdateCredCacheRequest))
}
return interceptor(ctx, in, info, handler)
}
func _Proxy_ClearCredUsersCache_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(internalpb.ClearCredUsersCacheRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(ProxyServer).ClearCredUsersCache(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/milvus.proto.proxy.Proxy/ClearCredUsersCache",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(ProxyServer).ClearCredUsersCache(ctx, req.(*internalpb.ClearCredUsersCacheRequest))
}
return interceptor(ctx, in, info, handler)
}
var _Proxy_serviceDesc = grpc.ServiceDesc{
ServiceName: "milvus.proto.proxy.Proxy",
HandlerType: (*ProxyServer)(nil),
@ -468,6 +674,18 @@ var _Proxy_serviceDesc = grpc.ServiceDesc{
MethodName: "SendRetrieveResult",
Handler: _Proxy_SendRetrieveResult_Handler,
},
{
MethodName: "InvalidateCredentialCache",
Handler: _Proxy_InvalidateCredentialCache_Handler,
},
{
MethodName: "UpdateCredentialCache",
Handler: _Proxy_UpdateCredentialCache_Handler,
},
{
MethodName: "ClearCredUsersCache",
Handler: _Proxy_ClearCredUsersCache_Handler,
},
},
Streams: []grpc.StreamDesc{},
Metadata: "proxy.proto",

View File

@ -112,6 +112,14 @@ service RootCoord {
rpc Import(milvus.ImportRequest) returns (milvus.ImportResponse) {}
rpc GetImportState(milvus.GetImportStateRequest) returns (milvus.GetImportStateResponse) {}
rpc ReportImport(ImportResult) returns (common.Status) {}
// https://wiki.lfaidata.foundation/display/MIL/MEP+27+--+Support+Basic+Authentication
rpc CreateCredential(internal.CredentialInfo) returns (common.Status) {}
rpc UpdateCredential(internal.CredentialInfo) returns (common.Status) {}
rpc DeleteCredential(milvus.DeleteCredentialRequest) returns (common.Status) {}
rpc ListCredUsers(milvus.ListCredUsersRequest) returns (milvus.ListCredUsersResponse) {}
// userd by proxy, not exposed to sdk
rpc GetCredential(GetCredentialRequest) returns (GetCredentialResponse) {}
}
message AllocTimestampRequest {
@ -172,3 +180,19 @@ message DescribeSegmentsResponse {
int64 collectionID = 2;
map<int64, SegmentInfos> segment_infos = 3; // segment_id -> segment infos
}
message GetCredentialRequest {
// Not useful for now
common.MsgBase base = 1;
// username
string username = 2;
}
message GetCredentialResponse {
// Contain error_code and reason
common.Status status = 1;
// username
string username = 2;
// password
string password = 3;
}

View File

@ -549,6 +549,113 @@ func (m *DescribeSegmentsResponse) GetSegmentInfos() map[int64]*SegmentInfos {
return nil
}
type GetCredentialRequest struct {
// Not useful for now
Base *commonpb.MsgBase `protobuf:"bytes,1,opt,name=base,proto3" json:"base,omitempty"`
// username
Username string `protobuf:"bytes,2,opt,name=username,proto3" json:"username,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *GetCredentialRequest) Reset() { *m = GetCredentialRequest{} }
func (m *GetCredentialRequest) String() string { return proto.CompactTextString(m) }
func (*GetCredentialRequest) ProtoMessage() {}
func (*GetCredentialRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_4513485a144f6b06, []int{9}
}
func (m *GetCredentialRequest) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_GetCredentialRequest.Unmarshal(m, b)
}
func (m *GetCredentialRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_GetCredentialRequest.Marshal(b, m, deterministic)
}
func (m *GetCredentialRequest) XXX_Merge(src proto.Message) {
xxx_messageInfo_GetCredentialRequest.Merge(m, src)
}
func (m *GetCredentialRequest) XXX_Size() int {
return xxx_messageInfo_GetCredentialRequest.Size(m)
}
func (m *GetCredentialRequest) XXX_DiscardUnknown() {
xxx_messageInfo_GetCredentialRequest.DiscardUnknown(m)
}
var xxx_messageInfo_GetCredentialRequest proto.InternalMessageInfo
func (m *GetCredentialRequest) GetBase() *commonpb.MsgBase {
if m != nil {
return m.Base
}
return nil
}
func (m *GetCredentialRequest) GetUsername() string {
if m != nil {
return m.Username
}
return ""
}
type GetCredentialResponse struct {
// Contain error_code and reason
Status *commonpb.Status `protobuf:"bytes,1,opt,name=status,proto3" json:"status,omitempty"`
// username
Username string `protobuf:"bytes,2,opt,name=username,proto3" json:"username,omitempty"`
// password
Password string `protobuf:"bytes,3,opt,name=password,proto3" json:"password,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *GetCredentialResponse) Reset() { *m = GetCredentialResponse{} }
func (m *GetCredentialResponse) String() string { return proto.CompactTextString(m) }
func (*GetCredentialResponse) ProtoMessage() {}
func (*GetCredentialResponse) Descriptor() ([]byte, []int) {
return fileDescriptor_4513485a144f6b06, []int{10}
}
func (m *GetCredentialResponse) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_GetCredentialResponse.Unmarshal(m, b)
}
func (m *GetCredentialResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_GetCredentialResponse.Marshal(b, m, deterministic)
}
func (m *GetCredentialResponse) XXX_Merge(src proto.Message) {
xxx_messageInfo_GetCredentialResponse.Merge(m, src)
}
func (m *GetCredentialResponse) XXX_Size() int {
return xxx_messageInfo_GetCredentialResponse.Size(m)
}
func (m *GetCredentialResponse) XXX_DiscardUnknown() {
xxx_messageInfo_GetCredentialResponse.DiscardUnknown(m)
}
var xxx_messageInfo_GetCredentialResponse proto.InternalMessageInfo
func (m *GetCredentialResponse) GetStatus() *commonpb.Status {
if m != nil {
return m.Status
}
return nil
}
func (m *GetCredentialResponse) GetUsername() string {
if m != nil {
return m.Username
}
return ""
}
func (m *GetCredentialResponse) GetPassword() string {
if m != nil {
return m.Password
}
return ""
}
func init() {
proto.RegisterType((*AllocTimestampRequest)(nil), "milvus.proto.rootcoord.AllocTimestampRequest")
proto.RegisterType((*AllocTimestampResponse)(nil), "milvus.proto.rootcoord.AllocTimestampResponse")
@ -561,93 +668,103 @@ func init() {
proto.RegisterMapType((map[int64]*etcdpb.IndexInfo)(nil), "milvus.proto.rootcoord.SegmentInfos.ExtraIndexInfosEntry")
proto.RegisterType((*DescribeSegmentsResponse)(nil), "milvus.proto.rootcoord.DescribeSegmentsResponse")
proto.RegisterMapType((map[int64]*SegmentInfos)(nil), "milvus.proto.rootcoord.DescribeSegmentsResponse.SegmentInfosEntry")
proto.RegisterType((*GetCredentialRequest)(nil), "milvus.proto.rootcoord.GetCredentialRequest")
proto.RegisterType((*GetCredentialResponse)(nil), "milvus.proto.rootcoord.GetCredentialResponse")
}
func init() { proto.RegisterFile("root_coord.proto", fileDescriptor_4513485a144f6b06) }
var fileDescriptor_4513485a144f6b06 = []byte{
// 1295 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x58, 0xed, 0x72, 0xda, 0x46,
0x14, 0x35, 0xe0, 0xcf, 0x0b, 0x06, 0x67, 0xc7, 0x8e, 0x29, 0xc9, 0xb4, 0x84, 0xb6, 0x31, 0xce,
0x07, 0x78, 0xc8, 0x4c, 0x9a, 0xe6, 0x9f, 0x0d, 0xa9, 0xc3, 0xb4, 0x9e, 0x49, 0x44, 0xd2, 0xe9,
0x57, 0x46, 0x15, 0xd2, 0x0d, 0xd6, 0x58, 0x68, 0xb1, 0x76, 0x89, 0xed, 0x9f, 0x7d, 0x82, 0xbe,
0x53, 0xfb, 0x00, 0x7d, 0x88, 0xbe, 0x48, 0x67, 0xb5, 0x92, 0x90, 0x84, 0x84, 0xe5, 0xa4, 0xff,
0xd8, 0xd5, 0xd1, 0x39, 0xf7, 0x9e, 0xbb, 0xba, 0xbb, 0x0b, 0x6c, 0x39, 0x94, 0x72, 0x55, 0xa7,
0xd4, 0x31, 0x5a, 0x13, 0x87, 0x72, 0x4a, 0x6e, 0x8f, 0x4d, 0xeb, 0xc3, 0x94, 0xc9, 0x51, 0x4b,
0x3c, 0x76, 0x9f, 0xd6, 0x4a, 0x3a, 0x1d, 0x8f, 0xa9, 0x2d, 0xe7, 0x6b, 0xa5, 0x30, 0xaa, 0x56,
0x36, 0x6d, 0x8e, 0x8e, 0xad, 0x59, 0xde, 0xb8, 0x38, 0x71, 0xe8, 0xe5, 0x95, 0x37, 0xd8, 0x32,
0x34, 0xae, 0x85, 0x25, 0x6a, 0x15, 0xe4, 0xba, 0xa1, 0x8e, 0x91, 0x6b, 0x72, 0xa2, 0xa1, 0xc2,
0xce, 0xa1, 0x65, 0x51, 0xfd, 0x8d, 0x39, 0x46, 0xc6, 0xb5, 0xf1, 0x44, 0xc1, 0xf3, 0x29, 0x32,
0x4e, 0x0e, 0x60, 0x79, 0xa8, 0x31, 0xac, 0xe6, 0xea, 0xb9, 0x66, 0xb1, 0x73, 0xb7, 0x15, 0x89,
0xcd, 0x0b, 0xe8, 0x84, 0x8d, 0x8e, 0x34, 0x86, 0x8a, 0x8b, 0x24, 0xdb, 0xb0, 0xa2, 0xd3, 0xa9,
0xcd, 0xab, 0x85, 0x7a, 0xae, 0xb9, 0xa9, 0xc8, 0x41, 0xe3, 0x8f, 0x1c, 0xdc, 0x8e, 0x2b, 0xb0,
0x09, 0xb5, 0x19, 0x92, 0x27, 0xb0, 0xca, 0xb8, 0xc6, 0xa7, 0xcc, 0x13, 0xb9, 0x93, 0x28, 0x32,
0x70, 0x21, 0x8a, 0x07, 0x25, 0x77, 0x61, 0x83, 0xfb, 0x4c, 0xd5, 0x7c, 0x3d, 0xd7, 0x5c, 0x56,
0x66, 0x13, 0x29, 0x31, 0xfc, 0x04, 0x65, 0x37, 0x84, 0x7e, 0xef, 0x7f, 0xc8, 0x2e, 0x1f, 0x66,
0xb6, 0xa0, 0x12, 0x30, 0x7f, 0x4a, 0x56, 0x65, 0xc8, 0xf7, 0x7b, 0x2e, 0x75, 0x41, 0xc9, 0xf7,
0x7b, 0x29, 0x79, 0xfc, 0x95, 0x87, 0x52, 0x7f, 0x3c, 0xa1, 0x0e, 0x57, 0x90, 0x4d, 0x2d, 0xfe,
0x71, 0x5a, 0xbb, 0xb0, 0xc6, 0x35, 0x76, 0xa6, 0x9a, 0x86, 0x27, 0xb8, 0x2a, 0x86, 0x7d, 0x83,
0x7c, 0x01, 0x45, 0xb1, 0x60, 0x6c, 0x6a, 0xa0, 0x78, 0x58, 0x70, 0x1f, 0x82, 0x3f, 0xd5, 0x37,
0xc8, 0x53, 0x58, 0x11, 0x1c, 0x58, 0x5d, 0xae, 0xe7, 0x9a, 0xe5, 0x4e, 0x3d, 0x51, 0x4d, 0x06,
0x28, 0x34, 0x51, 0x91, 0x70, 0x52, 0x83, 0x75, 0x86, 0xa3, 0x31, 0xda, 0x9c, 0x55, 0x57, 0xea,
0x85, 0x66, 0x41, 0x09, 0xc6, 0xe4, 0x33, 0x58, 0xd7, 0xa6, 0x9c, 0xaa, 0xa6, 0xc1, 0xaa, 0xab,
0xee, 0xb3, 0x35, 0x31, 0xee, 0x1b, 0x8c, 0xdc, 0x81, 0x0d, 0x87, 0x5e, 0xa8, 0xd2, 0x88, 0x35,
0x37, 0x9a, 0x75, 0x87, 0x5e, 0x74, 0xc5, 0x98, 0x7c, 0x03, 0x2b, 0xa6, 0xfd, 0x9e, 0xb2, 0xea,
0x7a, 0xbd, 0xd0, 0x2c, 0x76, 0xee, 0x25, 0xc6, 0xf2, 0x3d, 0x5e, 0xfd, 0xa8, 0x59, 0x53, 0x7c,
0xa5, 0x99, 0x8e, 0x22, 0xf1, 0x8d, 0x3f, 0x73, 0xb0, 0xdb, 0x43, 0xa6, 0x3b, 0xe6, 0x10, 0x07,
0x5e, 0x14, 0x1f, 0xbf, 0x2c, 0x1a, 0x50, 0xd2, 0xa9, 0x65, 0xa1, 0xce, 0x4d, 0x6a, 0x07, 0x25,
0x8c, 0xcc, 0x91, 0xcf, 0x01, 0xbc, 0x74, 0xfb, 0x3d, 0x56, 0x2d, 0xb8, 0x49, 0x86, 0x66, 0x1a,
0x53, 0xa8, 0x78, 0x81, 0x08, 0xe2, 0xbe, 0xfd, 0x9e, 0xce, 0xd1, 0xe6, 0x12, 0x68, 0xeb, 0x50,
0x9c, 0x68, 0x0e, 0x37, 0x23, 0xca, 0xe1, 0x29, 0xf1, 0xad, 0x04, 0x32, 0x5e, 0x39, 0x67, 0x13,
0x8d, 0x7f, 0xf3, 0x50, 0xf2, 0x74, 0x85, 0x26, 0x23, 0x3d, 0xd8, 0x10, 0x39, 0xa9, 0xc2, 0x27,
0xcf, 0x82, 0xbd, 0x56, 0x72, 0x4f, 0x6a, 0xc5, 0x02, 0x56, 0xd6, 0x87, 0x7e, 0xe8, 0x3d, 0x28,
0x9a, 0xb6, 0x81, 0x97, 0xaa, 0x2c, 0x4f, 0xde, 0x2d, 0xcf, 0x97, 0x51, 0x1e, 0xd1, 0x85, 0x5a,
0x81, 0xb6, 0x81, 0x97, 0x2e, 0x07, 0x98, 0xfe, 0x4f, 0x46, 0x10, 0x6e, 0xe1, 0x25, 0x77, 0x34,
0x35, 0xcc, 0x55, 0x70, 0xb9, 0xbe, 0xbd, 0x26, 0x26, 0x97, 0xa0, 0xf5, 0x42, 0xbc, 0x1d, 0x70,
0xb3, 0x17, 0x36, 0x77, 0xae, 0x94, 0x0a, 0x46, 0x67, 0x6b, 0xbf, 0xc3, 0x76, 0x12, 0x90, 0x6c,
0x41, 0xe1, 0x0c, 0xaf, 0x3c, 0xdb, 0xc5, 0x4f, 0xd2, 0x81, 0x95, 0x0f, 0x62, 0x29, 0xb9, 0x3e,
0xcf, 0xad, 0x0d, 0x37, 0xa1, 0x59, 0x26, 0x12, 0xfa, 0x3c, 0xff, 0x2c, 0xd7, 0xf8, 0x3b, 0x0f,
0xd5, 0xf9, 0xe5, 0xf6, 0x29, 0xbd, 0x22, 0xcb, 0x92, 0x1b, 0xc1, 0xa6, 0x57, 0xe8, 0x88, 0x75,
0x47, 0x69, 0xd6, 0xa5, 0x45, 0x18, 0xf1, 0x54, 0x7a, 0x58, 0x62, 0xa1, 0xa9, 0x1a, 0xc2, 0xad,
0x39, 0x48, 0x82, 0x7b, 0xcf, 0xa3, 0xee, 0x7d, 0x95, 0xa5, 0x84, 0x21, 0x17, 0x3b, 0xff, 0xec,
0xc2, 0x86, 0x42, 0x29, 0xef, 0x0a, 0x14, 0x99, 0x00, 0x39, 0x46, 0xde, 0xa5, 0xe3, 0x09, 0xb5,
0xd1, 0x96, 0xbd, 0x86, 0x91, 0x83, 0x28, 0x69, 0xb0, 0x31, 0xce, 0x43, 0xbd, 0xcf, 0xbd, 0x76,
0x3f, 0xe5, 0x8d, 0x18, 0xbc, 0xb1, 0x44, 0xc6, 0xae, 0xa2, 0xd8, 0xc2, 0xde, 0x98, 0xfa, 0x59,
0xf7, 0x54, 0xb3, 0x6d, 0xb4, 0x16, 0x29, 0xc6, 0xa0, 0xbe, 0x62, 0xec, 0x3b, 0xf0, 0x06, 0x03,
0xee, 0x98, 0xf6, 0xc8, 0xf7, 0xbc, 0xb1, 0x44, 0xce, 0x61, 0xfb, 0x18, 0x5d, 0x75, 0x93, 0x71,
0x53, 0x67, 0xbe, 0x60, 0x27, 0x5d, 0x70, 0x0e, 0x7c, 0x43, 0x49, 0x15, 0xb6, 0xba, 0x0e, 0x6a,
0x1c, 0xbb, 0xc1, 0x3a, 0x22, 0x8f, 0x12, 0x5f, 0x8d, 0xc3, 0x7c, 0xa1, 0x45, 0x8b, 0xb7, 0xb1,
0x44, 0x7e, 0x85, 0x72, 0xcf, 0xa1, 0x93, 0x10, 0xfd, 0x83, 0x44, 0xfa, 0x28, 0x28, 0x23, 0xb9,
0x0a, 0x9b, 0x2f, 0x35, 0x16, 0xe2, 0xde, 0x4f, 0xe4, 0x8e, 0x60, 0x7c, 0xea, 0x7b, 0x89, 0xd0,
0x23, 0x4a, 0xad, 0x90, 0x3d, 0x17, 0x40, 0xfc, 0x6f, 0x24, 0xa4, 0xd2, 0x4a, 0xce, 0x60, 0x0e,
0xe8, 0x4b, 0xb5, 0x33, 0xe3, 0x03, 0xe1, 0xb7, 0x50, 0x94, 0x86, 0x1f, 0x5a, 0xa6, 0xc6, 0xc8,
0xde, 0x82, 0x92, 0xb8, 0x88, 0x8c, 0x86, 0xbd, 0x86, 0x0d, 0x61, 0xb4, 0x24, 0xfd, 0x3a, 0xb5,
0x10, 0x37, 0xa1, 0x1c, 0x00, 0x1c, 0x5a, 0x1c, 0x1d, 0xc9, 0x79, 0x3f, 0x91, 0x73, 0x06, 0xc8,
0x48, 0x6a, 0x43, 0x65, 0x70, 0x2a, 0xf6, 0x7c, 0xdf, 0x1a, 0x46, 0x1e, 0x26, 0x2f, 0xe8, 0x28,
0xca, 0xa7, 0x7f, 0x94, 0x0d, 0x1c, 0xd8, 0xfd, 0x0e, 0x2a, 0xd2, 0xcc, 0x57, 0xfe, 0x3e, 0x9a,
0xa2, 0x17, 0x43, 0x65, 0x4c, 0xe7, 0x67, 0xd8, 0x14, 0xb6, 0xce, 0xc8, 0xf7, 0x53, 0xad, 0xbf,
0x29, 0xf5, 0x3b, 0x28, 0xbd, 0xd4, 0xd8, 0x8c, 0xb9, 0x99, 0xf6, 0x05, 0xcc, 0x11, 0x67, 0xfa,
0x00, 0xce, 0xa0, 0x2c, 0x5c, 0x0b, 0x5e, 0x66, 0x29, 0x9f, 0x6f, 0x14, 0xe4, 0x4b, 0x3c, 0xcc,
0x84, 0x0d, 0xc4, 0x6c, 0xa8, 0xc4, 0x76, 0xa4, 0x94, 0x2a, 0xc4, 0x50, 0x8b, 0xab, 0x3e, 0x07,
0x0e, 0xf4, 0x10, 0x4a, 0x22, 0x16, 0x7f, 0xf7, 0x4b, 0xf1, 0x2e, 0x0c, 0xf1, 0x95, 0xf6, 0x33,
0x20, 0x43, 0x4d, 0x64, 0x2b, 0xbe, 0xd1, 0x92, 0x76, 0xf6, 0x2d, 0x59, 0x2a, 0x1e, 0xdc, 0x74,
0x0f, 0x0f, 0x37, 0x11, 0xf7, 0x88, 0xb2, 0xb0, 0x89, 0xb8, 0x88, 0x8c, 0x4b, 0xee, 0x14, 0x36,
0x7d, 0x51, 0x49, 0xbc, 0xbf, 0xd0, 0xf7, 0x08, 0xf5, 0x83, 0x2c, 0xd0, 0x20, 0x01, 0xaf, 0x5d,
0x49, 0x95, 0xf4, 0x76, 0x75, 0x93, 0xe0, 0xcf, 0xbd, 0x4b, 0x61, 0x70, 0x2f, 0x25, 0x8f, 0xd3,
0x9c, 0x4d, 0xbc, 0x21, 0xd7, 0x5a, 0x59, 0xe1, 0x41, 0x16, 0xbf, 0xc1, 0x9a, 0x77, 0x5b, 0x8c,
0xb7, 0xc7, 0xd8, 0xcb, 0xc1, 0x45, 0xb5, 0xb6, 0x77, 0x2d, 0x2e, 0x60, 0xd7, 0x60, 0xe7, 0xed,
0xc4, 0x10, 0x5b, 0xb3, 0x3c, 0x00, 0xf8, 0x47, 0x90, 0x78, 0x55, 0x66, 0xc7, 0x9c, 0x28, 0xee,
0x84, 0x8d, 0xae, 0xf3, 0xcc, 0x82, 0x5d, 0x05, 0x2d, 0xd4, 0x18, 0xf6, 0x5e, 0xff, 0x70, 0x82,
0x8c, 0x69, 0x23, 0x1c, 0x70, 0x07, 0xb5, 0x71, 0xfc, 0x68, 0x22, 0xff, 0x86, 0x48, 0x01, 0x67,
0xac, 0x90, 0x0e, 0x3b, 0xde, 0x5a, 0xfe, 0xce, 0x9a, 0xb2, 0x53, 0x71, 0x2a, 0xb3, 0x90, 0xa3,
0x11, 0xef, 0x05, 0xe2, 0x86, 0xda, 0x4a, 0x44, 0x66, 0x48, 0x49, 0x05, 0x38, 0x46, 0x7e, 0x82,
0xdc, 0x31, 0xf5, 0xb4, 0x5d, 0x6b, 0x06, 0x48, 0x29, 0x4b, 0x02, 0x2e, 0x28, 0xcb, 0x00, 0x56,
0xe5, 0x95, 0x98, 0x34, 0x12, 0x5f, 0xf2, 0x2f, 0xf4, 0x8b, 0x4e, 0x6b, 0xc1, 0xa5, 0x3f, 0xd4,
0x8d, 0x8f, 0x91, 0x87, 0xae, 0xda, 0x29, 0xdd, 0x38, 0x0a, 0x5a, 0xdc, 0x8d, 0xe3, 0xd8, 0x50,
0x06, 0x25, 0x05, 0xc5, 0x03, 0x2f, 0x8f, 0xd4, 0xd3, 0x7b, 0xf8, 0xbf, 0x89, 0x6b, 0x7c, 0x3f,
0x7a, 0xf6, 0xcb, 0xd3, 0x91, 0xc9, 0x4f, 0xa7, 0x43, 0xf1, 0xa4, 0x2d, 0xa1, 0x8f, 0x4d, 0xea,
0xfd, 0x6a, 0xfb, 0x8b, 0xb4, 0xed, 0xbe, 0xdd, 0x0e, 0x34, 0x26, 0xc3, 0xe1, 0xaa, 0x3b, 0xf5,
0xe4, 0xbf, 0x00, 0x00, 0x00, 0xff, 0xff, 0x4f, 0x2c, 0xbd, 0x42, 0x41, 0x13, 0x00, 0x00,
// 1420 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x58, 0x5b, 0x73, 0xd3, 0x46,
0x14, 0xc6, 0x36, 0xb9, 0xf8, 0xd8, 0x89, 0xc3, 0x0e, 0x01, 0xd7, 0x30, 0xad, 0x71, 0x5b, 0x70,
0xb8, 0x38, 0x4c, 0x98, 0xa1, 0x94, 0x37, 0x12, 0x53, 0xf0, 0x94, 0xcc, 0x80, 0x0c, 0x1d, 0x7a,
0x61, 0xd4, 0xb5, 0x75, 0x70, 0x34, 0x91, 0xb5, 0x46, 0xbb, 0x26, 0xc9, 0x63, 0x67, 0xfa, 0xde,
0x7f, 0xd4, 0x87, 0xf6, 0xa7, 0xf4, 0x8f, 0x74, 0x56, 0x2b, 0xad, 0x25, 0x59, 0x72, 0x14, 0xc2,
0x9b, 0x76, 0xf5, 0xe9, 0xfb, 0xce, 0x65, 0xf7, 0xec, 0x59, 0xc1, 0x86, 0xc7, 0x98, 0x30, 0x87,
0x8c, 0x79, 0x56, 0x67, 0xe2, 0x31, 0xc1, 0xc8, 0x95, 0xb1, 0xed, 0x7c, 0x9c, 0x72, 0x35, 0xea,
0xc8, 0xd7, 0xfe, 0xdb, 0x46, 0x75, 0xc8, 0xc6, 0x63, 0xe6, 0xaa, 0xf9, 0x46, 0x35, 0x8a, 0x6a,
0xac, 0xdb, 0xae, 0x40, 0xcf, 0xa5, 0x4e, 0x30, 0xae, 0x4c, 0x3c, 0x76, 0x7c, 0x12, 0x0c, 0x36,
0x2c, 0x2a, 0x68, 0x54, 0xa2, 0x51, 0x43, 0x31, 0xb4, 0xcc, 0x31, 0x0a, 0xaa, 0x26, 0x5a, 0x26,
0x6c, 0x3e, 0x71, 0x1c, 0x36, 0x7c, 0x6d, 0x8f, 0x91, 0x0b, 0x3a, 0x9e, 0x18, 0xf8, 0x61, 0x8a,
0x5c, 0x90, 0xfb, 0x70, 0x71, 0x40, 0x39, 0xd6, 0x0b, 0xcd, 0x42, 0xbb, 0xb2, 0x73, 0xbd, 0x13,
0xb3, 0x2d, 0x30, 0x68, 0x9f, 0x8f, 0x76, 0x29, 0x47, 0xc3, 0x47, 0x92, 0xcb, 0xb0, 0x34, 0x64,
0x53, 0x57, 0xd4, 0x4b, 0xcd, 0x42, 0x7b, 0xcd, 0x50, 0x83, 0xd6, 0x1f, 0x05, 0xb8, 0x92, 0x54,
0xe0, 0x13, 0xe6, 0x72, 0x24, 0x0f, 0x60, 0x99, 0x0b, 0x2a, 0xa6, 0x3c, 0x10, 0xb9, 0x96, 0x2a,
0xd2, 0xf7, 0x21, 0x46, 0x00, 0x25, 0xd7, 0xa1, 0x2c, 0x42, 0xa6, 0x7a, 0xb1, 0x59, 0x68, 0x5f,
0x34, 0x66, 0x13, 0x19, 0x36, 0xbc, 0x85, 0x75, 0xdf, 0x84, 0x5e, 0xf7, 0x33, 0x78, 0x57, 0x8c,
0x32, 0x3b, 0x50, 0xd3, 0xcc, 0xe7, 0xf1, 0x6a, 0x1d, 0x8a, 0xbd, 0xae, 0x4f, 0x5d, 0x32, 0x8a,
0xbd, 0x6e, 0x86, 0x1f, 0xff, 0x14, 0xa1, 0xda, 0x1b, 0x4f, 0x98, 0x27, 0x0c, 0xe4, 0x53, 0x47,
0x7c, 0x9a, 0xd6, 0x55, 0x58, 0x11, 0x94, 0x1f, 0x9a, 0xb6, 0x15, 0x08, 0x2e, 0xcb, 0x61, 0xcf,
0x22, 0x5f, 0x41, 0x45, 0x2e, 0x18, 0x97, 0x59, 0x28, 0x5f, 0x96, 0xfc, 0x97, 0x10, 0x4e, 0xf5,
0x2c, 0xf2, 0x10, 0x96, 0x24, 0x07, 0xd6, 0x2f, 0x36, 0x0b, 0xed, 0xf5, 0x9d, 0x66, 0xaa, 0x9a,
0x32, 0x50, 0x6a, 0xa2, 0xa1, 0xe0, 0xa4, 0x01, 0xab, 0x1c, 0x47, 0x63, 0x74, 0x05, 0xaf, 0x2f,
0x35, 0x4b, 0xed, 0x92, 0xa1, 0xc7, 0xe4, 0x0b, 0x58, 0xa5, 0x53, 0xc1, 0x4c, 0xdb, 0xe2, 0xf5,
0x65, 0xff, 0xdd, 0x8a, 0x1c, 0xf7, 0x2c, 0x4e, 0xae, 0x41, 0xd9, 0x63, 0x47, 0xa6, 0x0a, 0xc4,
0x8a, 0x6f, 0xcd, 0xaa, 0xc7, 0x8e, 0xf6, 0xe4, 0x98, 0x7c, 0x07, 0x4b, 0xb6, 0xfb, 0x9e, 0xf1,
0xfa, 0x6a, 0xb3, 0xd4, 0xae, 0xec, 0xdc, 0x48, 0xb5, 0xe5, 0x47, 0x3c, 0xf9, 0x89, 0x3a, 0x53,
0x7c, 0x49, 0x6d, 0xcf, 0x50, 0xf8, 0xd6, 0x5f, 0x05, 0xb8, 0xda, 0x45, 0x3e, 0xf4, 0xec, 0x01,
0xf6, 0x03, 0x2b, 0x3e, 0x7d, 0x59, 0xb4, 0xa0, 0x3a, 0x64, 0x8e, 0x83, 0x43, 0x61, 0x33, 0x57,
0xa7, 0x30, 0x36, 0x47, 0xbe, 0x04, 0x08, 0xdc, 0xed, 0x75, 0x79, 0xbd, 0xe4, 0x3b, 0x19, 0x99,
0x69, 0x4d, 0xa1, 0x16, 0x18, 0x22, 0x89, 0x7b, 0xee, 0x7b, 0x36, 0x47, 0x5b, 0x48, 0xa1, 0x6d,
0x42, 0x65, 0x42, 0x3d, 0x61, 0xc7, 0x94, 0xa3, 0x53, 0x72, 0xaf, 0x68, 0x99, 0x20, 0x9d, 0xb3,
0x89, 0xd6, 0x7f, 0x45, 0xa8, 0x06, 0xba, 0x52, 0x93, 0x93, 0x2e, 0x94, 0xa5, 0x4f, 0xa6, 0x8c,
0x53, 0x10, 0x82, 0x5b, 0x9d, 0xf4, 0x9a, 0xd4, 0x49, 0x18, 0x6c, 0xac, 0x0e, 0x42, 0xd3, 0xbb,
0x50, 0xb1, 0x5d, 0x0b, 0x8f, 0x4d, 0x95, 0x9e, 0xa2, 0x9f, 0x9e, 0xaf, 0xe3, 0x3c, 0xb2, 0x0a,
0x75, 0xb4, 0xb6, 0x85, 0xc7, 0x3e, 0x07, 0xd8, 0xe1, 0x23, 0x27, 0x08, 0x97, 0xf0, 0x58, 0x78,
0xd4, 0x8c, 0x72, 0x95, 0x7c, 0xae, 0xef, 0x4f, 0xb1, 0xc9, 0x27, 0xe8, 0x3c, 0x95, 0x5f, 0x6b,
0x6e, 0xfe, 0xd4, 0x15, 0xde, 0x89, 0x51, 0xc3, 0xf8, 0x6c, 0xe3, 0x77, 0xb8, 0x9c, 0x06, 0x24,
0x1b, 0x50, 0x3a, 0xc4, 0x93, 0x20, 0xec, 0xf2, 0x91, 0xec, 0xc0, 0xd2, 0x47, 0xb9, 0x94, 0xfc,
0x38, 0xcf, 0xad, 0x0d, 0xdf, 0xa1, 0x99, 0x27, 0x0a, 0xfa, 0xb8, 0xf8, 0xa8, 0xd0, 0xfa, 0xb7,
0x08, 0xf5, 0xf9, 0xe5, 0x76, 0x9e, 0x5a, 0x91, 0x67, 0xc9, 0x8d, 0x60, 0x2d, 0x48, 0x74, 0x2c,
0x74, 0xbb, 0x59, 0xa1, 0xcb, 0xb2, 0x30, 0x16, 0x53, 0x15, 0xc3, 0x2a, 0x8f, 0x4c, 0x35, 0x10,
0x2e, 0xcd, 0x41, 0x52, 0xa2, 0xf7, 0x38, 0x1e, 0xbd, 0x6f, 0xf2, 0xa4, 0x30, 0x1a, 0x45, 0x0b,
0x2e, 0x3f, 0x43, 0xb1, 0xe7, 0xa1, 0x85, 0xae, 0xb0, 0xa9, 0xf3, 0xe9, 0x1b, 0xb6, 0x01, 0xab,
0x53, 0x2e, 0x4f, 0xcc, 0xb1, 0x32, 0xa6, 0x6c, 0xe8, 0x71, 0xeb, 0xcf, 0x02, 0x6c, 0x26, 0x64,
0xce, 0x93, 0xa8, 0x05, 0x52, 0xf2, 0xdd, 0x84, 0x72, 0x7e, 0xc4, 0x3c, 0x55, 0x68, 0xcb, 0x86,
0x1e, 0xef, 0xfc, 0x7d, 0x0d, 0xca, 0x06, 0x63, 0x62, 0x4f, 0x86, 0x84, 0x4c, 0x80, 0x48, 0x9b,
0xd8, 0x78, 0xc2, 0x5c, 0x74, 0x55, 0x61, 0xe5, 0xe4, 0x7e, 0xdc, 0x00, 0xdd, 0x05, 0xcc, 0x43,
0x83, 0x50, 0x35, 0x6e, 0x66, 0x7c, 0x91, 0x80, 0xb7, 0x2e, 0x90, 0xb1, 0xaf, 0x28, 0xcf, 0xeb,
0xd7, 0xf6, 0xf0, 0x70, 0xef, 0x80, 0xba, 0x2e, 0x3a, 0x8b, 0x14, 0x13, 0xd0, 0x50, 0x31, 0xb1,
0xe9, 0x83, 0x41, 0x5f, 0x78, 0xb6, 0x3b, 0x0a, 0x23, 0xdb, 0xba, 0x40, 0x3e, 0xf8, 0xb9, 0x95,
0xea, 0x36, 0x17, 0xf6, 0x90, 0x87, 0x82, 0x3b, 0xd9, 0x82, 0x73, 0xe0, 0x33, 0x4a, 0x9a, 0xb0,
0xb1, 0xe7, 0x21, 0x15, 0xb8, 0xa7, 0x37, 0x0d, 0xb9, 0x9b, 0xfa, 0x69, 0x12, 0x16, 0x0a, 0x2d,
0x5a, 0x00, 0xad, 0x0b, 0xe4, 0x57, 0x58, 0xef, 0x7a, 0x6c, 0x12, 0xa1, 0xbf, 0x9d, 0x4a, 0x1f,
0x07, 0xe5, 0x24, 0x37, 0x61, 0xed, 0x39, 0xe5, 0x11, 0xee, 0xad, 0x54, 0xee, 0x18, 0x26, 0xa4,
0xbe, 0x91, 0x0a, 0xdd, 0x65, 0xcc, 0x89, 0x84, 0xe7, 0x08, 0x48, 0x58, 0x10, 0x22, 0x2a, 0x9d,
0x74, 0x0f, 0xe6, 0x80, 0xa1, 0xd4, 0x76, 0x6e, 0xbc, 0x16, 0x7e, 0x03, 0x15, 0x15, 0xf0, 0x27,
0x8e, 0x4d, 0x39, 0xb9, 0xb5, 0x20, 0x25, 0x3e, 0x22, 0x67, 0xc0, 0x5e, 0x41, 0x59, 0x06, 0x5a,
0x91, 0x7e, 0x9b, 0x99, 0x88, 0xb3, 0x50, 0xf6, 0x01, 0x9e, 0x38, 0x02, 0x3d, 0xc5, 0x79, 0x33,
0x95, 0x73, 0x06, 0xc8, 0x49, 0xea, 0x42, 0xad, 0x7f, 0x20, 0x1b, 0x9c, 0x30, 0x34, 0x9c, 0xdc,
0x49, 0x5f, 0xd0, 0x71, 0x54, 0x48, 0x7f, 0x37, 0x1f, 0x58, 0x87, 0xfb, 0x1d, 0xd4, 0x54, 0x30,
0x5f, 0x86, 0x4d, 0x43, 0x86, 0x5e, 0x02, 0x95, 0xd3, 0x9d, 0x9f, 0x61, 0x4d, 0x86, 0x75, 0x46,
0xbe, 0x95, 0x19, 0xfa, 0xb3, 0x52, 0xbf, 0x83, 0xea, 0x73, 0xca, 0x67, 0xcc, 0xed, 0xac, 0x1d,
0x30, 0x47, 0x9c, 0x6b, 0x03, 0x1c, 0xc2, 0xba, 0x8c, 0x9a, 0xfe, 0x98, 0x67, 0x6c, 0xdf, 0x38,
0x28, 0x94, 0xb8, 0x93, 0x0b, 0xab, 0xc5, 0x5c, 0xa8, 0x25, 0x8e, 0xdf, 0x8c, 0x2c, 0x24, 0x50,
0x8b, 0xb3, 0x3e, 0x07, 0xd6, 0x7a, 0x08, 0x55, 0x69, 0x4b, 0x78, 0xd4, 0x67, 0xc4, 0x2e, 0x0a,
0x09, 0x95, 0xb6, 0x72, 0x20, 0x23, 0x45, 0x64, 0x23, 0xd9, 0x55, 0x90, 0xed, 0xfc, 0xfd, 0x87,
0x52, 0xbc, 0x7f, 0xd6, 0x86, 0x25, 0x5a, 0x44, 0xfc, 0x7e, 0x6c, 0x61, 0x11, 0xf1, 0x11, 0x39,
0x97, 0xdc, 0x01, 0xac, 0x85, 0xa2, 0x8a, 0x78, 0x6b, 0x61, 0xdc, 0x63, 0xd4, 0xb7, 0xf3, 0x40,
0xb5, 0x03, 0x41, 0xb9, 0x52, 0x2a, 0xd9, 0xe5, 0xea, 0x2c, 0xc6, 0x7f, 0x08, 0x6e, 0xc0, 0xfa,
0x12, 0x4e, 0xee, 0x65, 0x45, 0x36, 0xf5, 0x77, 0x40, 0xa3, 0x93, 0x17, 0xae, 0xbd, 0xf8, 0x0d,
0x56, 0x82, 0xab, 0x71, 0xb2, 0x3c, 0x26, 0x3e, 0xd6, 0xb7, 0xf2, 0xc6, 0xad, 0x53, 0x71, 0x9a,
0x9d, 0xc2, 0xe6, 0x9b, 0x89, 0x25, 0x8f, 0x66, 0xd5, 0x00, 0x84, 0x2d, 0x48, 0x32, 0x2b, 0xb3,
0x36, 0x27, 0x8e, 0xdb, 0xe7, 0xa3, 0xd3, 0x62, 0xe6, 0xc0, 0x55, 0x03, 0x1d, 0xa4, 0x1c, 0xbb,
0xaf, 0x5e, 0xec, 0x23, 0xe7, 0x74, 0x84, 0x7d, 0xe1, 0x21, 0x1d, 0x27, 0x5b, 0x13, 0xf5, 0xcf,
0x25, 0x03, 0x9c, 0x33, 0x43, 0x43, 0xd8, 0x0c, 0xd6, 0xf2, 0x0f, 0xce, 0x94, 0x1f, 0xc8, 0xae,
0xcc, 0x41, 0x81, 0x56, 0xb2, 0x16, 0xc8, 0xeb, 0x78, 0x27, 0x15, 0x99, 0xc3, 0x25, 0x13, 0xe0,
0x19, 0x8a, 0x7d, 0x14, 0x9e, 0x3d, 0xcc, 0x3a, 0xb5, 0x66, 0x80, 0x8c, 0xb4, 0xa4, 0xe0, 0x74,
0x5a, 0xfa, 0xb0, 0xac, 0xee, 0xff, 0xa4, 0x95, 0xfa, 0x51, 0xf8, 0xf7, 0x62, 0x51, 0xb7, 0xa6,
0xff, 0x70, 0x44, 0xaa, 0xf1, 0x33, 0x14, 0x91, 0xff, 0x0a, 0x19, 0xd5, 0x38, 0x0e, 0x5a, 0x5c,
0x8d, 0x93, 0xd8, 0x88, 0x07, 0x55, 0x03, 0xe5, 0x8b, 0xc0, 0x8f, 0xcc, 0xab, 0x4a, 0xf4, 0x47,
0xcc, 0x69, 0x71, 0x7f, 0xab, 0xfb, 0x4d, 0x7d, 0xb5, 0x48, 0x6e, 0xec, 0xd9, 0x42, 0xd5, 0x10,
0x79, 0x0b, 0xca, 0xc1, 0x1c, 0xec, 0x83, 0xcf, 0xcd, 0x6c, 0xca, 0xfa, 0x2d, 0x17, 0x56, 0x84,
0x39, 0xeb, 0xa8, 0x89, 0xc3, 0xf2, 0x17, 0xd4, 0x17, 0x36, 0xf7, 0x6f, 0x5b, 0x6f, 0x38, 0x7a,
0x3c, 0xa3, 0xa0, 0xc6, 0x30, 0x8b, 0x0b, 0x6a, 0x02, 0x1a, 0x39, 0x61, 0xd7, 0x62, 0xd7, 0xba,
0xa4, 0x1f, 0xb3, 0xa4, 0xa6, 0x5d, 0x32, 0x1b, 0xf7, 0x72, 0xa2, 0x43, 0xbd, 0xdd, 0x47, 0xbf,
0x3c, 0x1c, 0xd9, 0xe2, 0x60, 0x3a, 0x90, 0x3e, 0x6f, 0xab, 0x8f, 0xef, 0xd9, 0x2c, 0x78, 0xda,
0x0e, 0x13, 0xb2, 0xed, 0xf3, 0x6d, 0x6b, 0xbe, 0xc9, 0x60, 0xb0, 0xec, 0x4f, 0x3d, 0xf8, 0x3f,
0x00, 0x00, 0xff, 0xff, 0x3d, 0xc9, 0x68, 0x0c, 0x1d, 0x16, 0x00, 0x00,
}
// Reference imports to suppress errors if they are not otherwise used.
@ -740,6 +857,13 @@ type RootCoordClient interface {
Import(ctx context.Context, in *milvuspb.ImportRequest, opts ...grpc.CallOption) (*milvuspb.ImportResponse, error)
GetImportState(ctx context.Context, in *milvuspb.GetImportStateRequest, opts ...grpc.CallOption) (*milvuspb.GetImportStateResponse, error)
ReportImport(ctx context.Context, in *ImportResult, opts ...grpc.CallOption) (*commonpb.Status, error)
// https://wiki.lfaidata.foundation/display/MIL/MEP+27+--+Support+Basic+Authentication
CreateCredential(ctx context.Context, in *internalpb.CredentialInfo, opts ...grpc.CallOption) (*commonpb.Status, error)
UpdateCredential(ctx context.Context, in *internalpb.CredentialInfo, opts ...grpc.CallOption) (*commonpb.Status, error)
DeleteCredential(ctx context.Context, in *milvuspb.DeleteCredentialRequest, opts ...grpc.CallOption) (*commonpb.Status, error)
ListCredUsers(ctx context.Context, in *milvuspb.ListCredUsersRequest, opts ...grpc.CallOption) (*milvuspb.ListCredUsersResponse, error)
// userd by proxy, not exposed to sdk
GetCredential(ctx context.Context, in *GetCredentialRequest, opts ...grpc.CallOption) (*GetCredentialResponse, error)
}
type rootCoordClient struct {
@ -1020,6 +1144,51 @@ func (c *rootCoordClient) ReportImport(ctx context.Context, in *ImportResult, op
return out, nil
}
func (c *rootCoordClient) CreateCredential(ctx context.Context, in *internalpb.CredentialInfo, opts ...grpc.CallOption) (*commonpb.Status, error) {
out := new(commonpb.Status)
err := c.cc.Invoke(ctx, "/milvus.proto.rootcoord.RootCoord/CreateCredential", in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *rootCoordClient) UpdateCredential(ctx context.Context, in *internalpb.CredentialInfo, opts ...grpc.CallOption) (*commonpb.Status, error) {
out := new(commonpb.Status)
err := c.cc.Invoke(ctx, "/milvus.proto.rootcoord.RootCoord/UpdateCredential", in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *rootCoordClient) DeleteCredential(ctx context.Context, in *milvuspb.DeleteCredentialRequest, opts ...grpc.CallOption) (*commonpb.Status, error) {
out := new(commonpb.Status)
err := c.cc.Invoke(ctx, "/milvus.proto.rootcoord.RootCoord/DeleteCredential", in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *rootCoordClient) ListCredUsers(ctx context.Context, in *milvuspb.ListCredUsersRequest, opts ...grpc.CallOption) (*milvuspb.ListCredUsersResponse, error) {
out := new(milvuspb.ListCredUsersResponse)
err := c.cc.Invoke(ctx, "/milvus.proto.rootcoord.RootCoord/ListCredUsers", in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *rootCoordClient) GetCredential(ctx context.Context, in *GetCredentialRequest, opts ...grpc.CallOption) (*GetCredentialResponse, error) {
out := new(GetCredentialResponse)
err := c.cc.Invoke(ctx, "/milvus.proto.rootcoord.RootCoord/GetCredential", in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
// RootCoordServer is the server API for RootCoord service.
type RootCoordServer interface {
GetComponentStates(context.Context, *internalpb.GetComponentStatesRequest) (*internalpb.ComponentStates, error)
@ -1100,6 +1269,13 @@ type RootCoordServer interface {
Import(context.Context, *milvuspb.ImportRequest) (*milvuspb.ImportResponse, error)
GetImportState(context.Context, *milvuspb.GetImportStateRequest) (*milvuspb.GetImportStateResponse, error)
ReportImport(context.Context, *ImportResult) (*commonpb.Status, error)
// https://wiki.lfaidata.foundation/display/MIL/MEP+27+--+Support+Basic+Authentication
CreateCredential(context.Context, *internalpb.CredentialInfo) (*commonpb.Status, error)
UpdateCredential(context.Context, *internalpb.CredentialInfo) (*commonpb.Status, error)
DeleteCredential(context.Context, *milvuspb.DeleteCredentialRequest) (*commonpb.Status, error)
ListCredUsers(context.Context, *milvuspb.ListCredUsersRequest) (*milvuspb.ListCredUsersResponse, error)
// userd by proxy, not exposed to sdk
GetCredential(context.Context, *GetCredentialRequest) (*GetCredentialResponse, error)
}
// UnimplementedRootCoordServer can be embedded to have forward compatible implementations.
@ -1196,6 +1372,21 @@ func (*UnimplementedRootCoordServer) GetImportState(ctx context.Context, req *mi
func (*UnimplementedRootCoordServer) ReportImport(ctx context.Context, req *ImportResult) (*commonpb.Status, error) {
return nil, status.Errorf(codes.Unimplemented, "method ReportImport not implemented")
}
func (*UnimplementedRootCoordServer) CreateCredential(ctx context.Context, req *internalpb.CredentialInfo) (*commonpb.Status, error) {
return nil, status.Errorf(codes.Unimplemented, "method CreateCredential not implemented")
}
func (*UnimplementedRootCoordServer) UpdateCredential(ctx context.Context, req *internalpb.CredentialInfo) (*commonpb.Status, error) {
return nil, status.Errorf(codes.Unimplemented, "method UpdateCredential not implemented")
}
func (*UnimplementedRootCoordServer) DeleteCredential(ctx context.Context, req *milvuspb.DeleteCredentialRequest) (*commonpb.Status, error) {
return nil, status.Errorf(codes.Unimplemented, "method DeleteCredential not implemented")
}
func (*UnimplementedRootCoordServer) ListCredUsers(ctx context.Context, req *milvuspb.ListCredUsersRequest) (*milvuspb.ListCredUsersResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method ListCredUsers not implemented")
}
func (*UnimplementedRootCoordServer) GetCredential(ctx context.Context, req *GetCredentialRequest) (*GetCredentialResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method GetCredential not implemented")
}
func RegisterRootCoordServer(s *grpc.Server, srv RootCoordServer) {
s.RegisterService(&_RootCoord_serviceDesc, srv)
@ -1741,6 +1932,96 @@ func _RootCoord_ReportImport_Handler(srv interface{}, ctx context.Context, dec f
return interceptor(ctx, in, info, handler)
}
func _RootCoord_CreateCredential_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(internalpb.CredentialInfo)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(RootCoordServer).CreateCredential(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/milvus.proto.rootcoord.RootCoord/CreateCredential",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(RootCoordServer).CreateCredential(ctx, req.(*internalpb.CredentialInfo))
}
return interceptor(ctx, in, info, handler)
}
func _RootCoord_UpdateCredential_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(internalpb.CredentialInfo)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(RootCoordServer).UpdateCredential(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/milvus.proto.rootcoord.RootCoord/UpdateCredential",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(RootCoordServer).UpdateCredential(ctx, req.(*internalpb.CredentialInfo))
}
return interceptor(ctx, in, info, handler)
}
func _RootCoord_DeleteCredential_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(milvuspb.DeleteCredentialRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(RootCoordServer).DeleteCredential(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/milvus.proto.rootcoord.RootCoord/DeleteCredential",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(RootCoordServer).DeleteCredential(ctx, req.(*milvuspb.DeleteCredentialRequest))
}
return interceptor(ctx, in, info, handler)
}
func _RootCoord_ListCredUsers_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(milvuspb.ListCredUsersRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(RootCoordServer).ListCredUsers(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/milvus.proto.rootcoord.RootCoord/ListCredUsers",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(RootCoordServer).ListCredUsers(ctx, req.(*milvuspb.ListCredUsersRequest))
}
return interceptor(ctx, in, info, handler)
}
func _RootCoord_GetCredential_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(GetCredentialRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(RootCoordServer).GetCredential(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/milvus.proto.rootcoord.RootCoord/GetCredential",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(RootCoordServer).GetCredential(ctx, req.(*GetCredentialRequest))
}
return interceptor(ctx, in, info, handler)
}
var _RootCoord_serviceDesc = grpc.ServiceDesc{
ServiceName: "milvus.proto.rootcoord.RootCoord",
HandlerType: (*RootCoordServer)(nil),
@ -1865,6 +2146,26 @@ var _RootCoord_serviceDesc = grpc.ServiceDesc{
MethodName: "ReportImport",
Handler: _RootCoord_ReportImport_Handler,
},
{
MethodName: "CreateCredential",
Handler: _RootCoord_CreateCredential_Handler,
},
{
MethodName: "UpdateCredential",
Handler: _RootCoord_UpdateCredential_Handler,
},
{
MethodName: "DeleteCredential",
Handler: _RootCoord_DeleteCredential_Handler,
},
{
MethodName: "ListCredUsers",
Handler: _RootCoord_ListCredUsers_Handler,
},
{
MethodName: "GetCredential",
Handler: _RootCoord_GetCredential_Handler,
},
},
Streams: []grpc.StreamDesc{},
Metadata: "root_coord.proto",

View File

@ -0,0 +1,76 @@
package proxy
import (
"context"
"strings"
"github.com/milvus-io/milvus/internal/util"
"go.uber.org/zap"
"github.com/milvus-io/milvus/internal/log"
"github.com/milvus-io/milvus/internal/util/crypto"
"google.golang.org/grpc/metadata"
)
// validAuth validates the authentication
func validAuth(ctx context.Context, authorization []string) bool {
if len(authorization) < 1 {
//log.Warn("key not found in header", zap.String("key", headerAuthorize))
return false
}
// token format: base64<username:password>
//token := strings.TrimPrefix(authorization[0], "Bearer ")
token := authorization[0]
rawToken, err := crypto.Base64Decode(token)
if err != nil {
return false
}
secrets := strings.SplitN(rawToken, util.CredentialSeperator, 2)
username := secrets[0]
password := secrets[1]
credInfo, err := globalMetaCache.GetCredentialInfo(ctx, username)
if err != nil {
log.Error("found no credential", zap.String("username", username), zap.Error(err))
return false
}
return crypto.PasswordVerify(password, credInfo.EncryptedPassword)
}
func validSourceID(ctx context.Context, authorization []string) bool {
if len(authorization) < 1 {
//log.Warn("key not found in header", zap.String("key", util.HeaderSourceID))
return false
}
// token format: base64<sourceID>
token := authorization[0]
sourceID, err := crypto.Base64Decode(token)
if err != nil {
return false
}
return sourceID == util.MemberCredID
}
// AuthenticationInterceptor verify based on kv pair <"authorization": "token"> in header
func AuthenticationInterceptor(ctx context.Context) (context.Context, error) {
// The keys within metadata.MD are normalized to lowercase.
// See: https://godoc.org/google.golang.org/grpc/metadata#New
md, ok := metadata.FromIncomingContext(ctx)
if !ok {
return nil, ErrMissingMetadata()
}
// check:
// 1. if rpc call from a member (like index/query/data component)
// 2. if rpc call from sdk
usernames, _ := globalMetaCache.GetCredUsernames(ctx)
if len(usernames) > 0 {
if !validSourceID(ctx, md[strings.ToLower(util.HeaderSourceID)]) &&
!validAuth(ctx, md[strings.ToLower(util.HeaderAuthorize)]) {
return nil, ErrUnauthenticated()
}
}
return ctx, nil
}

View File

@ -0,0 +1,69 @@
package proxy
import (
"context"
"testing"
"google.golang.org/grpc/metadata"
"github.com/milvus-io/milvus/internal/util"
"github.com/milvus-io/milvus/internal/util/crypto"
"github.com/stretchr/testify/assert"
)
// validAuth validates the authentication
func TestValidAuth(t *testing.T) {
ctx := context.Background()
// no metadata
res := validAuth(ctx, nil)
assert.False(t, res)
// illegal metadata
res = validAuth(ctx, []string{"xxx"})
assert.False(t, res)
// normal metadata
client := &MockRootCoordClientInterface{}
err := InitMetaCache(client)
assert.Nil(t, err)
res = validAuth(ctx, []string{crypto.Base64Encode("mockUser:mockPass")})
assert.True(t, res)
}
func TestValidSourceID(t *testing.T) {
ctx := context.Background()
// no metadata
res := validSourceID(ctx, nil)
assert.False(t, res)
// illegal metadata
res = validSourceID(ctx, []string{"invalid_sourceid"})
assert.False(t, res)
// normal sourceId
res = validSourceID(ctx, []string{crypto.Base64Encode(util.MemberCredID)})
assert.True(t, res)
}
func TestAuthenticationInterceptor(t *testing.T) {
ctx := context.Background()
// no metadata
_, err := AuthenticationInterceptor(ctx)
assert.NotNil(t, err)
// mock metacache
client := &MockRootCoordClientInterface{}
err = InitMetaCache(client)
assert.Nil(t, err)
// with invalid metadata
md := metadata.Pairs("xxx", "yyy")
ctx = metadata.NewIncomingContext(ctx, md)
_, err = AuthenticationInterceptor(ctx)
assert.NotNil(t, err)
// with valid username/password
md = metadata.Pairs(util.HeaderAuthorize, crypto.Base64Encode("mockUser:mockPass"))
ctx = metadata.NewIncomingContext(ctx, md)
_, err = AuthenticationInterceptor(ctx)
assert.Nil(t, err)
// with valid sourceId
md = metadata.Pairs("sourceid", crypto.Base64Encode(util.MemberCredID))
ctx = metadata.NewIncomingContext(ctx, md)
_, err = AuthenticationInterceptor(ctx)
assert.Nil(t, err)
}

View File

@ -71,3 +71,11 @@ func msgProxyIsUnhealthy(id UniqueID) string {
func errProxyIsUnhealthy(id UniqueID) error {
return errors.New(msgProxyIsUnhealthy(id))
}
func ErrMissingMetadata() error {
return fmt.Errorf("invalid argument: missing metadata")
}
func ErrUnauthenticated() error {
return fmt.Errorf("unauthenticated: invalid credential")
}

View File

@ -23,8 +23,6 @@ import (
"os"
"strconv"
"github.com/milvus-io/milvus/internal/util/timerecord"
"go.uber.org/zap"
"github.com/milvus-io/milvus/internal/common"
@ -38,10 +36,12 @@ import (
"github.com/milvus-io/milvus/internal/proto/proxypb"
"github.com/milvus-io/milvus/internal/proto/querypb"
"github.com/milvus-io/milvus/internal/proto/schemapb"
"github.com/milvus-io/milvus/internal/util/crypto"
"github.com/milvus-io/milvus/internal/util/distance"
"github.com/milvus-io/milvus/internal/util/funcutil"
"github.com/milvus-io/milvus/internal/util/logutil"
"github.com/milvus-io/milvus/internal/util/metricsinfo"
"github.com/milvus-io/milvus/internal/util/timerecord"
"github.com/milvus-io/milvus/internal/util/trace"
"github.com/milvus-io/milvus/internal/util/typeutil"
)
@ -3959,3 +3959,187 @@ func (node *Proxy) GetImportState(ctx context.Context, req *milvuspb.GetImportSt
log.Info("received get import state response", zap.Int64("taskID", req.GetTask()), zap.Any("resp", resp), zap.Error(err))
return resp, err
}
// InvalidateCredentialCache invalidate the credential cache of specified username.
func (node *Proxy) InvalidateCredentialCache(ctx context.Context, request *proxypb.InvalidateCredCacheRequest) (*commonpb.Status, error) {
ctx = logutil.WithModule(ctx, moduleName)
logutil.Logger(ctx).Debug("received request to invalidate credential cache",
zap.String("role", typeutil.ProxyRole),
zap.String("username", request.Username))
username := request.Username
if globalMetaCache != nil {
globalMetaCache.RemoveCredential(username) // no need to return error, though credential may be not cached
}
logutil.Logger(ctx).Debug("complete to invalidate credential cache",
zap.String("role", typeutil.ProxyRole),
zap.String("username", request.Username))
return &commonpb.Status{
ErrorCode: commonpb.ErrorCode_Success,
Reason: "",
}, nil
}
// UpdateCredentialCache update the credential cache of specified username.
func (node *Proxy) UpdateCredentialCache(ctx context.Context, request *proxypb.UpdateCredCacheRequest) (*commonpb.Status, error) {
ctx = logutil.WithModule(ctx, moduleName)
logutil.Logger(ctx).Debug("received request to update credential cache",
zap.String("role", typeutil.ProxyRole),
zap.String("username", request.Username))
credInfo := &internalpb.CredentialInfo{
Username: request.Username,
EncryptedPassword: request.Password,
}
if globalMetaCache != nil {
globalMetaCache.UpdateCredential(credInfo) // no need to return error, though credential may be not cached
}
logutil.Logger(ctx).Debug("complete to update credential cache",
zap.String("role", typeutil.ProxyRole),
zap.String("username", request.Username))
return &commonpb.Status{
ErrorCode: commonpb.ErrorCode_Success,
Reason: "",
}, nil
}
func (node *Proxy) ClearCredUsersCache(ctx context.Context, request *internalpb.ClearCredUsersCacheRequest) (*commonpb.Status, error) {
ctx = logutil.WithModule(ctx, moduleName)
logutil.Logger(ctx).Debug("received request to clear credential usernames cache",
zap.String("role", typeutil.ProxyRole))
if globalMetaCache != nil {
globalMetaCache.ClearCredUsers() // no need to return error, though credential may be not cached
}
logutil.Logger(ctx).Debug("complete to clear credential usernames cache",
zap.String("role", typeutil.ProxyRole))
return &commonpb.Status{
ErrorCode: commonpb.ErrorCode_Success,
Reason: "",
}, nil
}
func (node *Proxy) CreateCredential(ctx context.Context, req *milvuspb.CreateCredentialRequest) (*commonpb.Status, error) {
log.Debug("CreateCredential", zap.String("role", typeutil.RootCoordRole), zap.String("username", req.Username))
// validate params
username := req.Username
if err := ValidateUsername(username); err != nil {
return &commonpb.Status{
ErrorCode: commonpb.ErrorCode_IllegalArgument,
Reason: err.Error(),
}, nil
}
rawPassword, err := crypto.Base64Decode(req.Password)
if err != nil {
log.Error("decode password fail", zap.String("username", req.Username), zap.Error(err))
return &commonpb.Status{
ErrorCode: commonpb.ErrorCode_CreateCredentialFailure,
Reason: "decode password fail key:" + req.Username,
}, nil
}
if err = ValidatePassword(rawPassword); err != nil {
log.Error("illegal password", zap.String("username", req.Username), zap.Error(err))
return &commonpb.Status{
ErrorCode: commonpb.ErrorCode_IllegalArgument,
Reason: err.Error(),
}, nil
}
encryptedPassword, err := crypto.PasswordEncrypt(rawPassword)
if err != nil {
log.Error("encrypt password fail", zap.String("username", req.Username), zap.Error(err))
return &commonpb.Status{
ErrorCode: commonpb.ErrorCode_CreateCredentialFailure,
Reason: "encrypt password fail key:" + req.Username,
}, nil
}
credInfo := &internalpb.CredentialInfo{
Username: req.Username,
EncryptedPassword: encryptedPassword,
}
result, err := node.rootCoord.CreateCredential(ctx, credInfo)
if err != nil { // for error like conntext timeout etc.
log.Error("create credential fail", zap.String("username", req.Username), zap.Error(err))
return &commonpb.Status{
ErrorCode: commonpb.ErrorCode_UnexpectedError,
Reason: err.Error(),
}, nil
}
return result, err
}
func (node *Proxy) UpdateCredential(ctx context.Context, req *milvuspb.CreateCredentialRequest) (*commonpb.Status, error) {
log.Debug("UpdateCredential", zap.String("role", typeutil.RootCoordRole), zap.String("username", req.Username))
// validate params
rawPassword, err := crypto.Base64Decode(req.Password)
if err != nil {
log.Error("decode password fail", zap.String("username", req.Username), zap.Error(err))
return &commonpb.Status{
ErrorCode: commonpb.ErrorCode_UpdateCredentialFailure,
Reason: "decode password fail when updating:" + req.Username,
}, nil
}
if err = ValidatePassword(rawPassword); err != nil {
log.Error("illegal password", zap.String("username", req.Username), zap.Error(err))
return &commonpb.Status{
ErrorCode: commonpb.ErrorCode_IllegalArgument,
Reason: err.Error(),
}, nil
}
encryptedPassword, err := crypto.PasswordEncrypt(rawPassword)
if err != nil {
log.Error("encrypt password fail", zap.String("username", req.Username), zap.Error(err))
return &commonpb.Status{
ErrorCode: commonpb.ErrorCode_UpdateCredentialFailure,
Reason: "encrypt password fail when updating:" + req.Username,
}, nil
}
credInfo := &internalpb.CredentialInfo{
Username: req.Username,
EncryptedPassword: encryptedPassword,
}
result, err := node.rootCoord.UpdateCredential(ctx, credInfo)
if err != nil { // for error like conntext timeout etc.
log.Error("update credential fail", zap.String("username", req.Username), zap.Error(err))
return &commonpb.Status{
ErrorCode: commonpb.ErrorCode_UnexpectedError,
Reason: err.Error(),
}, nil
}
return result, err
}
func (node *Proxy) DeleteCredential(ctx context.Context, req *milvuspb.DeleteCredentialRequest) (*commonpb.Status, error) {
log.Debug("DeleteCredential", zap.String("role", typeutil.RootCoordRole), zap.String("username", req.Username))
result, err := node.rootCoord.DeleteCredential(ctx, req)
if err != nil { // for error like conntext timeout etc.
log.Error("delete credential fail", zap.String("username", req.Username), zap.Error(err))
return &commonpb.Status{
ErrorCode: commonpb.ErrorCode_UnexpectedError,
Reason: err.Error(),
}, nil
}
return result, err
}
func (node *Proxy) ListCredUsers(ctx context.Context, req *milvuspb.ListCredUsersRequest) (*milvuspb.ListCredUsersResponse, error) {
log.Debug("ListCredUsers", zap.String("role", typeutil.RootCoordRole))
// get from cache
usernames, err := globalMetaCache.GetCredUsernames(ctx)
if err != nil {
return &milvuspb.ListCredUsersResponse{
Status: &commonpb.Status{
ErrorCode: commonpb.ErrorCode_UnexpectedError,
Reason: err.Error(),
},
}, nil
}
return &milvuspb.ListCredUsersResponse{
Status: &commonpb.Status{
ErrorCode: commonpb.ErrorCode_Success,
},
Usernames: usernames,
}, nil
}

View File

@ -29,7 +29,9 @@ import (
"github.com/milvus-io/milvus/internal/log"
"github.com/milvus-io/milvus/internal/metrics"
"github.com/milvus-io/milvus/internal/proto/commonpb"
"github.com/milvus-io/milvus/internal/proto/internalpb"
"github.com/milvus-io/milvus/internal/proto/milvuspb"
"github.com/milvus-io/milvus/internal/proto/rootcoordpb"
"github.com/milvus-io/milvus/internal/proto/schemapb"
"github.com/milvus-io/milvus/internal/types"
"github.com/milvus-io/milvus/internal/util/timerecord"
@ -52,6 +54,13 @@ type Cache interface {
GetCollectionSchema(ctx context.Context, collectionName string) (*schemapb.CollectionSchema, error)
RemoveCollection(ctx context.Context, collectionName string)
RemovePartition(ctx context.Context, collectionName string, partitionName string)
// GetCredentialInfo operate credential cache
GetCredentialInfo(ctx context.Context, username string) (*internalpb.CredentialInfo, error)
RemoveCredential(username string)
UpdateCredential(credInfo *internalpb.CredentialInfo)
GetCredUsernames(ctx context.Context) ([]string, error)
ClearCredUsers()
}
type collectionInfo struct {
@ -75,8 +84,11 @@ var _ Cache = (*MetaCache)(nil)
type MetaCache struct {
client types.RootCoord
collInfo map[string]*collectionInfo
mu sync.RWMutex
collInfo map[string]*collectionInfo
credMap map[string]*internalpb.CredentialInfo // cache for credential, lazy load
credUsernameList []string // no need initialize when NewMetaCache
mu sync.RWMutex
credMut sync.RWMutex
}
// globalMetaCache is singleton instance of Cache
@ -97,6 +109,7 @@ func NewMetaCache(client types.RootCoord) (*MetaCache, error) {
return &MetaCache{
client: client,
collInfo: map[string]*collectionInfo{},
credMap: map[string]*internalpb.CredentialInfo{},
}, nil
}
@ -417,3 +430,93 @@ func (m *MetaCache) RemovePartition(ctx context.Context, collectionName, partiti
}
delete(partInfo, partitionName)
}
// GetCredentialInfo returns the credential related to provided username
// If the cache missed, proxy will try to fetch from storage
func (m *MetaCache) GetCredentialInfo(ctx context.Context, username string) (*internalpb.CredentialInfo, error) {
m.credMut.RLock()
var credInfo *internalpb.CredentialInfo
credInfo, ok := m.credMap[username]
m.credMut.RUnlock()
if !ok {
req := &rootcoordpb.GetCredentialRequest{
Base: &commonpb.MsgBase{
MsgType: commonpb.MsgType_GetCredential,
},
Username: username,
}
resp, err := m.client.GetCredential(ctx, req)
if err != nil {
return &internalpb.CredentialInfo{}, err
}
credInfo = &internalpb.CredentialInfo{
Username: resp.Username,
EncryptedPassword: resp.Password,
}
m.UpdateCredential(credInfo)
}
return &internalpb.CredentialInfo{
Username: credInfo.Username,
EncryptedPassword: credInfo.EncryptedPassword,
}, nil
}
func (m *MetaCache) ClearCredUsers() {
m.credMut.Lock()
defer m.credMut.Unlock()
// clear credUsernameList
m.credUsernameList = nil
}
func (m *MetaCache) RemoveCredential(username string) {
m.credMut.Lock()
defer m.credMut.Unlock()
// delete pair in credMap
delete(m.credMap, username)
// clear credUsernameList
m.credUsernameList = nil
}
func (m *MetaCache) UpdateCredential(credInfo *internalpb.CredentialInfo) {
m.credMut.Lock()
defer m.credMut.Unlock()
// update credMap
username := credInfo.Username
password := credInfo.EncryptedPassword
_, ok := m.credMap[username]
if !ok {
m.credMap[username] = &internalpb.CredentialInfo{}
}
m.credMap[username].Username = username
m.credMap[username].EncryptedPassword = password
}
func (m *MetaCache) UpdateCredUsersListCache(usernames []string) {
m.credMut.Lock()
defer m.credMut.Unlock()
m.credUsernameList = usernames
}
func (m *MetaCache) GetCredUsernames(ctx context.Context) ([]string, error) {
m.credMut.RLock()
usernames := m.credUsernameList
m.credMut.RUnlock()
if usernames == nil {
req := &milvuspb.ListCredUsersRequest{
Base: &commonpb.MsgBase{
MsgType: commonpb.MsgType_ListCredUsernames,
},
}
resp, err := m.client.ListCredUsers(ctx, req)
if err != nil {
return nil, err
}
usernames = resp.Usernames
m.UpdateCredUsersListCache(usernames)
}
return usernames, nil
}

View File

@ -22,6 +22,10 @@ import (
"fmt"
"testing"
"github.com/milvus-io/milvus/internal/util/crypto"
"github.com/milvus-io/milvus/internal/proto/rootcoordpb"
"github.com/milvus-io/milvus/internal/log"
"github.com/milvus-io/milvus/internal/proto/commonpb"
"github.com/milvus-io/milvus/internal/proto/milvuspb"
@ -134,6 +138,39 @@ func (m *MockRootCoordClientInterface) DescribeCollection(ctx context.Context, i
}, nil
}
func (m *MockRootCoordClientInterface) GetCredential(ctx context.Context, req *rootcoordpb.GetCredentialRequest) (*rootcoordpb.GetCredentialResponse, error) {
if m.Error {
return nil, errors.New("mocked error")
}
m.AccessCount++
if req.Username == "mockUser" {
encryptedPassword, _ := crypto.PasswordEncrypt("mockPass")
return &rootcoordpb.GetCredentialResponse{
Status: &commonpb.Status{
ErrorCode: commonpb.ErrorCode_Success,
},
Username: "mockUser",
Password: encryptedPassword,
}, nil
}
err := fmt.Errorf("can't find credential: " + req.Username)
return nil, err
}
func (m *MockRootCoordClientInterface) ListCredUsers(ctx context.Context, req *milvuspb.ListCredUsersRequest) (*milvuspb.ListCredUsersResponse, error) {
if m.Error {
return nil, errors.New("mocked error")
}
return &milvuspb.ListCredUsersResponse{
Status: &commonpb.Status{
ErrorCode: commonpb.ErrorCode_Success,
},
Usernames: []string{"mockUser"},
}, nil
}
//Simulate the cache path and the
func TestMetaCache_GetCollection(t *testing.T) {
ctx := context.Background()

View File

@ -30,6 +30,10 @@ import (
"testing"
"time"
"github.com/milvus-io/milvus/internal/proto/rootcoordpb"
"github.com/milvus-io/milvus/internal/util/crypto"
ot "github.com/grpc-ecosystem/go-grpc-middleware/tracing/opentracing"
"google.golang.org/grpc"
"google.golang.org/grpc/keepalive"
@ -1926,6 +1930,111 @@ func TestProxy(t *testing.T) {
assert.Equal(t, 0, len(resp.CollectionNames))
})
wg.Add(1)
t.Run("credential apis", func(t *testing.T) {
defer wg.Done()
// 1. create credential
password := "xxx"
newPassword := "yyy"
constructCreateCredentialRequest := func(rand string) *milvuspb.CreateCredentialRequest {
return &milvuspb.CreateCredentialRequest{
Base: nil,
Username: "test_username_" + rand,
Password: crypto.Base64Encode(password),
}
}
// success
createCredentialReq := constructCreateCredentialRequest(funcutil.RandomString(15))
resp, err := proxy.CreateCredential(ctx, createCredentialReq)
assert.NoError(t, err)
assert.Equal(t, commonpb.ErrorCode_Success, resp.ErrorCode)
// recreate -> fail (user already exists)
resp, err = proxy.CreateCredential(ctx, createCredentialReq)
assert.NoError(t, err)
assert.NotEqual(t, commonpb.ErrorCode_Success, resp.ErrorCode)
// invalid username
reqInvalidField := constructCreateCredentialRequest(funcutil.RandomString(15))
reqInvalidField.Username = "11_invalid_username"
resp, err = proxy.CreateCredential(ctx, reqInvalidField)
assert.NoError(t, err)
assert.NotEqual(t, commonpb.ErrorCode_Success, resp.ErrorCode)
// invalid password (not decode)
reqInvalidField = constructCreateCredentialRequest(funcutil.RandomString(15))
reqInvalidField.Password = "not_decoded_password"
resp, err = proxy.CreateCredential(ctx, reqInvalidField)
assert.NoError(t, err)
assert.NotEqual(t, commonpb.ErrorCode_Success, resp.ErrorCode)
// invalid password (length gt 256)
reqInvalidField = constructCreateCredentialRequest(funcutil.RandomString(15))
reqInvalidField.Password = "aaaaaaaaaabbbbbbbbbbccccccccccddddddddddeeeeeeeeeeffffffffffgggggggggghhhhhhhhhhiiiiiiiiiijjjjjjjjjjkkkkkkkkkkllllllllllmmmmmmmmmnnnnnnnnnnnooooooooooppppppppppqqqqqqqqqqrrrrrrrrrrsssssssssstttttttttttuuuuuuuuuuuvvvvvvvvvvwwwwwwwwwwwxxxxxxxxxxyyyyyyyyyzzzzzzzzzzz"
resp, err = proxy.CreateCredential(ctx, reqInvalidField)
assert.NoError(t, err)
assert.NotEqual(t, commonpb.ErrorCode_Success, resp.ErrorCode)
// 2. update credential
createCredentialReq.Password = crypto.Base64Encode(newPassword)
updateResp, err := proxy.UpdateCredential(ctx, createCredentialReq)
assert.NoError(t, err)
assert.Equal(t, commonpb.ErrorCode_Success, updateResp.ErrorCode)
// invalid password (not decode)
createCredentialReq.Password = newPassword
updateResp, err = proxy.UpdateCredential(ctx, createCredentialReq)
assert.NoError(t, err)
assert.NotEqual(t, commonpb.ErrorCode_Success, updateResp.ErrorCode)
// invalid password (length gt 256)
createCredentialReq.Password = "aaaaaaaaaabbbbbbbbbbccccccccccddddddddddeeeeeeeeeeffffffffffgggggggggghhhhhhhhhhiiiiiiiiiijjjjjjjjjjkkkkkkkkkkllllllllllmmmmmmmmmnnnnnnnnnnnooooooooooppppppppppqqqqqqqqqqrrrrrrrrrrsssssssssstttttttttttuuuuuuuuuuuvvvvvvvvvvwwwwwwwwwwwxxxxxxxxxxyyyyyyyyyzzzzzzzzzzz"
updateResp, err = proxy.UpdateCredential(ctx, createCredentialReq)
assert.NoError(t, err)
assert.NotEqual(t, commonpb.ErrorCode_Success, updateResp.ErrorCode)
// 3. get credential
constructGetCredentialRequest := func() *rootcoordpb.GetCredentialRequest {
return &rootcoordpb.GetCredentialRequest{
Base: nil,
Username: createCredentialReq.Username,
}
}
getCredentialReq := constructGetCredentialRequest()
getResp, err := rootCoordClient.GetCredential(ctx, getCredentialReq)
assert.NoError(t, err)
assert.Equal(t, commonpb.ErrorCode_Success, getResp.Status.ErrorCode)
assert.True(t, crypto.PasswordVerify(newPassword, getResp.Password))
getCredentialReq.Username = "("
getResp, err = rootCoordClient.GetCredential(ctx, getCredentialReq)
assert.Error(t, err)
// 4. list credential usernames
constructListCredUsersRequest := func() *milvuspb.ListCredUsersRequest {
return &milvuspb.ListCredUsersRequest{
Base: nil,
}
}
listCredUsersReq := constructListCredUsersRequest()
listUsersResp, err := proxy.ListCredUsers(ctx, listCredUsersReq)
assert.NoError(t, err)
assert.True(t, len(listUsersResp.Usernames) > 0)
// 5. delete credential
constructDelCredRequest := func() *milvuspb.DeleteCredentialRequest {
return &milvuspb.DeleteCredentialRequest{
Base: nil,
Username: createCredentialReq.Username,
}
}
delCredReq := constructDelCredRequest()
deleteResp, err := proxy.DeleteCredential(ctx, delCredReq)
assert.NoError(t, err)
assert.Equal(t, commonpb.ErrorCode_Success, deleteResp.ErrorCode)
})
// proxy unhealthy
//
//notStateCode := "not state code"
@ -2685,6 +2794,39 @@ func TestProxy(t *testing.T) {
assert.NotEqual(t, commonpb.ErrorCode_Success, resp.ErrorCode)
})
wg.Add(1)
t.Run("CreateCredential fail, timeout", func(t *testing.T) {
defer wg.Done()
resp, err := proxy.CreateCredential(shortCtx, &milvuspb.CreateCredentialRequest{Username: "xxx"})
assert.NoError(t, err)
assert.NotEqual(t, commonpb.ErrorCode_Success, resp.ErrorCode)
})
wg.Add(1)
t.Run("UpdateCredential fail, timeout", func(t *testing.T) {
defer wg.Done()
resp, err := proxy.UpdateCredential(shortCtx, &milvuspb.CreateCredentialRequest{Username: "xxx"})
assert.NoError(t, err)
assert.NotEqual(t, commonpb.ErrorCode_Success, resp.ErrorCode)
})
wg.Add(1)
t.Run("DeleteCredential fail, timeout", func(t *testing.T) {
defer wg.Done()
resp, err := proxy.DeleteCredential(shortCtx, &milvuspb.DeleteCredentialRequest{Username: "xxx"})
assert.NoError(t, err)
assert.NotEqual(t, commonpb.ErrorCode_Success, resp.ErrorCode)
})
wg.Add(1)
t.Run("ListCredUsers fail, timeout", func(t *testing.T) {
defer wg.Done()
globalMetaCache.ClearCredUsers() // precondition
resp, err := proxy.ListCredUsers(shortCtx, &milvuspb.ListCredUsersRequest{})
assert.NoError(t, err)
assert.NotEqual(t, commonpb.ErrorCode_Success, resp.Status.ErrorCode)
})
testServer.gracefulStop()
wg.Wait()

View File

@ -1004,3 +1004,23 @@ func NewRootCoordMock(opts ...RootCoordMockOption) *RootCoordMock {
return rc
}
func (coord *RootCoordMock) CreateCredential(ctx context.Context, req *internalpb.CredentialInfo) (*commonpb.Status, error) {
return &commonpb.Status{}, nil
}
func (coord *RootCoordMock) UpdateCredential(ctx context.Context, req *internalpb.CredentialInfo) (*commonpb.Status, error) {
return &commonpb.Status{}, nil
}
func (coord *RootCoordMock) DeleteCredential(ctx context.Context, req *milvuspb.DeleteCredentialRequest) (*commonpb.Status, error) {
return &commonpb.Status{}, nil
}
func (coord *RootCoordMock) ListCredUsers(ctx context.Context, req *milvuspb.ListCredUsersRequest) (*milvuspb.ListCredUsersResponse, error) {
return &milvuspb.ListCredUsersResponse{}, nil
}
func (coord *RootCoordMock) GetCredential(ctx context.Context, req *rootcoordpb.GetCredentialRequest) (*rootcoordpb.GetCredentialResponse, error) {
return &rootcoordpb.GetCredentialResponse{}, nil
}

View File

@ -487,3 +487,43 @@ func fillFieldIDBySchema(columns []*schemapb.FieldData, schema *schemapb.Collect
return nil
}
func ValidateUsername(username string) error {
username = strings.TrimSpace(username)
if username == "" {
return errors.New("username should not be empty")
}
invalidMsg := "Invalid username: " + username + ". "
if int64(len(username)) > Params.ProxyCfg.MaxUsernameLength {
msg := invalidMsg + "The length of username must be less than " +
strconv.FormatInt(Params.ProxyCfg.MaxUsernameLength, 10) + " characters."
return errors.New(msg)
}
firstChar := username[0]
if !isAlpha(firstChar) {
msg := invalidMsg + "The first character of username must be a letter."
return errors.New(msg)
}
usernameSize := len(username)
for i := 1; i < usernameSize; i++ {
c := username[i]
if c != '_' && !isAlpha(c) && !isNumber(c) {
msg := invalidMsg + "Username should only contain numbers, letters, and underscores."
return errors.New(msg)
}
}
return nil
}
func ValidatePassword(password string) error {
if int64(len(password)) > Params.ProxyCfg.MaxPasswordLength {
msg := "The length of password must be less than " +
strconv.FormatInt(Params.ProxyCfg.MaxPasswordLength, 10) + " characters."
return errors.New(msg)
}
return nil
}

View File

@ -527,3 +527,38 @@ func TestFillFieldIDBySchema(t *testing.T) {
assert.Equal(t, schemapb.DataType_Int64, columns[0].Type)
assert.Equal(t, int64(1), columns[0].FieldId)
}
func TestValidateUsername(t *testing.T) {
// only spaces
res := ValidateUsername(" ")
assert.Error(t, res)
// starts with non-alphabet
res = ValidateUsername("1abc")
assert.Error(t, res)
// length gt 32
res = ValidateUsername("aaaaaaaaaabbbbbbbbbbccccccccccddddd")
assert.Error(t, res)
// illegal character which not alphabet, _, or number
res = ValidateUsername("a1^7*).,")
assert.Error(t, res)
// normal username that only contains alphabet, _, and number
Params.InitOnce()
res = ValidateUsername("a17_good")
assert.Nil(t, res)
}
func TestValidatePassword(t *testing.T) {
Params.InitOnce()
// only spaces
res := ValidatePassword(" ")
assert.Nil(t, res)
//
res = ValidatePassword("1abc")
assert.Nil(t, res)
//
res = ValidatePassword("a1^7*).,")
assert.Nil(t, res)
//
res = ValidatePassword("aaaaaaaaaabbbbbbbbbbccccccccccddddddddddeeeeeeeeeeffffffffffgggggggggghhhhhhhhhhiiiiiiiiiijjjjjjjjjjkkkkkkkkkkllllllllllmmmmmmmmmnnnnnnnnnnnooooooooooppppppppppqqqqqqqqqqrrrrrrrrrrsssssssssstttttttttttuuuuuuuuuuuvvvvvvvvvvwwwwwwwwwwwxxxxxxxxxxyyyyyyyyyzzzzzzzzzzz")
assert.Error(t, res)
}

View File

@ -59,6 +59,18 @@ func (m *mockProxy) SendRetrieveResult(ctx context.Context, req *internalpb.Retr
}, nil
}
func (m *mockProxy) InvalidateCredentialCache(ctx context.Context, request *proxypb.InvalidateCredCacheRequest) (*commonpb.Status, error) {
return nil, nil
}
func (m *mockProxy) UpdateCredentialCache(ctx context.Context, request *proxypb.UpdateCredCacheRequest) (*commonpb.Status, error) {
return nil, nil
}
func (m *mockProxy) ClearCredUsersCache(ctx context.Context, request *internalpb.ClearCredUsersCacheRequest) (*commonpb.Status, error) {
return nil, nil
}
func newMockProxy() types.Proxy {
return &mockProxy{}
}

View File

@ -30,6 +30,8 @@ import (
"github.com/milvus-io/milvus/internal/log"
"github.com/milvus-io/milvus/internal/proto/commonpb"
pb "github.com/milvus-io/milvus/internal/proto/etcdpb"
"github.com/milvus-io/milvus/internal/proto/internalpb"
"github.com/milvus-io/milvus/internal/proto/milvuspb"
"github.com/milvus-io/milvus/internal/proto/schemapb"
"github.com/milvus-io/milvus/internal/util/typeutil"
)
@ -76,6 +78,12 @@ const (
// DropPartitionDDType name of DD type for drop partition
DropPartitionDDType = "DropPartition"
// UserSubPrefix subpath for credential user
UserSubPrefix = "/credential/users"
// CredentialPrefix prefix for credential user
CredentialPrefix = ComponentPrefix + UserSubPrefix
)
// MetaTable store all rootcoord meta info
@ -94,6 +102,7 @@ type MetaTable struct {
tenantLock sync.RWMutex
proxyLock sync.RWMutex
ddLock sync.RWMutex
credLock sync.RWMutex
}
// NewMetaTable creates meta table for rootcoord, which stores all in-memory information
@ -105,6 +114,7 @@ func NewMetaTable(txn kv.TxnKV, snap kv.SnapShotKV) (*MetaTable, error) {
tenantLock: sync.RWMutex{},
proxyLock: sync.RWMutex{},
ddLock: sync.RWMutex{},
credLock: sync.RWMutex{},
}
err := mt.reloadFromKV()
if err != nil {
@ -1340,3 +1350,72 @@ func (mt *MetaTable) IsAlias(collectionAlias string) bool {
_, ok := mt.collAlias2ID[collectionAlias]
return ok
}
// AddCredential add credential
func (mt *MetaTable) AddCredential(credInfo *internalpb.CredentialInfo) error {
mt.credLock.Lock()
defer mt.credLock.Unlock()
if credInfo.Username == "" {
return fmt.Errorf("username is empty")
}
k := fmt.Sprintf("%s/%s", CredentialPrefix, credInfo.Username)
err := mt.txn.Save(k, credInfo.EncryptedPassword)
if err != nil {
log.Error("MetaTable save fail", zap.Error(err))
return fmt.Errorf("save credential fail key:%s, err:%w", credInfo.Username, err)
}
return nil
}
// GetCredential get credential by username
func (mt *MetaTable) getCredential(username string) (*internalpb.CredentialInfo, error) {
mt.credLock.RLock()
defer mt.credLock.RUnlock()
k := fmt.Sprintf("%s/%s", CredentialPrefix, username)
v, err := mt.txn.Load(k)
if err != nil {
log.Warn("MetaTable load fail", zap.String("key", k), zap.Error(err))
return nil, err
}
return &internalpb.CredentialInfo{Username: username, EncryptedPassword: v}, nil
}
// DeleteCredential delete credential
func (mt *MetaTable) DeleteCredential(username string) error {
mt.credLock.Lock()
defer mt.credLock.Unlock()
k := fmt.Sprintf("%s/%s", CredentialPrefix, username)
err := mt.txn.Remove(k)
if err != nil {
log.Error("MetaTable remove fail", zap.Error(err))
return fmt.Errorf("remove credential fail key:%s, err:%w", username, err)
}
return nil
}
// ListCredentialUsernames list credential usernames
func (mt *MetaTable) ListCredentialUsernames() (*milvuspb.ListCredUsersResponse, error) {
mt.credLock.RLock()
defer mt.credLock.RUnlock()
keys, _, err := mt.txn.LoadWithPrefix(CredentialPrefix)
if err != nil {
log.Error("MetaTable list all credential usernames fail", zap.Error(err))
return &milvuspb.ListCredUsersResponse{}, err
}
var usernames []string
for _, path := range keys {
username := typeutil.After(path, UserSubPrefix+"/")
if len(username) == 0 {
log.Warn("no username extract from path:", zap.String("path", path))
continue
}
usernames = append(usernames, username)
}
return &milvuspb.ListCredUsersResponse{Usernames: usernames}, nil
}

View File

@ -72,6 +72,7 @@ type mockTestTxnKV struct {
save func(key, value string) error
multiSave func(kvs map[string]string) error
multiSaveAndRemoveWithPrefix func(saves map[string]string, removals []string) error
remove func(key string) error
}
func (m *mockTestTxnKV) LoadWithPrefix(key string) ([]string, []string, error) {
@ -90,6 +91,10 @@ func (m *mockTestTxnKV) MultiSaveAndRemoveWithPrefix(saves map[string]string, re
return m.multiSaveAndRemoveWithPrefix(saves, removals)
}
func (m *mockTestTxnKV) Remove(key string) error {
return m.remove(key)
}
func Test_MockKV(t *testing.T) {
k1 := &mockTestKV{}
kt := &mockTestTxnKV{}
@ -561,6 +566,17 @@ func TestMetaTable(t *testing.T) {
assert.Equal(t, "false", flag)
})
wg.Add(1)
t.Run("delete credential", func(t *testing.T) {
defer wg.Done()
err = mt.DeleteCredential("")
assert.Nil(t, err)
err = mt.DeleteCredential("abcxyz")
assert.Nil(t, err)
})
/////////////////////////// these tests should run at last, it only used to hit the error lines ////////////////////////
txnkv := etcdkv.NewEtcdKV(etcdCli, rootPath)
mockKV := &mockTestKV{}
@ -573,6 +589,7 @@ func TestMetaTable(t *testing.T) {
multiSaveAndRemoveWithPrefix: func(kvs map[string]string, removal []string) error {
return txnkv.MultiSaveAndRemoveWithPrefix(kvs, removal)
},
remove: func(key string) error { return txnkv.Remove(key) },
}
mt.txn = mockTxnKV
@ -1117,6 +1134,16 @@ func TestMetaTable(t *testing.T) {
assert.NotNil(t, err)
assert.EqualError(t, err, fmt.Sprintf("cannot find index, id = %d", idxInfo[0].IndexID))
})
wg.Add(1)
t.Run("delete credential failed", func(t *testing.T) {
defer wg.Done()
mockTxnKV.remove = func(key string) error {
return fmt.Errorf("delete error")
}
err := mt.DeleteCredential("")
assert.Error(t, err)
})
wg.Wait()
}

View File

@ -21,6 +21,8 @@ import (
"fmt"
"sync"
"github.com/milvus-io/milvus/internal/proto/internalpb"
"github.com/milvus-io/milvus/internal/log"
"github.com/milvus-io/milvus/internal/proto/commonpb"
"github.com/milvus-io/milvus/internal/proto/proxypb"
@ -172,3 +174,81 @@ func (p *proxyClientManager) ReleaseDQLMessageStream(ctx context.Context, in *pr
ErrorCode: commonpb.ErrorCode_Success,
}, nil
}
func (p *proxyClientManager) InvalidateCredentialCache(ctx context.Context, request *proxypb.InvalidateCredCacheRequest) error {
p.lock.Lock()
defer p.lock.Unlock()
defer func() {
if err := recover(); err != nil {
log.Debug("call InvalidateCredentialCache panic", zap.Any("msg", err))
}
}()
if len(p.proxyClient) == 0 {
log.Warn("proxy client is empty, InvalidateCredentialCache will not send to any client")
return nil
}
for _, f := range p.proxyClient {
sta, err := f.InvalidateCredentialCache(ctx, request)
if err != nil {
return fmt.Errorf("grpc fail, error=%w", err)
}
if sta.ErrorCode != commonpb.ErrorCode_Success {
return fmt.Errorf("message = %s", sta.Reason)
}
}
return nil
}
func (p *proxyClientManager) UpdateCredentialCache(ctx context.Context, request *proxypb.UpdateCredCacheRequest) error {
p.lock.Lock()
defer p.lock.Unlock()
defer func() {
if err := recover(); err != nil {
log.Debug("call UpdateCredentialCache panic", zap.Any("msg", err))
}
}()
if len(p.proxyClient) == 0 {
log.Warn("proxy client is empty, UpdateCredentialCache will not send to any client")
return nil
}
for _, f := range p.proxyClient {
sta, err := f.UpdateCredentialCache(ctx, request)
if err != nil {
return fmt.Errorf("grpc fail, error=%w", err)
}
if sta.ErrorCode != commonpb.ErrorCode_Success {
return fmt.Errorf("message = %s", sta.Reason)
}
}
return nil
}
func (p *proxyClientManager) ClearCredUsersCache(ctx context.Context, request *internalpb.ClearCredUsersCacheRequest) error {
p.lock.Lock()
defer p.lock.Unlock()
defer func() {
if err := recover(); err != nil {
log.Debug("call ClearCredUsersCache panic", zap.Any("msg", err))
}
}()
if len(p.proxyClient) == 0 {
log.Warn("proxy client is empty, ClearCredUsersCache will not send to any client")
return nil
}
for _, f := range p.proxyClient {
sta, err := f.ClearCredUsersCache(ctx, request)
if err != nil {
return fmt.Errorf("grpc fail, error=%w", err)
}
if sta.ErrorCode != commonpb.ErrorCode_Success {
return fmt.Errorf("message = %s", sta.Reason)
}
}
return nil
}

View File

@ -147,3 +147,34 @@ func TestProxyClientManager_ReleaseDQLMessageStream(t *testing.T) {
assert.Panics(t, func() { pcm.ReleaseDQLMessageStream(ctx, nil) })
}
func TestProxyClientManager_InvalidateCredentialCache(t *testing.T) {
Params.Init()
ctx := context.Background()
core, err := NewCore(ctx, nil)
assert.Nil(t, err)
cli, err := etcd.GetEtcdClient(&Params.EtcdCfg)
assert.Nil(t, err)
defer cli.Close()
core.etcdCli = cli
pcm := newProxyClientManager(core)
pcm.InvalidateCredentialCache(ctx, nil)
core.SetNewProxyClient(
func(se *sessionutil.Session) (types.Proxy, error) {
return nil, nil
},
)
session := &sessionutil.Session{
ServerID: 100,
Address: "localhost",
}
pcm.AddProxyClient(session)
pcm.InvalidateCredentialCache(ctx, nil)
}

View File

@ -2503,3 +2503,187 @@ func segmentsOnlineReady(idxBuilt, segCount int) bool {
}
return false
}
// ExpireCredCache will call invalidate credential cache
func (c *Core) ExpireCredCache(ctx context.Context, username string) error {
req := proxypb.InvalidateCredCacheRequest{
Base: &commonpb.MsgBase{
MsgType: 0, //TODO, msg type
MsgID: 0, //TODO, msg id
SourceID: c.session.ServerID,
},
Username: username,
}
return c.proxyClientManager.InvalidateCredentialCache(ctx, &req)
}
// UpdateCredCache will call update credential cache
func (c *Core) UpdateCredCache(ctx context.Context, credInfo *internalpb.CredentialInfo) error {
req := proxypb.UpdateCredCacheRequest{
Base: &commonpb.MsgBase{
MsgType: 0, //TODO, msg type
MsgID: 0, //TODO, msg id
SourceID: c.session.ServerID,
},
Username: credInfo.Username,
Password: credInfo.EncryptedPassword,
}
return c.proxyClientManager.UpdateCredentialCache(ctx, &req)
}
// ClearCredUsersCache will call clear credential usernames cache
func (c *Core) ClearCredUsersCache(ctx context.Context) error {
req := internalpb.ClearCredUsersCacheRequest{}
return c.proxyClientManager.ClearCredUsersCache(ctx, &req)
}
// CreateCredential create new user and password
// 1. decode ciphertext password to raw password
// 2. encrypt raw password
// 3. save in to etcd
func (c *Core) CreateCredential(ctx context.Context, credInfo *internalpb.CredentialInfo) (*commonpb.Status, error) {
metrics.RootCoordCreateCredentialCounter.WithLabelValues(metrics.TotalLabel).Inc()
tr := timerecord.NewTimeRecorder("CreateCredential")
log.Debug("CreateCredential", zap.String("role", typeutil.RootCoordRole),
zap.String("username", credInfo.Username))
if cred, _ := c.MetaTable.getCredential(credInfo.Username); cred != nil {
return failStatus(commonpb.ErrorCode_CreateCredentialFailure, "user already exists:"+credInfo.Username), nil
}
// update proxy's local cache
err := c.ClearCredUsersCache(ctx)
if err != nil {
log.Error("CreateCredential clear credential username list cache failed", zap.String("role", typeutil.RootCoordRole),
zap.String("username", credInfo.Username), zap.Error(err))
metrics.RootCoordCreateCredentialCounter.WithLabelValues(metrics.FailLabel).Inc()
return failStatus(commonpb.ErrorCode_CreateCredentialFailure, "CreateCredential failed: "+err.Error()), nil
}
// insert to db
err = c.MetaTable.AddCredential(credInfo)
if err != nil {
log.Error("CreateCredential save credential failed", zap.String("role", typeutil.RootCoordRole),
zap.String("username", credInfo.Username), zap.Error(err))
metrics.RootCoordCreateCredentialCounter.WithLabelValues(metrics.FailLabel).Inc()
return failStatus(commonpb.ErrorCode_CreateCredentialFailure, "CreateCredential failed: "+err.Error()), nil
}
log.Debug("CreateCredential success", zap.String("role", typeutil.RootCoordRole),
zap.String("username", credInfo.Username))
metrics.RootCoordCreateCredentialCounter.WithLabelValues(metrics.SuccessLabel).Inc()
metrics.RootCoordCredentialWriteTypeLatency.WithLabelValues("CreateCredential").Observe(float64(tr.ElapseSpan().Milliseconds()))
metrics.RootCoordNumOfCredentials.Inc()
return succStatus(), nil
}
// GetCredential get credential by username
func (c *Core) GetCredential(ctx context.Context, in *rootcoordpb.GetCredentialRequest) (*rootcoordpb.GetCredentialResponse, error) {
metrics.RootCoordGetCredentialCounter.WithLabelValues(metrics.TotalLabel).Inc()
tr := timerecord.NewTimeRecorder("GetCredential")
log.Debug("GetCredential", zap.String("role", typeutil.RootCoordRole),
zap.String("username", in.Username))
credInfo, err := c.MetaTable.getCredential(in.Username)
if err != nil {
log.Error("GetCredential query credential failed", zap.String("role", typeutil.RootCoordRole),
zap.String("username", in.Username), zap.Error(err))
metrics.RootCoordGetCredentialCounter.WithLabelValues(metrics.FailLabel).Inc()
return &rootcoordpb.GetCredentialResponse{
Status: failStatus(commonpb.ErrorCode_GetCredentialFailure, "GetCredential failed: "+err.Error()),
}, err
}
log.Debug("GetCredential success", zap.String("role", typeutil.RootCoordRole),
zap.String("username", in.Username))
metrics.RootCoordGetCredentialCounter.WithLabelValues(metrics.SuccessLabel).Inc()
metrics.RootCoordCredentialReadTypeLatency.WithLabelValues("GetCredential", in.Username).Observe(float64(tr.ElapseSpan().Milliseconds()))
return &rootcoordpb.GetCredentialResponse{
Status: succStatus(),
Username: credInfo.Username,
Password: credInfo.EncryptedPassword,
}, nil
}
// UpdateCredential update password for a user
func (c *Core) UpdateCredential(ctx context.Context, credInfo *internalpb.CredentialInfo) (*commonpb.Status, error) {
metrics.RootCoordUpdateCredentialCounter.WithLabelValues(metrics.TotalLabel).Inc()
tr := timerecord.NewTimeRecorder("UpdateCredential")
log.Debug("UpdateCredential", zap.String("role", typeutil.RootCoordRole),
zap.String("username", credInfo.Username))
// update proxy's local cache
err := c.UpdateCredCache(ctx, credInfo)
if err != nil {
log.Error("UpdateCredential update credential cache failed", zap.String("role", typeutil.RootCoordRole),
zap.String("username", credInfo.Username), zap.Error(err))
metrics.RootCoordUpdateCredentialCounter.WithLabelValues(metrics.FailLabel).Inc()
return failStatus(commonpb.ErrorCode_UpdateCredentialFailure, "UpdateCredential failed: "+err.Error()), nil
}
// update data on storage
err = c.MetaTable.AddCredential(credInfo)
if err != nil {
log.Error("UpdateCredential save credential failed", zap.String("role", typeutil.RootCoordRole),
zap.String("username", credInfo.Username), zap.Error(err))
metrics.RootCoordUpdateCredentialCounter.WithLabelValues(metrics.FailLabel).Inc()
return failStatus(commonpb.ErrorCode_UpdateCredentialFailure, "UpdateCredential failed: "+err.Error()), nil
}
log.Debug("UpdateCredential success", zap.String("role", typeutil.RootCoordRole),
zap.String("username", credInfo.Username))
metrics.RootCoordUpdateCredentialCounter.WithLabelValues(metrics.SuccessLabel).Inc()
metrics.RootCoordCredentialWriteTypeLatency.WithLabelValues("UpdateCredential").Observe(float64(tr.ElapseSpan().Milliseconds()))
return succStatus(), nil
}
// DeleteCredential delete a user
func (c *Core) DeleteCredential(ctx context.Context, in *milvuspb.DeleteCredentialRequest) (*commonpb.Status, error) {
metrics.RootCoordDeleteCredentialCounter.WithLabelValues(metrics.TotalLabel).Inc()
tr := timerecord.NewTimeRecorder("DeleteCredential")
log.Debug("DeleteCredential", zap.String("role", typeutil.RootCoordRole),
zap.String("username", in.Username))
// invalidate proxy's local cache
err := c.ExpireCredCache(ctx, in.Username)
if err != nil {
log.Error("DeleteCredential expire credential cache failed", zap.String("role", typeutil.RootCoordRole),
zap.String("username", in.Username), zap.Error(err))
metrics.RootCoordDeleteCredentialCounter.WithLabelValues(metrics.FailLabel).Inc()
return failStatus(commonpb.ErrorCode_DeleteCredentialFailure, "DeleteCredential failed: "+err.Error()), nil
}
// delete data on storage
err = c.MetaTable.DeleteCredential(in.Username)
if err != nil {
log.Error("DeleteCredential remove credential failed", zap.String("role", typeutil.RootCoordRole),
zap.String("username", in.Username), zap.Error(err))
metrics.RootCoordDeleteCredentialCounter.WithLabelValues(metrics.FailLabel).Inc()
return failStatus(commonpb.ErrorCode_DeleteCredentialFailure, "DeleteCredential failed: "+err.Error()), err
}
log.Debug("DeleteCredential success", zap.String("role", typeutil.RootCoordRole),
zap.String("username", in.Username))
metrics.RootCoordDeleteCredentialCounter.WithLabelValues(metrics.SuccessLabel).Inc()
metrics.RootCoordCredentialWriteTypeLatency.WithLabelValues("DeleteCredential").Observe(float64(tr.ElapseSpan().Milliseconds()))
metrics.RootCoordNumOfCredentials.Dec()
return succStatus(), nil
}
// ListCredUsers list all usernames
func (c *Core) ListCredUsers(ctx context.Context, in *milvuspb.ListCredUsersRequest) (*milvuspb.ListCredUsersResponse, error) {
metrics.RootCoordListCredUsersCounter.WithLabelValues(metrics.TotalLabel).Inc()
tr := timerecord.NewTimeRecorder("ListCredUsers")
credInfo, err := c.MetaTable.ListCredentialUsernames()
if err != nil {
log.Error("ListCredUsers query usernames failed", zap.String("role", typeutil.RootCoordRole),
zap.Int64("msgID", in.Base.MsgID), zap.Error(err))
return &milvuspb.ListCredUsersResponse{
Status: failStatus(commonpb.ErrorCode_ListCredUsersFailure, "ListCredUsers failed: "+err.Error()),
}, err
}
log.Debug("ListCredUsers success", zap.String("role", typeutil.RootCoordRole))
metrics.RootCoordListCredUsersCounter.WithLabelValues(metrics.SuccessLabel).Inc()
metrics.RootCoordCredentialReadTypeLatency.WithLabelValues("ListCredUsers", "ALL.API").Observe(float64(tr.ElapseSpan().Milliseconds()))
return &milvuspb.ListCredUsersResponse{
Status: succStatus(),
Usernames: credInfo.Usernames,
}, nil
}

View File

@ -629,6 +629,17 @@ type RootCoord interface {
// response status contains the status/error code and failing reason if any error is returned
// error is always nil
ReportImport(ctx context.Context, req *rootcoordpb.ImportResult) (*commonpb.Status, error)
// CreateCredential create new user and password
CreateCredential(ctx context.Context, req *internalpb.CredentialInfo) (*commonpb.Status, error)
// UpdateCredential update password for a user
UpdateCredential(ctx context.Context, req *internalpb.CredentialInfo) (*commonpb.Status, error)
// DeleteCredential delete a user
DeleteCredential(ctx context.Context, req *milvuspb.DeleteCredentialRequest) (*commonpb.Status, error)
// ListCredUsers list all usernames
ListCredUsers(ctx context.Context, req *milvuspb.ListCredUsersRequest) (*milvuspb.ListCredUsersResponse, error)
// GetCredential get credential by username
GetCredential(ctx context.Context, req *rootcoordpb.GetCredentialRequest) (*rootcoordpb.GetCredentialResponse, error)
}
// RootCoordComponent is used by grpc server of RootCoord
@ -687,6 +698,21 @@ type Proxy interface {
// error is returned only when some communication issue occurs.
InvalidateCollectionMetaCache(ctx context.Context, request *proxypb.InvalidateCollMetaCacheRequest) (*commonpb.Status, error)
// InvalidateCredentialCache notifies Proxy to clear all the credential cache of specified username.
//
// InvalidateCredentialCache should be called when there are credential changes for specified username.
// Such as `CreateCredential`, `UpdateCredential`, `DeleteCredential`, etc.
//
// InvalidateCredentialCache should always succeed even though the specified username doesn't exist in Proxy.
// So the code of response `Status` should be always `Success`.
//
// error is returned only when some communication issue occurs.
InvalidateCredentialCache(ctx context.Context, request *proxypb.InvalidateCredCacheRequest) (*commonpb.Status, error)
UpdateCredentialCache(ctx context.Context, request *proxypb.UpdateCredCacheRequest) (*commonpb.Status, error)
ClearCredUsersCache(ctx context.Context, request *internalpb.ClearCredUsersCacheRequest) (*commonpb.Status, error)
// ReleaseDQLMessageStream notifies Proxy to release and close the search message stream of specific collection.
//
// ReleaseDQLMessageStream should be called when the specific collection was released.
@ -1104,6 +1130,15 @@ type ProxyComponent interface {
GetImportState(ctx context.Context, req *milvuspb.GetImportStateRequest) (*milvuspb.GetImportStateResponse, error)
GetReplicas(ctx context.Context, req *milvuspb.GetReplicasRequest) (*milvuspb.GetReplicasResponse, error)
// CreateCredential create new user and password
CreateCredential(ctx context.Context, req *milvuspb.CreateCredentialRequest) (*commonpb.Status, error)
// UpdateCredential update password for a user
UpdateCredential(ctx context.Context, req *milvuspb.CreateCredentialRequest) (*commonpb.Status, error)
// DeleteCredential delete a user
DeleteCredential(ctx context.Context, req *milvuspb.DeleteCredentialRequest) (*commonpb.Status, error)
// ListCredUsers list all usernames
ListCredUsers(ctx context.Context, req *milvuspb.ListCredUsersRequest) (*milvuspb.ListCredUsersResponse, error)
}
// QueryNode is the interface `querynode` package implements

View File

@ -20,4 +20,10 @@ package util
const (
SegmentMetaPrefix = "queryCoord-segmentMeta"
ChangeInfoMetaPrefix = "queryCoord-sealedSegmentChangeInfo"
HeaderAuthorize = "authorization"
// HeaderSourceID identify requests from Milvus members and client requests
HeaderSourceID = "sourceId"
// MemberCredID id for Milvus members (data/index/query node/coord component)
MemberCredID = "@@milvus-member@@"
CredentialSeperator = ":"
)

View File

@ -0,0 +1,43 @@
package crypto
import (
"encoding/base64"
"github.com/milvus-io/milvus/internal/log"
"go.uber.org/zap"
"golang.org/x/crypto/bcrypt"
)
// PasswordEncrypt encrypt password
func PasswordEncrypt(pwd string) (string, error) {
bytes, err := bcrypt.GenerateFromPassword([]byte(pwd), bcrypt.DefaultCost)
if err != nil {
return "", err
}
return string(bytes), err
}
// PasswordVerify verify encrypted password
func PasswordVerify(pwd, hashPwd string) bool {
err := bcrypt.CompareHashAndPassword([]byte(hashPwd), []byte(pwd))
if err != nil {
log.Error("Verify password failed", zap.Error(err))
}
return err == nil
}
func Base64Decode(pwd string) (string, error) {
bytes, err := base64.StdEncoding.DecodeString(pwd)
if err != nil {
return "", err
}
return string(bytes), err
}
func Base64Encode(pwd string) string {
return base64.StdEncoding.EncodeToString([]byte(pwd))
}

View File

@ -0,0 +1,15 @@
package crypto
import (
"testing"
"github.com/stretchr/testify/assert"
)
func TestPasswordVerify(t *testing.T) {
wrongPassword := "test_my_name"
correctPassword := "test_my_pass_new"
hashedPass, _ := PasswordEncrypt(correctPassword)
assert.True(t, PasswordVerify(correctPassword, "$2a$10$3H9DLiHyPxJ29bMWRNyueOrGkbzJfE3BAR159ju3UetytAoKk7Ne2"))
assert.False(t, PasswordVerify(wrongPassword, hashedPass))
}

View File

@ -0,0 +1,19 @@
package grpcclient
import (
"context"
"github.com/milvus-io/milvus/internal/util"
)
type Token struct {
Value string
}
func (t *Token) GetRequestMetadata(ctx context.Context, uri ...string) (map[string]string, error) {
return map[string]string{util.HeaderSourceID: t.Value}, nil
}
func (t *Token) RequireTransportSecurity() bool {
return false
}

View File

@ -22,6 +22,10 @@ import (
"sync"
"time"
"github.com/milvus-io/milvus/internal/util"
"github.com/milvus-io/milvus/internal/util/crypto"
grpcopentracing "github.com/grpc-ecosystem/go-grpc-middleware/tracing/opentracing"
"github.com/milvus-io/milvus/internal/log"
"github.com/milvus-io/milvus/internal/util/funcutil"
@ -175,6 +179,7 @@ func (c *ClientBase) connect(ctx context.Context) error {
},
MinConnectTimeout: dialTimeout,
}),
grpc.WithPerRPCCredentials(&Token{Value: crypto.Base64Encode(util.MemberCredID)}),
)
cancel()
if err != nil {

View File

@ -58,3 +58,15 @@ func (m *ProxyClient) SendSearchResult(ctx context.Context, in *internalpb.Searc
func (m *ProxyClient) SendRetrieveResult(ctx context.Context, in *internalpb.RetrieveResults, opts ...grpc.CallOption) (*commonpb.Status, error) {
return &commonpb.Status{}, m.Err
}
func (m *ProxyClient) InvalidateCredentialCache(ctx context.Context, in *proxypb.InvalidateCredCacheRequest, opts ...grpc.CallOption) (*commonpb.Status, error) {
return &commonpb.Status{}, m.Err
}
func (m *ProxyClient) UpdateCredentialCache(ctx context.Context, in *proxypb.UpdateCredCacheRequest, opts ...grpc.CallOption) (*commonpb.Status, error) {
return &commonpb.Status{}, m.Err
}
func (m *ProxyClient) ClearCredUsersCache(ctx context.Context, in *internalpb.ClearCredUsersCacheRequest, opts ...grpc.CallOption) (*commonpb.Status, error) {
return &commonpb.Status{}, m.Err
}

View File

@ -150,3 +150,23 @@ func (m *RootCoordClient) GetImportState(ctx context.Context, req *milvuspb.GetI
func (m *RootCoordClient) ReportImport(ctx context.Context, req *rootcoordpb.ImportResult, opts ...grpc.CallOption) (*commonpb.Status, error) {
return &commonpb.Status{}, m.Err
}
func (m *RootCoordClient) CreateCredential(ctx context.Context, in *internalpb.CredentialInfo, opts ...grpc.CallOption) (*commonpb.Status, error) {
return &commonpb.Status{}, m.Err
}
func (m *RootCoordClient) UpdateCredential(ctx context.Context, in *internalpb.CredentialInfo, opts ...grpc.CallOption) (*commonpb.Status, error) {
return &commonpb.Status{}, m.Err
}
func (m *RootCoordClient) DeleteCredential(ctx context.Context, in *milvuspb.DeleteCredentialRequest, opts ...grpc.CallOption) (*commonpb.Status, error) {
return &commonpb.Status{}, m.Err
}
func (m *RootCoordClient) ListCredUsers(ctx context.Context, in *milvuspb.ListCredUsersRequest, opts ...grpc.CallOption) (*milvuspb.ListCredUsersResponse, error) {
return &milvuspb.ListCredUsersResponse{}, m.Err
}
func (m *RootCoordClient) GetCredential(ctx context.Context, in *rootcoordpb.GetCredentialRequest, opts ...grpc.CallOption) (*rootcoordpb.GetCredentialResponse, error) {
return &rootcoordpb.GetCredentialResponse{}, m.Err
}

View File

@ -385,6 +385,8 @@ type proxyConfig struct {
TimeTickInterval time.Duration
MsgStreamTimeTickBufSize int64
MaxNameLength int64
MaxUsernameLength int64
MaxPasswordLength int64
MaxFieldNum int64
MaxShardNum int32
MaxDimension int64
@ -409,6 +411,8 @@ func (p *proxyConfig) init(base *BaseTable) {
p.initMsgStreamTimeTickBufSize()
p.initMaxNameLength()
p.initMaxUsernameLength()
p.initMaxPasswordLength()
p.initMaxFieldNum()
p.initMaxShardNum()
p.initMaxDimension()
@ -442,6 +446,24 @@ func (p *proxyConfig) initMaxNameLength() {
p.MaxNameLength = maxNameLength
}
func (p *proxyConfig) initMaxUsernameLength() {
str := p.Base.LoadWithDefault("proxy.maxUsernameLength", "32")
maxUsernameLength, err := strconv.ParseInt(str, 10, 64)
if err != nil {
panic(err)
}
p.MaxUsernameLength = maxUsernameLength
}
func (p *proxyConfig) initMaxPasswordLength() {
str := p.Base.LoadWithDefault("proxy.maxPasswordLength", "256")
maxPasswordLength, err := strconv.ParseInt(str, 10, 64)
if err != nil {
panic(err)
}
p.MaxPasswordLength = maxPasswordLength
}
func (p *proxyConfig) initMaxShardNum() {
str := p.Base.LoadWithDefault("proxy.maxShardNum", "256")
maxShardNum, err := strconv.ParseInt(str, 10, 64)

View File

@ -16,6 +16,8 @@
package typeutil
import "strings"
// AddOne add one to last byte in string, on empty string return empty
// it helps with key iteration upper bound
func AddOne(data string) string {
@ -30,3 +32,16 @@ func AddOne(data string) string {
}
return string(datab)
}
// After get substring after sub string.
func After(str string, sub string) string {
pos := strings.LastIndex(str, sub)
if pos == -1 {
return ""
}
adjustedPos := pos + len(sub)
if adjustedPos >= len(str) {
return ""
}
return str[adjustedPos:]
}

View File

@ -43,3 +43,14 @@ func TestAddOne(t *testing.T) {
resultb := []byte(output)
assert.Equal(t, resultb, []byte{1, 20, 255, 0})
}
func TestAfter(t *testing.T) {
res := After("abc", "x")
assert.Equal(t, res, "")
res = After("abc", "bc")
assert.Equal(t, res, "")
res = After("abc", "ab")
assert.Equal(t, res, "c")
}