diff --git a/.github/workflows/post-release.yaml b/.github/workflows/post-release.yaml index 9641d2c00758a..df1c33bb64798 100644 --- a/.github/workflows/post-release.yaml +++ b/.github/workflows/post-release.yaml @@ -94,8 +94,8 @@ jobs: git config --global user.email "noreply@github.com" git config --global user.name "GitHub" - # get Go version from go.mod - GO_VERSION=$(go mod edit -json | jq -r .Go) + # get Go version from go.mod (preferring the toolchain directive if it's present) + GO_VERSION=$(go mod edit -json | jq -r 'if has("Toolchain") then .Toolchain | sub("go"; "") else .Go end') # update versions in docs/config.json # for docker images replace version number after : diff --git a/api/accessrequest/access_request.go b/api/accessrequest/access_request.go index 2823aefbdc7d5..1af10ac4400d3 100644 --- a/api/accessrequest/access_request.go +++ b/api/accessrequest/access_request.go @@ -60,7 +60,7 @@ func GetResourceDetails(ctx context.Context, clusterName string, lister client.L // We're interested in hostname or friendly name details. These apply to // nodes, app servers, and user groups. switch resourceID.Kind { - case types.KindNode, types.KindApp, types.KindUserGroup: + case types.KindNode, types.KindApp, types.KindUserGroup, types.KindIdentityCenterAccount: resourceIDs = append(resourceIDs, resourceID) } } diff --git a/api/client/client.go b/api/client/client.go index c9a89cfdf820e..ffea2bee8101e 100644 --- a/api/client/client.go +++ b/api/client/client.go @@ -55,6 +55,7 @@ import ( "github.com/gravitational/teleport/api/client/discoveryconfig" "github.com/gravitational/teleport/api/client/dynamicwindows" "github.com/gravitational/teleport/api/client/externalauditstorage" + gitserverclient "github.com/gravitational/teleport/api/client/gitserver" kubewaitingcontainerclient "github.com/gravitational/teleport/api/client/kubewaitingcontainer" "github.com/gravitational/teleport/api/client/okta" "github.com/gravitational/teleport/api/client/proto" @@ -77,7 +78,7 @@ import ( discoveryconfigv1 "github.com/gravitational/teleport/api/gen/proto/go/teleport/discoveryconfig/v1" dynamicwindowsv1 "github.com/gravitational/teleport/api/gen/proto/go/teleport/dynamicwindows/v1" externalauditstoragev1 "github.com/gravitational/teleport/api/gen/proto/go/teleport/externalauditstorage/v1" - gitserverv1 "github.com/gravitational/teleport/api/gen/proto/go/teleport/gitserver/v1" + gitserverpb "github.com/gravitational/teleport/api/gen/proto/go/teleport/gitserver/v1" identitycenterv1 "github.com/gravitational/teleport/api/gen/proto/go/teleport/identitycenter/v1" integrationpb "github.com/gravitational/teleport/api/gen/proto/go/teleport/integration/v1" kubeproto "github.com/gravitational/teleport/api/gen/proto/go/teleport/kube/v1" @@ -3807,6 +3808,12 @@ func (c *Client) ListResources(ctx context.Context, req proto.ListResourcesReque resources[i] = respResource.GetAppServerOrSAMLIdPServiceProvider() case types.KindSAMLIdPServiceProvider: resources[i] = respResource.GetSAMLIdPServiceProvider() + case types.KindIdentityCenterAccount: + resources[i] = respResource.GetAppServer() + case types.KindIdentityCenterAccountAssignment: + src := respResource.GetIdentityCenterAccountAssignment() + dst := proto.UnpackICAccountAssignment(src) + resources[i] = dst default: return nil, trace.NotImplemented("resource type %s does not support pagination", req.ResourceType) } @@ -3896,6 +3903,8 @@ func convertEnrichedResource(resource *proto.PaginatedResource) (*types.Enriched return &types.EnrichedResource{ResourceWithLabels: r, Logins: resource.Logins, RequiresRequest: resource.RequiresRequest}, nil } else if r := resource.GetSAMLIdPServiceProvider(); r != nil { return &types.EnrichedResource{ResourceWithLabels: r, RequiresRequest: resource.RequiresRequest}, nil + } else if r := resource.GetGitServer(); r != nil { + return &types.EnrichedResource{ResourceWithLabels: r, RequiresRequest: resource.RequiresRequest}, nil } else { return nil, trace.BadParameter("received unsupported resource %T", resource.Resource) } @@ -4876,8 +4885,8 @@ func (c *Client) UserTasksServiceClient() *usertaskapi.Client { } // GitServerClient returns a client for managing git servers -func (c *Client) GitServerClient() gitserverv1.GitServerServiceClient { - return gitserverv1.NewGitServerServiceClient(c.conn) +func (c *Client) GitServerClient() *gitserverclient.Client { + return gitserverclient.NewClient(gitserverpb.NewGitServerServiceClient(c.conn)) } // GetCertAuthority retrieves a CA by type and domain. diff --git a/api/client/events.go b/api/client/events.go index 44c239b4c960d..349e57213676a 100644 --- a/api/client/events.go +++ b/api/client/events.go @@ -30,6 +30,7 @@ import ( provisioningv1 "github.com/gravitational/teleport/api/gen/proto/go/teleport/provisioning/v1" userprovisioningpb "github.com/gravitational/teleport/api/gen/proto/go/teleport/userprovisioning/v2" usertasksv1 "github.com/gravitational/teleport/api/gen/proto/go/teleport/usertasks/v1" + workloadidentityv1pb "github.com/gravitational/teleport/api/gen/proto/go/teleport/workloadidentity/v1" "github.com/gravitational/teleport/api/types" "github.com/gravitational/teleport/api/types/accesslist" accesslistv1conv "github.com/gravitational/teleport/api/types/accesslist/convert/v1" @@ -135,6 +136,10 @@ func EventToGRPC(in types.Event) (*proto.Event, error) { out.Resource = &proto.Event_IdentityCenterAccountAssignment{ IdentityCenterAccountAssignment: r, } + case *workloadidentityv1pb.WorkloadIdentity: + out.Resource = &proto.Event_WorkloadIdentity{ + WorkloadIdentity: r, + } default: return nil, trace.BadParameter("resource type %T is not supported", r) } @@ -616,6 +621,9 @@ func EventFromGRPC(in *proto.Event) (*types.Event, error) { } else if r := in.GetPluginStaticCredentials(); r != nil { out.Resource = r return &out, nil + } else if r := in.GetWorkloadIdentity(); r != nil { + out.Resource = types.Resource153ToLegacy(r) + return &out, nil } else { return nil, trace.BadParameter("received unsupported resource %T", in.Resource) } diff --git a/api/client/gitserver/gitserver.go b/api/client/gitserver/gitserver.go new file mode 100644 index 0000000000000..70c69aa73dc75 --- /dev/null +++ b/api/client/gitserver/gitserver.go @@ -0,0 +1,125 @@ +// Copyright 2024 Gravitational, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +package gitserver + +import ( + "context" + + "github.com/gravitational/trace" + + gitserverv1 "github.com/gravitational/teleport/api/gen/proto/go/teleport/gitserver/v1" + "github.com/gravitational/teleport/api/types" +) + +// Client is an Git servers client. +type Client struct { + grpcClient gitserverv1.GitServerServiceClient +} + +// NewClient creates a new Git servers client. +func NewClient(grpcClient gitserverv1.GitServerServiceClient) *Client { + return &Client{ + grpcClient: grpcClient, + } +} + +// GetGitServer returns Git servers by name. +func (c *Client) GetGitServer(ctx context.Context, name string) (types.Server, error) { + server, err := c.grpcClient.GetGitServer(ctx, &gitserverv1.GetGitServerRequest{Name: name}) + if err != nil { + return nil, trace.Wrap(err) + } + return server, nil +} + +// ListGitServers returns all Git servers matching filter. +func (c *Client) ListGitServers(ctx context.Context, pageSize int, pageToken string) ([]types.Server, string, error) { + resp, err := c.grpcClient.ListGitServers(ctx, &gitserverv1.ListGitServersRequest{ + PageSize: int32(pageSize), + PageToken: pageToken, + }) + if err != nil { + return nil, "", trace.Wrap(err) + } + + servers := make([]types.Server, 0, len(resp.Servers)) + for _, server := range resp.Servers { + servers = append(servers, server) + } + return servers, resp.NextPageToken, nil +} + +func toServerV2(server types.Server) (*types.ServerV2, error) { + serverV2, ok := server.(*types.ServerV2) + if !ok { + return nil, trace.Errorf("encountered unexpected server type: %T", serverV2) + } + return serverV2, nil +} + +// CreateGitServer creates a Git server resource. +func (c *Client) CreateGitServer(ctx context.Context, item types.Server) (types.Server, error) { + serverV2, err := toServerV2(item) + if err != nil { + return nil, trace.Wrap(err) + } + resp, err := c.grpcClient.CreateGitServer(ctx, &gitserverv1.CreateGitServerRequest{ + Server: serverV2, + }) + if err != nil { + return nil, trace.Wrap(err) + } + return resp, nil +} + +// UpdateGitServer updates a Git server resource. +func (c *Client) UpdateGitServer(ctx context.Context, item types.Server) (types.Server, error) { + serverV2, err := toServerV2(item) + if err != nil { + return nil, trace.Wrap(err) + } + resp, err := c.grpcClient.UpdateGitServer(ctx, &gitserverv1.UpdateGitServerRequest{ + Server: serverV2, + }) + if err != nil { + return nil, trace.Wrap(err) + } + return resp, nil +} + +// UpsertGitServer updates a Git server resource, creating it if it doesn't exist. +func (c *Client) UpsertGitServer(ctx context.Context, item types.Server) (types.Server, error) { + serverV2, err := toServerV2(item) + if err != nil { + return nil, trace.Wrap(err) + } + resp, err := c.grpcClient.UpsertGitServer(ctx, &gitserverv1.UpsertGitServerRequest{ + Server: serverV2, + }) + if err != nil { + return nil, trace.Wrap(err) + } + return resp, nil +} + +// DeleteGitServer removes the specified Git server resource. +func (c *Client) DeleteGitServer(ctx context.Context, name string) error { + _, err := c.grpcClient.DeleteGitServer(ctx, &gitserverv1.DeleteGitServerRequest{Name: name}) + return trace.Wrap(err) +} + +// DeleteAllGitServers removes all Git server resources. +func (c *Client) DeleteAllGitServers(ctx context.Context) error { + return trace.NotImplemented("DeleteAllGitServers servers not implemented") +} diff --git a/api/client/proto/authservice.pb.go b/api/client/proto/authservice.pb.go index ea0cb89fb6621..dd1161bbfcac2 100644 --- a/api/client/proto/authservice.pb.go +++ b/api/client/proto/authservice.pb.go @@ -10628,6 +10628,249 @@ func (m *CreateRegisterChallengeRequest) GetDeviceUsage() DeviceUsage { return DeviceUsage_DEVICE_USAGE_UNSPECIFIED } +// IdentityCenterAccount holds information about an Identity Center account +// within an IdentityCenterAccountAssignment +type IdentityCenterAccount struct { + // ID is the AWS-assigned account ID + ID string `protobuf:"bytes,1,opt,name=ID,proto3" json:"ID,omitempty"` + // ARN is the full Amazon Resource Name for the AWS account + ARN string `protobuf:"bytes,2,opt,name=ARN,proto3" json:"ARN,omitempty"` + // AccountName is the human-readable name of the account + AccountName string `protobuf:"bytes,3,opt,name=AccountName,proto3" json:"AccountName,omitempty"` + // Description is a free text description of the account + Description string `protobuf:"bytes,4,opt,name=Description,proto3" json:"Description,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *IdentityCenterAccount) Reset() { *m = IdentityCenterAccount{} } +func (m *IdentityCenterAccount) String() string { return proto.CompactTextString(m) } +func (*IdentityCenterAccount) ProtoMessage() {} +func (*IdentityCenterAccount) Descriptor() ([]byte, []int) { + return fileDescriptor_0ffcffcda38ae159, []int{156} +} +func (m *IdentityCenterAccount) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *IdentityCenterAccount) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_IdentityCenterAccount.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *IdentityCenterAccount) XXX_Merge(src proto.Message) { + xxx_messageInfo_IdentityCenterAccount.Merge(m, src) +} +func (m *IdentityCenterAccount) XXX_Size() int { + return m.Size() +} +func (m *IdentityCenterAccount) XXX_DiscardUnknown() { + xxx_messageInfo_IdentityCenterAccount.DiscardUnknown(m) +} + +var xxx_messageInfo_IdentityCenterAccount proto.InternalMessageInfo + +func (m *IdentityCenterAccount) GetID() string { + if m != nil { + return m.ID + } + return "" +} + +func (m *IdentityCenterAccount) GetARN() string { + if m != nil { + return m.ARN + } + return "" +} + +func (m *IdentityCenterAccount) GetAccountName() string { + if m != nil { + return m.AccountName + } + return "" +} + +func (m *IdentityCenterAccount) GetDescription() string { + if m != nil { + return m.Description + } + return "" +} + +// IdentityCenterPermissionSet holds information about an Identity Center +// permission set within an IdentityCenterAccountAssignment +type IdentityCenterPermissionSet struct { + // ARN is the full Amazon Resource Name for the Permission Set + ARN string `protobuf:"bytes,1,opt,name=ARN,proto3" json:"ARN,omitempty"` + // Name is the human readable name for the Permission Set + Name string `protobuf:"bytes,2,opt,name=Name,proto3" json:"Name,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *IdentityCenterPermissionSet) Reset() { *m = IdentityCenterPermissionSet{} } +func (m *IdentityCenterPermissionSet) String() string { return proto.CompactTextString(m) } +func (*IdentityCenterPermissionSet) ProtoMessage() {} +func (*IdentityCenterPermissionSet) Descriptor() ([]byte, []int) { + return fileDescriptor_0ffcffcda38ae159, []int{157} +} +func (m *IdentityCenterPermissionSet) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *IdentityCenterPermissionSet) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_IdentityCenterPermissionSet.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *IdentityCenterPermissionSet) XXX_Merge(src proto.Message) { + xxx_messageInfo_IdentityCenterPermissionSet.Merge(m, src) +} +func (m *IdentityCenterPermissionSet) XXX_Size() int { + return m.Size() +} +func (m *IdentityCenterPermissionSet) XXX_DiscardUnknown() { + xxx_messageInfo_IdentityCenterPermissionSet.DiscardUnknown(m) +} + +var xxx_messageInfo_IdentityCenterPermissionSet proto.InternalMessageInfo + +func (m *IdentityCenterPermissionSet) GetARN() string { + if m != nil { + return m.ARN + } + return "" +} + +func (m *IdentityCenterPermissionSet) GetName() string { + if m != nil { + return m.Name + } + return "" +} + +// IdentityCenterAccountAssignment represents a requestable Identity Center +// Account Assignment. This is strictly a wire-format object for use with the +// Unfied resource cache, and the types defined in the `identitycenter` package +// should be used for actual processing. +type IdentityCenterAccountAssignment struct { + // Kind is the database server resource kind. + Kind string `protobuf:"bytes,1,opt,name=Kind,proto3" json:"kind"` + // SubKind is an optional resource subkind. + SubKind string `protobuf:"bytes,2,opt,name=SubKind,proto3" json:"sub_kind,omitempty"` + // Version is the resource version. + Version string `protobuf:"bytes,3,opt,name=Version,proto3" json:"version"` + // Metadata is the account metadata. + Metadata types.Metadata `protobuf:"bytes,4,opt,name=Metadata,proto3" json:"metadata"` + // DisplayName is a human-readable name for the Account assignment + DisplayName string `protobuf:"bytes,5,opt,name=DisplayName,proto3" json:"DisplayName,omitempty"` + // Account is the Identity Center Account this assigment references + Account *IdentityCenterAccount `protobuf:"bytes,6,opt,name=Account,proto3" json:"Account,omitempty"` + // PermissionSet is the Identity Center Permission Set this assignment + // references + PermissionSet *IdentityCenterPermissionSet `protobuf:"bytes,7,opt,name=PermissionSet,proto3" json:"PermissionSet,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *IdentityCenterAccountAssignment) Reset() { *m = IdentityCenterAccountAssignment{} } +func (m *IdentityCenterAccountAssignment) String() string { return proto.CompactTextString(m) } +func (*IdentityCenterAccountAssignment) ProtoMessage() {} +func (*IdentityCenterAccountAssignment) Descriptor() ([]byte, []int) { + return fileDescriptor_0ffcffcda38ae159, []int{158} +} +func (m *IdentityCenterAccountAssignment) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *IdentityCenterAccountAssignment) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_IdentityCenterAccountAssignment.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *IdentityCenterAccountAssignment) XXX_Merge(src proto.Message) { + xxx_messageInfo_IdentityCenterAccountAssignment.Merge(m, src) +} +func (m *IdentityCenterAccountAssignment) XXX_Size() int { + return m.Size() +} +func (m *IdentityCenterAccountAssignment) XXX_DiscardUnknown() { + xxx_messageInfo_IdentityCenterAccountAssignment.DiscardUnknown(m) +} + +var xxx_messageInfo_IdentityCenterAccountAssignment proto.InternalMessageInfo + +func (m *IdentityCenterAccountAssignment) GetKind() string { + if m != nil { + return m.Kind + } + return "" +} + +func (m *IdentityCenterAccountAssignment) GetSubKind() string { + if m != nil { + return m.SubKind + } + return "" +} + +func (m *IdentityCenterAccountAssignment) GetVersion() string { + if m != nil { + return m.Version + } + return "" +} + +func (m *IdentityCenterAccountAssignment) GetMetadata() types.Metadata { + if m != nil { + return m.Metadata + } + return types.Metadata{} +} + +func (m *IdentityCenterAccountAssignment) GetDisplayName() string { + if m != nil { + return m.DisplayName + } + return "" +} + +func (m *IdentityCenterAccountAssignment) GetAccount() *IdentityCenterAccount { + if m != nil { + return m.Account + } + return nil +} + +func (m *IdentityCenterAccountAssignment) GetPermissionSet() *IdentityCenterPermissionSet { + if m != nil { + return m.PermissionSet + } + return nil +} + // PaginatedResource represents one of the supported resources. type PaginatedResource struct { // Resource is the resource itself. @@ -10644,6 +10887,8 @@ type PaginatedResource struct { // *PaginatedResource_UserGroup // *PaginatedResource_AppServerOrSAMLIdPServiceProvider // *PaginatedResource_SAMLIdPServiceProvider + // *PaginatedResource_GitServer + // *PaginatedResource_IdentityCenterAccountAssignment Resource isPaginatedResource_Resource `protobuf_oneof:"resource"` // Logins allowed for the included resource. Only to be populated for SSH and Desktops. Logins []string `protobuf:"bytes,13,rep,name=Logins,proto3" json:"logins,omitempty"` @@ -10659,7 +10904,7 @@ func (m *PaginatedResource) Reset() { *m = PaginatedResource{} } func (m *PaginatedResource) String() string { return proto.CompactTextString(m) } func (*PaginatedResource) ProtoMessage() {} func (*PaginatedResource) Descriptor() ([]byte, []int) { - return fileDescriptor_0ffcffcda38ae159, []int{156} + return fileDescriptor_0ffcffcda38ae159, []int{159} } func (m *PaginatedResource) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -10727,6 +10972,12 @@ type PaginatedResource_AppServerOrSAMLIdPServiceProvider struct { type PaginatedResource_SAMLIdPServiceProvider struct { SAMLIdPServiceProvider *types.SAMLIdPServiceProviderV1 `protobuf:"bytes,12,opt,name=SAMLIdPServiceProvider,proto3,oneof" json:"saml_idp_service_provider,omitempty"` } +type PaginatedResource_GitServer struct { + GitServer *types.ServerV2 `protobuf:"bytes,15,opt,name=git_server,json=gitServer,proto3,oneof" json:"git_server,omitempty"` +} +type PaginatedResource_IdentityCenterAccountAssignment struct { + IdentityCenterAccountAssignment *IdentityCenterAccountAssignment `protobuf:"bytes,16,opt,name=IdentityCenterAccountAssignment,proto3,oneof" json:"identity_center_account_assignment,omitempty"` +} func (*PaginatedResource_DatabaseServer) isPaginatedResource_Resource() {} func (*PaginatedResource_AppServer) isPaginatedResource_Resource() {} @@ -10739,6 +10990,8 @@ func (*PaginatedResource_DatabaseService) isPaginatedResource_Resource() func (*PaginatedResource_UserGroup) isPaginatedResource_Resource() {} func (*PaginatedResource_AppServerOrSAMLIdPServiceProvider) isPaginatedResource_Resource() {} func (*PaginatedResource_SAMLIdPServiceProvider) isPaginatedResource_Resource() {} +func (*PaginatedResource_GitServer) isPaginatedResource_Resource() {} +func (*PaginatedResource_IdentityCenterAccountAssignment) isPaginatedResource_Resource() {} func (m *PaginatedResource) GetResource() isPaginatedResource_Resource { if m != nil { @@ -10825,6 +11078,20 @@ func (m *PaginatedResource) GetSAMLIdPServiceProvider() *types.SAMLIdPServicePro return nil } +func (m *PaginatedResource) GetGitServer() *types.ServerV2 { + if x, ok := m.GetResource().(*PaginatedResource_GitServer); ok { + return x.GitServer + } + return nil +} + +func (m *PaginatedResource) GetIdentityCenterAccountAssignment() *IdentityCenterAccountAssignment { + if x, ok := m.GetResource().(*PaginatedResource_IdentityCenterAccountAssignment); ok { + return x.IdentityCenterAccountAssignment + } + return nil +} + func (m *PaginatedResource) GetLogins() []string { if m != nil { return m.Logins @@ -10853,6 +11120,8 @@ func (*PaginatedResource) XXX_OneofWrappers() []interface{} { (*PaginatedResource_UserGroup)(nil), (*PaginatedResource_AppServerOrSAMLIdPServiceProvider)(nil), (*PaginatedResource_SAMLIdPServiceProvider)(nil), + (*PaginatedResource_GitServer)(nil), + (*PaginatedResource_IdentityCenterAccountAssignment)(nil), } } @@ -10900,7 +11169,7 @@ func (m *ListUnifiedResourcesRequest) Reset() { *m = ListUnifiedResource func (m *ListUnifiedResourcesRequest) String() string { return proto.CompactTextString(m) } func (*ListUnifiedResourcesRequest) ProtoMessage() {} func (*ListUnifiedResourcesRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_0ffcffcda38ae159, []int{157} + return fileDescriptor_0ffcffcda38ae159, []int{160} } func (m *ListUnifiedResourcesRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -11037,7 +11306,7 @@ func (m *ListUnifiedResourcesResponse) Reset() { *m = ListUnifiedResourc func (m *ListUnifiedResourcesResponse) String() string { return proto.CompactTextString(m) } func (*ListUnifiedResourcesResponse) ProtoMessage() {} func (*ListUnifiedResourcesResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_0ffcffcda38ae159, []int{158} + return fileDescriptor_0ffcffcda38ae159, []int{161} } func (m *ListUnifiedResourcesResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -11133,7 +11402,7 @@ func (m *ListResourcesRequest) Reset() { *m = ListResourcesRequest{} } func (m *ListResourcesRequest) String() string { return proto.CompactTextString(m) } func (*ListResourcesRequest) ProtoMessage() {} func (*ListResourcesRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_0ffcffcda38ae159, []int{159} + return fileDescriptor_0ffcffcda38ae159, []int{162} } func (m *ListResourcesRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -11269,7 +11538,7 @@ func (m *GetSSHTargetsRequest) Reset() { *m = GetSSHTargetsRequest{} } func (m *GetSSHTargetsRequest) String() string { return proto.CompactTextString(m) } func (*GetSSHTargetsRequest) ProtoMessage() {} func (*GetSSHTargetsRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_0ffcffcda38ae159, []int{160} + return fileDescriptor_0ffcffcda38ae159, []int{163} } func (m *GetSSHTargetsRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -11325,7 +11594,7 @@ func (m *GetSSHTargetsResponse) Reset() { *m = GetSSHTargetsResponse{} } func (m *GetSSHTargetsResponse) String() string { return proto.CompactTextString(m) } func (*GetSSHTargetsResponse) ProtoMessage() {} func (*GetSSHTargetsResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_0ffcffcda38ae159, []int{161} + return fileDescriptor_0ffcffcda38ae159, []int{164} } func (m *GetSSHTargetsResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -11380,7 +11649,7 @@ func (m *ListResourcesResponse) Reset() { *m = ListResourcesResponse{} } func (m *ListResourcesResponse) String() string { return proto.CompactTextString(m) } func (*ListResourcesResponse) ProtoMessage() {} func (*ListResourcesResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_0ffcffcda38ae159, []int{162} + return fileDescriptor_0ffcffcda38ae159, []int{165} } func (m *ListResourcesResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -11445,7 +11714,7 @@ func (m *CreateSessionTrackerRequest) Reset() { *m = CreateSessionTracke func (m *CreateSessionTrackerRequest) String() string { return proto.CompactTextString(m) } func (*CreateSessionTrackerRequest) ProtoMessage() {} func (*CreateSessionTrackerRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_0ffcffcda38ae159, []int{163} + return fileDescriptor_0ffcffcda38ae159, []int{166} } func (m *CreateSessionTrackerRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -11494,7 +11763,7 @@ func (m *GetSessionTrackerRequest) Reset() { *m = GetSessionTrackerReque func (m *GetSessionTrackerRequest) String() string { return proto.CompactTextString(m) } func (*GetSessionTrackerRequest) ProtoMessage() {} func (*GetSessionTrackerRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_0ffcffcda38ae159, []int{164} + return fileDescriptor_0ffcffcda38ae159, []int{167} } func (m *GetSessionTrackerRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -11543,7 +11812,7 @@ func (m *RemoveSessionTrackerRequest) Reset() { *m = RemoveSessionTracke func (m *RemoveSessionTrackerRequest) String() string { return proto.CompactTextString(m) } func (*RemoveSessionTrackerRequest) ProtoMessage() {} func (*RemoveSessionTrackerRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_0ffcffcda38ae159, []int{165} + return fileDescriptor_0ffcffcda38ae159, []int{168} } func (m *RemoveSessionTrackerRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -11591,7 +11860,7 @@ func (m *SessionTrackerUpdateState) Reset() { *m = SessionTrackerUpdateS func (m *SessionTrackerUpdateState) String() string { return proto.CompactTextString(m) } func (*SessionTrackerUpdateState) ProtoMessage() {} func (*SessionTrackerUpdateState) Descriptor() ([]byte, []int) { - return fileDescriptor_0ffcffcda38ae159, []int{166} + return fileDescriptor_0ffcffcda38ae159, []int{169} } func (m *SessionTrackerUpdateState) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -11639,7 +11908,7 @@ func (m *SessionTrackerAddParticipant) Reset() { *m = SessionTrackerAddP func (m *SessionTrackerAddParticipant) String() string { return proto.CompactTextString(m) } func (*SessionTrackerAddParticipant) ProtoMessage() {} func (*SessionTrackerAddParticipant) Descriptor() ([]byte, []int) { - return fileDescriptor_0ffcffcda38ae159, []int{167} + return fileDescriptor_0ffcffcda38ae159, []int{170} } func (m *SessionTrackerAddParticipant) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -11687,7 +11956,7 @@ func (m *SessionTrackerRemoveParticipant) Reset() { *m = SessionTrackerR func (m *SessionTrackerRemoveParticipant) String() string { return proto.CompactTextString(m) } func (*SessionTrackerRemoveParticipant) ProtoMessage() {} func (*SessionTrackerRemoveParticipant) Descriptor() ([]byte, []int) { - return fileDescriptor_0ffcffcda38ae159, []int{168} + return fileDescriptor_0ffcffcda38ae159, []int{171} } func (m *SessionTrackerRemoveParticipant) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -11736,7 +12005,7 @@ func (m *SessionTrackerUpdateExpiry) Reset() { *m = SessionTrackerUpdate func (m *SessionTrackerUpdateExpiry) String() string { return proto.CompactTextString(m) } func (*SessionTrackerUpdateExpiry) ProtoMessage() {} func (*SessionTrackerUpdateExpiry) Descriptor() ([]byte, []int) { - return fileDescriptor_0ffcffcda38ae159, []int{169} + return fileDescriptor_0ffcffcda38ae159, []int{172} } func (m *SessionTrackerUpdateExpiry) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -11791,7 +12060,7 @@ func (m *UpdateSessionTrackerRequest) Reset() { *m = UpdateSessionTracke func (m *UpdateSessionTrackerRequest) String() string { return proto.CompactTextString(m) } func (*UpdateSessionTrackerRequest) ProtoMessage() {} func (*UpdateSessionTrackerRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_0ffcffcda38ae159, []int{170} + return fileDescriptor_0ffcffcda38ae159, []int{173} } func (m *UpdateSessionTrackerRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -11912,7 +12181,7 @@ func (m *PresenceMFAChallengeRequest) Reset() { *m = PresenceMFAChalleng func (m *PresenceMFAChallengeRequest) String() string { return proto.CompactTextString(m) } func (*PresenceMFAChallengeRequest) ProtoMessage() {} func (*PresenceMFAChallengeRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_0ffcffcda38ae159, []int{171} + return fileDescriptor_0ffcffcda38ae159, []int{174} } func (m *PresenceMFAChallengeRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -11970,7 +12239,7 @@ func (m *PresenceMFAChallengeSend) Reset() { *m = PresenceMFAChallengeSe func (m *PresenceMFAChallengeSend) String() string { return proto.CompactTextString(m) } func (*PresenceMFAChallengeSend) ProtoMessage() {} func (*PresenceMFAChallengeSend) Descriptor() ([]byte, []int) { - return fileDescriptor_0ffcffcda38ae159, []int{172} + return fileDescriptor_0ffcffcda38ae159, []int{175} } func (m *PresenceMFAChallengeSend) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -12057,7 +12326,7 @@ func (m *GetDomainNameResponse) Reset() { *m = GetDomainNameResponse{} } func (m *GetDomainNameResponse) String() string { return proto.CompactTextString(m) } func (*GetDomainNameResponse) ProtoMessage() {} func (*GetDomainNameResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_0ffcffcda38ae159, []int{173} + return fileDescriptor_0ffcffcda38ae159, []int{176} } func (m *GetDomainNameResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -12106,7 +12375,7 @@ func (m *GetClusterCACertResponse) Reset() { *m = GetClusterCACertRespon func (m *GetClusterCACertResponse) String() string { return proto.CompactTextString(m) } func (*GetClusterCACertResponse) ProtoMessage() {} func (*GetClusterCACertResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_0ffcffcda38ae159, []int{174} + return fileDescriptor_0ffcffcda38ae159, []int{177} } func (m *GetClusterCACertResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -12154,7 +12423,7 @@ func (m *GetLicenseResponse) Reset() { *m = GetLicenseResponse{} } func (m *GetLicenseResponse) String() string { return proto.CompactTextString(m) } func (*GetLicenseResponse) ProtoMessage() {} func (*GetLicenseResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_0ffcffcda38ae159, []int{175} + return fileDescriptor_0ffcffcda38ae159, []int{178} } func (m *GetLicenseResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -12202,7 +12471,7 @@ func (m *ListReleasesResponse) Reset() { *m = ListReleasesResponse{} } func (m *ListReleasesResponse) String() string { return proto.CompactTextString(m) } func (*ListReleasesResponse) ProtoMessage() {} func (*ListReleasesResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_0ffcffcda38ae159, []int{176} + return fileDescriptor_0ffcffcda38ae159, []int{179} } func (m *ListReleasesResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -12251,7 +12520,7 @@ func (m *GetOIDCAuthRequestRequest) Reset() { *m = GetOIDCAuthRequestReq func (m *GetOIDCAuthRequestRequest) String() string { return proto.CompactTextString(m) } func (*GetOIDCAuthRequestRequest) ProtoMessage() {} func (*GetOIDCAuthRequestRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_0ffcffcda38ae159, []int{177} + return fileDescriptor_0ffcffcda38ae159, []int{180} } func (m *GetOIDCAuthRequestRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -12300,7 +12569,7 @@ func (m *GetSAMLAuthRequestRequest) Reset() { *m = GetSAMLAuthRequestReq func (m *GetSAMLAuthRequestRequest) String() string { return proto.CompactTextString(m) } func (*GetSAMLAuthRequestRequest) ProtoMessage() {} func (*GetSAMLAuthRequestRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_0ffcffcda38ae159, []int{178} + return fileDescriptor_0ffcffcda38ae159, []int{181} } func (m *GetSAMLAuthRequestRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -12349,7 +12618,7 @@ func (m *GetGithubAuthRequestRequest) Reset() { *m = GetGithubAuthReques func (m *GetGithubAuthRequestRequest) String() string { return proto.CompactTextString(m) } func (*GetGithubAuthRequestRequest) ProtoMessage() {} func (*GetGithubAuthRequestRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_0ffcffcda38ae159, []int{179} + return fileDescriptor_0ffcffcda38ae159, []int{182} } func (m *GetGithubAuthRequestRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -12398,7 +12667,7 @@ func (m *CreateOIDCConnectorRequest) Reset() { *m = CreateOIDCConnectorR func (m *CreateOIDCConnectorRequest) String() string { return proto.CompactTextString(m) } func (*CreateOIDCConnectorRequest) ProtoMessage() {} func (*CreateOIDCConnectorRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_0ffcffcda38ae159, []int{180} + return fileDescriptor_0ffcffcda38ae159, []int{183} } func (m *CreateOIDCConnectorRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -12447,7 +12716,7 @@ func (m *UpdateOIDCConnectorRequest) Reset() { *m = UpdateOIDCConnectorR func (m *UpdateOIDCConnectorRequest) String() string { return proto.CompactTextString(m) } func (*UpdateOIDCConnectorRequest) ProtoMessage() {} func (*UpdateOIDCConnectorRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_0ffcffcda38ae159, []int{181} + return fileDescriptor_0ffcffcda38ae159, []int{184} } func (m *UpdateOIDCConnectorRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -12496,7 +12765,7 @@ func (m *UpsertOIDCConnectorRequest) Reset() { *m = UpsertOIDCConnectorR func (m *UpsertOIDCConnectorRequest) String() string { return proto.CompactTextString(m) } func (*UpsertOIDCConnectorRequest) ProtoMessage() {} func (*UpsertOIDCConnectorRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_0ffcffcda38ae159, []int{182} + return fileDescriptor_0ffcffcda38ae159, []int{185} } func (m *UpsertOIDCConnectorRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -12545,7 +12814,7 @@ func (m *CreateSAMLConnectorRequest) Reset() { *m = CreateSAMLConnectorR func (m *CreateSAMLConnectorRequest) String() string { return proto.CompactTextString(m) } func (*CreateSAMLConnectorRequest) ProtoMessage() {} func (*CreateSAMLConnectorRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_0ffcffcda38ae159, []int{183} + return fileDescriptor_0ffcffcda38ae159, []int{186} } func (m *CreateSAMLConnectorRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -12594,7 +12863,7 @@ func (m *UpdateSAMLConnectorRequest) Reset() { *m = UpdateSAMLConnectorR func (m *UpdateSAMLConnectorRequest) String() string { return proto.CompactTextString(m) } func (*UpdateSAMLConnectorRequest) ProtoMessage() {} func (*UpdateSAMLConnectorRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_0ffcffcda38ae159, []int{184} + return fileDescriptor_0ffcffcda38ae159, []int{187} } func (m *UpdateSAMLConnectorRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -12643,7 +12912,7 @@ func (m *UpsertSAMLConnectorRequest) Reset() { *m = UpsertSAMLConnectorR func (m *UpsertSAMLConnectorRequest) String() string { return proto.CompactTextString(m) } func (*UpsertSAMLConnectorRequest) ProtoMessage() {} func (*UpsertSAMLConnectorRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_0ffcffcda38ae159, []int{185} + return fileDescriptor_0ffcffcda38ae159, []int{188} } func (m *UpsertSAMLConnectorRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -12692,7 +12961,7 @@ func (m *CreateGithubConnectorRequest) Reset() { *m = CreateGithubConnec func (m *CreateGithubConnectorRequest) String() string { return proto.CompactTextString(m) } func (*CreateGithubConnectorRequest) ProtoMessage() {} func (*CreateGithubConnectorRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_0ffcffcda38ae159, []int{186} + return fileDescriptor_0ffcffcda38ae159, []int{189} } func (m *CreateGithubConnectorRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -12741,7 +13010,7 @@ func (m *UpdateGithubConnectorRequest) Reset() { *m = UpdateGithubConnec func (m *UpdateGithubConnectorRequest) String() string { return proto.CompactTextString(m) } func (*UpdateGithubConnectorRequest) ProtoMessage() {} func (*UpdateGithubConnectorRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_0ffcffcda38ae159, []int{187} + return fileDescriptor_0ffcffcda38ae159, []int{190} } func (m *UpdateGithubConnectorRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -12790,7 +13059,7 @@ func (m *UpsertGithubConnectorRequest) Reset() { *m = UpsertGithubConnec func (m *UpsertGithubConnectorRequest) String() string { return proto.CompactTextString(m) } func (*UpsertGithubConnectorRequest) ProtoMessage() {} func (*UpsertGithubConnectorRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_0ffcffcda38ae159, []int{188} + return fileDescriptor_0ffcffcda38ae159, []int{191} } func (m *UpsertGithubConnectorRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -12841,7 +13110,7 @@ func (m *GetSSODiagnosticInfoRequest) Reset() { *m = GetSSODiagnosticInf func (m *GetSSODiagnosticInfoRequest) String() string { return proto.CompactTextString(m) } func (*GetSSODiagnosticInfoRequest) ProtoMessage() {} func (*GetSSODiagnosticInfoRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_0ffcffcda38ae159, []int{189} + return fileDescriptor_0ffcffcda38ae159, []int{192} } func (m *GetSSODiagnosticInfoRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -12907,7 +13176,7 @@ func (m *SystemRoleAssertion) Reset() { *m = SystemRoleAssertion{} } func (m *SystemRoleAssertion) String() string { return proto.CompactTextString(m) } func (*SystemRoleAssertion) ProtoMessage() {} func (*SystemRoleAssertion) Descriptor() ([]byte, []int) { - return fileDescriptor_0ffcffcda38ae159, []int{190} + return fileDescriptor_0ffcffcda38ae159, []int{193} } func (m *SystemRoleAssertion) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -12977,7 +13246,7 @@ func (m *SystemRoleAssertionSet) Reset() { *m = SystemRoleAssertionSet{} func (m *SystemRoleAssertionSet) String() string { return proto.CompactTextString(m) } func (*SystemRoleAssertionSet) ProtoMessage() {} func (*SystemRoleAssertionSet) Descriptor() ([]byte, []int) { - return fileDescriptor_0ffcffcda38ae159, []int{191} + return fileDescriptor_0ffcffcda38ae159, []int{194} } func (m *SystemRoleAssertionSet) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -13046,7 +13315,7 @@ func (m *UpstreamInventoryOneOf) Reset() { *m = UpstreamInventoryOneOf{} func (m *UpstreamInventoryOneOf) String() string { return proto.CompactTextString(m) } func (*UpstreamInventoryOneOf) ProtoMessage() {} func (*UpstreamInventoryOneOf) Descriptor() ([]byte, []int) { - return fileDescriptor_0ffcffcda38ae159, []int{192} + return fileDescriptor_0ffcffcda38ae159, []int{195} } func (m *UpstreamInventoryOneOf) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -13173,7 +13442,7 @@ func (m *DownstreamInventoryOneOf) Reset() { *m = DownstreamInventoryOne func (m *DownstreamInventoryOneOf) String() string { return proto.CompactTextString(m) } func (*DownstreamInventoryOneOf) ProtoMessage() {} func (*DownstreamInventoryOneOf) Descriptor() ([]byte, []int) { - return fileDescriptor_0ffcffcda38ae159, []int{193} + return fileDescriptor_0ffcffcda38ae159, []int{196} } func (m *DownstreamInventoryOneOf) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -13271,7 +13540,7 @@ func (m *DownstreamInventoryPing) Reset() { *m = DownstreamInventoryPing func (m *DownstreamInventoryPing) String() string { return proto.CompactTextString(m) } func (*DownstreamInventoryPing) ProtoMessage() {} func (*DownstreamInventoryPing) Descriptor() ([]byte, []int) { - return fileDescriptor_0ffcffcda38ae159, []int{194} + return fileDescriptor_0ffcffcda38ae159, []int{197} } func (m *DownstreamInventoryPing) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -13322,7 +13591,7 @@ func (m *UpstreamInventoryPong) Reset() { *m = UpstreamInventoryPong{} } func (m *UpstreamInventoryPong) String() string { return proto.CompactTextString(m) } func (*UpstreamInventoryPong) ProtoMessage() {} func (*UpstreamInventoryPong) Descriptor() ([]byte, []int) { - return fileDescriptor_0ffcffcda38ae159, []int{195} + return fileDescriptor_0ffcffcda38ae159, []int{198} } func (m *UpstreamInventoryPong) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -13396,7 +13665,7 @@ func (m *UpstreamInventoryHello) Reset() { *m = UpstreamInventoryHello{} func (m *UpstreamInventoryHello) String() string { return proto.CompactTextString(m) } func (*UpstreamInventoryHello) ProtoMessage() {} func (*UpstreamInventoryHello) Descriptor() ([]byte, []int) { - return fileDescriptor_0ffcffcda38ae159, []int{196} + return fileDescriptor_0ffcffcda38ae159, []int{199} } func (m *UpstreamInventoryHello) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -13496,7 +13765,7 @@ func (m *UpstreamInventoryAgentMetadata) Reset() { *m = UpstreamInventor func (m *UpstreamInventoryAgentMetadata) String() string { return proto.CompactTextString(m) } func (*UpstreamInventoryAgentMetadata) ProtoMessage() {} func (*UpstreamInventoryAgentMetadata) Descriptor() ([]byte, []int) { - return fileDescriptor_0ffcffcda38ae159, []int{197} + return fileDescriptor_0ffcffcda38ae159, []int{200} } func (m *UpstreamInventoryAgentMetadata) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -13598,7 +13867,7 @@ func (m *DownstreamInventoryHello) Reset() { *m = DownstreamInventoryHel func (m *DownstreamInventoryHello) String() string { return proto.CompactTextString(m) } func (*DownstreamInventoryHello) ProtoMessage() {} func (*DownstreamInventoryHello) Descriptor() ([]byte, []int) { - return fileDescriptor_0ffcffcda38ae159, []int{198} + return fileDescriptor_0ffcffcda38ae159, []int{201} } func (m *DownstreamInventoryHello) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -13701,7 +13970,7 @@ func (m *DownstreamInventoryHello_SupportedCapabilities) String() string { } func (*DownstreamInventoryHello_SupportedCapabilities) ProtoMessage() {} func (*DownstreamInventoryHello_SupportedCapabilities) Descriptor() ([]byte, []int) { - return fileDescriptor_0ffcffcda38ae159, []int{198, 0} + return fileDescriptor_0ffcffcda38ae159, []int{201, 0} } func (m *DownstreamInventoryHello_SupportedCapabilities) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -13874,7 +14143,7 @@ func (m *InventoryUpdateLabelsRequest) Reset() { *m = InventoryUpdateLab func (m *InventoryUpdateLabelsRequest) String() string { return proto.CompactTextString(m) } func (*InventoryUpdateLabelsRequest) ProtoMessage() {} func (*InventoryUpdateLabelsRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_0ffcffcda38ae159, []int{199} + return fileDescriptor_0ffcffcda38ae159, []int{202} } func (m *InventoryUpdateLabelsRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -13940,7 +14209,7 @@ func (m *DownstreamInventoryUpdateLabels) Reset() { *m = DownstreamInven func (m *DownstreamInventoryUpdateLabels) String() string { return proto.CompactTextString(m) } func (*DownstreamInventoryUpdateLabels) ProtoMessage() {} func (*DownstreamInventoryUpdateLabels) Descriptor() ([]byte, []int) { - return fileDescriptor_0ffcffcda38ae159, []int{200} + return fileDescriptor_0ffcffcda38ae159, []int{203} } func (m *DownstreamInventoryUpdateLabels) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -14005,7 +14274,7 @@ func (m *InventoryHeartbeat) Reset() { *m = InventoryHeartbeat{} } func (m *InventoryHeartbeat) String() string { return proto.CompactTextString(m) } func (*InventoryHeartbeat) ProtoMessage() {} func (*InventoryHeartbeat) Descriptor() ([]byte, []int) { - return fileDescriptor_0ffcffcda38ae159, []int{201} + return fileDescriptor_0ffcffcda38ae159, []int{204} } func (m *InventoryHeartbeat) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -14077,7 +14346,7 @@ func (m *UpstreamInventoryGoodbye) Reset() { *m = UpstreamInventoryGoodb func (m *UpstreamInventoryGoodbye) String() string { return proto.CompactTextString(m) } func (*UpstreamInventoryGoodbye) ProtoMessage() {} func (*UpstreamInventoryGoodbye) Descriptor() ([]byte, []int) { - return fileDescriptor_0ffcffcda38ae159, []int{202} + return fileDescriptor_0ffcffcda38ae159, []int{205} } func (m *UpstreamInventoryGoodbye) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -14127,7 +14396,7 @@ func (m *InventoryStatusRequest) Reset() { *m = InventoryStatusRequest{} func (m *InventoryStatusRequest) String() string { return proto.CompactTextString(m) } func (*InventoryStatusRequest) ProtoMessage() {} func (*InventoryStatusRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_0ffcffcda38ae159, []int{203} + return fileDescriptor_0ffcffcda38ae159, []int{206} } func (m *InventoryStatusRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -14185,7 +14454,7 @@ func (m *InventoryStatusSummary) Reset() { *m = InventoryStatusSummary{} func (m *InventoryStatusSummary) String() string { return proto.CompactTextString(m) } func (*InventoryStatusSummary) ProtoMessage() {} func (*InventoryStatusSummary) Descriptor() ([]byte, []int) { - return fileDescriptor_0ffcffcda38ae159, []int{204} + return fileDescriptor_0ffcffcda38ae159, []int{207} } func (m *InventoryStatusSummary) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -14262,7 +14531,7 @@ func (m *InventoryConnectedServiceCountsRequest) Reset() { func (m *InventoryConnectedServiceCountsRequest) String() string { return proto.CompactTextString(m) } func (*InventoryConnectedServiceCountsRequest) ProtoMessage() {} func (*InventoryConnectedServiceCountsRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_0ffcffcda38ae159, []int{205} + return fileDescriptor_0ffcffcda38ae159, []int{208} } func (m *InventoryConnectedServiceCountsRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -14304,7 +14573,7 @@ func (m *InventoryConnectedServiceCounts) Reset() { *m = InventoryConnec func (m *InventoryConnectedServiceCounts) String() string { return proto.CompactTextString(m) } func (*InventoryConnectedServiceCounts) ProtoMessage() {} func (*InventoryConnectedServiceCounts) Descriptor() ([]byte, []int) { - return fileDescriptor_0ffcffcda38ae159, []int{206} + return fileDescriptor_0ffcffcda38ae159, []int{209} } func (m *InventoryConnectedServiceCounts) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -14358,7 +14627,7 @@ func (m *InventoryPingRequest) Reset() { *m = InventoryPingRequest{} } func (m *InventoryPingRequest) String() string { return proto.CompactTextString(m) } func (*InventoryPingRequest) ProtoMessage() {} func (*InventoryPingRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_0ffcffcda38ae159, []int{207} + return fileDescriptor_0ffcffcda38ae159, []int{210} } func (m *InventoryPingRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -14415,7 +14684,7 @@ func (m *InventoryPingResponse) Reset() { *m = InventoryPingResponse{} } func (m *InventoryPingResponse) String() string { return proto.CompactTextString(m) } func (*InventoryPingResponse) ProtoMessage() {} func (*InventoryPingResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_0ffcffcda38ae159, []int{208} + return fileDescriptor_0ffcffcda38ae159, []int{211} } func (m *InventoryPingResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -14464,7 +14733,7 @@ func (m *GetClusterAlertsResponse) Reset() { *m = GetClusterAlertsRespon func (m *GetClusterAlertsResponse) String() string { return proto.CompactTextString(m) } func (*GetClusterAlertsResponse) ProtoMessage() {} func (*GetClusterAlertsResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_0ffcffcda38ae159, []int{209} + return fileDescriptor_0ffcffcda38ae159, []int{212} } func (m *GetClusterAlertsResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -14511,7 +14780,7 @@ func (m *GetAlertAcksRequest) Reset() { *m = GetAlertAcksRequest{} } func (m *GetAlertAcksRequest) String() string { return proto.CompactTextString(m) } func (*GetAlertAcksRequest) ProtoMessage() {} func (*GetAlertAcksRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_0ffcffcda38ae159, []int{210} + return fileDescriptor_0ffcffcda38ae159, []int{213} } func (m *GetAlertAcksRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -14553,7 +14822,7 @@ func (m *GetAlertAcksResponse) Reset() { *m = GetAlertAcksResponse{} } func (m *GetAlertAcksResponse) String() string { return proto.CompactTextString(m) } func (*GetAlertAcksResponse) ProtoMessage() {} func (*GetAlertAcksResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_0ffcffcda38ae159, []int{211} + return fileDescriptor_0ffcffcda38ae159, []int{214} } func (m *GetAlertAcksResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -14603,7 +14872,7 @@ func (m *ClearAlertAcksRequest) Reset() { *m = ClearAlertAcksRequest{} } func (m *ClearAlertAcksRequest) String() string { return proto.CompactTextString(m) } func (*ClearAlertAcksRequest) ProtoMessage() {} func (*ClearAlertAcksRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_0ffcffcda38ae159, []int{212} + return fileDescriptor_0ffcffcda38ae159, []int{215} } func (m *ClearAlertAcksRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -14652,7 +14921,7 @@ func (m *UpsertClusterAlertRequest) Reset() { *m = UpsertClusterAlertReq func (m *UpsertClusterAlertRequest) String() string { return proto.CompactTextString(m) } func (*UpsertClusterAlertRequest) ProtoMessage() {} func (*UpsertClusterAlertRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_0ffcffcda38ae159, []int{213} + return fileDescriptor_0ffcffcda38ae159, []int{216} } func (m *UpsertClusterAlertRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -14701,7 +14970,7 @@ func (m *GetConnectionDiagnosticRequest) Reset() { *m = GetConnectionDia func (m *GetConnectionDiagnosticRequest) String() string { return proto.CompactTextString(m) } func (*GetConnectionDiagnosticRequest) ProtoMessage() {} func (*GetConnectionDiagnosticRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_0ffcffcda38ae159, []int{214} + return fileDescriptor_0ffcffcda38ae159, []int{217} } func (m *GetConnectionDiagnosticRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -14752,7 +15021,7 @@ func (m *AppendDiagnosticTraceRequest) Reset() { *m = AppendDiagnosticTr func (m *AppendDiagnosticTraceRequest) String() string { return proto.CompactTextString(m) } func (*AppendDiagnosticTraceRequest) ProtoMessage() {} func (*AppendDiagnosticTraceRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_0ffcffcda38ae159, []int{215} + return fileDescriptor_0ffcffcda38ae159, []int{218} } func (m *AppendDiagnosticTraceRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -14807,7 +15076,7 @@ func (m *SubmitUsageEventRequest) Reset() { *m = SubmitUsageEventRequest func (m *SubmitUsageEventRequest) String() string { return proto.CompactTextString(m) } func (*SubmitUsageEventRequest) ProtoMessage() {} func (*SubmitUsageEventRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_0ffcffcda38ae159, []int{216} + return fileDescriptor_0ffcffcda38ae159, []int{219} } func (m *SubmitUsageEventRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -14854,7 +15123,7 @@ func (m *GetLicenseRequest) Reset() { *m = GetLicenseRequest{} } func (m *GetLicenseRequest) String() string { return proto.CompactTextString(m) } func (*GetLicenseRequest) ProtoMessage() {} func (*GetLicenseRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_0ffcffcda38ae159, []int{217} + return fileDescriptor_0ffcffcda38ae159, []int{220} } func (m *GetLicenseRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -14894,7 +15163,7 @@ func (m *ListReleasesRequest) Reset() { *m = ListReleasesRequest{} } func (m *ListReleasesRequest) String() string { return proto.CompactTextString(m) } func (*ListReleasesRequest) ProtoMessage() {} func (*ListReleasesRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_0ffcffcda38ae159, []int{218} + return fileDescriptor_0ffcffcda38ae159, []int{221} } func (m *ListReleasesRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -14938,7 +15207,7 @@ func (m *CreateTokenV2Request) Reset() { *m = CreateTokenV2Request{} } func (m *CreateTokenV2Request) String() string { return proto.CompactTextString(m) } func (*CreateTokenV2Request) ProtoMessage() {} func (*CreateTokenV2Request) Descriptor() ([]byte, []int) { - return fileDescriptor_0ffcffcda38ae159, []int{219} + return fileDescriptor_0ffcffcda38ae159, []int{222} } func (m *CreateTokenV2Request) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -15015,7 +15284,7 @@ func (m *UpsertTokenV2Request) Reset() { *m = UpsertTokenV2Request{} } func (m *UpsertTokenV2Request) String() string { return proto.CompactTextString(m) } func (*UpsertTokenV2Request) ProtoMessage() {} func (*UpsertTokenV2Request) Descriptor() ([]byte, []int) { - return fileDescriptor_0ffcffcda38ae159, []int{220} + return fileDescriptor_0ffcffcda38ae159, []int{223} } func (m *UpsertTokenV2Request) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -15090,7 +15359,7 @@ func (m *GetHeadlessAuthenticationRequest) Reset() { *m = GetHeadlessAut func (m *GetHeadlessAuthenticationRequest) String() string { return proto.CompactTextString(m) } func (*GetHeadlessAuthenticationRequest) ProtoMessage() {} func (*GetHeadlessAuthenticationRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_0ffcffcda38ae159, []int{221} + return fileDescriptor_0ffcffcda38ae159, []int{224} } func (m *GetHeadlessAuthenticationRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -15148,7 +15417,7 @@ func (m *UpdateHeadlessAuthenticationStateRequest) Reset() { func (m *UpdateHeadlessAuthenticationStateRequest) String() string { return proto.CompactTextString(m) } func (*UpdateHeadlessAuthenticationStateRequest) ProtoMessage() {} func (*UpdateHeadlessAuthenticationStateRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_0ffcffcda38ae159, []int{222} + return fileDescriptor_0ffcffcda38ae159, []int{225} } func (m *UpdateHeadlessAuthenticationStateRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -15214,7 +15483,7 @@ func (m *ExportUpgradeWindowsRequest) Reset() { *m = ExportUpgradeWindow func (m *ExportUpgradeWindowsRequest) String() string { return proto.CompactTextString(m) } func (*ExportUpgradeWindowsRequest) ProtoMessage() {} func (*ExportUpgradeWindowsRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_0ffcffcda38ae159, []int{223} + return fileDescriptor_0ffcffcda38ae159, []int{226} } func (m *ExportUpgradeWindowsRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -15280,7 +15549,7 @@ func (m *ExportUpgradeWindowsResponse) Reset() { *m = ExportUpgradeWindo func (m *ExportUpgradeWindowsResponse) String() string { return proto.CompactTextString(m) } func (*ExportUpgradeWindowsResponse) ProtoMessage() {} func (*ExportUpgradeWindowsResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_0ffcffcda38ae159, []int{224} + return fileDescriptor_0ffcffcda38ae159, []int{227} } func (m *ExportUpgradeWindowsResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -15355,7 +15624,7 @@ func (m *ListAccessRequestsRequest) Reset() { *m = ListAccessRequestsReq func (m *ListAccessRequestsRequest) String() string { return proto.CompactTextString(m) } func (*ListAccessRequestsRequest) ProtoMessage() {} func (*ListAccessRequestsRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_0ffcffcda38ae159, []int{225} + return fileDescriptor_0ffcffcda38ae159, []int{228} } func (m *ListAccessRequestsRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -15434,7 +15703,7 @@ func (m *ListAccessRequestsResponse) Reset() { *m = ListAccessRequestsRe func (m *ListAccessRequestsResponse) String() string { return proto.CompactTextString(m) } func (*ListAccessRequestsResponse) ProtoMessage() {} func (*ListAccessRequestsResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_0ffcffcda38ae159, []int{226} + return fileDescriptor_0ffcffcda38ae159, []int{229} } func (m *ListAccessRequestsResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -15490,7 +15759,7 @@ func (m *AccessRequestAllowedPromotionRequest) Reset() { *m = AccessRequ func (m *AccessRequestAllowedPromotionRequest) String() string { return proto.CompactTextString(m) } func (*AccessRequestAllowedPromotionRequest) ProtoMessage() {} func (*AccessRequestAllowedPromotionRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_0ffcffcda38ae159, []int{227} + return fileDescriptor_0ffcffcda38ae159, []int{230} } func (m *AccessRequestAllowedPromotionRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -15539,7 +15808,7 @@ func (m *AccessRequestAllowedPromotionResponse) Reset() { *m = AccessReq func (m *AccessRequestAllowedPromotionResponse) String() string { return proto.CompactTextString(m) } func (*AccessRequestAllowedPromotionResponse) ProtoMessage() {} func (*AccessRequestAllowedPromotionResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_0ffcffcda38ae159, []int{228} + return fileDescriptor_0ffcffcda38ae159, []int{231} } func (m *AccessRequestAllowedPromotionResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -15747,6 +16016,9 @@ func init() { proto.RegisterType((*CreateAuthenticateChallengeRequest)(nil), "proto.CreateAuthenticateChallengeRequest") proto.RegisterType((*CreatePrivilegeTokenRequest)(nil), "proto.CreatePrivilegeTokenRequest") proto.RegisterType((*CreateRegisterChallengeRequest)(nil), "proto.CreateRegisterChallengeRequest") + proto.RegisterType((*IdentityCenterAccount)(nil), "proto.IdentityCenterAccount") + proto.RegisterType((*IdentityCenterPermissionSet)(nil), "proto.IdentityCenterPermissionSet") + proto.RegisterType((*IdentityCenterAccountAssignment)(nil), "proto.IdentityCenterAccountAssignment") proto.RegisterType((*PaginatedResource)(nil), "proto.PaginatedResource") proto.RegisterType((*ListUnifiedResourcesRequest)(nil), "proto.ListUnifiedResourcesRequest") proto.RegisterMapType((map[string]string)(nil), "proto.ListUnifiedResourcesRequest.LabelsEntry") @@ -15836,955 +16108,971 @@ func init() { } var fileDescriptor_0ffcffcda38ae159 = []byte{ - // 15156 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xcc, 0xbd, 0x5b, 0x6c, 0x5c, 0x59, - 0x76, 0x18, 0xaa, 0x2a, 0xbe, 0x17, 0x1f, 0x2a, 0x6d, 0x92, 0x62, 0x89, 0x7a, 0x94, 0x74, 0xd4, - 0xea, 0x51, 0x6b, 0x7a, 0xf4, 0x60, 0x3f, 0xa6, 0x5f, 0xd3, 0xdd, 0x55, 0x24, 0x25, 0x52, 0xe2, - 0xab, 0x4f, 0x91, 0x54, 0xbf, 0x3c, 0x35, 0x47, 0x55, 0x5b, 0xe4, 0xb1, 0x8a, 0xe7, 0xd4, 0x9c, - 0x73, 0x4a, 0x6a, 0x8d, 0xaf, 0x7d, 0x61, 0xfb, 0x3e, 0x7c, 0x71, 0x71, 0x6f, 0x6c, 0x20, 0x09, - 0x9c, 0xe4, 0xc3, 0x09, 0x90, 0x00, 0x41, 0x80, 0x00, 0xfe, 0x09, 0xfc, 0x13, 0x23, 0xc8, 0x57, - 0x26, 0x06, 0x82, 0xc4, 0xb0, 0xfd, 0x13, 0x20, 0x74, 0x32, 0x80, 0x7f, 0x88, 0xe4, 0xc3, 0x08, - 0x12, 0x20, 0x03, 0x18, 0x08, 0xf6, 0xda, 0x8f, 0xb3, 0xf7, 0x79, 0x54, 0x91, 0x92, 0x7a, 0x9c, - 0x1f, 0x89, 0xb5, 0xf6, 0x5a, 0x6b, 0x3f, 0xcf, 0xde, 0x6b, 0xad, 0xbd, 0xf6, 0x5a, 0x70, 0x33, - 0xa2, 0x6d, 0xda, 0xf1, 0x83, 0xe8, 0x56, 0x9b, 0xee, 0x39, 0xcd, 0xe7, 0xb7, 0x9a, 0x6d, 0x97, - 0x7a, 0xd1, 0xad, 0x4e, 0xe0, 0x47, 0xfe, 0x2d, 0xa7, 0x1b, 0xed, 0x87, 0x34, 0x78, 0xea, 0x36, - 0xe9, 0x4d, 0x84, 0x90, 0x21, 0xfc, 0x6f, 0x7e, 0x66, 0xcf, 0xdf, 0xf3, 0x39, 0x0e, 0xfb, 0x8b, - 0x17, 0xce, 0x9f, 0xdf, 0xf3, 0xfd, 0xbd, 0x36, 0xe5, 0xc4, 0x8f, 0xba, 0x8f, 0x6f, 0xd1, 0x83, - 0x4e, 0xf4, 0x5c, 0x14, 0x56, 0x92, 0x85, 0x91, 0x7b, 0x40, 0xc3, 0xc8, 0x39, 0xe8, 0x08, 0x84, - 0x37, 0x54, 0x53, 0x9c, 0x28, 0x62, 0x25, 0x91, 0xeb, 0x7b, 0xb7, 0x9e, 0xde, 0xd1, 0x7f, 0x0a, - 0xd4, 0xeb, 0x3d, 0x5b, 0xdd, 0xa4, 0x41, 0x14, 0x1e, 0x0b, 0x93, 0x3e, 0xa5, 0x5e, 0x94, 0xaa, - 0x5e, 0x60, 0x46, 0xcf, 0x3b, 0x34, 0xe4, 0x28, 0xf2, 0x3f, 0x81, 0x7a, 0x25, 0x1b, 0x15, 0xff, - 0x15, 0x28, 0xdf, 0xcb, 0x46, 0x79, 0x46, 0x1f, 0xb1, 0x31, 0xf5, 0xd4, 0x1f, 0x7d, 0xd0, 0x03, - 0xa7, 0xd3, 0xa1, 0x41, 0xfc, 0x87, 0x40, 0x3f, 0xa7, 0xd0, 0x0f, 0x1e, 0x3b, 0x6c, 0x88, 0x0e, - 0x1e, 0x3b, 0xa9, 0x6e, 0x74, 0x43, 0x67, 0x8f, 0x8a, 0xe6, 0x3f, 0xbd, 0xa3, 0xff, 0xe4, 0xa8, - 0xd6, 0xef, 0x15, 0x60, 0xe8, 0xa1, 0x13, 0x35, 0xf7, 0xc9, 0x27, 0x30, 0xf4, 0xc0, 0xf5, 0x5a, - 0x61, 0xb9, 0x70, 0x79, 0xe0, 0xfa, 0xf8, 0x42, 0xe9, 0x26, 0xef, 0x0a, 0x16, 0xb2, 0x82, 0xda, - 0xdc, 0x4f, 0x0f, 0x2b, 0xa7, 0x8e, 0x0e, 0x2b, 0xa7, 0x9f, 0x30, 0xb4, 0x37, 0xfd, 0x03, 0x37, - 0xc2, 0xb9, 0xb5, 0x39, 0x1d, 0xd9, 0x81, 0xe9, 0x6a, 0xbb, 0xed, 0x3f, 0xdb, 0x72, 0x82, 0xc8, - 0x75, 0xda, 0xf5, 0x6e, 0xb3, 0x49, 0xc3, 0xb0, 0x5c, 0xbc, 0x5c, 0xb8, 0x3e, 0x5a, 0xbb, 0x7a, - 0x74, 0x58, 0xa9, 0x38, 0xac, 0xb8, 0xd1, 0xe1, 0xe5, 0x8d, 0x90, 0x23, 0x68, 0x8c, 0xb2, 0xe8, - 0xad, 0x3f, 0x1a, 0x86, 0xd2, 0x8a, 0x1f, 0x46, 0x8b, 0x6c, 0x46, 0x6d, 0xfa, 0xe3, 0x2e, 0x0d, - 0x23, 0x72, 0x15, 0x86, 0x19, 0x6c, 0x75, 0xa9, 0x5c, 0xb8, 0x5c, 0xb8, 0x3e, 0x56, 0x1b, 0x3f, - 0x3a, 0xac, 0x8c, 0xec, 0xfb, 0x61, 0xd4, 0x70, 0x5b, 0xb6, 0x28, 0x22, 0x6f, 0xc0, 0xe8, 0x86, - 0xdf, 0xa2, 0x1b, 0xce, 0x01, 0xc5, 0x56, 0x8c, 0xd5, 0x26, 0x8f, 0x0e, 0x2b, 0x63, 0x9e, 0xdf, - 0xa2, 0x0d, 0xcf, 0x39, 0xa0, 0xb6, 0x2a, 0x26, 0xbb, 0x30, 0x68, 0xfb, 0x6d, 0x5a, 0x1e, 0x40, - 0xb4, 0xda, 0xd1, 0x61, 0x65, 0x30, 0xf0, 0xdb, 0xf4, 0xe7, 0x87, 0x95, 0x77, 0xf7, 0xdc, 0x68, - 0xbf, 0xfb, 0xe8, 0x66, 0xd3, 0x3f, 0xb8, 0xb5, 0x17, 0x38, 0x4f, 0x5d, 0xbe, 0x08, 0x9d, 0xf6, - 0xad, 0x78, 0xa9, 0x76, 0x5c, 0x31, 0xef, 0xf5, 0xe7, 0x61, 0x44, 0x0f, 0x18, 0x27, 0x1b, 0xf9, - 0x91, 0x87, 0x30, 0x53, 0x6d, 0xb5, 0x5c, 0x4e, 0xb1, 0x15, 0xb8, 0x5e, 0xd3, 0xed, 0x38, 0xed, - 0xb0, 0x3c, 0x78, 0x79, 0xe0, 0xfa, 0x98, 0x18, 0x14, 0x55, 0xde, 0xe8, 0x28, 0x04, 0x6d, 0x50, - 0x32, 0x19, 0x90, 0xb7, 0x60, 0x74, 0x69, 0xa3, 0xce, 0xda, 0x1e, 0x96, 0x87, 0x90, 0xd9, 0xdc, - 0xd1, 0x61, 0x65, 0xba, 0xe5, 0x85, 0xd8, 0x35, 0x9d, 0x81, 0x42, 0x24, 0xef, 0xc2, 0xc4, 0x56, - 0xf7, 0x51, 0xdb, 0x6d, 0x6e, 0xaf, 0xd5, 0x1f, 0xd0, 0xe7, 0xe5, 0xe1, 0xcb, 0x85, 0xeb, 0x13, - 0x35, 0x72, 0x74, 0x58, 0x99, 0xea, 0x20, 0xbc, 0x11, 0xb5, 0xc3, 0xc6, 0x13, 0xfa, 0xdc, 0x36, - 0xf0, 0x62, 0xba, 0x7a, 0x7d, 0x85, 0xd1, 0x8d, 0xa4, 0xe8, 0xc2, 0x70, 0x5f, 0xa7, 0xe3, 0x78, - 0xe4, 0x16, 0x80, 0x4d, 0x0f, 0xfc, 0x88, 0x56, 0x5b, 0xad, 0xa0, 0x3c, 0x8a, 0x63, 0x7b, 0xfa, - 0xe8, 0xb0, 0x32, 0x1e, 0x20, 0xb4, 0xe1, 0xb4, 0x5a, 0x81, 0xad, 0xa1, 0x90, 0x45, 0x18, 0xb5, - 0x7d, 0x3e, 0xc0, 0xe5, 0xb1, 0xcb, 0x85, 0xeb, 0xe3, 0x0b, 0xa7, 0xc5, 0x32, 0x94, 0xe0, 0xda, - 0xd9, 0xa3, 0xc3, 0x0a, 0x09, 0xc4, 0x2f, 0xbd, 0x97, 0x12, 0x83, 0x54, 0x60, 0x64, 0xc3, 0x5f, - 0x74, 0x9a, 0xfb, 0xb4, 0x0c, 0xb8, 0xf6, 0x86, 0x8e, 0x0e, 0x2b, 0x85, 0xef, 0xd9, 0x12, 0x4a, - 0x9e, 0xc2, 0x78, 0x3c, 0x51, 0x61, 0x79, 0x1c, 0x87, 0x6f, 0xfb, 0xe8, 0xb0, 0x72, 0x36, 0x44, - 0x70, 0x83, 0x4d, 0xbd, 0x36, 0x82, 0x2f, 0xb1, 0x0a, 0xf4, 0x8a, 0xc8, 0xd7, 0x30, 0x1b, 0xff, - 0xac, 0x86, 0x21, 0x0d, 0x18, 0x8f, 0xd5, 0xa5, 0xf2, 0x24, 0x8e, 0xcc, 0xeb, 0x47, 0x87, 0x15, - 0x4b, 0x6b, 0x41, 0xc3, 0x91, 0x28, 0x0d, 0xb7, 0xa5, 0xf5, 0x34, 0x9b, 0xc9, 0xfd, 0xc1, 0xd1, - 0x89, 0xd2, 0xa4, 0x7d, 0x71, 0xc7, 0x0b, 0x23, 0xe7, 0x51, 0x9b, 0x66, 0x22, 0x59, 0x7f, 0x55, - 0x00, 0xb2, 0xd9, 0xa1, 0x5e, 0xbd, 0xbe, 0xc2, 0xbe, 0x27, 0xf9, 0x39, 0xbd, 0x09, 0x63, 0x7c, - 0xe2, 0xd8, 0xec, 0x16, 0x71, 0x76, 0xa7, 0x8e, 0x0e, 0x2b, 0x20, 0x66, 0x97, 0xcd, 0x6c, 0x8c, - 0x40, 0xae, 0xc1, 0xc0, 0xf6, 0xf6, 0x1a, 0x7e, 0x2b, 0x03, 0xb5, 0xe9, 0xa3, 0xc3, 0xca, 0x40, - 0x14, 0xb5, 0x7f, 0x7e, 0x58, 0x19, 0x5d, 0xea, 0x06, 0x38, 0x2c, 0x36, 0x2b, 0x27, 0xd7, 0x60, - 0x64, 0xb1, 0xdd, 0x0d, 0x23, 0x1a, 0x94, 0x07, 0xe3, 0x8f, 0xb4, 0xc9, 0x41, 0xb6, 0x2c, 0x23, - 0xdf, 0x85, 0xc1, 0x9d, 0x90, 0x06, 0xe5, 0x21, 0x9c, 0xef, 0x49, 0x31, 0xdf, 0x0c, 0xb4, 0xbb, - 0x50, 0x1b, 0x65, 0x5f, 0x62, 0x37, 0xa4, 0x81, 0x8d, 0x48, 0xe4, 0x26, 0x0c, 0xf1, 0x49, 0x1b, - 0xc6, 0x4d, 0x6a, 0x52, 0xad, 0x8e, 0x36, 0xdd, 0x7d, 0xb7, 0x36, 0x76, 0x74, 0x58, 0x19, 0xc2, - 0xc9, 0xb3, 0x39, 0xda, 0xfd, 0xc1, 0xd1, 0x42, 0xa9, 0x68, 0x8f, 0x32, 0x5a, 0xf6, 0x59, 0x58, - 0xdf, 0x85, 0x71, 0xad, 0xfb, 0xe4, 0x02, 0x0c, 0xb2, 0xff, 0x71, 0x13, 0x99, 0xe0, 0x95, 0xb1, - 0x83, 0xc3, 0x46, 0xa8, 0xf5, 0xf7, 0xa7, 0xa1, 0xc4, 0x28, 0x8d, 0x9d, 0xe7, 0xa6, 0x3e, 0x54, - 0x9c, 0xae, 0x64, 0x0e, 0x55, 0xb9, 0xa0, 0x0f, 0xd6, 0x75, 0x50, 0xb5, 0x8b, 0x4d, 0x68, 0xe2, - 0xe8, 0xb0, 0x32, 0xda, 0x15, 0xb0, 0xb8, 0x6d, 0xa4, 0x0e, 0x23, 0xcb, 0xdf, 0x74, 0xdc, 0x80, - 0x86, 0x38, 0xb4, 0xe3, 0x0b, 0xf3, 0x37, 0xf9, 0x71, 0x79, 0x53, 0x1e, 0x97, 0x37, 0xb7, 0xe5, - 0x71, 0x59, 0xbb, 0x28, 0x36, 0xe3, 0x33, 0x94, 0x93, 0xc4, 0xeb, 0xe3, 0xb7, 0xff, 0xbc, 0x52, - 0xb0, 0x25, 0x27, 0xf2, 0x26, 0x0c, 0xdf, 0xf5, 0x83, 0x03, 0x27, 0x12, 0x73, 0x30, 0x73, 0x74, - 0x58, 0x29, 0x3d, 0x46, 0x88, 0xb6, 0xa4, 0x04, 0x0e, 0xb9, 0x0b, 0x53, 0xb6, 0xdf, 0x8d, 0xe8, - 0xb6, 0x2f, 0x67, 0x6e, 0x08, 0xa9, 0x2e, 0x1d, 0x1d, 0x56, 0xe6, 0x03, 0x56, 0xd2, 0x88, 0xfc, - 0x86, 0x98, 0x42, 0x8d, 0x3e, 0x41, 0x45, 0x96, 0x61, 0xaa, 0x8a, 0xbb, 0xb7, 0x18, 0x35, 0x3e, - 0x5f, 0x63, 0xb5, 0x8b, 0x47, 0x87, 0x95, 0x73, 0x0e, 0x96, 0x34, 0x02, 0x51, 0xa4, 0xb3, 0x31, - 0x89, 0xc8, 0x06, 0x9c, 0x79, 0xd0, 0x7d, 0x44, 0x03, 0x8f, 0x46, 0x34, 0x94, 0x2d, 0x1a, 0xc1, - 0x16, 0x5d, 0x3e, 0x3a, 0xac, 0x5c, 0x78, 0xa2, 0x0a, 0x33, 0xda, 0x94, 0x26, 0x25, 0x14, 0x4e, - 0x8b, 0x86, 0x2e, 0x39, 0x91, 0xf3, 0xc8, 0x09, 0x29, 0x6e, 0x4a, 0xe3, 0x0b, 0x67, 0xf9, 0x10, - 0xdf, 0x4c, 0x94, 0xd6, 0xae, 0x8a, 0x51, 0x3e, 0xaf, 0xfa, 0xde, 0x12, 0x45, 0x5a, 0x45, 0x49, - 0x9e, 0x6c, 0x6f, 0x56, 0xe7, 0xce, 0x18, 0xb6, 0x16, 0xf7, 0x66, 0x75, 0xee, 0xe8, 0xbb, 0x96, - 0x3a, 0x81, 0xd6, 0x60, 0x68, 0x87, 0x9d, 0xce, 0xb8, 0x67, 0x4d, 0x2d, 0x5c, 0x11, 0x2d, 0x4a, - 0xae, 0xbf, 0x9b, 0xec, 0x07, 0x22, 0xe2, 0x97, 0x77, 0x1a, 0x4f, 0x74, 0xfd, 0x2c, 0xc6, 0x32, - 0xf2, 0x19, 0x80, 0x68, 0x55, 0xb5, 0xd3, 0x29, 0x8f, 0x63, 0x27, 0xcf, 0x98, 0x9d, 0xac, 0x76, - 0x3a, 0xb5, 0x4b, 0xa2, 0x7f, 0x67, 0x55, 0xff, 0x9c, 0x4e, 0x47, 0xe3, 0xa6, 0x31, 0x21, 0x9f, - 0xc0, 0x04, 0x6e, 0x69, 0x72, 0x46, 0x27, 0x70, 0x46, 0xcf, 0x1f, 0x1d, 0x56, 0xe6, 0x70, 0xb7, - 0xca, 0x98, 0x4f, 0x83, 0x80, 0xfc, 0x1a, 0xcc, 0x0a, 0x76, 0x0f, 0x5d, 0xaf, 0xe5, 0x3f, 0x0b, - 0x97, 0x68, 0xf8, 0x24, 0xf2, 0x3b, 0xb8, 0xfd, 0x8d, 0x2f, 0x5c, 0x30, 0x9b, 0x67, 0xe2, 0xd4, - 0x6e, 0x88, 0x96, 0x5a, 0xaa, 0xa5, 0xcf, 0x38, 0x42, 0xa3, 0xc5, 0x31, 0xf4, 0x0d, 0x32, 0x93, - 0x05, 0x59, 0x85, 0xd3, 0x3b, 0x21, 0x35, 0xfa, 0x30, 0x85, 0xe7, 0x43, 0x85, 0xcd, 0x70, 0x37, - 0xa4, 0x8d, 0xbc, 0x7e, 0x24, 0xe9, 0x88, 0x0d, 0x64, 0x29, 0xf0, 0x3b, 0x89, 0x35, 0x7e, 0x1a, - 0x47, 0xc4, 0x3a, 0x3a, 0xac, 0x5c, 0x6a, 0x05, 0x7e, 0xa7, 0x91, 0xbf, 0xd0, 0x33, 0xa8, 0xc9, - 0x0f, 0xe1, 0xec, 0xa2, 0xef, 0x79, 0xb4, 0xc9, 0x76, 0xd0, 0x25, 0xd7, 0xd9, 0xf3, 0xfc, 0x30, - 0x72, 0x9b, 0xab, 0x4b, 0xe5, 0x52, 0x7c, 0x3c, 0x34, 0x15, 0x46, 0xa3, 0xa5, 0x50, 0xcc, 0xe3, - 0x21, 0x87, 0x0b, 0xf9, 0x0a, 0x26, 0x45, 0x5d, 0x34, 0xc0, 0xa5, 0x79, 0xa6, 0xf7, 0x42, 0x53, - 0xc8, 0xfc, 0xa0, 0x0f, 0xe4, 0x4f, 0x2e, 0x3a, 0x99, 0xbc, 0xc8, 0xd7, 0x30, 0xbe, 0x7e, 0xb7, - 0x6a, 0xd3, 0xb0, 0xe3, 0x7b, 0x21, 0x2d, 0x13, 0x9c, 0xd1, 0x4b, 0x82, 0xf5, 0xfa, 0xdd, 0x6a, - 0xb5, 0x1b, 0xed, 0x53, 0x2f, 0x72, 0x9b, 0x4e, 0x44, 0x25, 0x56, 0x6d, 0x9e, 0xad, 0xbc, 0x83, - 0xc7, 0x4e, 0x23, 0x10, 0x10, 0xad, 0x17, 0x3a, 0x3b, 0x32, 0x0f, 0xa3, 0xf5, 0xfa, 0xca, 0x9a, - 0xbf, 0xe7, 0x7a, 0xe5, 0x69, 0x36, 0x18, 0xb6, 0xfa, 0x4d, 0x1e, 0xc3, 0xac, 0xa6, 0x1b, 0x34, - 0xd8, 0xff, 0xf4, 0x80, 0x7a, 0x51, 0x79, 0x06, 0xdb, 0xf0, 0x3d, 0xa5, 0xdc, 0xdc, 0xd4, 0x55, - 0x88, 0xa7, 0x77, 0x6e, 0x56, 0xe3, 0x9f, 0x75, 0x49, 0x54, 0x2b, 0x96, 0x0b, 0xf6, 0x8c, 0x93, - 0x51, 0x42, 0xb6, 0x61, 0x64, 0xab, 0x1b, 0x74, 0xfc, 0x90, 0x96, 0x67, 0x71, 0xe0, 0xae, 0xf6, - 0xfa, 0x42, 0x05, 0x6a, 0x6d, 0x96, 0x6d, 0xd1, 0x1d, 0xfe, 0x43, 0xeb, 0x9d, 0x64, 0x45, 0x3e, - 0x85, 0x89, 0x7a, 0x7d, 0x25, 0x3e, 0x50, 0xce, 0xe2, 0x81, 0x72, 0xe1, 0xe8, 0xb0, 0x52, 0x66, - 0x22, 0x55, 0x7c, 0xa8, 0xe8, 0x5f, 0x95, 0x4e, 0xc1, 0x38, 0x6c, 0xaf, 0xd5, 0x63, 0x0e, 0x73, - 0x31, 0x07, 0x26, 0xcc, 0x65, 0x73, 0xd0, 0x29, 0xc8, 0x3f, 0x2d, 0xc0, 0x65, 0x9d, 0x65, 0xd6, - 0xc0, 0x94, 0xcf, 0xbd, 0xc8, 0x68, 0x2e, 0x1c, 0x1d, 0x56, 0x6e, 0x9a, 0xfd, 0x68, 0x64, 0x4e, - 0x96, 0xd6, 0xb6, 0xbe, 0x4d, 0xc1, 0xf6, 0xea, 0x1d, 0xc8, 0x6c, 0xef, 0xfc, 0x0b, 0xb7, 0xd7, - 0x1c, 0xb5, 0xfe, 0xed, 0xed, 0xd7, 0x14, 0xeb, 0x73, 0x18, 0x53, 0x9b, 0x36, 0x19, 0x81, 0x81, - 0x6a, 0xbb, 0x5d, 0x3a, 0xc5, 0xfe, 0xa8, 0xd7, 0x57, 0x4a, 0x05, 0x32, 0x05, 0x10, 0x9f, 0x54, - 0xa5, 0x22, 0x99, 0x80, 0x51, 0x79, 0x92, 0x94, 0x06, 0x10, 0xbf, 0xd3, 0x29, 0x0d, 0x12, 0x02, - 0x53, 0xe6, 0x7e, 0x56, 0x1a, 0xb2, 0x7e, 0xa7, 0x00, 0x63, 0xea, 0x3b, 0x24, 0xa7, 0x61, 0x7c, - 0x67, 0xa3, 0xbe, 0xb5, 0xbc, 0xb8, 0x7a, 0x77, 0x75, 0x79, 0xa9, 0x74, 0x8a, 0x5c, 0x84, 0x73, - 0xdb, 0xf5, 0x95, 0xc6, 0x52, 0xad, 0xb1, 0xb6, 0xb9, 0x58, 0x5d, 0x6b, 0x6c, 0xd9, 0x9b, 0x9f, - 0x7f, 0xd1, 0xd8, 0xde, 0xd9, 0xd8, 0x58, 0x5e, 0x2b, 0x15, 0x48, 0x19, 0x66, 0x58, 0xf1, 0x83, - 0x9d, 0xda, 0xb2, 0x8e, 0x50, 0x2a, 0x92, 0x2b, 0x70, 0x31, 0xab, 0xa4, 0xb1, 0xb2, 0x5c, 0x5d, - 0x5a, 0x5b, 0xae, 0xd7, 0x4b, 0x03, 0x64, 0x0e, 0xa6, 0x19, 0x4a, 0x75, 0x6b, 0xcb, 0xa0, 0x1d, - 0xb4, 0xda, 0x30, 0xae, 0x7d, 0x00, 0xe4, 0x02, 0x94, 0x17, 0x97, 0xed, 0xed, 0xc6, 0xd6, 0x8e, - 0xbd, 0xb5, 0x59, 0x5f, 0x6e, 0x98, 0x2d, 0x4c, 0x96, 0xae, 0x6d, 0xde, 0x5b, 0xdd, 0x68, 0x30, - 0x50, 0xbd, 0x54, 0x60, 0xcd, 0x30, 0x4a, 0xeb, 0xab, 0x1b, 0xf7, 0xd6, 0x96, 0x1b, 0x3b, 0xf5, - 0x65, 0x81, 0x52, 0xb4, 0x7e, 0xa3, 0x98, 0x3a, 0xd2, 0xc9, 0x02, 0x8c, 0xd7, 0xb9, 0xbd, 0x02, - 0xb7, 0x39, 0xae, 0x20, 0x32, 0x19, 0x6d, 0x42, 0x98, 0x31, 0xf8, 0x0e, 0xa6, 0x23, 0x31, 0x29, - 0x6d, 0x8b, 0x7d, 0xcd, 0x4d, 0xbf, 0xad, 0x4b, 0x69, 0x1d, 0x01, 0xb3, 0x55, 0x29, 0x59, 0xd0, - 0xe4, 0x39, 0xae, 0x2d, 0xa2, 0x46, 0x22, 0xe5, 0x39, 0xfd, 0x6c, 0x57, 0x92, 0xdd, 0x42, 0x3c, - 0xa5, 0x42, 0x0c, 0x43, 0x9a, 0x0c, 0x59, 0x42, 0xe1, 0x91, 0x37, 0xa4, 0xa4, 0xcb, 0xb5, 0x3b, - 0x3c, 0xec, 0x13, 0x7a, 0x89, 0x10, 0x72, 0xad, 0x6e, 0xce, 0xc1, 0x4a, 0x3e, 0x4c, 0xae, 0x19, - 0x31, 0x18, 0xc8, 0x2c, 0x71, 0x7e, 0xda, 0x09, 0x54, 0x52, 0x81, 0x21, 0xbe, 0xe3, 0xf2, 0xf1, - 0x40, 0xd9, 0xba, 0xcd, 0x00, 0x36, 0x87, 0x5b, 0x7f, 0x3c, 0xa0, 0x0b, 0x19, 0x4c, 0x96, 0xd6, - 0xc6, 0x1b, 0x65, 0x69, 0x1c, 0x67, 0x84, 0x32, 0x55, 0x90, 0x7f, 0x25, 0xa8, 0x0a, 0x0e, 0xc4, - 0xaa, 0xa0, 0xf8, 0xd4, 0xb8, 0x2a, 0x18, 0xa3, 0xb0, 0x59, 0x14, 0x62, 0x1b, 0x72, 0x1d, 0x8c, - 0x67, 0x51, 0x88, 0x7a, 0x62, 0x16, 0x35, 0x24, 0xf2, 0x01, 0x40, 0xf5, 0x61, 0x1d, 0x75, 0x1e, - 0x7b, 0x43, 0x88, 0xae, 0x78, 0xc8, 0x38, 0xcf, 0x42, 0xa1, 0x52, 0x05, 0xba, 0xce, 0xa8, 0x61, - 0x93, 0x1a, 0x4c, 0x56, 0x7f, 0xd2, 0x0d, 0xe8, 0x6a, 0x8b, 0x9d, 0x53, 0x11, 0x57, 0x8e, 0xc7, - 0xf8, 0x46, 0xea, 0xb0, 0x82, 0x86, 0x2b, 0x4a, 0x34, 0x06, 0x26, 0x09, 0xd9, 0x84, 0x33, 0xf7, - 0x16, 0xb7, 0xc4, 0xba, 0xaa, 0x36, 0x9b, 0x7e, 0xd7, 0x8b, 0x84, 0xbc, 0x7a, 0xe5, 0xe8, 0xb0, - 0x72, 0x71, 0xaf, 0xd9, 0x69, 0xc8, 0x35, 0xe8, 0xf0, 0x62, 0x5d, 0x60, 0x4d, 0xd1, 0x92, 0xab, - 0x30, 0xb0, 0x63, 0xaf, 0x0a, 0xcd, 0xf9, 0xcc, 0xd1, 0x61, 0x65, 0xb2, 0x1b, 0xb8, 0x1a, 0x09, - 0x2b, 0x25, 0xef, 0x03, 0x6c, 0x3b, 0xc1, 0x1e, 0x8d, 0xb6, 0xfc, 0x20, 0x42, 0x81, 0x73, 0xb2, - 0x76, 0xee, 0xe8, 0xb0, 0x32, 0x1b, 0x21, 0xb4, 0xc1, 0xb6, 0x3f, 0xbd, 0xd3, 0x31, 0xf2, 0xfd, - 0xc1, 0xd1, 0x62, 0x69, 0xc0, 0x1e, 0xab, 0xd3, 0x30, 0xe4, 0xfa, 0x61, 0x1b, 0xa6, 0xee, 0xd1, - 0x88, 0x2d, 0x5c, 0xa9, 0xef, 0xf4, 0x9e, 0xd6, 0x8f, 0x60, 0xfc, 0xa1, 0x1b, 0xed, 0xd7, 0x69, - 0x33, 0xa0, 0x91, 0xb4, 0xf5, 0xe0, 0x90, 0x3f, 0x73, 0xa3, 0xfd, 0x46, 0xc8, 0xe1, 0xfa, 0xb9, - 0xae, 0xa1, 0x5b, 0xcb, 0x70, 0x5a, 0xd4, 0xa6, 0xd4, 0xab, 0x05, 0x93, 0x61, 0x01, 0x19, 0xe2, - 0xb4, 0xeb, 0x0c, 0x4d, 0x36, 0xff, 0xac, 0x08, 0xb3, 0x8b, 0xfb, 0x8e, 0xb7, 0x47, 0xb7, 0x9c, - 0x30, 0x7c, 0xe6, 0x07, 0x2d, 0xad, 0xf1, 0xa8, 0x5b, 0xa6, 0x1a, 0x8f, 0xca, 0xe4, 0x02, 0x8c, - 0x6f, 0xb6, 0x5b, 0x92, 0x46, 0xe8, 0xbd, 0x58, 0x97, 0xdf, 0x6e, 0x35, 0x3a, 0x92, 0x97, 0x8e, - 0xc4, 0x68, 0x36, 0xe8, 0x33, 0x45, 0x33, 0x10, 0xd3, 0x78, 0xf4, 0x99, 0x46, 0xa3, 0x21, 0x91, - 0x65, 0x38, 0x53, 0xa7, 0x4d, 0xdf, 0x6b, 0xdd, 0x75, 0x9a, 0x91, 0x1f, 0x6c, 0xfb, 0x4f, 0xa8, - 0x27, 0x16, 0x34, 0x2a, 0x06, 0x21, 0x16, 0x36, 0x1e, 0x63, 0x69, 0x23, 0x62, 0xc5, 0x76, 0x9a, - 0x82, 0x6c, 0xc2, 0xe8, 0x43, 0x61, 0x31, 0x14, 0xca, 0xf2, 0xb5, 0x9b, 0xca, 0x84, 0xb8, 0x18, - 0x50, 0x5c, 0x85, 0x4e, 0x5b, 0xa9, 0xfb, 0x4a, 0xce, 0xc2, 0xad, 0x4c, 0x62, 0xda, 0x8a, 0x89, - 0xb5, 0x03, 0x93, 0x5b, 0xed, 0xee, 0x9e, 0xeb, 0xb1, 0x4d, 0xa7, 0x4e, 0x7f, 0x4c, 0x96, 0x00, - 0x62, 0x80, 0xb0, 0x03, 0x4e, 0x0b, 0x15, 0x3b, 0x2e, 0xd8, 0x7d, 0x4b, 0x7c, 0xb9, 0x08, 0x41, - 0x8d, 0xc8, 0xd6, 0xe8, 0xac, 0xff, 0x31, 0x00, 0x44, 0x4c, 0x00, 0x1e, 0x82, 0x75, 0x1a, 0xb1, - 0xe3, 0xe9, 0x2c, 0x14, 0x95, 0xb9, 0x6e, 0xf8, 0xe8, 0xb0, 0x52, 0x74, 0x5b, 0x76, 0x71, 0x75, - 0x89, 0xbc, 0x0d, 0x43, 0x88, 0x86, 0xe3, 0x3f, 0xa5, 0xea, 0xd3, 0x39, 0xf0, 0xcd, 0x07, 0x4f, - 0x5f, 0x9b, 0x23, 0x93, 0x77, 0x60, 0x6c, 0x89, 0xb6, 0xe9, 0x9e, 0x13, 0xf9, 0x72, 0x3b, 0xe1, - 0x06, 0x30, 0x09, 0xd4, 0xd6, 0x5c, 0x8c, 0xc9, 0xd4, 0x61, 0x9b, 0x3a, 0xa1, 0xef, 0xe9, 0xea, - 0x70, 0x80, 0x10, 0x5d, 0x1d, 0xe6, 0x38, 0xe4, 0x6f, 0x15, 0x60, 0xbc, 0xea, 0x79, 0xc2, 0xb0, - 0x14, 0x8a, 0x51, 0x9f, 0xbd, 0xa9, 0x2c, 0xb1, 0x6b, 0xce, 0x23, 0xda, 0xde, 0x75, 0xda, 0x5d, - 0x1a, 0xd6, 0xbe, 0x66, 0x1a, 0xca, 0xbf, 0x3f, 0xac, 0x7c, 0x78, 0x02, 0x53, 0x51, 0x6c, 0xd3, - 0xdd, 0x0e, 0x1c, 0x37, 0x0a, 0xd9, 0x57, 0xeb, 0xc4, 0x15, 0xea, 0xdf, 0x8d, 0xd6, 0x8e, 0xf8, - 0x6c, 0x18, 0xee, 0x77, 0x36, 0x90, 0x03, 0x38, 0x5d, 0x0d, 0xc3, 0xee, 0x01, 0xad, 0x47, 0x4e, - 0x10, 0x6d, 0xbb, 0x07, 0x14, 0x37, 0xa4, 0xde, 0xc6, 0x85, 0xef, 0xfc, 0xf4, 0xb0, 0x52, 0x60, - 0x4a, 0x91, 0x83, 0xa4, 0x4c, 0xee, 0x09, 0xa2, 0x46, 0xe4, 0xea, 0xc7, 0x1b, 0x9a, 0x19, 0x92, - 0xbc, 0xad, 0xab, 0x4a, 0x20, 0x59, 0x5d, 0xca, 0x9b, 0x71, 0x6b, 0x11, 0x2e, 0xdc, 0xa3, 0x91, - 0x4d, 0x43, 0x1a, 0xc9, 0x6f, 0x04, 0x57, 0x78, 0x6c, 0xdc, 0x1d, 0xc1, 0xdf, 0x8a, 0x18, 0xa7, - 0x9f, 0x7f, 0x17, 0xb2, 0xc4, 0xfa, 0x3f, 0x0a, 0x50, 0x59, 0x0c, 0x28, 0xd7, 0x27, 0x72, 0x18, - 0xf5, 0xde, 0xbb, 0x2e, 0xc0, 0xe0, 0xf6, 0xf3, 0x8e, 0xb4, 0xca, 0x60, 0x29, 0x9b, 0x14, 0x1b, - 0xa1, 0xc7, 0x34, 0x72, 0x59, 0x8f, 0x61, 0xd6, 0xa6, 0x1e, 0x7d, 0xe6, 0x3c, 0x6a, 0x53, 0xc3, - 0x4e, 0x54, 0x81, 0x21, 0xfe, 0xa1, 0xa7, 0xba, 0xc0, 0xe1, 0x27, 0xb3, 0xb9, 0x59, 0x93, 0x30, - 0xbe, 0xe5, 0x7a, 0x7b, 0x82, 0xbb, 0xf5, 0x17, 0x83, 0x30, 0xc1, 0x7f, 0x0b, 0x15, 0x29, 0x71, - 0x5c, 0x16, 0x8e, 0x73, 0x5c, 0xbe, 0x07, 0x93, 0xec, 0xbc, 0xa1, 0xc1, 0x2e, 0x0d, 0xd8, 0xfe, - 0x2f, 0x46, 0x02, 0xd5, 0xbd, 0x10, 0x0b, 0x1a, 0x4f, 0x79, 0x89, 0x6d, 0x22, 0x92, 0x35, 0x98, - 0xe2, 0x80, 0xbb, 0xd4, 0x89, 0xba, 0xb1, 0xc5, 0xea, 0xb4, 0xd0, 0x89, 0x24, 0x98, 0x2f, 0x4d, - 0xc1, 0xeb, 0xb1, 0x00, 0xda, 0x09, 0x5a, 0xf2, 0x09, 0x9c, 0xde, 0x0a, 0xfc, 0x6f, 0x9e, 0x6b, - 0x02, 0x02, 0xff, 0x3a, 0xb9, 0xf6, 0xc4, 0x8a, 0x1a, 0xba, 0x98, 0x90, 0xc4, 0x26, 0x6f, 0xc0, - 0xe8, 0x6a, 0x58, 0xf3, 0x03, 0xd7, 0xdb, 0xc3, 0x6f, 0x74, 0x94, 0x1b, 0xfa, 0xdd, 0xb0, 0xf1, - 0x08, 0x81, 0xb6, 0x2a, 0x4e, 0x98, 0xa4, 0x47, 0xfa, 0x9b, 0xa4, 0x6f, 0x03, 0xac, 0xf9, 0x4e, - 0xab, 0xda, 0x6e, 0x2f, 0x56, 0x43, 0x3c, 0x89, 0xc5, 0x79, 0xd4, 0xf6, 0x9d, 0x56, 0xc3, 0x69, - 0xb7, 0x1b, 0x4d, 0x27, 0xb4, 0x35, 0x1c, 0xf2, 0x25, 0x9c, 0x0b, 0xdd, 0x3d, 0x0f, 0x3b, 0xd7, - 0x70, 0xda, 0x7b, 0x7e, 0xe0, 0x46, 0xfb, 0x07, 0x8d, 0xb0, 0xeb, 0x46, 0xdc, 0x1e, 0x34, 0xb5, - 0x70, 0x49, 0x6c, 0x72, 0x75, 0x89, 0x57, 0x95, 0x68, 0x75, 0x86, 0x65, 0xcf, 0x85, 0xd9, 0x05, - 0xe4, 0x21, 0x4c, 0xae, 0xb9, 0x4d, 0xea, 0x85, 0x14, 0x0d, 0x7c, 0xcf, 0xd1, 0x5a, 0xd4, 0xfb, - 0x63, 0x66, 0x83, 0x38, 0xd9, 0xd6, 0x89, 0xf0, 0xd3, 0x35, 0xf9, 0xdc, 0x1f, 0x1c, 0x1d, 0x2e, - 0x8d, 0xd8, 0xa7, 0x05, 0xf0, 0xa1, 0x13, 0x78, 0xae, 0xb7, 0x17, 0x5a, 0xff, 0x2f, 0x81, 0x51, - 0x35, 0x4f, 0x37, 0x75, 0x4d, 0x45, 0x1c, 0xcd, 0xb8, 0x64, 0x63, 0x3b, 0x9c, 0xad, 0x61, 0x90, - 0x73, 0xa8, 0xbb, 0x08, 0xa1, 0x60, 0x84, 0x7d, 0x42, 0x4e, 0xa7, 0x63, 0x33, 0x18, 0xdb, 0x1a, - 0x96, 0x6a, 0xb8, 0x68, 0x46, 0xf9, 0xd6, 0xd0, 0x7a, 0x64, 0x17, 0x97, 0x6a, 0xec, 0x9b, 0xdc, - 0x5c, 0x5d, 0x5a, 0xc4, 0xf9, 0x1f, 0xe5, 0xdf, 0xa4, 0xef, 0xb6, 0x9a, 0x36, 0x42, 0x59, 0x69, - 0xbd, 0xba, 0xbe, 0x26, 0xe6, 0x18, 0x4b, 0x43, 0xe7, 0xa0, 0x6d, 0x23, 0x94, 0x49, 0xbb, 0xdc, - 0xa4, 0xb2, 0xe8, 0x7b, 0x51, 0xe0, 0xb7, 0x43, 0x14, 0xe1, 0x46, 0xf9, 0x1a, 0x14, 0xb6, 0x98, - 0xa6, 0x28, 0xb2, 0x13, 0xa8, 0xe4, 0x21, 0xcc, 0x55, 0x5b, 0x4f, 0x1d, 0xaf, 0x49, 0x5b, 0xbc, - 0xe4, 0xa1, 0x1f, 0x3c, 0x79, 0xdc, 0xf6, 0x9f, 0x85, 0xb8, 0x48, 0x46, 0x85, 0xe9, 0x52, 0xa0, - 0x48, 0xd3, 0xce, 0x33, 0x89, 0x64, 0xe7, 0x51, 0xb3, 0x7d, 0x60, 0xb1, 0xed, 0x77, 0x5b, 0x62, - 0xe9, 0xe0, 0x3e, 0xd0, 0x64, 0x00, 0x9b, 0xc3, 0xd9, 0x28, 0xad, 0xd4, 0xd7, 0x71, 0x61, 0x88, - 0x51, 0xda, 0x0f, 0x0f, 0x6c, 0x06, 0x23, 0xd7, 0x60, 0x44, 0x0a, 0xee, 0xfc, 0x26, 0x03, 0x2d, - 0xe8, 0x52, 0x60, 0x97, 0x65, 0xec, 0x3b, 0xb6, 0x69, 0xd3, 0x7f, 0x4a, 0x83, 0xe7, 0x8b, 0x7e, - 0x8b, 0x4a, 0xb3, 0x96, 0x30, 0xdb, 0xf0, 0x82, 0x46, 0x93, 0x95, 0xd8, 0x26, 0x22, 0xab, 0x80, - 0x1f, 0xdc, 0x61, 0xf9, 0x74, 0x5c, 0x01, 0x3f, 0xd8, 0x43, 0x5b, 0x96, 0x91, 0x25, 0x38, 0x53, - 0xed, 0x46, 0xfe, 0x81, 0x13, 0xb9, 0xcd, 0x9d, 0xce, 0x5e, 0xe0, 0xb0, 0x4a, 0x4a, 0x48, 0x80, - 0x8a, 0x8c, 0x23, 0x0b, 0x1b, 0x5d, 0x51, 0x6a, 0xa7, 0x09, 0xc8, 0xbb, 0x30, 0xb1, 0x1a, 0x72, - 0xd3, 0xa5, 0x13, 0xd2, 0x16, 0xda, 0x9f, 0x44, 0x2b, 0xdd, 0xb0, 0x81, 0x86, 0xcc, 0x06, 0x53, - 0x7d, 0x5a, 0xb6, 0x81, 0x47, 0x2c, 0x18, 0xae, 0x86, 0xa1, 0x1b, 0x46, 0x68, 0x56, 0x1a, 0xad, - 0xc1, 0xd1, 0x61, 0x65, 0xd8, 0x41, 0x88, 0x2d, 0x4a, 0xc8, 0x43, 0x18, 0x5f, 0xa2, 0x4c, 0x72, - 0xde, 0x0e, 0xba, 0x61, 0x84, 0x46, 0xa2, 0xf1, 0x85, 0x73, 0x62, 0x37, 0xd2, 0x4a, 0xc4, 0x5a, - 0xe6, 0x22, 0x6a, 0x0b, 0xe1, 0x8d, 0x88, 0x15, 0xe8, 0x47, 0xad, 0x86, 0xcf, 0xd4, 0x02, 0x41, - 0xb3, 0xe2, 0xb6, 0xd8, 0xfe, 0x32, 0x83, 0x6d, 0x40, 0xb5, 0x40, 0x6c, 0x68, 0x8d, 0x7d, 0x2c, - 0xd1, 0xd5, 0x02, 0x83, 0x84, 0x34, 0x53, 0xd6, 0xf0, 0x59, 0xc3, 0xe2, 0x69, 0x16, 0xca, 0x26, - 0x9e, 0xd0, 0x56, 0xfe, 0x11, 0x8c, 0x2f, 0x76, 0xc3, 0xc8, 0x3f, 0xd8, 0xde, 0xa7, 0x07, 0x14, - 0x0d, 0x49, 0x42, 0xf9, 0x69, 0x22, 0xb8, 0x11, 0x31, 0xb8, 0xde, 0x4d, 0x0d, 0x9d, 0x7c, 0x06, - 0x44, 0x6a, 0x31, 0xf7, 0xd8, 0xfa, 0xf0, 0xd8, 0x5a, 0x46, 0x5b, 0xd2, 0x28, 0x57, 0x5d, 0xa4, - 0xf2, 0xd3, 0xd8, 0x53, 0xc5, 0xba, 0x3d, 0x33, 0x4d, 0xcc, 0x1a, 0xc4, 0x9b, 0x78, 0x2f, 0x70, - 0x3a, 0xfb, 0xe5, 0x72, 0xac, 0x1a, 0x88, 0x4e, 0xed, 0x31, 0xb8, 0x21, 0xe2, 0xc4, 0xe8, 0xa4, - 0x0e, 0xc0, 0x7f, 0xae, 0xb1, 0x89, 0xe7, 0xd6, 0xa7, 0xb2, 0x31, 0x5e, 0xac, 0x40, 0x8e, 0x15, - 0xaa, 0x3b, 0x82, 0x6d, 0xdb, 0x35, 0x66, 0x53, 0x63, 0x43, 0x9e, 0x40, 0x89, 0xff, 0x5a, 0xf7, - 0x3d, 0x37, 0xe2, 0xe7, 0xc5, 0xbc, 0x61, 0xaa, 0x4c, 0x16, 0xcb, 0x0a, 0xd0, 0x44, 0x2c, 0x2a, - 0x38, 0x50, 0xa5, 0x5a, 0x35, 0x29, 0xc6, 0x64, 0x0b, 0xc6, 0xb7, 0x02, 0xbf, 0xd5, 0x6d, 0x46, - 0x28, 0x65, 0x9c, 0xc7, 0x8d, 0x9f, 0x88, 0x7a, 0xb4, 0x12, 0x3e, 0x26, 0x1d, 0x0e, 0x68, 0xb0, - 0x73, 0x41, 0x1f, 0x13, 0x0d, 0x91, 0xd4, 0x60, 0x78, 0xcb, 0x6f, 0xbb, 0xcd, 0xe7, 0xe5, 0x0b, - 0xd8, 0xe8, 0x19, 0xc9, 0x0c, 0x81, 0xb2, 0xa9, 0x28, 0xd2, 0x76, 0x10, 0xa4, 0x8b, 0xb4, 0x1c, - 0x89, 0x54, 0x61, 0xf2, 0x33, 0xb6, 0x60, 0x5c, 0xdf, 0xf3, 0x1c, 0x37, 0xa0, 0xe5, 0x8b, 0x38, - 0x2f, 0x68, 0xc6, 0xff, 0xb1, 0x5e, 0xa0, 0x2f, 0x67, 0x83, 0x82, 0xac, 0xc2, 0xe9, 0xd5, 0xb0, - 0x1e, 0x05, 0x6e, 0x87, 0xae, 0x3b, 0x9e, 0xb3, 0x47, 0x5b, 0xe5, 0x4b, 0xb1, 0x1d, 0xdd, 0x0d, - 0x1b, 0x21, 0x96, 0x35, 0x0e, 0x78, 0xa1, 0x6e, 0x47, 0x4f, 0xd0, 0x91, 0xcf, 0x61, 0x66, 0xf9, - 0x9b, 0x88, 0xad, 0x98, 0x76, 0xb5, 0xdb, 0x72, 0xa3, 0x7a, 0xe4, 0x07, 0xce, 0x1e, 0x2d, 0x57, - 0x90, 0xdf, 0x6b, 0x47, 0x87, 0x95, 0xcb, 0x54, 0x94, 0x37, 0x1c, 0x86, 0xd0, 0x08, 0x39, 0x86, - 0x7e, 0x3f, 0x9e, 0xc5, 0x81, 0x8d, 0x7e, 0xbd, 0xdb, 0x61, 0xd2, 0x36, 0x8e, 0xfe, 0x65, 0x63, - 0xf4, 0xb5, 0x12, 0x3e, 0xfa, 0x21, 0x07, 0xa4, 0x46, 0x5f, 0x43, 0x24, 0x36, 0x90, 0xfb, 0xbe, - 0xeb, 0x55, 0x9b, 0x91, 0xfb, 0x94, 0x0a, 0x8d, 0x39, 0x2c, 0x5f, 0xc1, 0x96, 0xa2, 0xcd, 0xff, - 0x97, 0x7d, 0xd7, 0x6b, 0x38, 0x58, 0xdc, 0x08, 0x45, 0xb9, 0xfe, 0x8d, 0xa4, 0xa9, 0xc9, 0x0f, - 0xe1, 0xec, 0xba, 0xff, 0xc8, 0x6d, 0x53, 0xbe, 0xe5, 0xf0, 0x61, 0x41, 0xfb, 0xa5, 0x85, 0x7c, - 0xd1, 0xe6, 0x7f, 0x80, 0x18, 0x0d, 0xb1, 0x5b, 0x1d, 0x28, 0x1c, 0xdd, 0xe6, 0x9f, 0xcd, 0x85, - 0x2c, 0xc3, 0x04, 0x7e, 0x97, 0x6d, 0xfc, 0x19, 0x96, 0xaf, 0xa2, 0x4a, 0x77, 0x25, 0x21, 0xa5, - 0xdd, 0x5c, 0xd6, 0x70, 0x96, 0xbd, 0x28, 0x78, 0x6e, 0x1b, 0x64, 0xe4, 0x63, 0x98, 0x4f, 0x2e, - 0xef, 0x45, 0xdf, 0x7b, 0xec, 0xee, 0x75, 0x03, 0xda, 0x2a, 0xbf, 0xc6, 0x9a, 0x6a, 0xf7, 0xc0, - 0x20, 0x5f, 0xc1, 0x2c, 0x9e, 0x75, 0x55, 0xcf, 0xf7, 0x9e, 0x1f, 0xb8, 0x3f, 0x41, 0xf9, 0x99, - 0x89, 0xbd, 0xd7, 0x50, 0xec, 0xbd, 0x76, 0x74, 0x58, 0xb9, 0x82, 0x67, 0x62, 0xc3, 0xd1, 0x31, - 0x12, 0x56, 0xeb, 0x6c, 0x1e, 0xf3, 0x0f, 0xe1, 0x4c, 0xaa, 0xfd, 0xa4, 0x04, 0x03, 0x4f, 0xc4, - 0xfd, 0xec, 0x98, 0xcd, 0xfe, 0x24, 0x6f, 0xc2, 0xd0, 0x53, 0xa6, 0xa8, 0xa1, 0x38, 0x12, 0xdf, - 0xf8, 0x69, 0xa4, 0xab, 0xde, 0x63, 0xdf, 0xe6, 0x48, 0x1f, 0x14, 0xdf, 0x2b, 0xdc, 0x1f, 0x1c, - 0x1d, 0x2f, 0x4d, 0xf0, 0x6b, 0xf5, 0xfb, 0x83, 0xa3, 0x93, 0xa5, 0x29, 0xab, 0x0a, 0xa7, 0x13, - 0xf8, 0xa4, 0x0c, 0x23, 0xd4, 0x63, 0xc2, 0x7f, 0x8b, 0x0b, 0x44, 0xb6, 0xfc, 0x49, 0x66, 0x60, - 0xa8, 0xed, 0x1e, 0xb8, 0x11, 0x56, 0x38, 0x64, 0xf3, 0x1f, 0xd6, 0xef, 0x16, 0x80, 0xa4, 0xcf, - 0x23, 0x72, 0x2b, 0xc1, 0x86, 0x8b, 0xbe, 0x02, 0xa4, 0x5f, 0x1c, 0x48, 0xee, 0x9f, 0xc1, 0x34, - 0x5f, 0x10, 0xf2, 0xe4, 0xd4, 0xea, 0xe2, 0x3b, 0x76, 0x46, 0xb1, 0x6e, 0x6c, 0x12, 0xc5, 0x78, - 0xce, 0xae, 0x61, 0xd3, 0xba, 0x30, 0x9b, 0x79, 0x12, 0x91, 0x75, 0x98, 0x3d, 0xf0, 0xbd, 0x68, - 0xbf, 0xfd, 0x5c, 0x1e, 0x44, 0xa2, 0xb6, 0x02, 0xd6, 0x86, 0x9b, 0x6f, 0x26, 0x82, 0x3d, 0x2d, - 0xc0, 0x82, 0x23, 0xd6, 0x23, 0x8c, 0x4e, 0xb2, 0x27, 0x96, 0x0d, 0x67, 0x52, 0x1b, 0x3a, 0xf9, - 0x01, 0x4c, 0x34, 0x51, 0xb9, 0x33, 0x6a, 0xe2, 0xc7, 0x99, 0x06, 0xd7, 0xbf, 0x55, 0x0e, 0xe7, - 0x5d, 0xf9, 0x47, 0x05, 0x98, 0xcb, 0xd9, 0xca, 0x4f, 0x3e, 0xd4, 0x5f, 0xc0, 0xd9, 0x03, 0xe7, - 0x9b, 0x46, 0x80, 0xba, 0x7b, 0x23, 0x70, 0xbc, 0xc4, 0x68, 0xe3, 0x36, 0x95, 0x8d, 0xa1, 0xfb, - 0x36, 0x1d, 0x38, 0xdf, 0xd8, 0x88, 0x60, 0xb3, 0x72, 0xde, 0xce, 0x4f, 0x61, 0xd2, 0xd8, 0xbc, - 0x4f, 0xdc, 0x38, 0xeb, 0x0e, 0x9c, 0x59, 0xa2, 0x6d, 0x1a, 0xd1, 0x63, 0xdb, 0xec, 0xac, 0x2d, - 0x80, 0x3a, 0x3d, 0x70, 0x3a, 0xfb, 0x3e, 0x13, 0xea, 0x6b, 0xfa, 0x2f, 0x61, 0xf3, 0x21, 0x52, - 0x3d, 0x91, 0x05, 0xbb, 0x6f, 0x71, 0x41, 0x3f, 0x54, 0x98, 0xb6, 0x46, 0x65, 0xfd, 0x9b, 0x22, - 0x10, 0xb1, 0xfb, 0x06, 0xd4, 0x39, 0x90, 0xcd, 0x78, 0x1f, 0x26, 0xb8, 0x86, 0xce, 0xc1, 0xd8, - 0x9c, 0xf1, 0x85, 0x69, 0xf1, 0xe5, 0xe9, 0x45, 0x2b, 0xa7, 0x6c, 0x03, 0x95, 0x91, 0xda, 0x94, - 0x9b, 0x16, 0x90, 0xb4, 0x68, 0x90, 0xea, 0x45, 0x8c, 0x54, 0xff, 0x4d, 0x3e, 0x81, 0xa9, 0x45, - 0xff, 0xa0, 0xc3, 0xc6, 0x44, 0x10, 0x0f, 0x08, 0xb3, 0x8d, 0xa8, 0xd7, 0x28, 0x5c, 0x39, 0x65, - 0x27, 0xd0, 0xc9, 0x06, 0x4c, 0xdf, 0x6d, 0x77, 0xc3, 0xfd, 0xaa, 0xd7, 0x5a, 0x6c, 0xfb, 0xa1, - 0xe4, 0x32, 0x28, 0x34, 0x2d, 0xb1, 0x77, 0xa6, 0x31, 0x56, 0x4e, 0xd9, 0x59, 0x84, 0xe4, 0x1a, - 0x0c, 0x2d, 0x3f, 0x65, 0x7b, 0xba, 0xf4, 0x70, 0x11, 0x0e, 0x78, 0x9b, 0x1e, 0xdd, 0x7c, 0xbc, - 0x72, 0xca, 0xe6, 0xa5, 0xb5, 0x31, 0x18, 0x91, 0xda, 0xfd, 0x2d, 0x26, 0x6f, 0xab, 0xe1, 0xac, - 0x47, 0x4e, 0xd4, 0x0d, 0xc9, 0x3c, 0x8c, 0xee, 0x74, 0x98, 0xd2, 0x29, 0xcd, 0x22, 0xb6, 0xfa, - 0x6d, 0xbd, 0x69, 0x8e, 0x34, 0xb9, 0x00, 0xb1, 0x4d, 0x57, 0x20, 0x6b, 0x46, 0xde, 0x15, 0x73, - 0x70, 0x7b, 0x63, 0x1b, 0xf5, 0x16, 0x13, 0xf5, 0x96, 0x92, 0x63, 0x6d, 0xcd, 0x66, 0x0e, 0x9e, - 0xf5, 0x39, 0x5c, 0xda, 0xe9, 0x84, 0x34, 0x88, 0xaa, 0x9d, 0x4e, 0xdb, 0x6d, 0xf2, 0x1b, 0x32, - 0xb4, 0x02, 0xc8, 0xc5, 0xf2, 0x2e, 0x0c, 0x73, 0x80, 0x58, 0x26, 0x72, 0x0d, 0x56, 0x3b, 0x1d, - 0x61, 0x7b, 0x78, 0x8b, 0x4b, 0xfe, 0xdc, 0x9a, 0x60, 0x0b, 0x6c, 0xeb, 0xb7, 0x0b, 0x70, 0x89, - 0x7f, 0x01, 0xb9, 0xac, 0xbf, 0x0b, 0x63, 0xe8, 0xff, 0xd6, 0x71, 0x9a, 0xf2, 0x9b, 0xe0, 0x8e, - 0x80, 0x12, 0x68, 0xc7, 0xe5, 0x9a, 0x67, 0x61, 0x31, 0xdf, 0xb3, 0x50, 0x7e, 0x60, 0x03, 0x99, - 0x1f, 0xd8, 0x67, 0x60, 0x89, 0x16, 0xb5, 0xdb, 0xa9, 0x46, 0x85, 0x2f, 0xd2, 0x2a, 0xeb, 0xbf, - 0x14, 0x61, 0xee, 0x1e, 0xf5, 0x68, 0xe0, 0x60, 0x3f, 0x0d, 0x2b, 0x97, 0xee, 0x61, 0x54, 0xe8, - 0xe9, 0x61, 0x54, 0x91, 0x76, 0xc3, 0x22, 0xda, 0x0d, 0x53, 0xee, 0x52, 0x4c, 0x17, 0xdd, 0xb1, - 0x57, 0x45, 0xb7, 0x50, 0x17, 0xed, 0x06, 0x2e, 0xbf, 0x65, 0x58, 0x8d, 0xbd, 0x93, 0x06, 0xfb, - 0xda, 0x1c, 0xa6, 0x85, 0xb7, 0xc6, 0x88, 0xf0, 0x4e, 0x32, 0x7d, 0x92, 0x36, 0x60, 0x98, 0x9b, - 0x3b, 0xf1, 0x6e, 0x6b, 0x7c, 0xe1, 0x86, 0xf8, 0xa6, 0x72, 0x3a, 0x28, 0x6c, 0xa3, 0x78, 0xb0, - 0xf3, 0x25, 0x10, 0x21, 0xc0, 0x16, 0x5c, 0xe6, 0x3f, 0x83, 0x71, 0x0d, 0xe5, 0x38, 0x67, 0xbf, - 0x32, 0xbb, 0x32, 0x71, 0xd4, 0xdb, 0xe3, 0x16, 0x5c, 0xed, 0xec, 0xb7, 0x3e, 0x84, 0x72, 0xba, - 0x35, 0xc2, 0xd4, 0xd6, 0xcf, 0xb2, 0x67, 0x2d, 0xc1, 0xcc, 0x3d, 0x1a, 0xe1, 0xc2, 0xc5, 0x8f, - 0x48, 0xf3, 0xb2, 0x4b, 0x7c, 0x67, 0x72, 0x57, 0x45, 0x20, 0x5b, 0x60, 0xda, 0x57, 0x5a, 0x87, - 0xd9, 0x04, 0x17, 0x51, 0xff, 0x07, 0x30, 0x22, 0x40, 0x6a, 0x47, 0x15, 0xae, 0xba, 0xf4, 0x91, - 0x28, 0xd8, 0x5d, 0xe0, 0xeb, 0x56, 0x70, 0xb6, 0x25, 0x81, 0xb5, 0x0f, 0x67, 0xd9, 0x31, 0x1b, - 0x73, 0x55, 0xcb, 0xf1, 0x3c, 0x8c, 0x75, 0x98, 0xa0, 0x10, 0xba, 0x3f, 0xe1, 0xcb, 0x68, 0xc8, - 0x1e, 0x65, 0x80, 0xba, 0xfb, 0x13, 0x4a, 0x2e, 0x02, 0x60, 0x21, 0x76, 0x53, 0xec, 0x02, 0x88, - 0xce, 0x4d, 0x99, 0x04, 0xd0, 0x47, 0x8f, 0xaf, 0x1b, 0x1b, 0xff, 0xb6, 0x02, 0x98, 0x4b, 0xd5, - 0x24, 0x3a, 0x70, 0x0b, 0x46, 0xa5, 0x7c, 0x9c, 0xb8, 0x64, 0xd0, 0x7b, 0x60, 0x2b, 0x24, 0xf2, - 0x3a, 0x9c, 0xf6, 0xe8, 0x37, 0x51, 0x23, 0xd5, 0x86, 0x49, 0x06, 0xde, 0x92, 0xed, 0xb0, 0x7e, - 0x09, 0x0d, 0xcb, 0x75, 0xcf, 0x7f, 0xf6, 0xb8, 0xed, 0x3c, 0xa1, 0xa9, 0x8a, 0x7f, 0x00, 0xa3, - 0xf5, 0xfe, 0x15, 0xf3, 0xcf, 0x47, 0x56, 0x6e, 0x2b, 0x12, 0xab, 0x0d, 0xf3, 0xac, 0x4b, 0xf5, - 0xea, 0xfa, 0xda, 0x6a, 0x6b, 0xeb, 0xdb, 0x1e, 0xc0, 0xa7, 0x70, 0x3e, 0xb3, 0xb6, 0x6f, 0x7b, - 0x10, 0xff, 0x70, 0x10, 0xe6, 0xf8, 0x61, 0x92, 0x5e, 0xc1, 0xc7, 0xdf, 0x6a, 0x7e, 0x21, 0xf7, - 0xbd, 0xb7, 0x33, 0xee, 0x7b, 0x91, 0x44, 0xbf, 0xef, 0x35, 0x6e, 0x79, 0xdf, 0xcb, 0xbe, 0xe5, - 0x45, 0x23, 0x94, 0x79, 0xcb, 0x9b, 0xbc, 0xdb, 0x5d, 0xce, 0xbf, 0xdb, 0xc5, 0x8b, 0xa7, 0x8c, - 0xbb, 0xdd, 0xac, 0x1b, 0xdd, 0x84, 0xa3, 0xd4, 0xe8, 0xab, 0x75, 0x94, 0x7a, 0x1d, 0x46, 0xaa, - 0x9d, 0x8e, 0xe6, 0x78, 0x88, 0xd3, 0xe3, 0x74, 0x3a, 0x7c, 0xf0, 0x64, 0xa1, 0xdc, 0xe7, 0x21, - 0x63, 0x9f, 0x7f, 0x1f, 0x60, 0x11, 0x9f, 0x47, 0xe0, 0xc4, 0x8d, 0x23, 0x06, 0x4a, 0xf8, 0xfc, - 0xd1, 0x04, 0x4e, 0x9c, 0x6e, 0x5e, 0x89, 0x91, 0xb9, 0x60, 0x6f, 0xed, 0x42, 0x39, 0xbd, 0x7c, - 0x5e, 0xc1, 0xd6, 0xf5, 0x07, 0x05, 0xb8, 0x28, 0x84, 0x9c, 0xc4, 0x07, 0x7e, 0xf2, 0xd5, 0xf9, - 0x0e, 0x4c, 0x08, 0xda, 0xed, 0xf8, 0x43, 0xe0, 0x17, 0xec, 0x72, 0x33, 0xe6, 0x3b, 0xba, 0x81, - 0x46, 0xde, 0x81, 0x51, 0xfc, 0x23, 0xbe, 0x18, 0x62, 0x23, 0x33, 0x86, 0xa8, 0x8d, 0xe4, 0xf5, - 0x90, 0x42, 0xb5, 0xbe, 0x86, 0x4b, 0x79, 0x0d, 0x7f, 0x05, 0xe3, 0xf2, 0x2f, 0x0b, 0x70, 0x5e, - 0xb0, 0x37, 0xb6, 0x8a, 0x17, 0x3a, 0x75, 0x4e, 0xe0, 0xae, 0x7c, 0x1f, 0xc6, 0x59, 0x85, 0xb2, - 0xdd, 0x03, 0xe2, 0x68, 0x15, 0x9a, 0x43, 0x5c, 0xb2, 0xe4, 0x44, 0x8e, 0x70, 0xbf, 0x71, 0x0e, - 0xda, 0xd2, 0x32, 0x62, 0xeb, 0xc4, 0xd6, 0x97, 0x70, 0x21, 0xbb, 0x0b, 0xaf, 0x60, 0x7c, 0xee, - 0xc3, 0x7c, 0xc6, 0xa1, 0xf0, 0x62, 0x67, 0xf2, 0x17, 0x70, 0x3e, 0x93, 0xd7, 0x2b, 0x68, 0xe6, - 0x0a, 0x93, 0x38, 0xa2, 0x57, 0x30, 0x85, 0xd6, 0x43, 0x38, 0x97, 0xc1, 0xe9, 0x15, 0x34, 0xf1, - 0x1e, 0xcc, 0x29, 0x49, 0xfb, 0xa5, 0x5a, 0xb8, 0x0e, 0x17, 0x39, 0xa3, 0x57, 0x33, 0x2b, 0x0f, - 0xe0, 0xbc, 0x60, 0xf7, 0x0a, 0x46, 0x6f, 0x05, 0x2e, 0xc4, 0x0a, 0x75, 0x86, 0x9c, 0x74, 0xec, - 0x4d, 0xc6, 0x5a, 0x83, 0xcb, 0x31, 0xa7, 0x1c, 0xa1, 0xe1, 0xf8, 0xdc, 0xb8, 0x38, 0x18, 0xcf, - 0xd2, 0x2b, 0x99, 0xd1, 0x87, 0x70, 0xd6, 0x60, 0xfa, 0xca, 0x44, 0xa5, 0x55, 0x98, 0xe6, 0x8c, - 0x4d, 0xd1, 0x79, 0x41, 0x17, 0x9d, 0xc7, 0x17, 0xce, 0xc4, 0x2c, 0x11, 0xbc, 0xfb, 0x56, 0x86, - 0x34, 0xbd, 0x8e, 0xd2, 0xb4, 0x44, 0x89, 0x5b, 0xf8, 0x0e, 0x0c, 0x73, 0x88, 0x68, 0x5f, 0x06, - 0x33, 0xae, 0x2c, 0x70, 0x32, 0x81, 0x6c, 0xfd, 0x10, 0x2e, 0x72, 0x4d, 0x34, 0xbe, 0xa8, 0x34, - 0xb5, 0xc5, 0x1f, 0x24, 0x14, 0xd1, 0x73, 0x82, 0x6f, 0x12, 0x3f, 0x47, 0x1f, 0x7d, 0x24, 0xd7, - 0x76, 0x1e, 0xff, 0x63, 0x3d, 0x5d, 0x93, 0x0a, 0x66, 0x31, 0x53, 0xc1, 0xbc, 0x0a, 0x57, 0x94, - 0x82, 0x99, 0xac, 0x46, 0x2e, 0x2d, 0xeb, 0x4b, 0x38, 0xcf, 0x3b, 0x2a, 0x5d, 0x0a, 0xcd, 0x66, - 0x7c, 0x98, 0xe8, 0xe6, 0x9c, 0xe8, 0xa6, 0x89, 0x9d, 0xd3, 0xc9, 0xff, 0xaf, 0x20, 0x3f, 0xb9, - 0x6c, 0xe6, 0xbf, 0x68, 0x8d, 0x7b, 0x03, 0x2a, 0x6a, 0x40, 0xcc, 0x16, 0xbd, 0x98, 0xba, 0xbd, - 0x0e, 0xb3, 0x3a, 0x1b, 0xb7, 0x49, 0x77, 0xef, 0xe0, 0x0d, 0xd2, 0xdb, 0xec, 0xb3, 0x40, 0x80, - 0x5c, 0x76, 0xe5, 0x8c, 0x71, 0x43, 0x7c, 0x5b, 0x61, 0x5a, 0x0d, 0xb8, 0x90, 0x9e, 0x0a, 0xb7, - 0x29, 0xdf, 0x13, 0x90, 0x4f, 0xd8, 0x27, 0x8c, 0x10, 0x31, 0x19, 0xb9, 0x4c, 0xe5, 0x77, 0xcc, - 0xc9, 0x25, 0x95, 0x65, 0xc9, 0xad, 0x26, 0xd1, 0x7f, 0x56, 0xbb, 0x5c, 0x0f, 0xbf, 0x0a, 0x44, - 0x16, 0x2d, 0xd6, 0x6d, 0x59, 0xf5, 0x39, 0x18, 0x58, 0xac, 0xdb, 0xe2, 0x21, 0x13, 0x4a, 0x82, - 0xcd, 0x30, 0xb0, 0x19, 0x2c, 0x29, 0x91, 0x17, 0x8f, 0x21, 0x91, 0xdf, 0x1f, 0x1c, 0x1d, 0x28, - 0x0d, 0xda, 0xa4, 0xee, 0xee, 0x79, 0x0f, 0xdd, 0x68, 0x5f, 0x55, 0x58, 0xb5, 0xbe, 0x82, 0x69, - 0xa3, 0x7a, 0xf1, 0x15, 0xf7, 0x7c, 0x81, 0xc5, 0xe4, 0xd9, 0xc5, 0x2a, 0xba, 0xd5, 0xa0, 0xc9, - 0x62, 0x82, 0xef, 0x37, 0x4d, 0xa7, 0x81, 0xcf, 0x7b, 0x6d, 0x59, 0x68, 0xfd, 0xc3, 0x41, 0x8d, - 0xbb, 0xf6, 0xae, 0xad, 0x47, 0xef, 0xee, 0x00, 0xf0, 0x15, 0xa2, 0x75, 0x8e, 0x09, 0x80, 0xe3, - 0xc2, 0x5b, 0x85, 0x6f, 0xc9, 0xb6, 0x86, 0x74, 0xdc, 0x77, 0x6f, 0xc2, 0xff, 0x98, 0x13, 0xc9, - 0xa7, 0x9e, 0xca, 0xff, 0x58, 0xb0, 0x0e, 0x6d, 0x1d, 0x89, 0xfc, 0x30, 0xf9, 0x38, 0x63, 0x08, - 0x2f, 0xac, 0x5e, 0x93, 0x37, 0xd8, 0xe9, 0xbe, 0x9d, 0xec, 0x7d, 0xc6, 0x33, 0x98, 0x65, 0xb4, - 0xee, 0x63, 0x54, 0x2c, 0x96, 0xbf, 0x89, 0xa8, 0xc7, 0xf7, 0xf6, 0x61, 0xac, 0xe7, 0x5a, 0x8f, - 0x7a, 0x62, 0x64, 0x61, 0x7f, 0x8f, 0xf9, 0x34, 0xa8, 0x2a, 0xb3, 0xb3, 0xf9, 0xe3, 0x22, 0xb2, - 0xd7, 0x96, 0xbd, 0x56, 0xc7, 0x77, 0x95, 0xc2, 0xc4, 0x17, 0x51, 0xd0, 0x6e, 0x50, 0x01, 0xb7, - 0x75, 0x24, 0xeb, 0xf5, 0x9e, 0x5e, 0xed, 0xa3, 0x30, 0xb8, 0xbd, 0xb8, 0xbd, 0x56, 0x2a, 0x58, - 0xb7, 0x00, 0xb4, 0x9a, 0x00, 0x86, 0x37, 0x36, 0xed, 0xf5, 0xea, 0x5a, 0xe9, 0x14, 0x99, 0x85, - 0x33, 0x0f, 0x57, 0x37, 0x96, 0x36, 0x1f, 0xd6, 0x1b, 0xf5, 0xf5, 0xaa, 0xbd, 0xbd, 0x58, 0xb5, - 0x97, 0x4a, 0x05, 0xeb, 0x6b, 0x98, 0x31, 0x7b, 0xf8, 0x4a, 0x17, 0x61, 0x04, 0xd3, 0x4a, 0x9e, - 0xb9, 0xff, 0x70, 0x5b, 0xf3, 0x68, 0x15, 0xca, 0x5f, 0xd2, 0x33, 0x4b, 0xa8, 0x89, 0xe2, 0x33, - 0xd2, 0x90, 0xc8, 0x1b, 0x5c, 0x2c, 0x48, 0xbe, 0x5c, 0x66, 0x62, 0x41, 0x23, 0x96, 0x0b, 0x70, - 0xeb, 0xfb, 0x3e, 0xcc, 0x98, 0xb5, 0x1e, 0xd7, 0x4a, 0xf5, 0x1a, 0xba, 0xfa, 0x6a, 0xcf, 0x9a, - 0x08, 0xd1, 0xaf, 0x0d, 0xc4, 0xce, 0xfa, 0x7d, 0x28, 0x09, 0xac, 0xf8, 0xe4, 0xbd, 0x2a, 0xcd, - 0x88, 0x85, 0x8c, 0x47, 0x98, 0xd2, 0x29, 0xdd, 0x87, 0x12, 0xdb, 0x31, 0x05, 0x25, 0xaf, 0x60, - 0x06, 0x86, 0xd6, 0xe2, 0xeb, 0x1c, 0x9b, 0xff, 0xc0, 0xd7, 0x3d, 0x91, 0x13, 0x44, 0xd2, 0x0f, - 0x6e, 0xcc, 0x56, 0xbf, 0xc9, 0x1b, 0x30, 0x7c, 0xd7, 0x6d, 0x47, 0xc2, 0x34, 0x12, 0x1f, 0xf2, - 0x8c, 0x2d, 0x2f, 0xb0, 0x05, 0x82, 0x65, 0xc3, 0x19, 0xad, 0xc2, 0x13, 0x34, 0x95, 0x94, 0x61, - 0x64, 0x83, 0x7e, 0xa3, 0xd5, 0x2f, 0x7f, 0x5a, 0xef, 0xc2, 0x19, 0xe1, 0x63, 0xa8, 0x0d, 0xd3, - 0x15, 0xf1, 0x56, 0xbc, 0x60, 0x3c, 0x58, 0x15, 0x2c, 0xb1, 0x88, 0xd1, 0xed, 0x74, 0x5a, 0x2f, - 0x48, 0xc7, 0x0e, 0x8a, 0x13, 0xd2, 0x7d, 0x47, 0xde, 0x02, 0xf5, 0x9b, 0xce, 0xff, 0xab, 0x08, - 0xe5, 0x84, 0x95, 0x61, 0x71, 0xdf, 0x69, 0xb7, 0xa9, 0xb7, 0x47, 0xc9, 0x75, 0x18, 0xdc, 0xde, - 0xdc, 0xde, 0x12, 0x56, 0x52, 0xe9, 0x5d, 0xc0, 0x40, 0x0a, 0xc7, 0x46, 0x0c, 0xf2, 0x00, 0xce, - 0x48, 0x2f, 0x62, 0x55, 0x24, 0x66, 0xe8, 0x62, 0x6f, 0x9f, 0xe4, 0x34, 0x1d, 0x79, 0x5b, 0x98, - 0x44, 0x7e, 0xdc, 0x75, 0x03, 0xda, 0x42, 0xcb, 0x4f, 0x7c, 0x55, 0xaf, 0x95, 0xd8, 0x3a, 0x1a, - 0xf9, 0x3e, 0x4c, 0xd4, 0xeb, 0x9b, 0x71, 0xed, 0x43, 0xc6, 0x0d, 0x91, 0x5e, 0x64, 0x1b, 0x88, - 0xfc, 0x49, 0xb0, 0xf5, 0x87, 0x05, 0x98, 0xcb, 0x31, 0xb7, 0x90, 0x37, 0x8c, 0x71, 0x98, 0xd6, - 0xc6, 0x41, 0xa2, 0xac, 0x9c, 0x12, 0x03, 0xb1, 0xa8, 0xf9, 0x64, 0x0f, 0x9c, 0xc0, 0x27, 0x7b, - 0xe5, 0x54, 0xec, 0x87, 0x4d, 0x5e, 0x87, 0x81, 0x7a, 0x7d, 0x53, 0x98, 0xd5, 0x49, 0xdc, 0x03, - 0x0d, 0x99, 0x21, 0xd4, 0x00, 0x46, 0x25, 0xc8, 0x3a, 0x0d, 0x93, 0xc6, 0xc4, 0x58, 0x16, 0x4c, - 0xe8, 0x2d, 0x64, 0xb3, 0xbf, 0xe8, 0xb7, 0xd4, 0xec, 0xb3, 0xbf, 0xad, 0x5f, 0x35, 0xc7, 0x8c, - 0x5c, 0x04, 0x90, 0xf7, 0xb5, 0x6e, 0x4b, 0xde, 0xfc, 0x08, 0xc8, 0x6a, 0x8b, 0x5c, 0x81, 0x89, - 0x80, 0xb6, 0xdc, 0x80, 0x36, 0xa3, 0x46, 0x37, 0x10, 0x0f, 0x63, 0xec, 0x71, 0x09, 0xdb, 0x09, - 0xda, 0xe4, 0xbb, 0x30, 0xcc, 0x2f, 0x92, 0x45, 0xef, 0xa5, 0x92, 0x50, 0xaf, 0x6f, 0xae, 0xdf, - 0xad, 0xf2, 0x8b, 0x6e, 0x5b, 0xa0, 0x58, 0x35, 0x18, 0xd7, 0x7a, 0xd5, 0xaf, 0xf6, 0x19, 0x18, - 0xd2, 0xad, 0x94, 0xfc, 0x87, 0xf5, 0x3b, 0x05, 0x98, 0xc1, 0x65, 0xb0, 0xe7, 0xb2, 0xe3, 0x21, - 0xee, 0xcb, 0x82, 0x31, 0x69, 0x17, 0x8c, 0x49, 0x4b, 0xe0, 0xaa, 0xd9, 0xfb, 0x20, 0x35, 0x7b, - 0x17, 0xb2, 0x66, 0x0f, 0xb7, 0x00, 0xd7, 0xf7, 0xf4, 0x49, 0xd3, 0xaf, 0xeb, 0x7e, 0xb7, 0x00, - 0xd3, 0x5a, 0x9b, 0x54, 0x07, 0xef, 0x18, 0x4d, 0x3a, 0x9f, 0xd1, 0xa4, 0xd4, 0x7a, 0xaa, 0xa5, - 0x5a, 0xf4, 0x5a, 0xaf, 0x16, 0x65, 0x2d, 0x27, 0x63, 0x99, 0xfc, 0x45, 0x01, 0x66, 0x33, 0xc7, - 0x80, 0x9c, 0x65, 0xf2, 0x7f, 0x33, 0xa0, 0x91, 0x18, 0x79, 0xf1, 0x8b, 0xc1, 0x57, 0xc3, 0xb0, - 0x4b, 0x03, 0x31, 0xee, 0xe2, 0x17, 0x79, 0x0d, 0x26, 0xb7, 0x68, 0xe0, 0xfa, 0x2d, 0xfe, 0x30, - 0x81, 0x7b, 0xfc, 0x4e, 0xda, 0x26, 0x90, 0x5c, 0x80, 0x31, 0xe5, 0xb1, 0xca, 0x6d, 0xb8, 0x76, - 0x0c, 0x60, 0xbc, 0x97, 0xdc, 0x3d, 0x7e, 0xf1, 0xc3, 0x88, 0xc5, 0x2f, 0xb6, 0x01, 0x4b, 0x8b, - 0xea, 0x30, 0xdf, 0x80, 0xa5, 0xb9, 0xf4, 0x2c, 0x0c, 0x7f, 0x66, 0xe3, 0x3a, 0xc6, 0x98, 0x13, - 0xb6, 0xf8, 0x45, 0xa6, 0xd0, 0xb5, 0x1c, 0xdf, 0xc5, 0xa0, 0x4b, 0xf9, 0x07, 0x30, 0x93, 0x35, - 0xae, 0x59, 0x5f, 0x81, 0xa0, 0x2d, 0x2a, 0xda, 0x2f, 0x61, 0xba, 0xda, 0x6a, 0xc5, 0xcb, 0x95, - 0xcf, 0x2a, 0xdf, 0x27, 0xb8, 0x4d, 0x53, 0x88, 0xb5, 0x83, 0xab, 0x9e, 0x1b, 0xd9, 0xd3, 0xcb, - 0xdf, 0xb8, 0x61, 0xe4, 0x7a, 0x7b, 0x9a, 0xe1, 0xd5, 0x3e, 0xbb, 0x41, 0x9f, 0x65, 0x2c, 0x01, - 0x26, 0x71, 0x98, 0xbc, 0x39, 0x3c, 0x83, 0xf9, 0x8c, 0xc6, 0x36, 0xde, 0xba, 0xe6, 0x4c, 0xbe, - 0x71, 0xc1, 0x40, 0xb5, 0xf9, 0xc4, 0xfa, 0x3e, 0x9c, 0xe5, 0xdb, 0x7e, 0xaf, 0xc6, 0x8b, 0x66, - 0xeb, 0x76, 0x62, 0xeb, 0x3d, 0x69, 0xc9, 0xe9, 0xd9, 0x32, 0x7b, 0xc2, 0x68, 0x0b, 0x56, 0xf9, - 0x9f, 0x0b, 0x30, 0x9f, 0x20, 0xad, 0x3f, 0xf7, 0x9a, 0xf2, 0xcc, 0x79, 0x3d, 0xe9, 0xba, 0x8f, - 0xb2, 0x12, 0x37, 0x90, 0xba, 0x2d, 0xe5, 0xbd, 0x4f, 0x6e, 0x01, 0x70, 0x62, 0x4d, 0xc4, 0xc1, - 0xeb, 0x01, 0xe1, 0xe5, 0x84, 0x42, 0x8e, 0x86, 0x42, 0xba, 0x90, 0x35, 0xee, 0xe2, 0x1b, 0xe9, - 0x67, 0x3f, 0xc7, 0x38, 0x2b, 0x54, 0x90, 0x37, 0x72, 0x0c, 0xe9, 0x59, 0xfc, 0xad, 0xff, 0x7f, - 0x00, 0xe6, 0xf4, 0x09, 0x7c, 0x91, 0xbe, 0x6e, 0xc1, 0xf8, 0xa2, 0xef, 0x45, 0xf4, 0x9b, 0x48, - 0x8b, 0x73, 0x41, 0x94, 0x37, 0x82, 0x2a, 0x11, 0xe2, 0x35, 0x07, 0x34, 0x98, 0xac, 0x67, 0x78, - 0x6b, 0xc6, 0x88, 0x64, 0x11, 0x26, 0x37, 0xe8, 0xb3, 0xd4, 0x00, 0xa2, 0xc7, 0xa8, 0x47, 0x9f, - 0x35, 0xb4, 0x41, 0xd4, 0xdd, 0xf8, 0x0c, 0x1a, 0xf2, 0x08, 0xa6, 0xe4, 0xe2, 0x32, 0x06, 0x73, - 0x5e, 0x3f, 0x79, 0xcd, 0xe5, 0xcc, 0xe3, 0x40, 0xb0, 0x1a, 0x72, 0xc6, 0x30, 0xc1, 0x91, 0x75, - 0x9d, 0xd7, 0xc8, 0x43, 0x1b, 0x98, 0x47, 0xbb, 0x56, 0x62, 0xf8, 0xe3, 0x26, 0x43, 0x1a, 0xe8, - 0x2c, 0xac, 0x2d, 0x28, 0xa7, 0xe7, 0x43, 0xd4, 0xf6, 0x36, 0x0c, 0x73, 0xa8, 0x10, 0x95, 0x64, - 0x08, 0x23, 0x85, 0xcd, 0x6d, 0x19, 0x2d, 0x71, 0x2a, 0x71, 0x98, 0xb5, 0x82, 0xf6, 0x25, 0x85, - 0xa3, 0x84, 0xd5, 0xdb, 0xc9, 0xe9, 0x45, 0x57, 0x67, 0x39, 0xbd, 0xba, 0x2f, 0x8e, 0x7c, 0x92, - 0xb2, 0x88, 0x26, 0x3a, 0x9d, 0x93, 0x68, 0xd8, 0x0d, 0x18, 0x11, 0xa0, 0x44, 0x70, 0xa5, 0xf8, - 0xf3, 0x93, 0x08, 0xd6, 0x07, 0x70, 0x0e, 0xed, 0x85, 0xae, 0xb7, 0xd7, 0xa6, 0x3b, 0xa1, 0xf1, - 0xa8, 0xa4, 0xdf, 0x67, 0xfd, 0x11, 0xcc, 0x67, 0xd1, 0xf6, 0xfd, 0xb2, 0x79, 0xb8, 0x93, 0x3f, - 0x2b, 0xc2, 0xcc, 0x6a, 0xa8, 0x0b, 0x5c, 0x2a, 0xe4, 0x49, 0x46, 0x18, 0x0e, 0x1c, 0x93, 0x95, - 0x53, 0x59, 0x61, 0x36, 0xde, 0xd6, 0x9e, 0xbb, 0x16, 0x7b, 0xc5, 0xd7, 0x60, 0xc7, 0x96, 0x7a, - 0xf0, 0xfa, 0x3a, 0x0c, 0x6e, 0xb0, 0xad, 0x7a, 0x40, 0xcc, 0x1d, 0xa7, 0x60, 0x20, 0x7c, 0x6e, - 0xca, 0x8e, 0x48, 0xf6, 0x83, 0xdc, 0x4d, 0x3d, 0x6a, 0x1d, 0xec, 0x1f, 0x3f, 0x62, 0xe5, 0x54, - 0xea, 0x7d, 0xeb, 0xbb, 0x30, 0x5e, 0x6d, 0x1d, 0x70, 0x97, 0x4c, 0xdf, 0x4b, 0x7c, 0x96, 0x5a, - 0xc9, 0xca, 0x29, 0x5b, 0x47, 0x24, 0xd7, 0xf8, 0xab, 0x86, 0xe1, 0x9c, 0x98, 0x1a, 0x4c, 0x58, - 0xab, 0x76, 0x3a, 0xb5, 0x51, 0x18, 0xe6, 0x0f, 0x2d, 0xad, 0x2f, 0x61, 0x5e, 0x38, 0xf2, 0x70, - 0xeb, 0x28, 0xba, 0xfb, 0x84, 0xb1, 0xaf, 0x56, 0x2f, 0xe7, 0x9b, 0x4b, 0x00, 0xa8, 0x0b, 0xad, - 0x7a, 0x2d, 0xfa, 0x8d, 0xf0, 0x24, 0xd4, 0x20, 0xd6, 0x3b, 0x30, 0xa6, 0x46, 0x08, 0x05, 0x7e, - 0xed, 0xb0, 0xc3, 0xd1, 0x9a, 0x31, 0x5e, 0xf1, 0xca, 0xa7, 0xbb, 0xe7, 0x8c, 0xbe, 0x8b, 0x28, - 0x39, 0x5c, 0x43, 0x70, 0x61, 0x36, 0xb1, 0x08, 0xe2, 0x20, 0x0c, 0x4a, 0x46, 0xe7, 0xae, 0x8e, - 0xea, 0x77, 0x52, 0x84, 0x2f, 0x1e, 0x4b, 0x84, 0xb7, 0xfe, 0x49, 0x11, 0x95, 0xcb, 0xd4, 0x78, - 0x24, 0xec, 0x74, 0xba, 0xad, 0xb0, 0x06, 0x63, 0xd8, 0xfb, 0x25, 0xf9, 0x60, 0xb0, 0xb7, 0x1f, - 0xca, 0xe8, 0x4f, 0x0f, 0x2b, 0xa7, 0xd0, 0xf9, 0x24, 0x26, 0x23, 0x1f, 0xc3, 0xc8, 0xb2, 0xd7, - 0x42, 0x0e, 0x03, 0x27, 0xe0, 0x20, 0x89, 0xd8, 0x9c, 0x60, 0x93, 0xb7, 0xd9, 0x27, 0xcc, 0xcd, - 0x3b, 0xb6, 0x06, 0x89, 0xb5, 0xdc, 0xa1, 0x3c, 0x2d, 0x77, 0x38, 0xa1, 0xe5, 0x5a, 0x30, 0xb4, - 0x19, 0xb4, 0x44, 0x6c, 0x9b, 0xa9, 0x85, 0x09, 0x31, 0x70, 0x08, 0xb3, 0x79, 0x91, 0xf5, 0x5f, - 0x0b, 0x30, 0x77, 0x8f, 0x46, 0x99, 0x6b, 0xc8, 0x18, 0x95, 0xc2, 0x4b, 0x8f, 0x4a, 0xf1, 0x45, - 0x46, 0x45, 0xf5, 0x7a, 0x20, 0xaf, 0xd7, 0x83, 0x79, 0xbd, 0x1e, 0xca, 0xef, 0xf5, 0x3d, 0x18, - 0xe6, 0x5d, 0x65, 0x9a, 0xfc, 0x6a, 0x44, 0x0f, 0x62, 0x4d, 0x5e, 0xf7, 0xa2, 0xb3, 0x79, 0x19, - 0x13, 0x24, 0xd7, 0x9c, 0x50, 0xd7, 0xe4, 0xc5, 0x4f, 0xeb, 0x47, 0xf8, 0xd4, 0x78, 0xcd, 0x6f, - 0x3e, 0xd1, 0x2c, 0xc2, 0x23, 0xfc, 0x0b, 0x4d, 0xde, 0x20, 0x30, 0x2c, 0x5e, 0x62, 0x4b, 0x0c, - 0x72, 0x19, 0xc6, 0x57, 0xbd, 0xbb, 0x7e, 0xd0, 0xa4, 0x9b, 0x5e, 0x9b, 0x73, 0x1f, 0xb5, 0x75, - 0x90, 0xb0, 0x94, 0x88, 0x1a, 0x62, 0xf3, 0x03, 0x02, 0x12, 0xe6, 0x07, 0x06, 0xdb, 0x5d, 0xb0, - 0x79, 0x99, 0x30, 0xc4, 0xb0, 0xbf, 0x7b, 0x69, 0xee, 0x4a, 0xc5, 0xef, 0x87, 0xf8, 0x08, 0xce, - 0xd9, 0xb4, 0xd3, 0x76, 0x98, 0x4c, 0x77, 0xe0, 0x73, 0x7c, 0xd5, 0xe7, 0xcb, 0x19, 0xcf, 0x04, - 0x4d, 0x9f, 0x0a, 0xd5, 0xe4, 0x62, 0x8f, 0x26, 0x1f, 0xc0, 0x95, 0x7b, 0x34, 0x32, 0x37, 0xd4, - 0xd8, 0xde, 0x2c, 0x3a, 0xbf, 0x02, 0xa3, 0xa1, 0x69, 0x2b, 0x97, 0xcf, 0xde, 0x32, 0x09, 0x77, - 0xdf, 0x92, 0xb7, 0x49, 0x82, 0x8f, 0xfa, 0xcb, 0xfa, 0x04, 0x2a, 0x79, 0xd5, 0x1d, 0xcf, 0xe5, - 0xd5, 0x85, 0xcb, 0xf9, 0x0c, 0x44, 0x73, 0x97, 0x41, 0xda, 0xd5, 0xc5, 0x27, 0xd4, 0xaf, 0xb5, - 0xa6, 0x29, 0x5e, 0xfc, 0x61, 0xd5, 0xa4, 0xf3, 0xdf, 0x4b, 0x34, 0xb7, 0x81, 0x57, 0xd6, 0x26, - 0x83, 0x78, 0x5c, 0xab, 0x30, 0x2a, 0x61, 0x62, 0x5c, 0xe7, 0x32, 0x5b, 0x2a, 0x07, 0xb4, 0x25, - 0x19, 0x28, 0x32, 0xeb, 0x47, 0xf2, 0xfa, 0xc6, 0xa4, 0x38, 0xde, 0xbb, 0xd9, 0xe3, 0xdc, 0xd7, - 0x58, 0x3e, 0x9c, 0x33, 0x79, 0xeb, 0x66, 0xf9, 0x92, 0x66, 0x96, 0xe7, 0xd6, 0xf8, 0xcb, 0xa6, - 0x99, 0x58, 0x58, 0x1a, 0x34, 0x10, 0xb9, 0xa4, 0x1b, 0xdf, 0x27, 0xd2, 0x0f, 0x71, 0x6f, 0xc3, - 0x7c, 0x56, 0x85, 0x9a, 0x1e, 0xa8, 0x2c, 0xbc, 0x42, 0xde, 0x59, 0x82, 0x4b, 0x32, 0xba, 0x94, - 0xef, 0x47, 0x61, 0x14, 0x38, 0x9d, 0x7a, 0x33, 0x70, 0x3b, 0x31, 0x95, 0x05, 0xc3, 0x1c, 0x22, - 0x46, 0x82, 0x5f, 0x85, 0x71, 0x1c, 0x51, 0x62, 0xfd, 0x7a, 0x01, 0x2c, 0xc3, 0x4f, 0x0b, 0xe7, - 0x79, 0x2b, 0xf0, 0x9f, 0xba, 0x2d, 0xed, 0xfa, 0xe9, 0x0d, 0xc3, 0xf4, 0xc9, 0xdf, 0x24, 0x26, - 0x5d, 0xc4, 0xc5, 0x9e, 0x79, 0x3b, 0x61, 0x8e, 0xe4, 0x82, 0x27, 0xfa, 0x6e, 0x99, 0x0f, 0x22, - 0x94, 0x99, 0xf2, 0xbf, 0x17, 0xe0, 0x6a, 0xcf, 0x36, 0x88, 0xfe, 0x3c, 0x82, 0x52, 0xb2, 0x4c, - 0xac, 0xa0, 0x8a, 0xe6, 0xb7, 0x91, 0xe6, 0xb0, 0x7b, 0x87, 0xfb, 0xa1, 0x4b, 0xff, 0xa6, 0x8e, - 0xe2, 0x9c, 0xe2, 0x77, 0xf2, 0xd6, 0x63, 0xfc, 0x0a, 0x3f, 0x72, 0xda, 0x8b, 0x68, 0x00, 0x18, - 0x88, 0xdf, 0x14, 0x44, 0x0c, 0xda, 0x48, 0x86, 0xc9, 0xd0, 0x90, 0xad, 0x4f, 0xf1, 0xbb, 0xce, - 0x6e, 0xf4, 0xf1, 0x3e, 0xb5, 0x45, 0xb8, 0x9a, 0xf0, 0x1d, 0x78, 0x01, 0x26, 0x11, 0xcc, 0xb2, - 0xe1, 0x67, 0xb2, 0xf7, 0xbd, 0xc0, 0xef, 0x76, 0x7e, 0x31, 0xb3, 0xfe, 0x47, 0x05, 0xee, 0xcc, - 0xa9, 0x57, 0x2b, 0x26, 0x7a, 0x11, 0x20, 0x86, 0x26, 0x9c, 0xfa, 0x55, 0xc1, 0xee, 0x1d, 0xae, - 0x72, 0xe3, 0xad, 0xc2, 0x1e, 0x67, 0xa0, 0x91, 0xfd, 0x62, 0x67, 0xf2, 0x2d, 0x74, 0x18, 0x50, - 0xb5, 0x1f, 0x6f, 0xdc, 0xdf, 0x95, 0xf6, 0x8f, 0x13, 0xd2, 0xed, 0xc3, 0x0c, 0xdb, 0x01, 0xaa, - 0xdd, 0x68, 0xdf, 0x0f, 0xdc, 0x48, 0x3e, 0x4f, 0x21, 0x5b, 0x22, 0x22, 0x00, 0xa7, 0xfa, 0xe8, - 0xe7, 0x87, 0x95, 0xf7, 0x4e, 0x12, 0xf7, 0x53, 0xf2, 0xdc, 0x56, 0x51, 0x04, 0xac, 0x39, 0x18, - 0x58, 0xb4, 0xd7, 0x70, 0xc3, 0xb3, 0xd7, 0xd4, 0x86, 0x67, 0xaf, 0x59, 0x7f, 0x59, 0x84, 0x0a, - 0x8f, 0x59, 0x82, 0x7e, 0x26, 0xb1, 0xd5, 0x42, 0x73, 0x5c, 0x39, 0xae, 0x81, 0x21, 0x11, 0x93, - 0xa4, 0x78, 0x9c, 0x98, 0x24, 0xbf, 0x02, 0x39, 0x26, 0xab, 0x63, 0x58, 0x01, 0xbe, 0x73, 0x74, - 0x58, 0xb9, 0x1a, 0x5b, 0x01, 0x78, 0x69, 0x96, 0x39, 0x20, 0xa7, 0x8a, 0xb4, 0xfd, 0x62, 0xf0, - 0x05, 0xec, 0x17, 0xb7, 0x61, 0x04, 0x95, 0x99, 0xd5, 0x2d, 0xe1, 0xf9, 0x89, 0xcb, 0x13, 0x23, - 0x14, 0x35, 0x5c, 0x3d, 0x1c, 0xa0, 0x44, 0xb3, 0xfe, 0x76, 0x11, 0x2e, 0xe7, 0x8f, 0xb9, 0x68, - 0xdb, 0x12, 0x40, 0xec, 0xe1, 0xd2, 0xcb, 0xa3, 0x06, 0xbf, 0x9d, 0x67, 0xf4, 0x91, 0xf2, 0x68, - 0xd3, 0xe8, 0x98, 0xec, 0x23, 0x5f, 0x5a, 0x27, 0xae, 0x53, 0x8c, 0x07, 0xd8, 0x22, 0x9a, 0xad, - 0x00, 0x19, 0xd1, 0x6c, 0x05, 0x8c, 0x3c, 0x82, 0xb9, 0xad, 0xc0, 0x7d, 0xea, 0x44, 0xf4, 0x01, - 0x7d, 0xce, 0x1f, 0x0b, 0x2d, 0x8b, 0x17, 0x42, 0xfc, 0xf9, 0xfc, 0xf5, 0xa3, 0xc3, 0xca, 0x6b, - 0x1d, 0x8e, 0x82, 0x11, 0xcb, 0xf8, 0xdb, 0xcf, 0x46, 0xfa, 0xd1, 0x50, 0x1e, 0x23, 0xeb, 0x5f, - 0x17, 0xe0, 0x3c, 0x8a, 0xe5, 0xc2, 0xec, 0x2a, 0x2b, 0x7f, 0x21, 0xc7, 0x4a, 0xbd, 0x83, 0x62, - 0x2d, 0xa2, 0x63, 0xa5, 0xf1, 0x12, 0xdd, 0x36, 0xd0, 0xc8, 0x2a, 0x8c, 0x8b, 0xdf, 0xf8, 0xfd, - 0x0d, 0xa0, 0x42, 0x30, 0xab, 0x6d, 0x58, 0xb8, 0xd4, 0xb9, 0xa9, 0x08, 0x17, 0xb6, 0x60, 0x86, - 0x0f, 0x36, 0x6d, 0x9d, 0xd6, 0xfa, 0x59, 0x11, 0x2e, 0xec, 0xd2, 0xc0, 0x7d, 0xfc, 0x3c, 0xa7, - 0x33, 0x9b, 0x30, 0x23, 0x41, 0x3c, 0x6e, 0x89, 0xf1, 0x89, 0xf1, 0x78, 0x96, 0xb2, 0xa9, 0x22, - 0xf0, 0x89, 0xfc, 0xe2, 0x32, 0x09, 0x4f, 0xe0, 0x32, 0xf9, 0x36, 0x8c, 0x26, 0x22, 0x07, 0xe1, - 0xfc, 0xcb, 0x2f, 0x34, 0x9e, 0xaa, 0x95, 0x53, 0xb6, 0xc2, 0x24, 0xbf, 0x99, 0x7f, 0x55, 0x25, - 0x4c, 0x1f, 0xfd, 0xec, 0x9f, 0xf8, 0xc1, 0xb2, 0x8f, 0xd5, 0xd1, 0x4a, 0x33, 0x3e, 0xd8, 0x95, - 0x53, 0x76, 0x5e, 0x4d, 0xb5, 0x71, 0x18, 0xab, 0xe2, 0xbd, 0x1d, 0xd3, 0xdc, 0xff, 0x5b, 0x11, - 0x2e, 0xc9, 0x87, 0x3f, 0x39, 0xc3, 0xfc, 0x39, 0xcc, 0x49, 0x50, 0xb5, 0xc3, 0x04, 0x06, 0xda, - 0x32, 0x47, 0x9a, 0xc7, 0x94, 0x95, 0x23, 0xed, 0x08, 0x9c, 0x78, 0xb0, 0xf3, 0xc8, 0x5f, 0x8d, - 0xf5, 0xf3, 0xe3, 0xac, 0x38, 0x4e, 0x68, 0x85, 0xd4, 0xf7, 0x4c, 0x63, 0x68, 0x8c, 0xfd, 0xb3, - 0x95, 0xb2, 0x9e, 0x0e, 0xbe, 0xac, 0xf5, 0x74, 0xe5, 0x54, 0xd2, 0x7e, 0x5a, 0x9b, 0x82, 0x89, - 0x0d, 0xfa, 0x2c, 0x1e, 0xf7, 0xff, 0xb3, 0x90, 0x08, 0xf5, 0xc0, 0x24, 0x0c, 0x1e, 0xf3, 0xa1, - 0x10, 0x87, 0x02, 0xc2, 0x50, 0x0f, 0xba, 0x84, 0xc1, 0x51, 0x57, 0x61, 0x84, 0x5f, 0x66, 0xb7, - 0x8e, 0xa1, 0xe1, 0xab, 0x17, 0x3c, 0xfc, 0x59, 0x65, 0x8b, 0x2b, 0xfb, 0x82, 0xde, 0x7a, 0x00, - 0x57, 0x84, 0x8f, 0xb7, 0x39, 0xf9, 0x58, 0xd1, 0x09, 0x8f, 0x2f, 0xcb, 0x81, 0x4b, 0xf7, 0x68, - 0x72, 0xeb, 0x31, 0x5e, 0x38, 0x7d, 0x02, 0xa7, 0x0d, 0xb8, 0xe2, 0x88, 0x52, 0xa9, 0x5a, 0x43, - 0x8a, 0x75, 0x12, 0xdb, 0xba, 0x9c, 0x55, 0x85, 0xde, 0x58, 0x8b, 0x62, 0x70, 0xd8, 0x20, 0xbe, - 0x62, 0x0b, 0x4f, 0xb0, 0xeb, 0x5d, 0xd7, 0xbe, 0x6b, 0xbe, 0xe3, 0xf1, 0xe8, 0x81, 0xf2, 0xe4, - 0x55, 0xa5, 0xd6, 0xa4, 0x71, 0x17, 0x60, 0x4d, 0xc1, 0x84, 0x2c, 0x6a, 0xd3, 0x30, 0xb4, 0xfe, - 0xc3, 0x10, 0x58, 0x62, 0x60, 0xb3, 0x6e, 0xe8, 0xe5, 0x78, 0x3c, 0x4a, 0x35, 0x56, 0x1c, 0x54, - 0x67, 0xf5, 0x98, 0xa4, 0x71, 0x29, 0x5f, 0x79, 0x28, 0xe7, 0x35, 0x63, 0xa8, 0xb1, 0xf2, 0x52, - 0xbd, 0xff, 0x2a, 0x67, 0x9b, 0xe4, 0x1f, 0x1b, 0x3e, 0xd9, 0xce, 0xd9, 0x26, 0x0d, 0xbe, 0xd9, - 0x5b, 0xa6, 0x6d, 0x5e, 0x89, 0x0c, 0xbc, 0xc8, 0x95, 0x08, 0xfb, 0x22, 0xf5, 0x4b, 0x91, 0x1d, - 0x73, 0x2c, 0xc5, 0xf7, 0x28, 0x6f, 0xef, 0xf5, 0x22, 0x11, 0x71, 0x41, 0x83, 0x18, 0x5c, 0x0d, - 0x36, 0xc4, 0x85, 0x92, 0x66, 0xb3, 0x5c, 0xdc, 0xa7, 0xcd, 0x27, 0xc2, 0x56, 0x2c, 0x2f, 0x74, - 0xb3, 0x6c, 0xe6, 0x3c, 0x3e, 0x35, 0xff, 0xce, 0x79, 0x41, 0xa3, 0xc9, 0x48, 0xf5, 0x88, 0x11, - 0x49, 0xb6, 0xe4, 0x27, 0x30, 0xad, 0xa6, 0x3a, 0xe1, 0xa2, 0x35, 0xbe, 0xf0, 0x5a, 0x1c, 0xca, - 0xf4, 0xe0, 0xb1, 0x73, 0xf3, 0xe9, 0x9d, 0x9b, 0x19, 0xb8, 0x3c, 0x10, 0x41, 0x53, 0x16, 0x68, - 0xfe, 0x59, 0xfa, 0x45, 0x57, 0x06, 0x21, 0xf9, 0x02, 0x66, 0xea, 0xf5, 0x4d, 0xfe, 0x98, 0xc3, - 0x96, 0x17, 0xfc, 0xf6, 0x9a, 0x70, 0xd8, 0xc2, 0xe9, 0x0e, 0x43, 0xbf, 0x21, 0x1e, 0x81, 0xe8, - 0x6e, 0x01, 0x7a, 0x28, 0x86, 0x2c, 0x16, 0xfa, 0x4d, 0xf9, 0xdf, 0x54, 0x6f, 0x15, 0x98, 0x28, - 0xe2, 0xb6, 0xa9, 0x78, 0x74, 0x24, 0x17, 0x76, 0xce, 0x2d, 0x5f, 0xe1, 0x5b, 0xbe, 0xe5, 0xfb, - 0xfd, 0xa2, 0x7c, 0xa1, 0x91, 0xbe, 0x68, 0x3d, 0xf1, 0x65, 0x5f, 0x66, 0x0f, 0x8e, 0x75, 0x4e, - 0x67, 0x36, 0x8e, 0xd4, 0xe4, 0x55, 0xa9, 0x0a, 0x56, 0x36, 0xa5, 0xae, 0x1d, 0xe2, 0x02, 0xe3, - 0xf6, 0x14, 0xa5, 0x22, 0x8d, 0x2a, 0x79, 0x0f, 0x37, 0xf0, 0xf2, 0xf7, 0x70, 0xff, 0x7c, 0x0c, - 0xce, 0x6c, 0x39, 0x7b, 0xae, 0xc7, 0xce, 0x03, 0x9b, 0x86, 0x7e, 0x37, 0x68, 0x52, 0x52, 0x85, - 0x29, 0xd3, 0xfd, 0xb6, 0x8f, 0x73, 0x31, 0x3b, 0xf2, 0x4c, 0x18, 0x59, 0x80, 0x31, 0xf5, 0xe4, - 0x57, 0x9c, 0x53, 0x19, 0x4f, 0x81, 0x57, 0x4e, 0xd9, 0x31, 0x1a, 0x79, 0xdf, 0xb8, 0x3a, 0x3a, - 0xad, 0x5e, 0xaf, 0x23, 0xee, 0x02, 0xf7, 0x8f, 0xf4, 0xfc, 0x96, 0x79, 0xd6, 0xf2, 0xfb, 0x91, - 0x1f, 0xa5, 0x6e, 0x93, 0x86, 0x8c, 0x16, 0xa7, 0x4c, 0x6a, 0x28, 0x66, 0xe4, 0xc6, 0x1e, 0xcf, - 0xb8, 0x67, 0xfa, 0x12, 0xc6, 0x1f, 0x74, 0x1f, 0x51, 0x79, 0x6f, 0x36, 0x2c, 0x8e, 0xde, 0xa4, - 0x53, 0xb9, 0x28, 0xdf, 0x7d, 0x8b, 0xcf, 0xc1, 0x93, 0xee, 0x23, 0x9a, 0x0e, 0x6a, 0xcf, 0xf6, - 0x3c, 0x8d, 0x19, 0xd9, 0x87, 0x52, 0xd2, 0xff, 0x5b, 0x84, 0xf7, 0xeb, 0xe1, 0xb5, 0x8e, 0x61, - 0x5a, 0xb4, 0xd0, 0xf9, 0xdc, 0x2b, 0xd5, 0xa8, 0x24, 0xc5, 0x95, 0xfc, 0x2a, 0xcc, 0x66, 0x1a, - 0x34, 0xd5, 0x0b, 0xb6, 0xde, 0xb6, 0x52, 0xdc, 0x40, 0x12, 0xa3, 0x26, 0x9f, 0xcb, 0x19, 0x35, - 0x67, 0xd7, 0x42, 0x5a, 0x70, 0x3a, 0xe1, 0xd7, 0x2c, 0xf2, 0x83, 0xe4, 0x7b, 0x4a, 0xe3, 0x99, - 0x27, 0x43, 0xec, 0x66, 0xd6, 0x95, 0x64, 0x49, 0xd6, 0x60, 0x4c, 0x59, 0x12, 0x44, 0x64, 0xb5, - 0x2c, 0xab, 0x49, 0xf9, 0xe8, 0xb0, 0x32, 0x13, 0x5b, 0x4d, 0x0c, 0x9e, 0x31, 0x03, 0xf2, 0x6b, - 0x70, 0x45, 0x2d, 0xd1, 0xcd, 0x20, 0xdb, 0xbe, 0x24, 0x42, 0xf3, 0xdf, 0x48, 0xae, 0xf0, 0x3c, - 0xfc, 0xdd, 0x3b, 0xb5, 0x62, 0xb9, 0xb0, 0x72, 0xca, 0xee, 0xcf, 0x9a, 0xfc, 0x46, 0x01, 0xce, - 0xe6, 0xd4, 0x3a, 0x81, 0xb5, 0xf6, 0x35, 0xfa, 0xa1, 0xde, 0x80, 0xaf, 0xb6, 0xdc, 0x56, 0xfc, - 0xba, 0x51, 0x5a, 0xff, 0x8c, 0x7e, 0xe7, 0xd4, 0x44, 0xde, 0x84, 0x61, 0x54, 0xbf, 0xc3, 0xf2, - 0x24, 0x0a, 0xa8, 0x18, 0x9d, 0x08, 0x95, 0x74, 0xfd, 0x48, 0x12, 0x38, 0x64, 0x85, 0x09, 0x7a, - 0x78, 0x24, 0x4a, 0xc1, 0x4c, 0xc4, 0x32, 0x13, 0xca, 0x02, 0x2f, 0x92, 0x41, 0x46, 0x8c, 0x1c, - 0x0c, 0x26, 0x59, 0x0d, 0x60, 0x34, 0x10, 0xbb, 0xd2, 0xfd, 0xc1, 0xd1, 0xc1, 0xd2, 0x10, 0xff, - 0x70, 0xa4, 0xc3, 0xfc, 0x6f, 0x8d, 0xf2, 0xd7, 0xb5, 0x3b, 0x9e, 0xfb, 0xd8, 0x8d, 0x37, 0x30, - 0xdd, 0x70, 0x17, 0x27, 0x43, 0x12, 0x62, 0x75, 0x4e, 0xda, 0x23, 0x65, 0xe3, 0x2b, 0xf6, 0xb5, - 0xf1, 0xbd, 0xa5, 0xdd, 0x86, 0x69, 0x31, 0x4b, 0xb9, 0xf8, 0x64, 0xda, 0xd4, 0xe2, 0x6b, 0xb2, - 0xaf, 0x61, 0x18, 0xc3, 0x8c, 0xf2, 0xab, 0xc6, 0xf1, 0x85, 0x9b, 0x62, 0xdb, 0xee, 0xd1, 0x7c, - 0x1e, 0x97, 0x54, 0xbc, 0x98, 0xe7, 0x23, 0x8e, 0x00, 0x63, 0xc4, 0x11, 0x42, 0xb6, 0x61, 0x7a, - 0x8b, 0x9d, 0xe6, 0xdc, 0x6d, 0xbb, 0x13, 0x08, 0xbb, 0x07, 0xb7, 0xa8, 0xa0, 0x34, 0xd1, 0x91, - 0xc5, 0x0d, 0xaa, 0xca, 0xf5, 0x03, 0x35, 0x83, 0x9c, 0x2c, 0xc3, 0x54, 0x9d, 0x3a, 0x41, 0x73, - 0xff, 0x01, 0x7d, 0xce, 0x24, 0x29, 0x23, 0xff, 0x47, 0x88, 0x25, 0xac, 0xbf, 0x58, 0xa4, 0xbb, - 0x8f, 0x98, 0x44, 0xe4, 0x53, 0x18, 0xae, 0xfb, 0x41, 0x54, 0x7b, 0x2e, 0x36, 0x35, 0x79, 0x19, - 0xc5, 0x81, 0xb5, 0x73, 0x32, 0x07, 0x4a, 0xe8, 0x07, 0x51, 0xe3, 0x91, 0x11, 0xee, 0x8a, 0xa3, - 0x90, 0xe7, 0x30, 0x63, 0x6e, 0x28, 0xc2, 0x9b, 0x78, 0x54, 0x48, 0x70, 0x59, 0xbb, 0x16, 0x47, - 0xa9, 0x5d, 0x17, 0xdc, 0x2f, 0x27, 0xb7, 0xad, 0xc7, 0x58, 0xae, 0x8b, 0x3d, 0x59, 0xf4, 0x64, - 0x1d, 0x93, 0xc7, 0xf0, 0x1e, 0x55, 0x43, 0xee, 0x85, 0x3c, 0x16, 0x07, 0x54, 0xeb, 0xe2, 0xa6, - 0x84, 0x23, 0xe1, 0x84, 0xc9, 0x8c, 0x43, 0x76, 0x8a, 0x94, 0x6c, 0xc1, 0x99, 0x9d, 0x90, 0x6e, - 0x05, 0xf4, 0xa9, 0x4b, 0x9f, 0x49, 0x7e, 0x10, 0x47, 0x9f, 0x62, 0xfc, 0x3a, 0xbc, 0x34, 0x8b, - 0x61, 0x9a, 0x98, 0xbc, 0x0f, 0xb0, 0xe5, 0x7a, 0x1e, 0x6d, 0xe1, 0x8d, 0xe6, 0x38, 0xb2, 0x42, - 0x6b, 0x6d, 0x07, 0xa1, 0x0d, 0xdf, 0x6b, 0xeb, 0x43, 0xaa, 0x21, 0x93, 0x1a, 0x4c, 0xae, 0x7a, - 0xcd, 0x76, 0x57, 0x78, 0x1e, 0x84, 0xb8, 0xa1, 0x88, 0xa8, 0x78, 0x2e, 0x2f, 0x68, 0xa4, 0x3e, - 0x72, 0x93, 0x84, 0x3c, 0x00, 0x22, 0x00, 0x62, 0xd5, 0x3a, 0x8f, 0xda, 0x54, 0x7c, 0xee, 0x68, - 0x85, 0x91, 0x8c, 0x70, 0xb9, 0x1b, 0xc1, 0xe6, 0x52, 0x64, 0xf3, 0xef, 0xc3, 0xb8, 0xb6, 0xe6, - 0x33, 0x42, 0x40, 0xcc, 0xe8, 0x21, 0x20, 0xc6, 0xf4, 0x50, 0x0f, 0xff, 0xa0, 0x00, 0x17, 0xb2, - 0xbf, 0x25, 0x21, 0x80, 0x6d, 0xc2, 0x98, 0x02, 0xaa, 0x47, 0x3f, 0x52, 0xab, 0x48, 0x48, 0x40, - 0xfc, 0x83, 0x96, 0x3b, 0x8f, 0xde, 0xfb, 0x98, 0xc7, 0x0b, 0x98, 0xfa, 0xff, 0xef, 0x51, 0x98, - 0x41, 0xe7, 0xf6, 0xe4, 0x3e, 0xf5, 0x09, 0x86, 0x72, 0x41, 0x98, 0x66, 0xb9, 0x16, 0x46, 0x2c, - 0x0e, 0x4f, 0x06, 0x35, 0x33, 0x08, 0xc8, 0x3b, 0xba, 0xbb, 0x45, 0x51, 0x4b, 0x56, 0x23, 0x81, - 0x7a, 0x17, 0x62, 0x3f, 0x8c, 0x37, 0x8c, 0xdb, 0xfe, 0x63, 0x6f, 0x7a, 0x83, 0xc7, 0xdd, 0xf4, - 0x76, 0xd4, 0xa6, 0xc7, 0x43, 0x84, 0x7c, 0x47, 0xdb, 0xf4, 0x5e, 0xfd, 0x6e, 0x37, 0xfc, 0xaa, - 0x77, 0xbb, 0x91, 0x97, 0xdb, 0xed, 0x46, 0x5f, 0x70, 0xb7, 0xbb, 0x0b, 0x53, 0x1b, 0x94, 0xb6, - 0xb4, 0x3b, 0x98, 0xb1, 0xf8, 0xf4, 0xf4, 0x28, 0x5a, 0xd7, 0xb2, 0x2e, 0x62, 0x12, 0x54, 0xb9, - 0xbb, 0x26, 0xfc, 0xf5, 0xec, 0x9a, 0xe3, 0xaf, 0x78, 0xd7, 0x9c, 0x78, 0x99, 0x5d, 0x33, 0xb5, - 0xf5, 0x4d, 0x9e, 0x78, 0xeb, 0x7b, 0x99, 0xdd, 0xea, 0x63, 0xf4, 0x56, 0xac, 0xd7, 0x57, 0x84, - 0x63, 0x8a, 0xe6, 0x09, 0xb2, 0xe2, 0x87, 0xd2, 0x99, 0x1b, 0xff, 0x66, 0x30, 0x4c, 0x09, 0xc0, - 0x99, 0xe0, 0xdf, 0x56, 0x0d, 0x7d, 0x14, 0x75, 0x7a, 0xf5, 0xe8, 0x61, 0x44, 0xbc, 0x98, 0x14, - 0x7b, 0x5c, 0x52, 0x8d, 0xb2, 0x65, 0xb9, 0xf5, 0x67, 0x05, 0x7e, 0xdf, 0xf9, 0xbf, 0xe2, 0x56, - 0xf9, 0x32, 0x77, 0x90, 0xbf, 0x19, 0x47, 0x52, 0x10, 0x51, 0x1f, 0x02, 0xa7, 0xf9, 0x24, 0xbe, - 0x04, 0xfe, 0x21, 0xfb, 0xce, 0xf5, 0x02, 0x0c, 0x9a, 0x1b, 0xeb, 0x8a, 0x66, 0xe1, 0xee, 0x1d, - 0xb9, 0x01, 0x88, 0x80, 0x12, 0x1c, 0x6c, 0x6e, 0x00, 0x3a, 0x01, 0xba, 0xe1, 0x9d, 0xb6, 0x6c, - 0x1e, 0x08, 0x20, 0xb3, 0x05, 0xef, 0xa6, 0x9f, 0xb2, 0xa3, 0x32, 0x12, 0x3f, 0x65, 0xd7, 0x87, - 0x31, 0x7e, 0xd4, 0xbe, 0x03, 0xe7, 0x6d, 0x7a, 0xe0, 0x3f, 0xa5, 0xaf, 0x96, 0xed, 0x57, 0x70, - 0xce, 0x64, 0xc8, 0x1f, 0x3d, 0xf1, 0x08, 0xfd, 0x1f, 0x67, 0xc7, 0xf5, 0x17, 0x04, 0x3c, 0xae, - 0x3f, 0x0f, 0x0f, 0xce, 0xfe, 0xd4, 0xcf, 0x0d, 0x2c, 0xb3, 0x7c, 0xb8, 0x60, 0x32, 0xaf, 0xb6, - 0x5a, 0x98, 0x1a, 0xb4, 0xe9, 0x76, 0x1c, 0x2f, 0x22, 0x9b, 0x30, 0xae, 0xfd, 0x4c, 0x98, 0x0a, - 0xb4, 0x12, 0x21, 0xd3, 0xc4, 0x00, 0x23, 0xbc, 0x6a, 0x0c, 0xb6, 0x28, 0x54, 0x92, 0xc3, 0xc3, - 0x86, 0x4c, 0xaf, 0xb3, 0x06, 0x93, 0xda, 0x4f, 0x65, 0x0d, 0xc5, 0x8f, 0x5f, 0xab, 0xc1, 0x1c, - 0x30, 0x93, 0xc4, 0x6a, 0xc2, 0x7c, 0xd6, 0xa0, 0xf1, 0x38, 0xdc, 0x64, 0x39, 0x0e, 0xb3, 0xd5, - 0xdf, 0x91, 0xef, 0x74, 0x5e, 0x88, 0x2d, 0xeb, 0x6f, 0x0c, 0xc2, 0x79, 0x31, 0x19, 0xaf, 0x72, - 0xc6, 0xc9, 0x8f, 0x60, 0x5c, 0x9b, 0x63, 0x31, 0xe8, 0x97, 0xe5, 0x93, 0xa5, 0xbc, 0xb5, 0xc0, - 0x4d, 0x1a, 0x5d, 0x04, 0x34, 0x12, 0xd3, 0xbd, 0x72, 0xca, 0xd6, 0x59, 0x92, 0x36, 0x4c, 0x99, - 0x13, 0x2d, 0xac, 0x3a, 0x57, 0x33, 0x2b, 0x31, 0x51, 0x65, 0x90, 0xee, 0x56, 0x23, 0x73, 0xba, - 0x57, 0x4e, 0xd9, 0x09, 0xde, 0xe4, 0x1b, 0x38, 0x93, 0x9a, 0x65, 0x61, 0xac, 0x7b, 0x3d, 0xb3, - 0xc2, 0x14, 0x36, 0xb7, 0xf4, 0x06, 0x08, 0xce, 0xad, 0x36, 0x5d, 0x09, 0x69, 0xc1, 0x84, 0x3e, - 0xf1, 0xc2, 0xec, 0x74, 0xa5, 0xc7, 0x50, 0x72, 0x44, 0x2e, 0xdc, 0x89, 0xb1, 0xc4, 0xb9, 0x7f, - 0x6e, 0x5a, 0xaf, 0x0d, 0xe4, 0x51, 0x18, 0xe6, 0xbf, 0xad, 0xdf, 0x2f, 0xc0, 0xf9, 0xad, 0x80, - 0x86, 0xd4, 0x6b, 0x52, 0xc3, 0xf9, 0xfb, 0x25, 0x57, 0x44, 0x9e, 0xe1, 0xb8, 0xf8, 0xd2, 0x86, - 0x63, 0xeb, 0x5f, 0x15, 0xa0, 0x9c, 0xd5, 0xe4, 0x3a, 0xf5, 0x5a, 0x64, 0x0b, 0x4a, 0xc9, 0x3e, - 0x88, 0x2f, 0xc6, 0x52, 0x31, 0x96, 0x73, 0x7b, 0xbb, 0x72, 0xca, 0x4e, 0x51, 0x93, 0x0d, 0x38, - 0xa3, 0xc1, 0x84, 0xe1, 0xb6, 0x78, 0x1c, 0xc3, 0x2d, 0x9b, 0xe1, 0x14, 0xa9, 0x6e, 0xf7, 0x5e, - 0xc1, 0x53, 0x77, 0xc9, 0x3f, 0x70, 0x5c, 0x8f, 0x09, 0xd1, 0x5a, 0x14, 0x2f, 0x88, 0xa1, 0x62, - 0xd8, 0xb9, 0x25, 0x17, 0xa1, 0xf2, 0x1d, 0x8c, 0x42, 0xb1, 0x3e, 0xc2, 0xd3, 0x41, 0xd8, 0xff, - 0xf8, 0xcb, 0x63, 0xc5, 0xec, 0x32, 0x0c, 0x6d, 0xaf, 0xd5, 0x17, 0xab, 0xe2, 0x1d, 0x33, 0x8f, - 0x7e, 0xd1, 0x0e, 0x1b, 0x4d, 0xc7, 0xe6, 0x05, 0xd6, 0x87, 0x40, 0xee, 0xd1, 0x48, 0x04, 0xf9, - 0x57, 0x74, 0xd7, 0x60, 0x44, 0x80, 0x04, 0x25, 0x7a, 0xf4, 0x89, 0x94, 0x01, 0xb6, 0x2c, 0xb3, - 0xb6, 0xa4, 0x0e, 0xd2, 0xa6, 0x4e, 0xa8, 0x1d, 0xfa, 0xef, 0xc1, 0x68, 0x20, 0x60, 0xe2, 0xcc, - 0x9f, 0x52, 0x39, 0x5c, 0x10, 0xcc, 0x6d, 0xe5, 0x12, 0xc7, 0x56, 0x7f, 0x59, 0x6b, 0x18, 0xa9, - 0x66, 0x73, 0x75, 0x69, 0x91, 0x8d, 0xaa, 0x18, 0x2c, 0x39, 0x1d, 0xb7, 0xd0, 0xf5, 0x3d, 0xa2, - 0xfa, 0x2b, 0x66, 0x1c, 0x1a, 0xdc, 0x40, 0x44, 0x7c, 0x26, 0x0d, 0xc5, 0x7a, 0x4b, 0xc5, 0xbd, - 0xc9, 0xe0, 0x96, 0x97, 0x8b, 0x64, 0x03, 0x23, 0xfa, 0xdc, 0x43, 0x2f, 0x9f, 0x57, 0xd1, 0x08, - 0x07, 0xe6, 0xb9, 0x08, 0xc1, 0x7a, 0x25, 0x32, 0x31, 0xfa, 0x6a, 0xdb, 0x5d, 0x84, 0x31, 0x05, - 0x53, 0x57, 0x76, 0x7c, 0xac, 0x0c, 0xfc, 0xdd, 0xb7, 0xf8, 0x83, 0xef, 0xa6, 0x62, 0x10, 0xd3, - 0xb1, 0x2a, 0xf8, 0x37, 0xfd, 0x2d, 0x57, 0x11, 0xd2, 0x20, 0xfa, 0x56, 0xab, 0x88, 0x43, 0x3e, - 0x9d, 0xa4, 0x0a, 0x03, 0x7f, 0x77, 0xe1, 0x38, 0x03, 0xf5, 0x2d, 0x57, 0xc1, 0x06, 0xea, 0xdb, - 0xab, 0x82, 0xca, 0xd8, 0x58, 0x7c, 0x91, 0xa6, 0x2a, 0x59, 0x4e, 0x57, 0x22, 0x8d, 0xe2, 0x09, - 0x8a, 0x9e, 0xf3, 0x41, 0xe1, 0x02, 0x1f, 0xac, 0x5f, 0x40, 0x35, 0x6c, 0xc0, 0xbe, 0xdd, 0x6a, - 0xfe, 0x4e, 0x81, 0x47, 0xea, 0xaa, 0x6f, 0x6a, 0x39, 0x50, 0xbd, 0xc7, 0xbe, 0xe6, 0x51, 0xa0, - 0x7d, 0xed, 0x0f, 0x5c, 0xaf, 0xa5, 0x7b, 0x14, 0x38, 0xdd, 0x68, 0x5f, 0x45, 0xb2, 0x7e, 0xe2, - 0x7a, 0x2d, 0x3b, 0x89, 0x4d, 0xde, 0x87, 0x49, 0x0d, 0xa4, 0x24, 0x41, 0x9e, 0x6b, 0x44, 0x27, - 0x77, 0x5b, 0xb6, 0x89, 0x69, 0xfd, 0x55, 0x01, 0xa6, 0x33, 0xb2, 0x73, 0xa3, 0xa1, 0x04, 0x35, - 0x2c, 0xb5, 0x51, 0x89, 0xec, 0x60, 0x18, 0x34, 0xc4, 0x38, 0x7f, 0x15, 0x22, 0x66, 0x59, 0xd0, - 0x32, 0x89, 0x17, 0xb5, 0x9c, 0x77, 0xd9, 0xd9, 0xc3, 0x75, 0x74, 0x12, 0x02, 0xc4, 0x2d, 0x11, - 0x26, 0xe9, 0x3a, 0x13, 0x97, 0xb5, 0x34, 0xe4, 0xaf, 0x24, 0x0f, 0xba, 0x56, 0x8d, 0xf5, 0x9b, - 0x45, 0x38, 0x9b, 0xd1, 0xff, 0x3a, 0x8d, 0xfe, 0x3a, 0x86, 0x20, 0x91, 0x0c, 0x7e, 0xe0, 0x17, - 0x94, 0x0c, 0xde, 0xfa, 0xe3, 0x22, 0x9c, 0xdd, 0xe9, 0x84, 0xf8, 0x30, 0x6c, 0xd5, 0x7b, 0x4a, - 0xbd, 0xc8, 0x0f, 0x9e, 0xe3, 0x63, 0x16, 0xf2, 0x0e, 0x0c, 0xad, 0xd0, 0x76, 0xdb, 0x17, 0xeb, - 0xff, 0xa2, 0x74, 0xea, 0x48, 0x62, 0x23, 0xd2, 0xca, 0x29, 0x9b, 0x63, 0x93, 0xf7, 0x61, 0x6c, - 0x85, 0x3a, 0x41, 0xf4, 0x88, 0x3a, 0x52, 0x1d, 0x92, 0x19, 0x50, 0x34, 0x12, 0x81, 0xb0, 0x72, - 0xca, 0x8e, 0xb1, 0xc9, 0x02, 0x0c, 0x6e, 0xf9, 0xde, 0x9e, 0x7a, 0x04, 0x9f, 0x53, 0x21, 0xc3, - 0x59, 0x39, 0x65, 0x23, 0x2e, 0x59, 0x87, 0xc9, 0xea, 0x1e, 0xf5, 0xa2, 0x75, 0x1a, 0x39, 0x2d, - 0x27, 0x72, 0x84, 0xd8, 0x7c, 0x2d, 0x8f, 0xd8, 0x40, 0x5e, 0x39, 0x65, 0x9b, 0xd4, 0xe4, 0x43, - 0x18, 0xb9, 0xe7, 0xfb, 0xad, 0x47, 0xcf, 0x65, 0x28, 0x87, 0x4a, 0x1e, 0x23, 0x81, 0xb6, 0x72, - 0xca, 0x96, 0x14, 0xb5, 0x21, 0x18, 0x58, 0x0f, 0xf7, 0xac, 0xc3, 0x02, 0x94, 0x97, 0xfc, 0x67, - 0x5e, 0xe6, 0xa8, 0x7e, 0xdf, 0x1c, 0x55, 0xc9, 0x3e, 0x03, 0x3f, 0x31, 0xae, 0x6f, 0xc3, 0xe0, - 0x96, 0xeb, 0xed, 0x25, 0x44, 0xc1, 0x0c, 0x3a, 0x86, 0x85, 0xc3, 0xe3, 0x7a, 0x7b, 0x64, 0x4d, - 0xca, 0xf7, 0xc2, 0x8e, 0x39, 0x60, 0x28, 0x15, 0x19, 0xd4, 0x3a, 0x76, 0x2c, 0xc7, 0xf3, 0xdf, - 0xb2, 0x83, 0x6f, 0xc0, 0x5c, 0x4e, 0xbd, 0xe2, 0x55, 0x3b, 0xeb, 0xdb, 0x20, 0x0a, 0x36, 0xff, - 0x4f, 0x01, 0x66, 0x33, 0x27, 0x30, 0x89, 0xc9, 0x74, 0x3a, 0xbe, 0x30, 0x17, 0xdb, 0x7e, 0xf3, - 0xc9, 0x31, 0x7c, 0xc3, 0x2c, 0x99, 0x35, 0x5c, 0x7c, 0x21, 0x4d, 0x46, 0x97, 0xc8, 0x0c, 0xa7, - 0xb3, 0xb4, 0xfe, 0x71, 0xd6, 0x5a, 0xe7, 0x83, 0x5b, 0x86, 0x11, 0x99, 0x7d, 0x8c, 0x9b, 0xae, - 0xe4, 0x4f, 0x7c, 0x3a, 0x26, 0xf7, 0x02, 0x19, 0x16, 0x46, 0x7e, 0xf2, 0xbb, 0x5a, 0x18, 0x2e, - 0xfe, 0xc5, 0x7e, 0xf0, 0x12, 0xdf, 0xa5, 0xe2, 0xc5, 0xea, 0x5c, 0xf1, 0xc3, 0xc8, 0x53, 0x3e, - 0xc9, 0xb6, 0xfa, 0x4d, 0x6e, 0x40, 0x49, 0x66, 0x1a, 0x11, 0x29, 0x8d, 0x44, 0x76, 0x7c, 0x3b, - 0x05, 0x27, 0xef, 0xc1, 0x5c, 0x12, 0x26, 0x7b, 0xc9, 0xdf, 0xfe, 0xe5, 0x15, 0x5b, 0x7f, 0x5a, - 0xc4, 0x48, 0xe9, 0x3d, 0x3e, 0x1d, 0x36, 0x7f, 0x9b, 0x75, 0x31, 0x5a, 0xc5, 0xcd, 0x3a, 0xb9, - 0x00, 0x63, 0x9b, 0x75, 0x23, 0x85, 0x9b, 0x1d, 0x03, 0x58, 0xb3, 0x59, 0x17, 0xaa, 0x41, 0x73, - 0xdf, 0x8d, 0x68, 0x33, 0xea, 0x06, 0x62, 0xa3, 0xb7, 0x53, 0x70, 0x62, 0xc1, 0xc4, 0xbd, 0xb6, - 0xfb, 0xa8, 0x29, 0x99, 0xf1, 0x21, 0x30, 0x60, 0xe4, 0x75, 0x98, 0x5a, 0xf5, 0xc2, 0xc8, 0x69, - 0xb7, 0xd7, 0x69, 0xb4, 0xef, 0xb7, 0x44, 0x82, 0x5a, 0x3b, 0x01, 0x65, 0xf5, 0x2e, 0xfa, 0x5e, - 0xe4, 0xb8, 0x1e, 0x0d, 0xec, 0xae, 0x17, 0xb9, 0x07, 0x54, 0xf4, 0x3d, 0x05, 0x27, 0x6f, 0xc3, - 0xac, 0x82, 0x6d, 0x06, 0xcd, 0x7d, 0x1a, 0x46, 0x01, 0x26, 0x76, 0x44, 0xef, 0x23, 0x3b, 0xbb, - 0x10, 0x6b, 0x68, 0xfb, 0xdd, 0xd6, 0xb2, 0xf7, 0xd4, 0x0d, 0x7c, 0x0f, 0xd3, 0xa6, 0x8c, 0x8a, - 0x1a, 0x12, 0x70, 0xeb, 0xf7, 0x46, 0x33, 0x77, 0x86, 0x97, 0x59, 0x83, 0x5f, 0xc0, 0xc4, 0xa2, - 0xd3, 0x71, 0x1e, 0xb9, 0x6d, 0x37, 0x72, 0x55, 0x06, 0xbc, 0x77, 0xfa, 0x6c, 0x2b, 0x32, 0xf7, - 0x0c, 0x6d, 0xe9, 0xc4, 0xb6, 0xc1, 0x6a, 0xfe, 0x2f, 0x87, 0x61, 0x36, 0x13, 0x8f, 0x5c, 0x17, - 0xa9, 0xf2, 0xd4, 0xd6, 0x2d, 0xf2, 0xb0, 0xd9, 0x49, 0x30, 0x9b, 0x4b, 0x04, 0x2d, 0xb6, 0xa9, - 0xe3, 0x75, 0x45, 0x16, 0x36, 0xdb, 0x80, 0xb1, 0xb9, 0x64, 0xa2, 0x89, 0xc6, 0x0c, 0x5d, 0xca, - 0xed, 0x04, 0x94, 0x5c, 0x86, 0x71, 0x06, 0x91, 0xac, 0x06, 0xf9, 0xe3, 0x47, 0x0d, 0xc4, 0x38, - 0x6d, 0xf8, 0x2d, 0xaa, 0x71, 0x1a, 0xe2, 0x9c, 0x4c, 0x28, 0xe3, 0xc4, 0x20, 0x92, 0xd3, 0x30, - 0xe7, 0xa4, 0x81, 0xc8, 0x6b, 0x30, 0x59, 0xed, 0x74, 0x34, 0x46, 0x98, 0x7e, 0xcd, 0x36, 0x81, - 0xe4, 0x12, 0x40, 0xb5, 0xd3, 0x91, 0x6c, 0x30, 0xb5, 0x9a, 0xad, 0x41, 0xc8, 0xcd, 0x38, 0xd8, - 0x9d, 0xc6, 0x0a, 0x6f, 0x43, 0xec, 0x8c, 0x12, 0x36, 0xae, 0x2a, 0x32, 0x98, 0x60, 0x0a, 0x7c, - 0x5c, 0x13, 0x60, 0xf2, 0x11, 0x9c, 0x4b, 0xb8, 0x8d, 0x68, 0x15, 0xe0, 0x4d, 0x85, 0x9d, 0x8f, - 0x40, 0xde, 0x85, 0xb3, 0x89, 0x42, 0x59, 0x1d, 0x5e, 0x4a, 0xd8, 0x39, 0xa5, 0xe4, 0x03, 0x28, - 0x27, 0x1e, 0xb4, 0xc7, 0x95, 0xe2, 0x05, 0x84, 0x9d, 0x5b, 0xce, 0xbe, 0xae, 0xc4, 0xcb, 0x38, - 0x51, 0x25, 0xde, 0xb5, 0xda, 0xd9, 0x85, 0x64, 0x05, 0x2a, 0x99, 0xae, 0x38, 0x5a, 0xc5, 0x98, - 0x32, 0xce, 0xee, 0x87, 0x46, 0x6a, 0x70, 0x21, 0x13, 0x45, 0x36, 0x03, 0x13, 0xc9, 0xd9, 0x3d, - 0x71, 0xc8, 0x02, 0xcc, 0xc4, 0x2e, 0x49, 0x5a, 0x13, 0x30, 0x87, 0x9c, 0x9d, 0x59, 0x46, 0xde, - 0x34, 0xc3, 0x16, 0xf0, 0xca, 0x30, 0x85, 0x9c, 0x9d, 0x2e, 0xb0, 0x8e, 0x0a, 0x70, 0x21, 0xf3, - 0x2c, 0x96, 0x2a, 0xc3, 0x7c, 0x52, 0x36, 0xd5, 0xf6, 0x82, 0x1b, 0x30, 0x88, 0x3a, 0x04, 0x37, - 0x75, 0x4b, 0x2f, 0x5c, 0xa4, 0xe7, 0xac, 0x58, 0xa9, 0x8d, 0x38, 0xe4, 0x9e, 0xba, 0xda, 0x1c, - 0x40, 0x63, 0xc9, 0xad, 0xa4, 0x8c, 0x96, 0x51, 0xb9, 0x7e, 0xc5, 0x29, 0x2f, 0x33, 0x5f, 0xe6, - 0x16, 0xe9, 0x4f, 0x0b, 0x50, 0xe9, 0x23, 0x82, 0xa8, 0x3e, 0x15, 0x8e, 0xd1, 0xa7, 0xfb, 0xaa, - 0x4f, 0xfc, 0xd5, 0xf0, 0xc2, 0xf1, 0xc4, 0x9c, 0x57, 0xdd, 0xad, 0xbf, 0x2a, 0x00, 0x49, 0x8b, - 0xba, 0xe4, 0x7b, 0x30, 0x56, 0xaf, 0xaf, 0x18, 0x0e, 0x89, 0xa9, 0xcb, 0xad, 0x18, 0x83, 0xdc, - 0x3e, 0x96, 0x07, 0xa2, 0xee, 0x7f, 0xf8, 0x49, 0xca, 0xed, 0x71, 0xa0, 0xa7, 0xdb, 0x63, 0xca, - 0xe9, 0x71, 0x39, 0xc3, 0x8f, 0x6f, 0xb0, 0x8f, 0x1f, 0x5f, 0xda, 0x49, 0xcf, 0x5a, 0x82, 0x72, - 0x9e, 0xb4, 0x8c, 0x3b, 0x1c, 0x0f, 0x11, 0xa7, 0x5d, 0xd0, 0xf1, 0x1d, 0xce, 0x04, 0x5b, 0xef, - 0xc2, 0x59, 0x45, 0xcd, 0x73, 0xcf, 0x68, 0xb1, 0x19, 0x84, 0x8a, 0xad, 0x62, 0x40, 0xc4, 0x00, - 0xeb, 0x4f, 0x06, 0x53, 0x84, 0xf5, 0xee, 0xc1, 0x81, 0x13, 0x3c, 0x27, 0x55, 0x93, 0x70, 0xa0, - 0xaf, 0x56, 0x53, 0x1b, 0x64, 0x32, 0xa6, 0xc6, 0x9d, 0x9d, 0x0b, 0x28, 0x61, 0x78, 0x4d, 0xca, - 0xaf, 0xf6, 0x8a, 0x3c, 0xfe, 0x94, 0x01, 0x24, 0xbb, 0x30, 0x29, 0xce, 0x6e, 0xfc, 0x2d, 0xbf, - 0xb1, 0xdb, 0xc9, 0x6f, 0xcc, 0x68, 0xde, 0x4d, 0x83, 0x84, 0xaf, 0x46, 0x93, 0x0d, 0xf9, 0x02, - 0xa6, 0xa4, 0xa4, 0x26, 0x18, 0x73, 0x67, 0xac, 0x3b, 0xbd, 0x19, 0x9b, 0x34, 0x9c, 0x73, 0x82, - 0x11, 0x6b, 0xb2, 0xdc, 0xec, 0x38, 0xe7, 0xa1, 0xe3, 0x34, 0xd9, 0x20, 0x11, 0x4d, 0x36, 0x60, - 0xf3, 0x9f, 0x02, 0x49, 0xf7, 0xab, 0xdf, 0xe7, 0x34, 0xa9, 0x7d, 0x4e, 0xf3, 0x55, 0x98, 0xce, - 0xe8, 0xc0, 0x89, 0x58, 0x7c, 0x0a, 0x24, 0xdd, 0xd2, 0x93, 0x70, 0xb0, 0xae, 0xc3, 0xeb, 0x6a, - 0x08, 0xd4, 0x6a, 0x30, 0x78, 0x4a, 0x23, 0xfb, 0xaf, 0x17, 0xa1, 0xd2, 0x07, 0x95, 0xfc, 0xbd, - 0x42, 0x72, 0xb4, 0xf9, 0x6a, 0x7c, 0x3f, 0x39, 0xda, 0xd9, 0xf4, 0x19, 0xc3, 0x5e, 0xfb, 0xe0, - 0x37, 0xfe, 0xfc, 0x85, 0x35, 0x8f, 0xf4, 0x94, 0x9d, 0x7c, 0xb4, 0x06, 0xf5, 0xd1, 0xda, 0x85, - 0x19, 0x43, 0x2d, 0x3c, 0xce, 0xe1, 0x65, 0x01, 0x88, 0x34, 0xb8, 0x6b, 0xfe, 0x9e, 0xc8, 0xd6, - 0x5b, 0x2c, 0x17, 0x6c, 0x0d, 0x6a, 0xdd, 0x85, 0xd9, 0x04, 0x5f, 0x61, 0xfc, 0xff, 0x1e, 0xa8, - 0x77, 0xf8, 0xc8, 0x78, 0xa0, 0x76, 0xe6, 0xe7, 0x87, 0x95, 0x49, 0x26, 0xd6, 0xdf, 0x8c, 0x53, - 0x21, 0xc8, 0xbf, 0xac, 0x75, 0xfd, 0xfa, 0xa2, 0xda, 0xd6, 0xe3, 0x13, 0x91, 0x3b, 0x30, 0xcc, - 0x21, 0x89, 0x80, 0xe3, 0x3a, 0xb6, 0xd8, 0x17, 0x04, 0xa2, 0x35, 0x8b, 0xaf, 0x86, 0xf1, 0x47, - 0x35, 0x8e, 0x72, 0x61, 0xed, 0xf0, 0x04, 0x3c, 0x31, 0x58, 0x05, 0x35, 0x1f, 0xac, 0xc6, 0xd1, - 0x38, 0xa4, 0x1f, 0x8b, 0xc4, 0xf3, 0xfc, 0x67, 0x6d, 0xda, 0xe2, 0x99, 0x13, 0x6b, 0x13, 0x42, - 0xc7, 0x1d, 0x74, 0x18, 0x03, 0x24, 0xb3, 0x3e, 0x81, 0x59, 0x26, 0x2d, 0x04, 0xc9, 0xfa, 0x30, - 0xed, 0x06, 0x83, 0x99, 0x8f, 0x03, 0x1c, 0x06, 0xc2, 0xc7, 0x01, 0xa2, 0xd0, 0x5a, 0x83, 0x73, - 0xdc, 0xf8, 0xa9, 0x77, 0x29, 0xbe, 0x6a, 0x18, 0xc2, 0xdf, 0x89, 0x37, 0xa7, 0x19, 0xbd, 0xe7, - 0x78, 0xd6, 0xc7, 0xf8, 0xa8, 0x49, 0x2c, 0x54, 0xd7, 0xf7, 0x62, 0x4b, 0xe7, 0xf1, 0x5e, 0x41, - 0xff, 0xef, 0x70, 0xa1, 0xda, 0xe9, 0x50, 0xaf, 0x15, 0x13, 0x6e, 0x07, 0xce, 0x31, 0x63, 0x54, - 0x90, 0x2a, 0x0c, 0x21, 0xb6, 0xba, 0x03, 0x16, 0xcd, 0xcd, 0x68, 0x0e, 0xe2, 0x89, 0x08, 0xb4, - 0x58, 0x01, 0xa7, 0xb4, 0x5a, 0x30, 0x57, 0xef, 0x3e, 0x3a, 0x70, 0x23, 0x7c, 0x52, 0x80, 0x71, - 0x5e, 0x64, 0xdd, 0xab, 0x32, 0x67, 0x1a, 0x1f, 0x8c, 0xeb, 0xf1, 0xe3, 0x17, 0x7c, 0x95, 0x20, - 0x62, 0xbf, 0x3c, 0xbd, 0x73, 0x33, 0x26, 0x45, 0x2b, 0x0f, 0xaf, 0x05, 0x8b, 0x45, 0x5e, 0x35, - 0x6b, 0x1a, 0xce, 0xe8, 0x77, 0x5e, 0x7c, 0x85, 0xcc, 0xc2, 0xb4, 0x79, 0x97, 0xc5, 0xc1, 0x5f, - 0xc3, 0x0c, 0xb7, 0xb5, 0xf3, 0x08, 0xf2, 0x0b, 0x71, 0xb0, 0xf4, 0xe2, 0xee, 0x42, 0xe2, 0x2d, - 0x03, 0xba, 0x38, 0xab, 0xdc, 0x20, 0xbb, 0x0b, 0xfc, 0x61, 0xea, 0xd3, 0x05, 0xe3, 0x36, 0xb6, - 0xb8, 0xbb, 0x50, 0x1b, 0x11, 0x91, 0x78, 0x19, 0x77, 0x3e, 0xfd, 0xdf, 0x0a, 0xf7, 0x05, 0x8c, - 0x85, 0xb0, 0x42, 0x1d, 0x7c, 0xb7, 0x94, 0xfd, 0xa2, 0x7c, 0x0a, 0x8a, 0x2a, 0xd4, 0x66, 0xd1, - 0x6d, 0x59, 0x7f, 0x50, 0x80, 0xeb, 0x5c, 0x20, 0xcb, 0xa6, 0xc3, 0x8b, 0xad, 0x1c, 0x62, 0xf2, - 0x1e, 0x0c, 0x85, 0x9a, 0x83, 0x87, 0x25, 0x5a, 0xde, 0x8b, 0x13, 0x27, 0x20, 0x55, 0x98, 0xd0, - 0x9f, 0xe7, 0x1c, 0x2f, 0x8a, 0x9f, 0x3d, 0x7e, 0xf0, 0xd8, 0x51, 0x4f, 0x76, 0x9e, 0xc0, 0xf9, - 0xe5, 0x6f, 0xd8, 0x82, 0x10, 0x27, 0x94, 0xd0, 0x1e, 0xe2, 0x17, 0xcb, 0xa7, 0xb7, 0xc5, 0x8a, - 0x31, 0x55, 0xfb, 0x24, 0x98, 0xe9, 0xc9, 0xf2, 0x90, 0x53, 0x22, 0xfc, 0x98, 0x6d, 0xc0, 0xac, - 0x3f, 0x29, 0xc0, 0x85, 0xec, 0xda, 0xc4, 0xc6, 0xb2, 0x0a, 0x67, 0x16, 0x1d, 0xcf, 0xf7, 0xdc, - 0xa6, 0xd3, 0xae, 0x37, 0xf7, 0x69, 0xab, 0xab, 0xe2, 0xf5, 0xaa, 0x5d, 0x66, 0x8f, 0x7a, 0x92, - 0x5c, 0xa2, 0xd8, 0x69, 0x2a, 0xa6, 0x21, 0xe2, 0x0b, 0x0f, 0xbe, 0xf7, 0xb6, 0x69, 0xa0, 0xf8, - 0xf1, 0x96, 0xe5, 0x94, 0x92, 0xdb, 0xf2, 0x52, 0xa1, 0xb5, 0xe3, 0xb9, 0x91, 0x22, 0xe2, 0xa6, - 0x9e, 0xac, 0x22, 0xeb, 0xdf, 0x16, 0xe0, 0x1c, 0xa6, 0xe8, 0x32, 0x92, 0x7e, 0xc6, 0x61, 0xab, - 0x65, 0xe4, 0xe5, 0x82, 0xf1, 0x62, 0xc5, 0xc0, 0x36, 0x43, 0x30, 0x93, 0x37, 0x61, 0xb0, 0x2e, - 0x1d, 0xce, 0xa6, 0x12, 0xe9, 0x9a, 0x05, 0x05, 0x2b, 0xb7, 0x11, 0x8b, 0xe9, 0xf0, 0x4b, 0x34, - 0x6c, 0x52, 0x0f, 0xf3, 0x6a, 0x73, 0xcb, 0x83, 0x06, 0x89, 0x23, 0x4a, 0x0d, 0xe6, 0x45, 0x94, - 0x1a, 0x32, 0x23, 0x4a, 0x59, 0x4f, 0x79, 0x82, 0xae, 0x64, 0x87, 0xc4, 0x24, 0x7d, 0x9c, 0x4a, - 0xc3, 0xcd, 0xcf, 0x81, 0xb3, 0x59, 0x3d, 0x63, 0x42, 0x7a, 0x22, 0xc3, 0x76, 0x7e, 0x98, 0xe8, - 0x2d, 0x78, 0xcd, 0xc0, 0xad, 0xb6, 0xdb, 0xfe, 0x33, 0xda, 0xda, 0x0a, 0xfc, 0x03, 0x3f, 0x32, - 0x12, 0x14, 0x89, 0x3c, 0xf4, 0xf1, 0xb5, 0x91, 0x58, 0x95, 0x09, 0xb0, 0xf5, 0xbf, 0xc1, 0xb5, - 0x3e, 0x1c, 0x45, 0xa7, 0xea, 0x70, 0xc6, 0x49, 0x94, 0x49, 0xcf, 0xa1, 0x6b, 0x59, 0xfd, 0x4a, - 0x32, 0x0a, 0xed, 0x34, 0xfd, 0x8d, 0x6d, 0x23, 0x75, 0x35, 0x29, 0xc3, 0xcc, 0x96, 0xbd, 0xb9, - 0xb4, 0xb3, 0xb8, 0xdd, 0xd8, 0xfe, 0x62, 0x6b, 0xb9, 0xb1, 0xb3, 0xf1, 0x60, 0x63, 0xf3, 0xe1, - 0x06, 0x8f, 0xb3, 0x6e, 0x94, 0x6c, 0x2f, 0x57, 0xd7, 0x4b, 0x05, 0x32, 0x03, 0x25, 0x03, 0xbc, - 0xbc, 0x53, 0x2b, 0x15, 0x6f, 0x7c, 0x6d, 0xa4, 0x64, 0x26, 0x17, 0xa0, 0x5c, 0xdf, 0xd9, 0xda, - 0xda, 0xb4, 0x15, 0x57, 0x3d, 0xca, 0xfb, 0x2c, 0x9c, 0x31, 0x4a, 0xef, 0xda, 0xcb, 0xcb, 0xa5, - 0x02, 0x6b, 0x8a, 0x01, 0xde, 0xb2, 0x97, 0xd7, 0x57, 0x77, 0xd6, 0x4b, 0xc5, 0x1b, 0x0d, 0xfd, - 0x99, 0x1c, 0x39, 0x0f, 0x73, 0x4b, 0xcb, 0xbb, 0xab, 0x8b, 0xcb, 0x59, 0xbc, 0x67, 0xa0, 0xa4, - 0x17, 0x6e, 0x6f, 0x6e, 0x6f, 0x71, 0xd6, 0x3a, 0xf4, 0xe1, 0x72, 0xad, 0xba, 0xb3, 0xbd, 0xb2, - 0x51, 0x1a, 0xb0, 0x06, 0x47, 0x8b, 0xa5, 0xe2, 0x8d, 0x1f, 0x19, 0x6f, 0xe8, 0x58, 0xf3, 0x05, - 0xfa, 0x4e, 0xbd, 0x7a, 0x2f, 0xbf, 0x0a, 0x5e, 0xba, 0x7e, 0xb7, 0x5a, 0x2a, 0x90, 0x8b, 0x70, - 0xce, 0x80, 0x6e, 0x55, 0xeb, 0xf5, 0x87, 0x9b, 0xf6, 0xd2, 0xda, 0x72, 0xbd, 0x5e, 0x2a, 0xde, - 0xd8, 0x35, 0xa2, 0xe8, 0xb1, 0x1a, 0xd6, 0xef, 0x56, 0x1b, 0xf6, 0xf2, 0x67, 0x3b, 0xab, 0xf6, - 0xf2, 0x52, 0xba, 0x06, 0xa3, 0xf4, 0x8b, 0xe5, 0x7a, 0xa9, 0x40, 0xa6, 0xe1, 0xb4, 0x01, 0xdd, - 0xd8, 0x2c, 0x15, 0x6f, 0xbc, 0x2e, 0x02, 0xad, 0x91, 0x29, 0x80, 0xa5, 0xe5, 0xfa, 0xe2, 0xf2, - 0xc6, 0xd2, 0xea, 0xc6, 0xbd, 0xd2, 0x29, 0x32, 0x09, 0x63, 0x55, 0xf5, 0xb3, 0x70, 0xe3, 0x03, - 0x38, 0x9d, 0x50, 0xef, 0x19, 0x86, 0x52, 0x8c, 0x4b, 0xa7, 0x70, 0xf8, 0xe5, 0x4f, 0xb4, 0xb1, - 0x72, 0x4d, 0xbd, 0x54, 0xb8, 0x51, 0x93, 0x59, 0x7c, 0xb5, 0xef, 0x9c, 0x8c, 0xc3, 0xc8, 0xd2, - 0xf2, 0xdd, 0xea, 0xce, 0xda, 0x76, 0xe9, 0x14, 0xfb, 0xb1, 0x68, 0x2f, 0x57, 0xb7, 0x97, 0x97, - 0x4a, 0x05, 0x32, 0x06, 0x43, 0xf5, 0xed, 0xea, 0xf6, 0x72, 0xa9, 0x48, 0x46, 0x61, 0x70, 0xa7, - 0xbe, 0x6c, 0x97, 0x06, 0x16, 0xfe, 0xc5, 0xdf, 0x2d, 0x70, 0x43, 0xa3, 0x7c, 0x8f, 0xf5, 0xb5, - 0xa6, 0x50, 0x8a, 0x2d, 0x4f, 0xa4, 0x2c, 0xcd, 0xd5, 0x1e, 0x51, 0x0a, 0x98, 0xef, 0x71, 0xb9, - 0x83, 0x08, 0xd7, 0x0b, 0xb7, 0x0b, 0xc4, 0x46, 0x67, 0x98, 0x84, 0x7e, 0xa5, 0x38, 0x67, 0xab, - 0xc0, 0xf3, 0x17, 0x7b, 0xaa, 0x65, 0xe4, 0x57, 0xc0, 0xd2, 0x79, 0xe6, 0x68, 0x21, 0xdf, 0x3b, - 0x9e, 0xb6, 0x21, 0xeb, 0x7c, 0xfd, 0x78, 0xe8, 0xe4, 0x3e, 0x4c, 0x32, 0xd9, 0x5c, 0xa1, 0x91, - 0xf3, 0x49, 0x42, 0x4d, 0x25, 0x98, 0xbf, 0x90, 0x5d, 0xa8, 0xb2, 0x0a, 0x4d, 0x60, 0x47, 0xb8, - 0x72, 0x1d, 0x12, 0x19, 0x8c, 0x43, 0x42, 0xf8, 0x8e, 0x3f, 0x7f, 0x26, 0x01, 0xde, 0xbd, 0x73, - 0xbb, 0x40, 0xea, 0x18, 0x09, 0xcf, 0x10, 0xf2, 0x89, 0x7c, 0x20, 0x98, 0x96, 0xfe, 0x79, 0x6b, - 0x2a, 0x2a, 0x07, 0x68, 0x8e, 0x76, 0xb0, 0x01, 0x24, 0x2d, 0x3b, 0x93, 0xcb, 0xf1, 0x3a, 0xc8, - 0x16, 0xab, 0xe7, 0xcf, 0xa6, 0x2e, 0xb2, 0x96, 0x99, 0xf4, 0x44, 0x96, 0x61, 0x4a, 0xbc, 0xb4, - 0x17, 0xd2, 0x3c, 0xe9, 0xa5, 0x0f, 0xe4, 0xb2, 0xb9, 0x87, 0xe3, 0xa4, 0x34, 0x02, 0x32, 0x1f, - 0xf7, 0x23, 0xa9, 0x26, 0xcc, 0x9f, 0xcf, 0x2c, 0x13, 0xfd, 0xbb, 0x0b, 0x53, 0xa6, 0x72, 0x41, - 0xe4, 0x04, 0x65, 0xea, 0x1c, 0xb9, 0x0d, 0x6a, 0xc0, 0xdc, 0xba, 0xe3, 0xe2, 0x7d, 0x89, 0x70, - 0xd2, 0x93, 0x7e, 0x70, 0xa4, 0xd2, 0xc3, 0x31, 0xae, 0x4e, 0xbd, 0x96, 0x9a, 0x84, 0xbc, 0x0c, - 0x01, 0xf8, 0xd9, 0xd4, 0xa5, 0x8c, 0x6c, 0xfa, 0x28, 0x12, 0xcb, 0xcc, 0xeb, 0x9c, 0xe5, 0x76, - 0x3a, 0x9f, 0xe7, 0x29, 0x4d, 0xd6, 0x51, 0x48, 0x4f, 0x70, 0xd4, 0xd6, 0xc4, 0x89, 0xd9, 0x95, - 0x31, 0xde, 0x83, 0x96, 0x6c, 0x5f, 0x14, 0x86, 0x24, 0x67, 0xe0, 0x72, 0x99, 0xdd, 0x2e, 0x90, - 0xaf, 0xf1, 0xab, 0xce, 0x64, 0xf7, 0xd0, 0x8d, 0xf6, 0x85, 0xf4, 0x73, 0x3e, 0x93, 0x81, 0xf8, - 0x50, 0x7a, 0x70, 0xb7, 0x61, 0x26, 0xcb, 0x39, 0x5b, 0x0d, 0x68, 0x0f, 0xcf, 0xed, 0xdc, 0x55, - 0x60, 0x33, 0x55, 0xa3, 0x95, 0x3f, 0x49, 0x3d, 0x7c, 0x83, 0x73, 0x79, 0x7e, 0x04, 0x53, 0x6c, - 0x95, 0x3c, 0xa0, 0xb4, 0x53, 0x6d, 0xbb, 0x4f, 0x69, 0x48, 0x64, 0x18, 0x63, 0x05, 0xca, 0xa3, - 0xbd, 0x5e, 0x20, 0xdf, 0x85, 0xf1, 0x87, 0x4e, 0xd4, 0xdc, 0x17, 0xe1, 0x3c, 0x65, 0xb4, 0x4f, - 0x84, 0xcd, 0xcb, 0x5f, 0x58, 0x78, 0xbb, 0x40, 0x7e, 0x00, 0x23, 0xf7, 0x68, 0x84, 0x0f, 0xb4, - 0xaf, 0x28, 0x5f, 0x42, 0x6e, 0x9f, 0x5c, 0xf5, 0xd4, 0x2b, 0x24, 0xd9, 0xe0, 0xa4, 0x31, 0x97, - 0xdc, 0x02, 0xe0, 0x1b, 0x02, 0x72, 0x48, 0x16, 0xcf, 0xa7, 0x9a, 0x4d, 0xee, 0x31, 0xe1, 0xa1, - 0x4d, 0x23, 0x7a, 0xdc, 0x2a, 0xf3, 0xc6, 0x68, 0x0d, 0xa6, 0x54, 0x22, 0xa6, 0x0d, 0x8c, 0xba, - 0x62, 0x25, 0x98, 0x85, 0x27, 0xe0, 0xf6, 0x01, 0xfb, 0x2a, 0x78, 0x16, 0x62, 0x0c, 0xcf, 0x81, - 0x3b, 0xe9, 0x9c, 0x1e, 0xe3, 0x43, 0xdf, 0x42, 0xe5, 0x20, 0x72, 0x34, 0x8d, 0x76, 0xc5, 0x0f, - 0x23, 0x93, 0x56, 0x41, 0xb2, 0x69, 0x7f, 0x19, 0xe6, 0xf5, 0x7a, 0xcd, 0x78, 0xd2, 0xf1, 0x9e, - 0x9b, 0x17, 0xa6, 0x7a, 0xfe, 0x4a, 0x0f, 0x0c, 0xa1, 0xbf, 0x0d, 0xfc, 0x56, 0xb1, 0x80, 0xdb, - 0xc9, 0x12, 0x4c, 0xcb, 0xba, 0x36, 0x3b, 0xd4, 0xab, 0xd7, 0x57, 0x30, 0xe9, 0x8e, 0xf4, 0x5c, - 0xd1, 0x60, 0x92, 0x3b, 0x49, 0x17, 0xb1, 0xa3, 0xcf, 0x08, 0xc3, 0x41, 0x7a, 0x05, 0xe7, 0x88, - 0x8f, 0xbe, 0xcc, 0x40, 0xc7, 0x0f, 0xb8, 0x51, 0xc9, 0x10, 0xfe, 0x77, 0x17, 0x48, 0x0f, 0x05, - 0x68, 0x3e, 0x47, 0x85, 0xb8, 0x5d, 0x20, 0x5f, 0x00, 0x49, 0xab, 0x24, 0x6a, 0x08, 0x73, 0xd5, - 0x2f, 0x35, 0x84, 0x3d, 0xf4, 0x99, 0x7b, 0x30, 0xab, 0x82, 0xf0, 0x68, 0xb5, 0x2e, 0x90, 0x9c, - 0xd6, 0xe4, 0xb5, 0x92, 0x7c, 0x02, 0xd3, 0x62, 0xd1, 0xea, 0x05, 0xa4, 0xa4, 0xf6, 0x1f, 0xa1, - 0x95, 0xe4, 0xae, 0xd3, 0xfb, 0x30, 0x5b, 0x4f, 0x8c, 0x18, 0x77, 0xe6, 0x3f, 0x67, 0xb2, 0x40, - 0x60, 0x9d, 0x46, 0x7c, 0xc8, 0xb2, 0x79, 0x3d, 0x00, 0xc2, 0x8d, 0x42, 0x92, 0xdd, 0x53, 0x97, - 0x3e, 0x23, 0x17, 0x13, 0x4d, 0x67, 0x40, 0x44, 0xc3, 0x0d, 0x2c, 0xb7, 0x67, 0xdb, 0x3c, 0x87, - 0x36, 0x42, 0x8d, 0x7b, 0xf4, 0xcb, 0x06, 0x81, 0x71, 0x15, 0x2f, 0x26, 0xe0, 0x5c, 0x2e, 0x06, - 0xf9, 0x35, 0x8c, 0x7e, 0xdb, 0x5b, 0xad, 0x22, 0xdf, 0xcd, 0xd2, 0x7e, 0x73, 0x14, 0xc3, 0xf9, - 0x37, 0x8f, 0x87, 0xac, 0x14, 0xd9, 0xc9, 0x7b, 0x34, 0xda, 0x6a, 0x77, 0xf7, 0x5c, 0xcc, 0xae, - 0x4a, 0x94, 0xd1, 0x48, 0x81, 0xc4, 0xba, 0x94, 0x41, 0xe7, 0xe2, 0x82, 0x3a, 0xfd, 0x31, 0x59, - 0x85, 0x12, 0xdf, 0xff, 0x35, 0x16, 0x17, 0x53, 0x2c, 0x04, 0x8a, 0x13, 0x38, 0x07, 0x61, 0xee, - 0x6c, 0xdd, 0xe2, 0xbe, 0x51, 0x44, 0x7e, 0x93, 0xba, 0x80, 0x39, 0x6d, 0xc0, 0x54, 0x46, 0x00, - 0x36, 0x23, 0x36, 0x0d, 0x69, 0x24, 0xc3, 0xec, 0xf0, 0xdc, 0xba, 0x57, 0xe3, 0xc3, 0x3e, 0x5d, - 0x1a, 0x7f, 0xfa, 0x89, 0x90, 0x70, 0xbb, 0x6f, 0x11, 0x95, 0x6f, 0x38, 0x83, 0xe9, 0xeb, 0x86, - 0x4c, 0x72, 0x32, 0xbe, 0x6f, 0xe3, 0x19, 0x84, 0xa1, 0x85, 0x66, 0xe3, 0xb6, 0xb1, 0xdf, 0x92, - 0x6a, 0x52, 0xa3, 0xda, 0x5d, 0xc0, 0x2d, 0x8d, 0x1d, 0x92, 0x4c, 0x84, 0xed, 0x06, 0x01, 0xf5, - 0x38, 0x71, 0x9e, 0xbc, 0x91, 0x45, 0xfd, 0x31, 0x6e, 0x3d, 0x1a, 0x35, 0x7f, 0x73, 0xd8, 0x8f, - 0x05, 0xcf, 0x05, 0x75, 0xbb, 0x40, 0xde, 0x83, 0x51, 0xd1, 0x46, 0x46, 0x64, 0x34, 0x3a, 0xec, - 0xd1, 0x6a, 0xa4, 0x04, 0x3e, 0x48, 0xd8, 0x66, 0x13, 0x27, 0x6f, 0xf6, 0x79, 0x9b, 0xdf, 0x63, - 0x87, 0x6d, 0xeb, 0x45, 0x28, 0x17, 0xe5, 0xa9, 0x8b, 0x94, 0x65, 0x15, 0x8e, 0x46, 0x82, 0xfa, - 0x1c, 0x8f, 0x9c, 0x09, 0x93, 0x9b, 0x31, 0xa6, 0xa3, 0x0a, 0xcd, 0xa6, 0xe4, 0x66, 0x03, 0xdc, - 0xef, 0xac, 0x5d, 0x85, 0x52, 0xb5, 0x89, 0x27, 0x41, 0x9d, 0x1e, 0x38, 0x9d, 0x7d, 0x3f, 0xa0, - 0x4a, 0x69, 0x49, 0x16, 0x48, 0x5e, 0xb3, 0x4a, 0xb2, 0x10, 0x05, 0x6b, 0xd4, 0xc1, 0xc0, 0xd7, - 0x73, 0x4a, 0xb4, 0x48, 0x14, 0x65, 0x53, 0xf4, 0x50, 0x52, 0x66, 0x16, 0x99, 0x5a, 0xd5, 0x7e, - 0x39, 0x36, 0x1f, 0xe0, 0x86, 0xa1, 0x90, 0x43, 0x75, 0x42, 0x28, 0x90, 0x52, 0xe7, 0xe4, 0xf3, - 0x23, 0x85, 0x5a, 0x95, 0xf7, 0xc6, 0xf1, 0xb0, 0xe4, 0x51, 0xe7, 0x55, 0xff, 0x7d, 0x98, 0x5a, - 0x66, 0x1b, 0x7a, 0xb7, 0xe5, 0xf2, 0x60, 0xff, 0xc4, 0x8c, 0xde, 0x9e, 0x4b, 0xb8, 0x22, 0xd3, - 0xaf, 0x21, 0xa9, 0x50, 0xfd, 0xe5, 0x99, 0xa2, 0xc1, 0xe4, 0x7c, 0xcc, 0x48, 0xb6, 0x22, 0xdf, - 0x02, 0xaa, 0xe6, 0x42, 0xd7, 0x9f, 0xe3, 0x12, 0x61, 0xb5, 0xd3, 0x69, 0x4b, 0x93, 0x34, 0xbf, - 0x7b, 0xbf, 0x66, 0xa8, 0x90, 0xa9, 0x72, 0xc9, 0x3b, 0x2d, 0x34, 0x7e, 0xae, 0xa5, 0x43, 0xce, - 0xe1, 0x99, 0x53, 0xde, 0x6f, 0x2d, 0xaa, 0xf0, 0xdc, 0xd5, 0x76, 0x3b, 0x45, 0x1c, 0x92, 0x37, - 0x4c, 0xee, 0x59, 0x38, 0xfd, 0x6a, 0x40, 0x15, 0x9d, 0x4b, 0x5d, 0xd5, 0x4e, 0x87, 0x6f, 0x96, - 0x97, 0xd4, 0x86, 0x61, 0x16, 0xa4, 0x55, 0xf4, 0x64, 0xb9, 0xd8, 0xdb, 0xef, 0xe3, 0x32, 0x8b, - 0x73, 0x26, 0x13, 0x5d, 0xe1, 0x4d, 0xa6, 0x8c, 0x56, 0x42, 0x58, 0xa2, 0x50, 0x9d, 0x13, 0xa7, - 0x51, 0xf4, 0x89, 0x13, 0x30, 0x2b, 0xcb, 0x4c, 0x02, 0x2e, 0xf9, 0x5d, 0xca, 0x2b, 0x56, 0x96, - 0xd2, 0x52, 0x32, 0x2f, 0xbd, 0xea, 0x72, 0x3a, 0x61, 0xbd, 0xd9, 0xe5, 0xdc, 0x84, 0xf6, 0xf7, - 0xa1, 0x94, 0x4c, 0x89, 0xad, 0x98, 0xe6, 0xe4, 0xca, 0xce, 0x9d, 0x93, 0xbb, 0x30, 0xa3, 0xcf, - 0xa8, 0xea, 0x77, 0xde, 0xee, 0x9f, 0xc7, 0x67, 0x1b, 0x66, 0x33, 0x33, 0x58, 0xab, 0x23, 0xb6, - 0x57, 0x7e, 0xeb, 0x5c, 0xae, 0x14, 0xce, 0x66, 0x27, 0xb1, 0x27, 0xaf, 0x99, 0x8a, 0x7f, 0x76, - 0x4a, 0xef, 0xf9, 0x6b, 0x7d, 0xb0, 0xc4, 0x80, 0x7e, 0x8d, 0x27, 0x60, 0xaa, 0x8e, 0x2b, 0x9a, - 0x29, 0x20, 0xa7, 0x02, 0xab, 0x17, 0x8a, 0x5a, 0x03, 0x33, 0x19, 0xc5, 0xf9, 0x43, 0x7c, 0x35, - 0x9f, 0x67, 0xbc, 0xb0, 0x76, 0x65, 0x14, 0xea, 0xdc, 0x91, 0xe9, 0x99, 0xec, 0xbc, 0x87, 0x2e, - 0x39, 0xaf, 0xd6, 0xc3, 0xf1, 0x9b, 0x9c, 0xc7, 0xad, 0xa5, 0xcc, 0x36, 0x46, 0x26, 0xf2, 0xa4, - 0xd9, 0x26, 0x2b, 0x83, 0xba, 0x1a, 0x86, 0x5e, 0x39, 0xfa, 0xf9, 0x69, 0xfc, 0x15, 0xb7, 0xe3, - 0x98, 0x55, 0xe8, 0x76, 0x9c, 0x4c, 0xfe, 0x97, 0xf3, 0x11, 0x74, 0xe6, 0x0e, 0xbf, 0xb4, 0x4d, - 0xa4, 0x52, 0x27, 0xba, 0xaa, 0x94, 0x9d, 0x66, 0x5d, 0xad, 0x8d, 0x4c, 0x14, 0xbd, 0x8a, 0x87, - 0xf2, 0x1b, 0xcc, 0x19, 0xa5, 0x1e, 0x79, 0xe6, 0x7b, 0x8b, 0x29, 0x9b, 0x50, 0x8e, 0x27, 0x33, - 0xd1, 0x81, 0x13, 0x4e, 0xa5, 0x1c, 0x8c, 0x73, 0xb9, 0xd9, 0xe5, 0xc9, 0x77, 0x52, 0x5f, 0x7a, - 0xce, 0xc0, 0xf4, 0xac, 0x82, 0xef, 0xe7, 0x5a, 0x54, 0xeb, 0xf3, 0xb1, 0x11, 0x57, 0x4f, 0x44, - 0x9f, 0xda, 0xcf, 0x33, 0xb2, 0xd4, 0xdf, 0x43, 0xb9, 0x58, 0xcb, 0x34, 0x9f, 0xdb, 0xeb, 0x8b, - 0x59, 0x7c, 0xc2, 0xf4, 0x8e, 0xab, 0xb5, 0x4b, 0xca, 0x69, 0xc9, 0x82, 0x93, 0xec, 0xb8, 0xc7, - 0x69, 0x5a, 0x1e, 0x9f, 0x25, 0x18, 0xd7, 0x52, 0xd4, 0x93, 0x73, 0xc6, 0x30, 0x19, 0x67, 0xe8, - 0xbc, 0xd1, 0x39, 0xf3, 0xf8, 0x5c, 0x44, 0x53, 0xb2, 0x4a, 0x74, 0x9f, 0xdb, 0x8a, 0xf3, 0x69, - 0x1e, 0x86, 0x19, 0x59, 0x8d, 0x02, 0x6f, 0xcd, 0x85, 0xe4, 0xe0, 0x18, 0x0d, 0xca, 0xef, 0x12, - 0xd1, 0x87, 0xa6, 0x4f, 0x93, 0xf2, 0xe5, 0xd7, 0x69, 0x91, 0x07, 0x17, 0x53, 0xd1, 0xc8, 0xb0, - 0x85, 0x67, 0x95, 0x4d, 0x4c, 0x83, 0xa2, 0x81, 0x22, 0x9b, 0xcd, 0x16, 0x3e, 0x1f, 0xc9, 0xc8, - 0xd9, 0xaf, 0x76, 0xd8, 0x9e, 0x29, 0xfd, 0x33, 0x64, 0x37, 0xb5, 0x67, 0xe7, 0x72, 0xec, 0x99, - 0xc4, 0x3f, 0xb7, 0xa5, 0x3f, 0xd4, 0xf6, 0xec, 0x54, 0x66, 0x7e, 0x72, 0x3d, 0x29, 0xb8, 0xe5, - 0x25, 0xef, 0xef, 0x71, 0x26, 0xcc, 0x64, 0x25, 0xf5, 0xd7, 0xec, 0xba, 0xb9, 0x19, 0xff, 0x33, - 0x46, 0xc1, 0x96, 0xeb, 0x3f, 0x87, 0x5b, 0x8f, 0x14, 0xff, 0xb9, 0x2d, 0xfc, 0x52, 0xdb, 0xe8, - 0x12, 0xa9, 0xf8, 0x95, 0x3a, 0xde, 0x27, 0x57, 0x7f, 0x2e, 0xef, 0x0d, 0x7c, 0xd2, 0x94, 0xce, - 0xa3, 0xaf, 0x24, 0x9b, 0x5e, 0x59, 0xf6, 0x33, 0xcd, 0xbe, 0xb3, 0xe9, 0x2e, 0x32, 0x7e, 0x67, - 0x13, 0x46, 0xdb, 0x7e, 0x0d, 0xfb, 0x5a, 0x6e, 0xc6, 0x19, 0xf9, 0xf7, 0x13, 0x9b, 0x71, 0x7e, - 0x86, 0xfe, 0x1e, 0x6a, 0xd0, 0xe9, 0xba, 0xbb, 0xe7, 0x69, 0xe9, 0xf3, 0x95, 0x12, 0x94, 0xce, - 0xe8, 0xaf, 0xb6, 0x98, 0xac, 0x6c, 0xfb, 0x9b, 0x4c, 0xfe, 0xe1, 0xd2, 0xbb, 0x9e, 0x08, 0x9d, - 0xcc, 0xe7, 0xe7, 0x7f, 0x57, 0xdb, 0x4d, 0x66, 0xe6, 0x74, 0x8d, 0xa1, 0x9e, 0x85, 0x5c, 0x31, - 0xcc, 0x48, 0x88, 0xae, 0x18, 0x66, 0xa6, 0x2d, 0xbf, 0x85, 0x56, 0x17, 0xdb, 0x6f, 0x53, 0xdd, - 0xea, 0xa2, 0xa5, 0xb5, 0x4e, 0x18, 0x3d, 0xc8, 0xc7, 0x30, 0xa6, 0xd2, 0x7e, 0x2b, 0xfb, 0x76, - 0x32, 0xf3, 0xf8, 0x7c, 0x39, 0x5d, 0x20, 0x2a, 0x7c, 0x47, 0x1a, 0x3e, 0xb0, 0xce, 0xb2, 0x69, - 0x30, 0xca, 0xaf, 0xf6, 0x1d, 0x69, 0xf5, 0x30, 0xc8, 0x52, 0x49, 0xbf, 0x93, 0x64, 0xdf, 0x87, - 0x89, 0x38, 0xc1, 0xf7, 0xee, 0x82, 0x46, 0x98, 0xc8, 0xfa, 0x9d, 0x24, 0x7c, 0x4f, 0x5e, 0x69, - 0x60, 0x7d, 0x66, 0x61, 0xef, 0x53, 0xfc, 0x63, 0x69, 0x65, 0x31, 0x5a, 0x9a, 0x4a, 0x17, 0xde, - 0x63, 0xf3, 0x9d, 0xd0, 0x33, 0x6e, 0xaa, 0xa9, 0xcd, 0xc8, 0x99, 0xab, 0xa6, 0x36, 0x2b, 0xe7, - 0x6d, 0x6c, 0xf2, 0xff, 0x42, 0x9a, 0x14, 0x62, 0xa6, 0x17, 0x8d, 0x66, 0xa5, 0xf8, 0x5e, 0xca, - 0x2b, 0x4e, 0xb2, 0xae, 0x43, 0x29, 0x99, 0x1e, 0x54, 0xe9, 0x63, 0x39, 0x79, 0x5c, 0x95, 0x92, - 0x97, 0x9b, 0x57, 0x74, 0x4b, 0xda, 0xc7, 0x4d, 0xbe, 0x57, 0xb2, 0x1b, 0xa5, 0xb3, 0xce, 0x37, - 0x98, 0x4f, 0x1a, 0x99, 0x42, 0x75, 0x4d, 0x39, 0x95, 0x89, 0x54, 0x97, 0xac, 0x32, 0x92, 0x8b, - 0xba, 0x32, 0x68, 0x55, 0x76, 0x52, 0xf7, 0x37, 0x4c, 0x15, 0xb6, 0x47, 0x58, 0xf9, 0xbe, 0xd7, - 0xbf, 0xe4, 0x97, 0x60, 0x2e, 0x27, 0x4c, 0x36, 0xb9, 0x96, 0xb0, 0xb4, 0x66, 0x87, 0xd1, 0x56, - 0x0b, 0x24, 0x33, 0x85, 0xf7, 0x3a, 0xfa, 0x0d, 0x18, 0x21, 0x24, 0x52, 0x77, 0x71, 0x0f, 0xdd, - 0x68, 0x9f, 0x67, 0xaa, 0xd6, 0xb6, 0xcd, 0xcc, 0xd8, 0x13, 0xa4, 0x8e, 0xba, 0x88, 0x01, 0xcd, - 0xb8, 0x8e, 0xcb, 0x60, 0x38, 0x9f, 0xcd, 0x90, 0xed, 0x1d, 0x6c, 0x2d, 0x64, 0xc4, 0xf7, 0x50, - 0x6b, 0x21, 0x3f, 0xf6, 0x47, 0x6e, 0x33, 0xb7, 0xa4, 0x8c, 0x94, 0xcd, 0x31, 0x3f, 0xd4, 0x47, - 0x2e, 0xc7, 0xfb, 0x8c, 0x63, 0x2a, 0x7a, 0x07, 0xc9, 0x41, 0xef, 0xbd, 0x7b, 0xd8, 0xf2, 0xc8, - 0x35, 0xa9, 0x16, 0xb4, 0xf6, 0xe5, 0xc5, 0x09, 0xc9, 0x6d, 0xdf, 0xb2, 0xfc, 0x9e, 0xb2, 0xdb, - 0x77, 0xdc, 0x43, 0x57, 0xdd, 0x7f, 0x25, 0x02, 0xc8, 0x18, 0x1d, 0xd5, 0xe0, 0xf3, 0x39, 0x70, - 0xb2, 0x81, 0x8e, 0x40, 0x49, 0xa8, 0xa6, 0x94, 0x66, 0x47, 0xa8, 0xc9, 0xe5, 0xc7, 0xd7, 0xb1, - 0x11, 0xe1, 0xe3, 0x24, 0xeb, 0x38, 0x11, 0x1a, 0x44, 0xac, 0x63, 0x03, 0x7a, 0xb2, 0x75, 0x9c, - 0x60, 0x68, 0xae, 0xe3, 0x64, 0x33, 0x93, 0x9a, 0x7e, 0xee, 0xac, 0x26, 0x9b, 0xa9, 0xd6, 0x71, - 0x36, 0xc7, 0xfc, 0x48, 0x2c, 0xb9, 0x1c, 0xd5, 0x3a, 0x36, 0x39, 0xe6, 0xa0, 0x1f, 0x73, 0x1d, - 0x27, 0x2b, 0x31, 0xd7, 0xf1, 0x89, 0xda, 0xa7, 0xd6, 0x71, 0x76, 0xfb, 0x4e, 0xbc, 0x8e, 0x13, - 0xa1, 0x8b, 0x8c, 0x8e, 0x66, 0xad, 0xe3, 0x24, 0x3e, 0x5f, 0xc7, 0x49, 0x68, 0xc2, 0xb8, 0xd2, - 0x63, 0x1d, 0x27, 0x29, 0x3f, 0x43, 0x7e, 0x89, 0xb0, 0x2b, 0xc7, 0x59, 0xc9, 0xb9, 0x11, 0x5b, - 0xc8, 0x43, 0x34, 0xef, 0x25, 0xe0, 0xc7, 0x5b, 0xcd, 0x17, 0xf2, 0x98, 0xe2, 0x7a, 0xde, 0x95, - 0x83, 0x98, 0x6c, 0xae, 0x69, 0xbb, 0xca, 0x8e, 0x3a, 0xd3, 0xa3, 0xc1, 0xbb, 0x6c, 0xdd, 0xb4, - 0x7a, 0xf0, 0xed, 0x15, 0x34, 0xa7, 0x07, 0x5f, 0xa5, 0xca, 0x24, 0xf9, 0xe6, 0x92, 0xf4, 0x5e, - 0xdf, 0x9f, 0xcb, 0x0b, 0x8e, 0x24, 0xdd, 0x42, 0x42, 0x39, 0x3a, 0x71, 0x4b, 0x95, 0x92, 0x94, - 0x6c, 0xe9, 0x49, 0xd7, 0xf9, 0xba, 0x94, 0x1e, 0x52, 0xd1, 0xb6, 0x12, 0x9d, 0xd6, 0xd7, 0x7a, - 0x6e, 0x09, 0xd9, 0x46, 0x5b, 0x6e, 0x1a, 0xae, 0xd9, 0x81, 0xf3, 0xc2, 0x7a, 0xf5, 0xe5, 0x9a, - 0x8a, 0x1b, 0xa4, 0x73, 0xcd, 0x0b, 0x2a, 0xa4, 0xb8, 0xa6, 0xa9, 0x3f, 0x41, 0xeb, 0x97, 0x78, - 0x71, 0xe5, 0x3d, 0xf6, 0xf3, 0x2d, 0x29, 0xd3, 0x86, 0xb3, 0x12, 0xc3, 0x45, 0x1f, 0xb1, 0x8f, - 0xc4, 0x0d, 0x9e, 0x04, 0xe6, 0x0e, 0x7e, 0x16, 0x3d, 0xf9, 0x04, 0x4a, 0x62, 0x7b, 0x8b, 0x19, - 0x64, 0x21, 0xe6, 0x4e, 0x5d, 0x4d, 0x1a, 0xdd, 0x8e, 0xd1, 0x82, 0xe3, 0x18, 0xdb, 0x8e, 0x33, - 0x12, 0xf9, 0x96, 0x29, 0x76, 0x1c, 0x6e, 0x07, 0xdd, 0x30, 0xa2, 0xad, 0xb4, 0x45, 0xc9, 0x6c, - 0x8c, 0xf4, 0x8c, 0x30, 0xd1, 0x77, 0x17, 0xc8, 0x2a, 0xee, 0x6d, 0x26, 0xb8, 0x97, 0xc9, 0x2d, - 0x9b, 0x0d, 0x6e, 0x3d, 0x2b, 0xea, 0x59, 0x8f, 0xd9, 0xa6, 0xbc, 0xba, 0xf3, 0x1b, 0xa5, 0x86, - 0xe8, 0x98, 0xbd, 0xcb, 0x1b, 0xa2, 0x0f, 0xd1, 0x0d, 0x80, 0x9b, 0xff, 0xfa, 0x8d, 0x4c, 0xf2, - 0xa1, 0x11, 0xf9, 0x14, 0xc6, 0x24, 0x71, 0xff, 0x01, 0x49, 0x52, 0xe3, 0x80, 0x2c, 0xc1, 0xa4, - 0xf1, 0x8a, 0x4a, 0x69, 0x37, 0x59, 0x6f, 0xab, 0x7a, 0xcc, 0xf3, 0xa4, 0xf1, 0x5a, 0x4a, 0x71, - 0xc9, 0x7a, 0x43, 0x95, 0xcb, 0xe5, 0x07, 0x30, 0x2e, 0x86, 0xb4, 0xe7, 0x68, 0xe4, 0xdb, 0xdb, - 0x66, 0x35, 0x8f, 0xe4, 0x6e, 0xcb, 0x8d, 0x16, 0x7d, 0xef, 0xb1, 0xbb, 0xd7, 0x77, 0x60, 0xd2, - 0x24, 0xbb, 0x0b, 0xe4, 0x2b, 0xcc, 0xeb, 0x2c, 0xb3, 0x6d, 0xd3, 0xe8, 0x99, 0x1f, 0x3c, 0x71, - 0xbd, 0xbd, 0x3e, 0x2c, 0x2f, 0x9b, 0x2c, 0x93, 0x74, 0xd2, 0x77, 0xe4, 0x2b, 0x98, 0xaf, 0xe7, - 0x33, 0xef, 0xcb, 0xa4, 0xf7, 0xf1, 0x52, 0x87, 0x0b, 0xe8, 0x3d, 0x73, 0xd2, 0xb6, 0xf7, 0x64, - 0xfa, 0x05, 0x0f, 0xd8, 0x28, 0x6d, 0xf5, 0x4d, 0x3f, 0x68, 0xf5, 0xe7, 0x58, 0x31, 0x1d, 0x69, - 0x13, 0x64, 0x72, 0x30, 0xbe, 0x80, 0x73, 0xf5, 0x5c, 0xd6, 0xfd, 0x58, 0xf4, 0x93, 0x24, 0xcf, - 0xe3, 0x50, 0x9c, 0xb0, 0xdd, 0x3d, 0x79, 0xae, 0xe2, 0x9e, 0xc6, 0xce, 0xa1, 0xad, 0x80, 0x3e, - 0xa6, 0x01, 0xba, 0x6b, 0xf7, 0x73, 0x54, 0x36, 0xd1, 0x65, 0xcf, 0x57, 0xe1, 0x4c, 0x3d, 0xc5, - 0x2a, 0x8f, 0xa4, 0xdf, 0xfd, 0xcf, 0x34, 0xf6, 0xf4, 0x98, 0xed, 0xea, 0xe3, 0x25, 0x34, 0x7e, - 0x8f, 0x46, 0x3b, 0xab, 0x7d, 0x46, 0x49, 0xbe, 0x27, 0x90, 0x88, 0xbb, 0x77, 0x18, 0x65, 0x5d, - 0xa3, 0x4c, 0x63, 0xe4, 0x7e, 0xbc, 0x9f, 0xca, 0xbb, 0x90, 0xbe, 0xd5, 0xe6, 0x71, 0x78, 0x0b, - 0xf7, 0x42, 0xe1, 0xb2, 0x3c, 0x17, 0x8b, 0x00, 0x1c, 0x12, 0x9b, 0xea, 0x34, 0xef, 0xe5, 0x90, - 0x54, 0xb9, 0xfa, 0xc7, 0x97, 0x87, 0x80, 0x5d, 0x4a, 0xb9, 0xb2, 0xf7, 0x64, 0xc1, 0xad, 0xa0, - 0x6b, 0x7e, 0xf3, 0x89, 0x6e, 0x05, 0xd5, 0x32, 0xff, 0xcf, 0x9b, 0x79, 0xf9, 0xc5, 0x8e, 0x8f, - 0xc9, 0xf9, 0x75, 0xc7, 0x2f, 0x3d, 0xf7, 0xff, 0xfc, 0x5c, 0x0a, 0x2e, 0x2c, 0x48, 0x6f, 0x49, - 0xdb, 0x22, 0x56, 0x68, 0x72, 0xce, 0x1d, 0x1a, 0x65, 0x56, 0x44, 0x22, 0xd3, 0xac, 0xa8, 0x37, - 0x34, 0xdf, 0x96, 0x4f, 0x6c, 0xda, 0x69, 0xa3, 0x17, 0xf4, 0x81, 0xcf, 0x69, 0x62, 0xc7, 0xd8, - 0x74, 0x51, 0x7f, 0xff, 0xad, 0x69, 0xe1, 0xf5, 0x63, 0x0c, 0xbc, 0x0a, 0xa8, 0x9c, 0x2e, 0x8b, - 0x87, 0x52, 0x77, 0x46, 0xba, 0x5d, 0x20, 0x1b, 0x70, 0xf6, 0x1e, 0x8d, 0xc4, 0x1e, 0x67, 0xd3, - 0x30, 0x0a, 0xdc, 0x66, 0xd4, 0xf3, 0x62, 0x50, 0xea, 0x26, 0x19, 0x34, 0xbb, 0x6f, 0x33, 0x7e, - 0xf5, 0x6c, 0x7e, 0x3d, 0xe9, 0x7a, 0xb8, 0xc8, 0x8a, 0xdb, 0x86, 0x93, 0x34, 0x31, 0x7f, 0x89, - 0x8f, 0x70, 0x0f, 0x9c, 0x7c, 0xd2, 0x52, 0x1c, 0xfd, 0x44, 0x68, 0x5b, 0x37, 0x61, 0x98, 0x13, - 0xe5, 0x1e, 0xa8, 0x13, 0x3a, 0x0d, 0xb9, 0x03, 0x63, 0xca, 0x85, 0x86, 0x18, 0x45, 0xb9, 0xed, - 0xba, 0x03, 0x63, 0x5c, 0xb5, 0x3a, 0x3e, 0xc9, 0x87, 0x30, 0xa6, 0x7c, 0x6e, 0x4e, 0x7c, 0xd2, - 0x7f, 0x02, 0x93, 0xba, 0xf7, 0xcd, 0xc9, 0x07, 0xf2, 0x07, 0x78, 0x7d, 0x2b, 0x6f, 0x49, 0xf2, - 0xe9, 0x67, 0x13, 0x41, 0x61, 0xc4, 0x90, 0xf2, 0x0d, 0x52, 0x02, 0x73, 0x9b, 0x7f, 0x26, 0x45, - 0x4d, 0x3e, 0x94, 0x2f, 0x99, 0x14, 0x71, 0x1a, 0xa9, 0xc7, 0x98, 0x4d, 0xf1, 0x61, 0x7e, 0x11, - 0x62, 0xb5, 0xc1, 0xf6, 0x6d, 0xf6, 0x71, 0xae, 0x99, 0xfb, 0x0f, 0x5d, 0x1e, 0x97, 0x4d, 0x94, - 0xd2, 0x52, 0xb9, 0xf4, 0xf2, 0x19, 0x5d, 0xca, 0x4f, 0xbf, 0x87, 0x93, 0x71, 0x1f, 0xb5, 0xc0, - 0x54, 0x69, 0x6e, 0xf7, 0x7a, 0xa4, 0xf3, 0x8b, 0xd5, 0xde, 0x34, 0xbb, 0x1e, 0x64, 0xbd, 0xb4, - 0x68, 0xf1, 0x3e, 0xf3, 0x95, 0xb0, 0x5b, 0x95, 0x4e, 0x8c, 0xc7, 0xef, 0x6c, 0x7e, 0xcb, 0xce, - 0x67, 0x5c, 0x6c, 0xf7, 0x9d, 0x8b, 0x3c, 0x76, 0xbf, 0x84, 0xd2, 0x61, 0x66, 0x54, 0xb0, 0x7c, - 0x66, 0xd7, 0x35, 0xdf, 0x88, 0x4c, 0x4a, 0x75, 0xe8, 0x3d, 0xc1, 0x27, 0x62, 0xd9, 0xd9, 0x06, - 0x5f, 0xef, 0xc3, 0x45, 0x8e, 0xc4, 0x77, 0xfa, 0xe2, 0xa9, 0x6b, 0xd2, 0xf3, 0xfc, 0x84, 0xcd, - 0xae, 0xaf, 0x4f, 0xf6, 0xc4, 0x8c, 0x9b, 0x6b, 0xe5, 0x21, 0x9a, 0xcd, 0xd0, 0xf4, 0x10, 0xed, - 0xd9, 0x87, 0xbc, 0xe1, 0xff, 0x0c, 0x2a, 0xb1, 0x03, 0xc8, 0xc9, 0x26, 0x21, 0xdf, 0x31, 0x91, - 0xa4, 0x46, 0x2a, 0x24, 0xbd, 0xd2, 0x09, 0xcd, 0x5f, 0xc9, 0x1b, 0x61, 0xfd, 0x19, 0x8c, 0x70, - 0x6c, 0x4b, 0xe4, 0xdd, 0xcc, 0xcb, 0xe0, 0xd9, 0xc3, 0x0e, 0x2b, 0xde, 0xcc, 0xbd, 0x12, 0x46, - 0xe9, 0xd9, 0x3e, 0x39, 0x23, 0xe5, 0x9f, 0x91, 0x60, 0x64, 0xf5, 0x98, 0xde, 0xfe, 0x57, 0x8f, - 0xe5, 0x9c, 0x79, 0x3d, 0xf9, 0x84, 0x3a, 0xf1, 0x3b, 0xb1, 0x44, 0x10, 0x41, 0xfd, 0x6d, 0x6e, - 0xba, 0x28, 0xf9, 0xc8, 0x29, 0x0b, 0x43, 0x39, 0x45, 0x95, 0x65, 0x15, 0x0c, 0xce, 0x54, 0x11, - 0x3f, 0x70, 0xa3, 0xe7, 0x8b, 0xf6, 0x5a, 0x6c, 0x56, 0xd0, 0x0b, 0x24, 0x6f, 0x90, 0x85, 0xf6, - 0x1a, 0xf9, 0x12, 0xb7, 0x12, 0xc1, 0xbe, 0xe6, 0xfb, 0x51, 0x18, 0x05, 0x4e, 0xa7, 0xde, 0x0c, - 0xdc, 0x4e, 0x94, 0xdb, 0xe9, 0xd8, 0x87, 0x3b, 0x8b, 0x4c, 0x73, 0x29, 0x15, 0x71, 0xec, 0xb3, - 0x22, 0xdf, 0xa8, 0x67, 0x35, 0x59, 0x85, 0x3d, 0x34, 0x97, 0xba, 0x8c, 0x5c, 0xff, 0x2a, 0x99, - 0x36, 0x60, 0x2e, 0x27, 0x5e, 0x90, 0xba, 0xbd, 0xed, 0x1d, 0x4f, 0x68, 0xbe, 0x77, 0xc5, 0xe4, - 0x2b, 0x98, 0xcd, 0x0c, 0x28, 0xa4, 0x2c, 0xd0, 0xbd, 0xc2, 0x0d, 0xf5, 0x63, 0xfe, 0x04, 0xca, - 0xfc, 0x41, 0x07, 0xfa, 0x2d, 0x1b, 0xb1, 0x65, 0xe2, 0x67, 0x3e, 0x39, 0x08, 0xc9, 0xfd, 0x3a, - 0x1f, 0x4f, 0x3d, 0x36, 0x9f, 0xc1, 0xa0, 0x22, 0x89, 0x8c, 0xf1, 0xea, 0xc3, 0xcb, 0x2a, 0xec, - 0xf5, 0x96, 0x68, 0x0b, 0x66, 0x77, 0x69, 0xe0, 0x3e, 0x7e, 0x9e, 0x64, 0x28, 0x47, 0x26, 0xb3, - 0xb4, 0x17, 0xc7, 0xcf, 0x61, 0x6e, 0xd1, 0x3f, 0xe8, 0x88, 0x57, 0x7b, 0x06, 0x4f, 0x75, 0x15, - 0x9f, 0x5d, 0xde, 0xdf, 0x97, 0x69, 0x3e, 0x3f, 0xb7, 0xbf, 0x72, 0x61, 0xeb, 0x9b, 0xfe, 0x5f, - 0xbd, 0x3d, 0x33, 0xe9, 0xb7, 0x71, 0x11, 0x66, 0x25, 0xfb, 0xd7, 0x17, 0x61, 0x56, 0x79, 0xef, - 0x37, 0x60, 0x73, 0x39, 0xf9, 0xfd, 0x7b, 0x70, 0x3d, 0x46, 0x6b, 0x37, 0xe4, 0xd9, 0x62, 0xa6, - 0x2b, 0x4f, 0x38, 0x4d, 0x67, 0xe6, 0x32, 0xcf, 0x6c, 0xa7, 0x16, 0x55, 0xa1, 0xdd, 0xee, 0x21, - 0x62, 0x11, 0x3d, 0xac, 0x02, 0xc3, 0x44, 0x23, 0xfe, 0xa4, 0x4e, 0xdb, 0x6b, 0xb7, 0x4e, 0x11, - 0xa3, 0x50, 0xfb, 0x01, 0x4c, 0xd4, 0xf5, 0xca, 0x33, 0x2a, 0xc9, 0x5d, 0x14, 0xea, 0x15, 0x50, - 0xff, 0xb6, 0xf7, 0xf0, 0x05, 0x55, 0x07, 0xcf, 0xb1, 0x7a, 0x91, 0xeb, 0x3a, 0x63, 0xe4, 0x9e, - 0x53, 0xa7, 0x40, 0x56, 0x6a, 0x48, 0xe5, 0x3a, 0x93, 0x9d, 0xae, 0xae, 0xc1, 0x33, 0xda, 0x24, - 0x33, 0x7f, 0x12, 0xab, 0x7f, 0x8a, 0x5d, 0xe5, 0x13, 0xdf, 0x33, 0x75, 0x28, 0xf7, 0xf3, 0x89, - 0xb3, 0xed, 0xe9, 0x7e, 0x3e, 0xa9, 0x1c, 0x7e, 0xba, 0x9f, 0x4f, 0x46, 0x82, 0xbe, 0x65, 0xe4, - 0x15, 0xa7, 0x02, 0xea, 0x61, 0x8c, 0x50, 0x6c, 0x32, 0x32, 0x0e, 0x3d, 0xd0, 0x83, 0x73, 0xf0, - 0x04, 0x42, 0x3d, 0x6c, 0xad, 0xc9, 0xa0, 0x1c, 0x89, 0x8c, 0x43, 0x77, 0xa1, 0xc4, 0x73, 0x29, - 0xc4, 0x31, 0x0d, 0x63, 0xd7, 0xbf, 0x74, 0x8a, 0x87, 0x1e, 0x93, 0x5a, 0x4a, 0x46, 0x82, 0x53, - 0x26, 0xb3, 0x9c, 0x10, 0x71, 0x3d, 0x96, 0x2a, 0xc4, 0xf1, 0xde, 0x94, 0x61, 0x2a, 0x15, 0x02, - 0x6e, 0xfe, 0x5c, 0x46, 0x89, 0x12, 0x29, 0x27, 0xf4, 0xe8, 0x70, 0xaa, 0x4b, 0x19, 0x21, 0xe3, - 0xe6, 0xcf, 0x67, 0x96, 0x09, 0x46, 0x11, 0xcf, 0x32, 0x9d, 0x9d, 0x1b, 0x3b, 0x7e, 0xc8, 0xd5, - 0x03, 0x47, 0x56, 0x73, 0xe3, 0x38, 0xa8, 0xa2, 0x56, 0xaa, 0x12, 0x21, 0x65, 0x24, 0xe4, 0xfe, - 0x4e, 0xc6, 0x5b, 0x0b, 0x03, 0x23, 0xf6, 0x06, 0xeb, 0x9d, 0x1d, 0x9c, 0x3c, 0x94, 0x89, 0x69, - 0x72, 0x6a, 0xea, 0xc7, 0x20, 0x77, 0x06, 0x1f, 0xca, 0x54, 0x34, 0xaf, 0x9a, 0xf1, 0x23, 0xb8, - 0x90, 0x78, 0xc0, 0x61, 0x32, 0xbe, 0x91, 0xfd, 0xca, 0x23, 0x73, 0x78, 0xf2, 0x65, 0xf6, 0xcb, - 0xe9, 0x87, 0x1e, 0x89, 0x79, 0x3f, 0xe9, 0x9e, 0xb7, 0x0e, 0x53, 0xb8, 0xcd, 0xc8, 0xd4, 0xf2, - 0x71, 0x6c, 0x18, 0x13, 0x9c, 0x0c, 0x52, 0x94, 0x2c, 0x55, 0xef, 0xc7, 0x27, 0xc4, 0xa3, 0x60, - 0x9e, 0xa8, 0x7e, 0xde, 0x7c, 0x29, 0x8c, 0xc0, 0xac, 0x53, 0x4c, 0xe4, 0xbf, 0x27, 0x3f, 0x80, - 0xd3, 0xf1, 0x5b, 0x61, 0xce, 0x22, 0x03, 0xad, 0x87, 0xa1, 0xec, 0x74, 0xfc, 0x60, 0xf8, 0xe4, - 0xe4, 0x2b, 0xf2, 0x28, 0x8a, 0xc9, 0x2f, 0xa6, 0x9e, 0xbb, 0x18, 0x7d, 0x38, 0xce, 0x89, 0xa4, - 0x8d, 0xed, 0x49, 0x67, 0xa7, 0x89, 0x9f, 0x5b, 0x76, 0xd8, 0x43, 0xfd, 0x73, 0xeb, 0x19, 0x9a, - 0x51, 0x89, 0xbf, 0x39, 0x7c, 0xd6, 0xe1, 0x2a, 0x86, 0x4a, 0xd9, 0xe2, 0xc1, 0xf1, 0xb2, 0xb1, - 0xf2, 0xdb, 0x9e, 0x0c, 0xb0, 0xd2, 0x86, 0x2b, 0x7d, 0xe3, 0x3e, 0x92, 0x5b, 0x86, 0x8b, 0x4b, - 0xff, 0x08, 0x91, 0x3d, 0x34, 0x8f, 0x99, 0xac, 0xf0, 0x89, 0xea, 0x9c, 0xed, 0x11, 0xc9, 0x51, - 0x9d, 0xb3, 0x3d, 0xe3, 0x2f, 0x7e, 0x8e, 0xd9, 0x9e, 0xc4, 0x19, 0x85, 0xe1, 0x8f, 0xa8, 0xc7, - 0x83, 0x42, 0xf7, 0xbc, 0xf6, 0xb9, 0x62, 0x5e, 0x8a, 0xa6, 0x08, 0x51, 0xa7, 0xb9, 0x24, 0x34, - 0xb1, 0x3c, 0xe6, 0xfd, 0x99, 0xf4, 0x70, 0xad, 0xbe, 0xc4, 0x17, 0xe0, 0x89, 0x5b, 0x9e, 0x03, - 0xaf, 0x2d, 0xfd, 0xf4, 0x3f, 0x5d, 0x2a, 0xfc, 0xf4, 0x67, 0x97, 0x0a, 0xff, 0xee, 0x67, 0x97, - 0x0a, 0xff, 0xf1, 0x67, 0x97, 0x0a, 0x5f, 0x2e, 0x1c, 0x2f, 0x34, 0x31, 0xcf, 0xcf, 0x78, 0x8b, - 0xb3, 0x1b, 0xc6, 0xff, 0xde, 0xfa, 0x9f, 0x01, 0x00, 0x00, 0xff, 0xff, 0x6f, 0xa1, 0x18, 0xaf, - 0x19, 0xec, 0x00, 0x00, + // 15418 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xcc, 0xbd, 0x59, 0x6c, 0x5c, 0xc9, + 0x7a, 0x18, 0xac, 0xe6, 0xce, 0x8f, 0x8b, 0x5a, 0x45, 0x52, 0x6c, 0x51, 0x4b, 0x4b, 0x47, 0xa3, + 0x19, 0x8d, 0xee, 0x5c, 0x2d, 0x9c, 0xe5, 0xce, 0x3e, 0xd3, 0x4d, 0x52, 0x22, 0x25, 0x6e, 0x73, + 0x9a, 0xa4, 0x66, 0xf3, 0xed, 0x7b, 0xd8, 0x5d, 0x22, 0x8f, 0xd5, 0x3c, 0xa7, 0xef, 0x39, 0xa7, + 0xa5, 0xd1, 0xf5, 0x7f, 0xfd, 0xc3, 0x76, 0x16, 0x07, 0x41, 0x12, 0x1b, 0x88, 0x03, 0x27, 0x79, + 0x70, 0x02, 0x38, 0x40, 0x10, 0x20, 0x80, 0x5f, 0x02, 0x3f, 0x19, 0x41, 0x9e, 0x72, 0x63, 0x20, + 0x48, 0x0c, 0xdb, 0x2f, 0x01, 0x42, 0x27, 0x17, 0xf0, 0x0b, 0x91, 0x3c, 0x18, 0x41, 0x02, 0xe4, + 0x06, 0x06, 0x82, 0xfa, 0x6a, 0x39, 0x55, 0x67, 0xe9, 0x26, 0x25, 0xcd, 0x75, 0x5e, 0x24, 0xf6, + 0xb7, 0x55, 0xd5, 0x57, 0x75, 0xaa, 0xea, 0xfb, 0xea, 0xab, 0xaf, 0xe0, 0x66, 0x44, 0x5b, 0xb4, + 0xed, 0x07, 0xd1, 0xad, 0x16, 0xdd, 0x73, 0x1a, 0xcf, 0x6e, 0x35, 0x5a, 0x2e, 0xf5, 0xa2, 0x5b, + 0xed, 0xc0, 0x8f, 0xfc, 0x5b, 0x4e, 0x27, 0xda, 0x0f, 0x69, 0xf0, 0xc4, 0x6d, 0xd0, 0x9b, 0x08, + 0x21, 0x83, 0xf8, 0xdf, 0xdc, 0xf4, 0x9e, 0xbf, 0xe7, 0x73, 0x1a, 0xf6, 0x17, 0x47, 0xce, 0x9d, + 0xdf, 0xf3, 0xfd, 0xbd, 0x16, 0xe5, 0xcc, 0xbb, 0x9d, 0x47, 0xb7, 0xe8, 0x41, 0x3b, 0x7a, 0x26, + 0x90, 0xe5, 0x24, 0x32, 0x72, 0x0f, 0x68, 0x18, 0x39, 0x07, 0x6d, 0x41, 0xf0, 0xba, 0xaa, 0x8a, + 0x13, 0x45, 0x0c, 0x13, 0xb9, 0xbe, 0x77, 0xeb, 0xc9, 0x1d, 0xfd, 0xa7, 0x20, 0xbd, 0xde, 0xb5, + 0xd6, 0x0d, 0x1a, 0x44, 0xe1, 0xb1, 0x28, 0xe9, 0x13, 0xea, 0x45, 0xa9, 0xe2, 0x05, 0x65, 0xf4, + 0xac, 0x4d, 0x43, 0x4e, 0x22, 0xff, 0x13, 0xa4, 0x57, 0xb2, 0x49, 0xf1, 0x5f, 0x41, 0xf2, 0xdd, + 0x6c, 0x92, 0xa7, 0x74, 0x97, 0xe9, 0xd4, 0x53, 0x7f, 0xf4, 0x20, 0x0f, 0x9c, 0x76, 0x9b, 0x06, + 0xf1, 0x1f, 0x82, 0xfc, 0x9c, 0x22, 0x3f, 0x78, 0xe4, 0x30, 0x15, 0x1d, 0x3c, 0x72, 0x52, 0xcd, + 0xe8, 0x84, 0xce, 0x1e, 0x15, 0xd5, 0x7f, 0x72, 0x47, 0xff, 0xc9, 0x49, 0xad, 0xdf, 0x29, 0xc0, + 0xe0, 0x43, 0x27, 0x6a, 0xec, 0x93, 0x4f, 0x60, 0xf0, 0x81, 0xeb, 0x35, 0xc3, 0x52, 0xe1, 0x72, + 0xff, 0xf5, 0xb1, 0xf9, 0xe2, 0x4d, 0xde, 0x14, 0x44, 0x32, 0x44, 0x75, 0xf6, 0x27, 0x87, 0xe5, + 0x53, 0x47, 0x87, 0xe5, 0xd3, 0x8f, 0x19, 0xd9, 0x1b, 0xfe, 0x81, 0x1b, 0x61, 0xdf, 0xda, 0x9c, + 0x8f, 0x6c, 0xc3, 0x54, 0xa5, 0xd5, 0xf2, 0x9f, 0x6e, 0x3a, 0x41, 0xe4, 0x3a, 0xad, 0x5a, 0xa7, + 0xd1, 0xa0, 0x61, 0x58, 0xea, 0xbb, 0x5c, 0xb8, 0x3e, 0x52, 0xbd, 0x7a, 0x74, 0x58, 0x2e, 0x3b, + 0x0c, 0x5d, 0x6f, 0x73, 0x7c, 0x3d, 0xe4, 0x04, 0x9a, 0xa0, 0x2c, 0x7e, 0xeb, 0x0f, 0x87, 0xa0, + 0xb8, 0xec, 0x87, 0xd1, 0x02, 0xeb, 0x51, 0x9b, 0xfe, 0xb0, 0x43, 0xc3, 0x88, 0x5c, 0x85, 0x21, + 0x06, 0x5b, 0x59, 0x2c, 0x15, 0x2e, 0x17, 0xae, 0x8f, 0x56, 0xc7, 0x8e, 0x0e, 0xcb, 0xc3, 0xfb, + 0x7e, 0x18, 0xd5, 0xdd, 0xa6, 0x2d, 0x50, 0xe4, 0x75, 0x18, 0x59, 0xf7, 0x9b, 0x74, 0xdd, 0x39, + 0xa0, 0x58, 0x8b, 0xd1, 0xea, 0xc4, 0xd1, 0x61, 0x79, 0xd4, 0xf3, 0x9b, 0xb4, 0xee, 0x39, 0x07, + 0xd4, 0x56, 0x68, 0xb2, 0x03, 0x03, 0xb6, 0xdf, 0xa2, 0xa5, 0x7e, 0x24, 0xab, 0x1e, 0x1d, 0x96, + 0x07, 0x02, 0xbf, 0x45, 0x7f, 0x76, 0x58, 0x7e, 0x67, 0xcf, 0x8d, 0xf6, 0x3b, 0xbb, 0x37, 0x1b, + 0xfe, 0xc1, 0xad, 0xbd, 0xc0, 0x79, 0xe2, 0xf2, 0x41, 0xe8, 0xb4, 0x6e, 0xc5, 0x43, 0xb5, 0xed, + 0x8a, 0x7e, 0xaf, 0x3d, 0x0b, 0x23, 0x7a, 0xc0, 0x24, 0xd9, 0x28, 0x8f, 0x3c, 0x84, 0xe9, 0x4a, + 0xb3, 0xe9, 0x72, 0x8e, 0xcd, 0xc0, 0xf5, 0x1a, 0x6e, 0xdb, 0x69, 0x85, 0xa5, 0x81, 0xcb, 0xfd, + 0xd7, 0x47, 0x85, 0x52, 0x14, 0xbe, 0xde, 0x56, 0x04, 0x9a, 0x52, 0x32, 0x05, 0x90, 0x37, 0x61, + 0x64, 0x71, 0xbd, 0xc6, 0xea, 0x1e, 0x96, 0x06, 0x51, 0xd8, 0xec, 0xd1, 0x61, 0x79, 0xaa, 0xe9, + 0x85, 0xd8, 0x34, 0x5d, 0x80, 0x22, 0x24, 0xef, 0xc0, 0xf8, 0x66, 0x67, 0xb7, 0xe5, 0x36, 0xb6, + 0x56, 0x6b, 0x0f, 0xe8, 0xb3, 0xd2, 0xd0, 0xe5, 0xc2, 0xf5, 0xf1, 0x2a, 0x39, 0x3a, 0x2c, 0x4f, + 0xb6, 0x11, 0x5e, 0x8f, 0x5a, 0x61, 0xfd, 0x31, 0x7d, 0x66, 0x1b, 0x74, 0x31, 0x5f, 0xad, 0xb6, + 0xcc, 0xf8, 0x86, 0x53, 0x7c, 0x61, 0xb8, 0xaf, 0xf3, 0x71, 0x3a, 0x72, 0x0b, 0xc0, 0xa6, 0x07, + 0x7e, 0x44, 0x2b, 0xcd, 0x66, 0x50, 0x1a, 0x41, 0xdd, 0x9e, 0x3e, 0x3a, 0x2c, 0x8f, 0x05, 0x08, + 0xad, 0x3b, 0xcd, 0x66, 0x60, 0x6b, 0x24, 0x64, 0x01, 0x46, 0x6c, 0x9f, 0x2b, 0xb8, 0x34, 0x7a, + 0xb9, 0x70, 0x7d, 0x6c, 0xfe, 0xb4, 0x18, 0x86, 0x12, 0x5c, 0x3d, 0x7b, 0x74, 0x58, 0x26, 0x81, + 0xf8, 0xa5, 0xb7, 0x52, 0x52, 0x90, 0x32, 0x0c, 0xaf, 0xfb, 0x0b, 0x4e, 0x63, 0x9f, 0x96, 0x00, + 0xc7, 0xde, 0xe0, 0xd1, 0x61, 0xb9, 0xf0, 0x5d, 0x5b, 0x42, 0xc9, 0x13, 0x18, 0x8b, 0x3b, 0x2a, + 0x2c, 0x8d, 0xa1, 0xfa, 0xb6, 0x8e, 0x0e, 0xcb, 0x67, 0x43, 0x04, 0xd7, 0x59, 0xd7, 0x6b, 0x1a, + 0x7c, 0x81, 0x51, 0xa0, 0x17, 0x44, 0xbe, 0x86, 0x99, 0xf8, 0x67, 0x25, 0x0c, 0x69, 0xc0, 0x64, + 0xac, 0x2c, 0x96, 0x26, 0x50, 0x33, 0xaf, 0x1e, 0x1d, 0x96, 0x2d, 0xad, 0x06, 0x75, 0x47, 0x92, + 0xd4, 0xdd, 0xa6, 0xd6, 0xd2, 0x6c, 0x21, 0xf7, 0x07, 0x46, 0xc6, 0x8b, 0x13, 0xf6, 0xc5, 0x6d, + 0x2f, 0x8c, 0x9c, 0xdd, 0x16, 0xcd, 0x24, 0xb2, 0xfe, 0xb2, 0x00, 0x64, 0xa3, 0x4d, 0xbd, 0x5a, + 0x6d, 0x99, 0x7d, 0x4f, 0xf2, 0x73, 0x7a, 0x03, 0x46, 0x79, 0xc7, 0xb1, 0xde, 0xed, 0xc3, 0xde, + 0x9d, 0x3c, 0x3a, 0x2c, 0x83, 0xe8, 0x5d, 0xd6, 0xb3, 0x31, 0x01, 0xb9, 0x06, 0xfd, 0x5b, 0x5b, + 0xab, 0xf8, 0xad, 0xf4, 0x57, 0xa7, 0x8e, 0x0e, 0xcb, 0xfd, 0x51, 0xd4, 0xfa, 0xd9, 0x61, 0x79, + 0x64, 0xb1, 0x13, 0xa0, 0x5a, 0x6c, 0x86, 0x27, 0xd7, 0x60, 0x78, 0xa1, 0xd5, 0x09, 0x23, 0x1a, + 0x94, 0x06, 0xe2, 0x8f, 0xb4, 0xc1, 0x41, 0xb6, 0xc4, 0x91, 0xef, 0xc0, 0xc0, 0x76, 0x48, 0x83, + 0xd2, 0x20, 0xf6, 0xf7, 0x84, 0xe8, 0x6f, 0x06, 0xda, 0x99, 0xaf, 0x8e, 0xb0, 0x2f, 0xb1, 0x13, + 0xd2, 0xc0, 0x46, 0x22, 0x72, 0x13, 0x06, 0x79, 0xa7, 0x0d, 0xe1, 0x24, 0x35, 0xa1, 0x46, 0x47, + 0x8b, 0xee, 0xbc, 0x53, 0x1d, 0x3d, 0x3a, 0x2c, 0x0f, 0x62, 0xe7, 0xd9, 0x9c, 0xec, 0xfe, 0xc0, + 0x48, 0xa1, 0xd8, 0x67, 0x8f, 0x30, 0x5e, 0xf6, 0x59, 0x58, 0xdf, 0x81, 0x31, 0xad, 0xf9, 0xe4, + 0x02, 0x0c, 0xb0, 0xff, 0x71, 0x12, 0x19, 0xe7, 0x85, 0xb1, 0x85, 0xc3, 0x46, 0xa8, 0xf5, 0x4f, + 0xa6, 0xa0, 0xc8, 0x38, 0x8d, 0x99, 0xe7, 0xa6, 0xae, 0x2a, 0xce, 0x57, 0x34, 0x55, 0x55, 0x2a, + 0xe8, 0xca, 0xba, 0x0e, 0xaa, 0x74, 0x31, 0x09, 0x8d, 0x1f, 0x1d, 0x96, 0x47, 0x3a, 0x02, 0x16, + 0xd7, 0x8d, 0xd4, 0x60, 0x78, 0xe9, 0x9b, 0xb6, 0x1b, 0xd0, 0x10, 0x55, 0x3b, 0x36, 0x3f, 0x77, + 0x93, 0x2f, 0x97, 0x37, 0xe5, 0x72, 0x79, 0x73, 0x4b, 0x2e, 0x97, 0xd5, 0x8b, 0x62, 0x32, 0x3e, + 0x43, 0x39, 0x4b, 0x3c, 0x3e, 0x7e, 0xe3, 0xcf, 0xca, 0x05, 0x5b, 0x4a, 0x22, 0x6f, 0xc0, 0xd0, + 0x5d, 0x3f, 0x38, 0x70, 0x22, 0xd1, 0x07, 0xd3, 0x47, 0x87, 0xe5, 0xe2, 0x23, 0x84, 0x68, 0x43, + 0x4a, 0xd0, 0x90, 0xbb, 0x30, 0x69, 0xfb, 0x9d, 0x88, 0x6e, 0xf9, 0xb2, 0xe7, 0x06, 0x91, 0xeb, + 0xd2, 0xd1, 0x61, 0x79, 0x2e, 0x60, 0x98, 0x7a, 0xe4, 0xd7, 0x45, 0x17, 0x6a, 0xfc, 0x09, 0x2e, + 0xb2, 0x04, 0x93, 0x15, 0x9c, 0xbd, 0x85, 0xd6, 0x78, 0x7f, 0x8d, 0x56, 0x2f, 0x1e, 0x1d, 0x96, + 0xcf, 0x39, 0x88, 0xa9, 0x07, 0x02, 0xa5, 0x8b, 0x31, 0x99, 0xc8, 0x3a, 0x9c, 0x79, 0xd0, 0xd9, + 0xa5, 0x81, 0x47, 0x23, 0x1a, 0xca, 0x1a, 0x0d, 0x63, 0x8d, 0x2e, 0x1f, 0x1d, 0x96, 0x2f, 0x3c, + 0x56, 0xc8, 0x8c, 0x3a, 0xa5, 0x59, 0x09, 0x85, 0xd3, 0xa2, 0xa2, 0x8b, 0x4e, 0xe4, 0xec, 0x3a, + 0x21, 0xc5, 0x49, 0x69, 0x6c, 0xfe, 0x2c, 0x57, 0xf1, 0xcd, 0x04, 0xb6, 0x7a, 0x55, 0x68, 0xf9, + 0xbc, 0x6a, 0x7b, 0x53, 0xa0, 0xb4, 0x82, 0x92, 0x32, 0xd9, 0xdc, 0xac, 0xd6, 0x9d, 0x51, 0xac, + 0x2d, 0xce, 0xcd, 0x6a, 0xdd, 0xd1, 0x67, 0x2d, 0xb5, 0x02, 0xad, 0xc2, 0xe0, 0x36, 0x5b, 0x9d, + 0x71, 0xce, 0x9a, 0x9c, 0xbf, 0x22, 0x6a, 0x94, 0x1c, 0x7f, 0x37, 0xd9, 0x0f, 0x24, 0xc4, 0x2f, + 0xef, 0x34, 0xae, 0xe8, 0xfa, 0x5a, 0x8c, 0x38, 0xf2, 0x19, 0x80, 0xa8, 0x55, 0xa5, 0xdd, 0x2e, + 0x8d, 0x61, 0x23, 0xcf, 0x98, 0x8d, 0xac, 0xb4, 0xdb, 0xd5, 0x4b, 0xa2, 0x7d, 0x67, 0x55, 0xfb, + 0x9c, 0x76, 0x5b, 0x93, 0xa6, 0x09, 0x21, 0x9f, 0xc0, 0x38, 0x4e, 0x69, 0xb2, 0x47, 0xc7, 0xb1, + 0x47, 0xcf, 0x1f, 0x1d, 0x96, 0x67, 0x71, 0xb6, 0xca, 0xe8, 0x4f, 0x83, 0x81, 0xfc, 0x32, 0xcc, + 0x08, 0x71, 0x0f, 0x5d, 0xaf, 0xe9, 0x3f, 0x0d, 0x17, 0x69, 0xf8, 0x38, 0xf2, 0xdb, 0x38, 0xfd, + 0x8d, 0xcd, 0x5f, 0x30, 0xab, 0x67, 0xd2, 0x54, 0x6f, 0x88, 0x9a, 0x5a, 0xaa, 0xa6, 0x4f, 0x39, + 0x41, 0xbd, 0xc9, 0x29, 0xf4, 0x09, 0x32, 0x53, 0x04, 0x59, 0x81, 0xd3, 0xdb, 0x21, 0x35, 0xda, + 0x30, 0x89, 0xeb, 0x43, 0x99, 0xf5, 0x70, 0x27, 0xa4, 0xf5, 0xbc, 0x76, 0x24, 0xf9, 0x88, 0x0d, + 0x64, 0x31, 0xf0, 0xdb, 0x89, 0x31, 0x7e, 0x1a, 0x35, 0x62, 0x1d, 0x1d, 0x96, 0x2f, 0x35, 0x03, + 0xbf, 0x5d, 0xcf, 0x1f, 0xe8, 0x19, 0xdc, 0xe4, 0xfb, 0x70, 0x76, 0xc1, 0xf7, 0x3c, 0xda, 0x60, + 0x33, 0xe8, 0xa2, 0xeb, 0xec, 0x79, 0x7e, 0x18, 0xb9, 0x8d, 0x95, 0xc5, 0x52, 0x31, 0x5e, 0x1e, + 0x1a, 0x8a, 0xa2, 0xde, 0x54, 0x24, 0xe6, 0xf2, 0x90, 0x23, 0x85, 0x7c, 0x05, 0x13, 0xa2, 0x2c, + 0x1a, 0xe0, 0xd0, 0x3c, 0xd3, 0x7d, 0xa0, 0x29, 0x62, 0xbe, 0xd0, 0x07, 0xf2, 0x27, 0xdf, 0x3a, + 0x99, 0xb2, 0xc8, 0xd7, 0x30, 0xb6, 0x76, 0xb7, 0x62, 0xd3, 0xb0, 0xed, 0x7b, 0x21, 0x2d, 0x11, + 0xec, 0xd1, 0x4b, 0x42, 0xf4, 0xda, 0xdd, 0x4a, 0xa5, 0x13, 0xed, 0x53, 0x2f, 0x72, 0x1b, 0x4e, + 0x44, 0x25, 0x55, 0x75, 0x8e, 0x8d, 0xbc, 0x83, 0x47, 0x4e, 0x3d, 0x10, 0x10, 0xad, 0x15, 0xba, + 0x38, 0x32, 0x07, 0x23, 0xb5, 0xda, 0xf2, 0xaa, 0xbf, 0xe7, 0x7a, 0xa5, 0x29, 0xa6, 0x0c, 0x5b, + 0xfd, 0x26, 0x8f, 0x60, 0x46, 0xb3, 0x0d, 0xea, 0xec, 0x7f, 0x7a, 0x40, 0xbd, 0xa8, 0x34, 0x8d, + 0x75, 0xf8, 0xae, 0x32, 0x6e, 0x6e, 0xea, 0x26, 0xc4, 0x93, 0x3b, 0x37, 0x2b, 0xf1, 0xcf, 0x9a, + 0x64, 0xaa, 0xf6, 0x95, 0x0a, 0xf6, 0xb4, 0x93, 0x81, 0x21, 0x5b, 0x30, 0xbc, 0xd9, 0x09, 0xda, + 0x7e, 0x48, 0x4b, 0x33, 0xa8, 0xb8, 0xab, 0xdd, 0xbe, 0x50, 0x41, 0x5a, 0x9d, 0x61, 0x53, 0x74, + 0x9b, 0xff, 0xd0, 0x5a, 0x27, 0x45, 0x91, 0x4f, 0x61, 0xbc, 0x56, 0x5b, 0x8e, 0x17, 0x94, 0xb3, + 0xb8, 0xa0, 0x5c, 0x38, 0x3a, 0x2c, 0x97, 0xd8, 0x96, 0x2a, 0x5e, 0x54, 0xf4, 0xaf, 0x4a, 0xe7, + 0x60, 0x12, 0xb6, 0x56, 0x6b, 0xb1, 0x84, 0xd9, 0x58, 0x02, 0xdb, 0xcc, 0x65, 0x4b, 0xd0, 0x39, + 0xc8, 0xbf, 0x2c, 0xc0, 0x65, 0x5d, 0x64, 0x96, 0x62, 0x4a, 0xe7, 0x9e, 0x47, 0x9b, 0xf3, 0x47, + 0x87, 0xe5, 0x9b, 0x66, 0x3b, 0xea, 0x99, 0x9d, 0xa5, 0xd5, 0xad, 0x67, 0x55, 0xb0, 0xbe, 0x7a, + 0x03, 0x32, 0xeb, 0x3b, 0xf7, 0xdc, 0xf5, 0x35, 0xb5, 0xd6, 0xbb, 0xbe, 0xbd, 0xaa, 0x62, 0x7d, + 0x0e, 0xa3, 0x6a, 0xd2, 0x26, 0xc3, 0xd0, 0x5f, 0x69, 0xb5, 0x8a, 0xa7, 0xd8, 0x1f, 0xb5, 0xda, + 0x72, 0xb1, 0x40, 0x26, 0x01, 0xe2, 0x95, 0xaa, 0xd8, 0x47, 0xc6, 0x61, 0x44, 0xae, 0x24, 0xc5, + 0x7e, 0xa4, 0x6f, 0xb7, 0x8b, 0x03, 0x84, 0xc0, 0xa4, 0x39, 0x9f, 0x15, 0x07, 0xad, 0xdf, 0x2c, + 0xc0, 0xa8, 0xfa, 0x0e, 0xc9, 0x69, 0x18, 0xdb, 0x5e, 0xaf, 0x6d, 0x2e, 0x2d, 0xac, 0xdc, 0x5d, + 0x59, 0x5a, 0x2c, 0x9e, 0x22, 0x17, 0xe1, 0xdc, 0x56, 0x6d, 0xb9, 0xbe, 0x58, 0xad, 0xaf, 0x6e, + 0x2c, 0x54, 0x56, 0xeb, 0x9b, 0xf6, 0xc6, 0xe7, 0x5f, 0xd4, 0xb7, 0xb6, 0xd7, 0xd7, 0x97, 0x56, + 0x8b, 0x05, 0x52, 0x82, 0x69, 0x86, 0x7e, 0xb0, 0x5d, 0x5d, 0xd2, 0x09, 0x8a, 0x7d, 0xe4, 0x0a, + 0x5c, 0xcc, 0xc2, 0xd4, 0x97, 0x97, 0x2a, 0x8b, 0xab, 0x4b, 0xb5, 0x5a, 0xb1, 0x9f, 0xcc, 0xc2, + 0x14, 0x23, 0xa9, 0x6c, 0x6e, 0x1a, 0xbc, 0x03, 0x56, 0x0b, 0xc6, 0xb4, 0x0f, 0x80, 0x5c, 0x80, + 0xd2, 0xc2, 0x92, 0xbd, 0x55, 0xdf, 0xdc, 0xb6, 0x37, 0x37, 0x6a, 0x4b, 0x75, 0xb3, 0x86, 0x49, + 0xec, 0xea, 0xc6, 0xbd, 0x95, 0xf5, 0x3a, 0x03, 0xd5, 0x8a, 0x05, 0x56, 0x0d, 0x03, 0x5b, 0x5b, + 0x59, 0xbf, 0xb7, 0xba, 0x54, 0xdf, 0xae, 0x2d, 0x09, 0x92, 0x3e, 0xeb, 0x57, 0xfb, 0x52, 0x4b, + 0x3a, 0x99, 0x87, 0xb1, 0x1a, 0xf7, 0x57, 0xe0, 0x34, 0xc7, 0x0d, 0x44, 0xb6, 0x47, 0x1b, 0x17, + 0x6e, 0x0c, 0x3e, 0x83, 0xe9, 0x44, 0x6c, 0x97, 0xb6, 0xc9, 0xbe, 0xe6, 0x86, 0xdf, 0xd2, 0x77, + 0x69, 0x6d, 0x01, 0xb3, 0x15, 0x96, 0xcc, 0x6b, 0xfb, 0x39, 0x6e, 0x2d, 0xa2, 0x45, 0x22, 0xf7, + 0x73, 0xfa, 0xda, 0xae, 0x76, 0x76, 0xf3, 0x71, 0x97, 0x8a, 0x6d, 0x18, 0xf2, 0x64, 0xec, 0x25, + 0x14, 0x1d, 0x79, 0x5d, 0xee, 0x74, 0xb9, 0x75, 0x87, 0x8b, 0x7d, 0xc2, 0x2e, 0x11, 0x9b, 0x5c, + 0xab, 0x93, 0xb3, 0xb0, 0x92, 0x0f, 0x92, 0x63, 0x46, 0x28, 0x03, 0x85, 0x25, 0xd6, 0x4f, 0x3b, + 0x41, 0x4a, 0xca, 0x30, 0xc8, 0x67, 0x5c, 0xae, 0x0f, 0xdc, 0x5b, 0xb7, 0x18, 0xc0, 0xe6, 0x70, + 0xeb, 0x8f, 0xfa, 0xf5, 0x4d, 0x06, 0xdb, 0x4b, 0x6b, 0xfa, 0xc6, 0xbd, 0x34, 0xea, 0x19, 0xa1, + 0xcc, 0x14, 0xe4, 0x5f, 0x09, 0x9a, 0x82, 0xfd, 0xb1, 0x29, 0x28, 0x3e, 0x35, 0x6e, 0x0a, 0xc6, + 0x24, 0xac, 0x17, 0xc5, 0xb6, 0x0d, 0xa5, 0x0e, 0xc4, 0xbd, 0x28, 0xb6, 0x7a, 0xa2, 0x17, 0x35, + 0x22, 0xf2, 0x3e, 0x40, 0xe5, 0x61, 0x0d, 0x6d, 0x1e, 0x7b, 0x5d, 0x6c, 0x5d, 0x71, 0x91, 0x71, + 0x9e, 0x86, 0xc2, 0xa4, 0x0a, 0x74, 0x9b, 0x51, 0xa3, 0x26, 0x55, 0x98, 0xa8, 0xfc, 0xa8, 0x13, + 0xd0, 0x95, 0x26, 0x5b, 0xa7, 0x22, 0x6e, 0x1c, 0x8f, 0xf2, 0x89, 0xd4, 0x61, 0x88, 0xba, 0x2b, + 0x30, 0x9a, 0x00, 0x93, 0x85, 0x6c, 0xc0, 0x99, 0x7b, 0x0b, 0x9b, 0x62, 0x5c, 0x55, 0x1a, 0x0d, + 0xbf, 0xe3, 0x45, 0x62, 0xbf, 0x7a, 0xe5, 0xe8, 0xb0, 0x7c, 0x71, 0xaf, 0xd1, 0xae, 0xcb, 0x31, + 0xe8, 0x70, 0xb4, 0xbe, 0x61, 0x4d, 0xf1, 0x92, 0xab, 0xd0, 0xbf, 0x6d, 0xaf, 0x08, 0xcb, 0xf9, + 0xcc, 0xd1, 0x61, 0x79, 0xa2, 0x13, 0xb8, 0x1a, 0x0b, 0xc3, 0x92, 0xf7, 0x00, 0xb6, 0x9c, 0x60, + 0x8f, 0x46, 0x9b, 0x7e, 0x10, 0xe1, 0x86, 0x73, 0xa2, 0x7a, 0xee, 0xe8, 0xb0, 0x3c, 0x13, 0x21, + 0xb4, 0xce, 0xa6, 0x3f, 0xbd, 0xd1, 0x31, 0xf1, 0xfd, 0x81, 0x91, 0xbe, 0x62, 0xbf, 0x3d, 0x5a, + 0xa3, 0x61, 0xc8, 0xed, 0xc3, 0x16, 0x4c, 0xde, 0xa3, 0x11, 0x1b, 0xb8, 0xd2, 0xde, 0xe9, 0xde, + 0xad, 0x1f, 0xc2, 0xd8, 0x43, 0x37, 0xda, 0xaf, 0xd1, 0x46, 0x40, 0x23, 0xe9, 0xeb, 0x41, 0x95, + 0x3f, 0x75, 0xa3, 0xfd, 0x7a, 0xc8, 0xe1, 0xfa, 0xba, 0xae, 0x91, 0x5b, 0x4b, 0x70, 0x5a, 0x94, + 0xa6, 0xcc, 0xab, 0x79, 0x53, 0x60, 0x01, 0x05, 0x62, 0xb7, 0xeb, 0x02, 0x4d, 0x31, 0xff, 0xaa, + 0x0f, 0x66, 0x16, 0xf6, 0x1d, 0x6f, 0x8f, 0x6e, 0x3a, 0x61, 0xf8, 0xd4, 0x0f, 0x9a, 0x5a, 0xe5, + 0xd1, 0xb6, 0x4c, 0x55, 0x1e, 0x8d, 0xc9, 0x79, 0x18, 0xdb, 0x68, 0x35, 0x25, 0x8f, 0xb0, 0x7b, + 0xb1, 0x2c, 0xbf, 0xd5, 0xac, 0xb7, 0xa5, 0x2c, 0x9d, 0x88, 0xf1, 0xac, 0xd3, 0xa7, 0x8a, 0xa7, + 0x3f, 0xe6, 0xf1, 0xe8, 0x53, 0x8d, 0x47, 0x23, 0x22, 0x4b, 0x70, 0xa6, 0x46, 0x1b, 0xbe, 0xd7, + 0xbc, 0xeb, 0x34, 0x22, 0x3f, 0xd8, 0xf2, 0x1f, 0x53, 0x4f, 0x0c, 0x68, 0x34, 0x0c, 0x42, 0x44, + 0xd6, 0x1f, 0x21, 0xb6, 0x1e, 0x31, 0xb4, 0x9d, 0xe6, 0x20, 0x1b, 0x30, 0xf2, 0x50, 0x78, 0x0c, + 0x85, 0xb1, 0x7c, 0xed, 0xa6, 0x72, 0x21, 0x2e, 0x04, 0x14, 0x47, 0xa1, 0xd3, 0x52, 0xe6, 0xbe, + 0xda, 0x67, 0xe1, 0x54, 0x26, 0x29, 0x6d, 0x25, 0xc4, 0xda, 0x86, 0x89, 0xcd, 0x56, 0x67, 0xcf, + 0xf5, 0xd8, 0xa4, 0x53, 0xa3, 0x3f, 0x24, 0x8b, 0x00, 0x31, 0x40, 0xf8, 0x01, 0xa7, 0x84, 0x89, + 0x1d, 0x23, 0x76, 0xde, 0x14, 0x5f, 0x2e, 0x42, 0xd0, 0x22, 0xb2, 0x35, 0x3e, 0xeb, 0x7f, 0xf7, + 0x03, 0x11, 0x1d, 0x80, 0x8b, 0x60, 0x8d, 0x46, 0x6c, 0x79, 0x3a, 0x0b, 0x7d, 0xca, 0x5d, 0x37, + 0x74, 0x74, 0x58, 0xee, 0x73, 0x9b, 0x76, 0xdf, 0xca, 0x22, 0x79, 0x0b, 0x06, 0x91, 0x0c, 0xf5, + 0x3f, 0xa9, 0xca, 0xd3, 0x25, 0xf0, 0xc9, 0x07, 0x57, 0x5f, 0x9b, 0x13, 0x93, 0xb7, 0x61, 0x74, + 0x91, 0xb6, 0xe8, 0x9e, 0x13, 0xf9, 0x72, 0x3a, 0xe1, 0x0e, 0x30, 0x09, 0xd4, 0xc6, 0x5c, 0x4c, + 0xc9, 0xcc, 0x61, 0x9b, 0x3a, 0xa1, 0xef, 0xe9, 0xe6, 0x70, 0x80, 0x10, 0xdd, 0x1c, 0xe6, 0x34, + 0xe4, 0xb7, 0x0a, 0x30, 0x56, 0xf1, 0x3c, 0xe1, 0x58, 0x0a, 0x85, 0xd6, 0x67, 0x6e, 0x2a, 0x4f, + 0xec, 0xaa, 0xb3, 0x4b, 0x5b, 0x3b, 0x4e, 0xab, 0x43, 0xc3, 0xea, 0xd7, 0xcc, 0x42, 0xf9, 0x4f, + 0x87, 0xe5, 0x0f, 0x4e, 0xe0, 0x2a, 0x8a, 0x7d, 0xba, 0x5b, 0x81, 0xe3, 0x46, 0x21, 0xfb, 0x6a, + 0x9d, 0xb8, 0x40, 0xfd, 0xbb, 0xd1, 0xea, 0x11, 0xaf, 0x0d, 0x43, 0xbd, 0xd6, 0x06, 0x72, 0x00, + 0xa7, 0x2b, 0x61, 0xd8, 0x39, 0xa0, 0xb5, 0xc8, 0x09, 0xa2, 0x2d, 0xf7, 0x80, 0xe2, 0x84, 0xd4, + 0xdd, 0xb9, 0xf0, 0xda, 0x4f, 0x0e, 0xcb, 0x05, 0x66, 0x14, 0x39, 0xc8, 0xca, 0xf6, 0x3d, 0x41, + 0x54, 0x8f, 0x5c, 0x7d, 0x79, 0x43, 0x37, 0x43, 0x52, 0xb6, 0x75, 0x55, 0x6d, 0x48, 0x56, 0x16, + 0xf3, 0x7a, 0xdc, 0x5a, 0x80, 0x0b, 0xf7, 0x68, 0x64, 0xd3, 0x90, 0x46, 0xf2, 0x1b, 0xc1, 0x11, + 0x1e, 0x3b, 0x77, 0x87, 0xf1, 0xb7, 0x62, 0xc6, 0xee, 0xe7, 0xdf, 0x85, 0xc4, 0x58, 0x7f, 0xad, + 0x00, 0xe5, 0x85, 0x80, 0x72, 0x7b, 0x22, 0x47, 0x50, 0xf7, 0xb9, 0xeb, 0x02, 0x0c, 0x6c, 0x3d, + 0x6b, 0x4b, 0xaf, 0x0c, 0x62, 0x59, 0xa7, 0xd8, 0x08, 0x3d, 0xa6, 0x93, 0xcb, 0x7a, 0x04, 0x33, + 0x36, 0xf5, 0xe8, 0x53, 0x67, 0xb7, 0x45, 0x0d, 0x3f, 0x51, 0x19, 0x06, 0xf9, 0x87, 0x9e, 0x6a, + 0x02, 0x87, 0x9f, 0xcc, 0xe7, 0x66, 0x4d, 0xc0, 0xd8, 0xa6, 0xeb, 0xed, 0x09, 0xe9, 0xd6, 0x9f, + 0x0f, 0xc0, 0x38, 0xff, 0x2d, 0x4c, 0xa4, 0xc4, 0x72, 0x59, 0x38, 0xce, 0x72, 0xf9, 0x2e, 0x4c, + 0xb0, 0xf5, 0x86, 0x06, 0x3b, 0x34, 0x60, 0xf3, 0xbf, 0xd0, 0x04, 0x9a, 0x7b, 0x21, 0x22, 0xea, + 0x4f, 0x38, 0xc6, 0x36, 0x09, 0xc9, 0x2a, 0x4c, 0x72, 0xc0, 0x5d, 0xea, 0x44, 0x9d, 0xd8, 0x63, + 0x75, 0x5a, 0xd8, 0x44, 0x12, 0xcc, 0x87, 0xa6, 0x90, 0xf5, 0x48, 0x00, 0xed, 0x04, 0x2f, 0xf9, + 0x04, 0x4e, 0x6f, 0x06, 0xfe, 0x37, 0xcf, 0xb4, 0x0d, 0x02, 0xff, 0x3a, 0xb9, 0xf5, 0xc4, 0x50, + 0x75, 0x7d, 0x9b, 0x90, 0xa4, 0x26, 0xaf, 0xc3, 0xc8, 0x4a, 0x58, 0xf5, 0x03, 0xd7, 0xdb, 0xc3, + 0x6f, 0x74, 0x84, 0x3b, 0xfa, 0xdd, 0xb0, 0xbe, 0x8b, 0x40, 0x5b, 0xa1, 0x13, 0x2e, 0xe9, 0xe1, + 0xde, 0x2e, 0xe9, 0xdb, 0x00, 0xab, 0xbe, 0xd3, 0xac, 0xb4, 0x5a, 0x0b, 0x95, 0x10, 0x57, 0x62, + 0xb1, 0x1e, 0xb5, 0x7c, 0xa7, 0x59, 0x77, 0x5a, 0xad, 0x7a, 0xc3, 0x09, 0x6d, 0x8d, 0x86, 0x7c, + 0x09, 0xe7, 0x42, 0x77, 0xcf, 0xc3, 0xc6, 0xd5, 0x9d, 0xd6, 0x9e, 0x1f, 0xb8, 0xd1, 0xfe, 0x41, + 0x3d, 0xec, 0xb8, 0x11, 0xf7, 0x07, 0x4d, 0xce, 0x5f, 0x12, 0x93, 0x5c, 0x4d, 0xd2, 0x55, 0x24, + 0x59, 0x8d, 0x51, 0xd9, 0xb3, 0x61, 0x36, 0x82, 0x3c, 0x84, 0x89, 0x55, 0xb7, 0x41, 0xbd, 0x90, + 0xa2, 0x83, 0xef, 0x19, 0x7a, 0x8b, 0xba, 0x7f, 0xcc, 0x4c, 0x89, 0x13, 0x2d, 0x9d, 0x09, 0x3f, + 0x5d, 0x53, 0xce, 0xfd, 0x81, 0x91, 0xa1, 0xe2, 0xb0, 0x7d, 0x5a, 0x00, 0x1f, 0x3a, 0x81, 0xe7, + 0x7a, 0x7b, 0xa1, 0xf5, 0xb7, 0x09, 0x8c, 0xa8, 0x7e, 0xba, 0xa9, 0x5b, 0x2a, 0x62, 0x69, 0xc6, + 0x21, 0x1b, 0xfb, 0xe1, 0x6c, 0x8d, 0x82, 0x9c, 0x43, 0xdb, 0x45, 0x6c, 0x0a, 0x86, 0xd9, 0x27, + 0xe4, 0xb4, 0xdb, 0x36, 0x83, 0xb1, 0xa9, 0x61, 0xb1, 0x8a, 0x83, 0x66, 0x84, 0x4f, 0x0d, 0xcd, + 0x5d, 0xbb, 0x6f, 0xb1, 0xca, 0xbe, 0xc9, 0x8d, 0x95, 0xc5, 0x05, 0xec, 0xff, 0x11, 0xfe, 0x4d, + 0xfa, 0x6e, 0xb3, 0x61, 0x23, 0x94, 0x61, 0x6b, 0x95, 0xb5, 0x55, 0xd1, 0xc7, 0x88, 0x0d, 0x9d, + 0x83, 0x96, 0x8d, 0x50, 0xb6, 0xdb, 0xe5, 0x2e, 0x95, 0x05, 0xdf, 0x8b, 0x02, 0xbf, 0x15, 0xe2, + 0x16, 0x6e, 0x84, 0x8f, 0x41, 0xe1, 0x8b, 0x69, 0x08, 0x94, 0x9d, 0x20, 0x25, 0x0f, 0x61, 0xb6, + 0xd2, 0x7c, 0xe2, 0x78, 0x0d, 0xda, 0xe4, 0x98, 0x87, 0x7e, 0xf0, 0xf8, 0x51, 0xcb, 0x7f, 0x1a, + 0xe2, 0x20, 0x19, 0x11, 0xae, 0x4b, 0x41, 0x22, 0x5d, 0x3b, 0x4f, 0x25, 0x91, 0x9d, 0xc7, 0xcd, + 0xe6, 0x81, 0x85, 0x96, 0xdf, 0x69, 0x8a, 0xa1, 0x83, 0xf3, 0x40, 0x83, 0x01, 0x6c, 0x0e, 0x67, + 0x5a, 0x5a, 0xae, 0xad, 0xe1, 0xc0, 0x10, 0x5a, 0xda, 0x0f, 0x0f, 0x6c, 0x06, 0x23, 0xd7, 0x60, + 0x58, 0x6e, 0xdc, 0xf9, 0x49, 0x06, 0x7a, 0xd0, 0xe5, 0x86, 0x5d, 0xe2, 0xd8, 0x77, 0x6c, 0xd3, + 0x86, 0xff, 0x84, 0x06, 0xcf, 0x16, 0xfc, 0x26, 0x95, 0x6e, 0x2d, 0xe1, 0xb6, 0xe1, 0x88, 0x7a, + 0x83, 0x61, 0x6c, 0x93, 0x90, 0x15, 0xc0, 0x17, 0xee, 0xb0, 0x74, 0x3a, 0x2e, 0x80, 0x2f, 0xec, + 0xa1, 0x2d, 0x71, 0x64, 0x11, 0xce, 0x54, 0x3a, 0x91, 0x7f, 0xe0, 0x44, 0x6e, 0x63, 0xbb, 0xbd, + 0x17, 0x38, 0xac, 0x90, 0x22, 0x32, 0xa0, 0x21, 0xe3, 0x48, 0x64, 0xbd, 0x23, 0xb0, 0x76, 0x9a, + 0x81, 0xbc, 0x03, 0xe3, 0x2b, 0x21, 0x77, 0x5d, 0x3a, 0x21, 0x6d, 0xa2, 0xff, 0x49, 0xd4, 0xd2, + 0x0d, 0xeb, 0xe8, 0xc8, 0xac, 0x33, 0xd3, 0xa7, 0x69, 0x1b, 0x74, 0xc4, 0x82, 0xa1, 0x4a, 0x18, + 0xba, 0x61, 0x84, 0x6e, 0xa5, 0x91, 0x2a, 0x1c, 0x1d, 0x96, 0x87, 0x1c, 0x84, 0xd8, 0x02, 0x43, + 0x1e, 0xc2, 0xd8, 0x22, 0x65, 0x3b, 0xe7, 0xad, 0xa0, 0x13, 0x46, 0xe8, 0x24, 0x1a, 0x9b, 0x3f, + 0x27, 0x66, 0x23, 0x0d, 0x23, 0xc6, 0x32, 0xdf, 0xa2, 0x36, 0x11, 0x5e, 0x8f, 0x18, 0x42, 0x5f, + 0x6a, 0x35, 0x7a, 0x66, 0x16, 0x08, 0x9e, 0x65, 0xb7, 0xc9, 0xe6, 0x97, 0x69, 0xac, 0x03, 0x9a, + 0x05, 0x62, 0x42, 0xab, 0xef, 0x23, 0x46, 0x37, 0x0b, 0x0c, 0x16, 0xd2, 0x48, 0x79, 0xc3, 0x67, + 0x0c, 0x8f, 0xa7, 0x89, 0x94, 0x55, 0x3c, 0xa1, 0xaf, 0xfc, 0x43, 0x18, 0x5b, 0xe8, 0x84, 0x91, + 0x7f, 0xb0, 0xb5, 0x4f, 0x0f, 0x28, 0x3a, 0x92, 0x84, 0xf1, 0xd3, 0x40, 0x70, 0x3d, 0x62, 0x70, + 0xbd, 0x99, 0x1a, 0x39, 0xf9, 0x0c, 0x88, 0xb4, 0x62, 0xee, 0xb1, 0xf1, 0xe1, 0xb1, 0xb1, 0x8c, + 0xbe, 0xa4, 0x11, 0x6e, 0xba, 0x48, 0xe3, 0xa7, 0xbe, 0xa7, 0xd0, 0xba, 0x3f, 0x33, 0xcd, 0xcc, + 0x2a, 0xc4, 0xab, 0x78, 0x2f, 0x70, 0xda, 0xfb, 0xa5, 0x52, 0x6c, 0x1a, 0x88, 0x46, 0xed, 0x31, + 0xb8, 0xb1, 0xc5, 0x89, 0xc9, 0x49, 0x0d, 0x80, 0xff, 0x5c, 0x65, 0x1d, 0xcf, 0xbd, 0x4f, 0x25, + 0x43, 0x5f, 0x0c, 0x21, 0x75, 0x85, 0xe6, 0x8e, 0x10, 0xdb, 0x72, 0x8d, 0xde, 0xd4, 0xc4, 0x90, + 0xc7, 0x50, 0xe4, 0xbf, 0xd6, 0x7c, 0xcf, 0x8d, 0xf8, 0x7a, 0x31, 0x67, 0xb8, 0x2a, 0x93, 0x68, + 0x59, 0x00, 0xba, 0x88, 0x45, 0x01, 0x07, 0x0a, 0xab, 0x15, 0x93, 0x12, 0x4c, 0x36, 0x61, 0x6c, + 0x33, 0xf0, 0x9b, 0x9d, 0x46, 0x84, 0xbb, 0x8c, 0xf3, 0x38, 0xf1, 0x13, 0x51, 0x8e, 0x86, 0xe1, + 0x3a, 0x69, 0x73, 0x40, 0x9d, 0xad, 0x0b, 0xba, 0x4e, 0x34, 0x42, 0x52, 0x85, 0xa1, 0x4d, 0xbf, + 0xe5, 0x36, 0x9e, 0x95, 0x2e, 0x60, 0xa5, 0xa7, 0xa5, 0x30, 0x04, 0xca, 0xaa, 0xe2, 0x96, 0xb6, + 0x8d, 0x20, 0x7d, 0x4b, 0xcb, 0x89, 0x48, 0x05, 0x26, 0x3e, 0x63, 0x03, 0xc6, 0xf5, 0x3d, 0xcf, + 0x71, 0x03, 0x5a, 0xba, 0x88, 0xfd, 0x82, 0x6e, 0xfc, 0x1f, 0xea, 0x08, 0x7d, 0x38, 0x1b, 0x1c, + 0x64, 0x05, 0x4e, 0xaf, 0x84, 0xb5, 0x28, 0x70, 0xdb, 0x74, 0xcd, 0xf1, 0x9c, 0x3d, 0xda, 0x2c, + 0x5d, 0x8a, 0xfd, 0xe8, 0x6e, 0x58, 0x0f, 0x11, 0x57, 0x3f, 0xe0, 0x48, 0xdd, 0x8f, 0x9e, 0xe0, + 0x23, 0x9f, 0xc3, 0xf4, 0xd2, 0x37, 0x11, 0x1b, 0x31, 0xad, 0x4a, 0xa7, 0xe9, 0x46, 0xb5, 0xc8, + 0x0f, 0x9c, 0x3d, 0x5a, 0x2a, 0xa3, 0xbc, 0x57, 0x8e, 0x0e, 0xcb, 0x97, 0xa9, 0xc0, 0xd7, 0x1d, + 0x46, 0x50, 0x0f, 0x39, 0x85, 0x7e, 0x3e, 0x9e, 0x25, 0x81, 0x69, 0xbf, 0xd6, 0x69, 0xb3, 0xdd, + 0x36, 0x6a, 0xff, 0xb2, 0xa1, 0x7d, 0x0d, 0xc3, 0xb5, 0x1f, 0x72, 0x40, 0x4a, 0xfb, 0x1a, 0x21, + 0xb1, 0x81, 0xdc, 0xf7, 0x5d, 0xaf, 0xd2, 0x88, 0xdc, 0x27, 0x54, 0x58, 0xcc, 0x61, 0xe9, 0x0a, + 0xd6, 0x14, 0x7d, 0xfe, 0xbf, 0xe8, 0xbb, 0x5e, 0xdd, 0x41, 0x74, 0x3d, 0x14, 0x78, 0xfd, 0x1b, + 0x49, 0x73, 0x93, 0xef, 0xc3, 0xd9, 0x35, 0x7f, 0xd7, 0x6d, 0x51, 0x3e, 0xe5, 0x70, 0xb5, 0xa0, + 0xff, 0xd2, 0x42, 0xb9, 0xe8, 0xf3, 0x3f, 0x40, 0x8a, 0xba, 0x98, 0xad, 0x0e, 0x14, 0x8d, 0xee, + 0xf3, 0xcf, 0x96, 0x42, 0x96, 0x60, 0x1c, 0xbf, 0xcb, 0x16, 0xfe, 0x0c, 0x4b, 0x57, 0xd1, 0xa4, + 0xbb, 0x92, 0xd8, 0xa5, 0xdd, 0x5c, 0xd2, 0x68, 0x96, 0xbc, 0x28, 0x78, 0x66, 0x1b, 0x6c, 0xe4, + 0x63, 0x98, 0x4b, 0x0e, 0xef, 0x05, 0xdf, 0x7b, 0xe4, 0xee, 0x75, 0x02, 0xda, 0x2c, 0xbd, 0xc2, + 0xaa, 0x6a, 0x77, 0xa1, 0x20, 0x5f, 0xc1, 0x0c, 0xae, 0x75, 0x15, 0xcf, 0xf7, 0x9e, 0x1d, 0xb8, + 0x3f, 0xc2, 0xfd, 0x33, 0xdb, 0xf6, 0x5e, 0xc3, 0x6d, 0xef, 0xb5, 0xa3, 0xc3, 0xf2, 0x15, 0x5c, + 0x13, 0xeb, 0x8e, 0x4e, 0x91, 0xf0, 0x5a, 0x67, 0xcb, 0x98, 0x7b, 0x08, 0x67, 0x52, 0xf5, 0x27, + 0x45, 0xe8, 0x7f, 0x2c, 0xce, 0x67, 0x47, 0x6d, 0xf6, 0x27, 0x79, 0x03, 0x06, 0x9f, 0x30, 0x43, + 0x0d, 0xb7, 0x23, 0xf1, 0x89, 0x9f, 0xc6, 0xba, 0xe2, 0x3d, 0xf2, 0x6d, 0x4e, 0xf4, 0x7e, 0xdf, + 0xbb, 0x85, 0xfb, 0x03, 0x23, 0x63, 0xc5, 0x71, 0x7e, 0xac, 0x7e, 0x7f, 0x60, 0x64, 0xa2, 0x38, + 0x69, 0x55, 0xe0, 0x74, 0x82, 0x9e, 0x94, 0x60, 0x98, 0x7a, 0x6c, 0xf3, 0xdf, 0xe4, 0x1b, 0x22, + 0x5b, 0xfe, 0x24, 0xd3, 0x30, 0xd8, 0x72, 0x0f, 0xdc, 0x08, 0x0b, 0x1c, 0xb4, 0xf9, 0x0f, 0xeb, + 0xb7, 0x0b, 0x40, 0xd2, 0xeb, 0x11, 0xb9, 0x95, 0x10, 0xc3, 0xb7, 0xbe, 0x02, 0xa4, 0x1f, 0x1c, + 0x48, 0xe9, 0x9f, 0xc1, 0x14, 0x1f, 0x10, 0x72, 0xe5, 0xd4, 0xca, 0xe2, 0x33, 0x76, 0x06, 0x5a, + 0x77, 0x36, 0x09, 0x34, 0xae, 0xb3, 0xab, 0x58, 0xb5, 0x0e, 0xcc, 0x64, 0xae, 0x44, 0x64, 0x0d, + 0x66, 0x0e, 0x7c, 0x2f, 0xda, 0x6f, 0x3d, 0x93, 0x0b, 0x91, 0x28, 0xad, 0x80, 0xa5, 0xe1, 0xe4, + 0x9b, 0x49, 0x60, 0x4f, 0x09, 0xb0, 0x90, 0x88, 0xe5, 0x08, 0xa7, 0x93, 0x6c, 0x89, 0x65, 0xc3, + 0x99, 0xd4, 0x84, 0x4e, 0x3e, 0x82, 0xf1, 0x06, 0x1a, 0x77, 0x46, 0x49, 0x7c, 0x39, 0xd3, 0xe0, + 0xfa, 0xb7, 0xca, 0xe1, 0xbc, 0x29, 0xff, 0xac, 0x00, 0xb3, 0x39, 0x53, 0xf9, 0xc9, 0x55, 0xfd, + 0x05, 0x9c, 0x3d, 0x70, 0xbe, 0xa9, 0x07, 0x68, 0xbb, 0xd7, 0x03, 0xc7, 0x4b, 0x68, 0x1b, 0xa7, + 0xa9, 0x6c, 0x0a, 0x3d, 0xb6, 0xe9, 0xc0, 0xf9, 0xc6, 0x46, 0x02, 0x9b, 0xe1, 0x79, 0x3d, 0x3f, + 0x85, 0x09, 0x63, 0xf2, 0x3e, 0x71, 0xe5, 0xac, 0x3b, 0x70, 0x66, 0x91, 0xb6, 0x68, 0x44, 0x8f, + 0xed, 0xb3, 0xb3, 0x36, 0x01, 0x6a, 0xf4, 0xc0, 0x69, 0xef, 0xfb, 0x6c, 0x53, 0x5f, 0xd5, 0x7f, + 0x09, 0x9f, 0x0f, 0x91, 0xe6, 0x89, 0x44, 0xec, 0xbc, 0xc9, 0x37, 0xfa, 0xa1, 0xa2, 0xb4, 0x35, + 0x2e, 0xeb, 0xdf, 0xf7, 0x01, 0x11, 0xb3, 0x6f, 0x40, 0x9d, 0x03, 0x59, 0x8d, 0xf7, 0x60, 0x9c, + 0x5b, 0xe8, 0x1c, 0x8c, 0xd5, 0x19, 0x9b, 0x9f, 0x12, 0x5f, 0x9e, 0x8e, 0x5a, 0x3e, 0x65, 0x1b, + 0xa4, 0x8c, 0xd5, 0xa6, 0xdc, 0xb5, 0x80, 0xac, 0x7d, 0x06, 0xab, 0x8e, 0x62, 0xac, 0xfa, 0x6f, + 0xf2, 0x09, 0x4c, 0x2e, 0xf8, 0x07, 0x6d, 0xa6, 0x13, 0xc1, 0xdc, 0x2f, 0xdc, 0x36, 0xa2, 0x5c, + 0x03, 0xb9, 0x7c, 0xca, 0x4e, 0x90, 0x93, 0x75, 0x98, 0xba, 0xdb, 0xea, 0x84, 0xfb, 0x15, 0xaf, + 0xb9, 0xd0, 0xf2, 0x43, 0x29, 0x65, 0x40, 0x58, 0x5a, 0x62, 0xee, 0x4c, 0x53, 0x2c, 0x9f, 0xb2, + 0xb3, 0x18, 0xc9, 0x35, 0x18, 0x5c, 0x7a, 0xc2, 0xe6, 0x74, 0x19, 0xe1, 0x22, 0x02, 0xf0, 0x36, + 0x3c, 0xba, 0xf1, 0x68, 0xf9, 0x94, 0xcd, 0xb1, 0xd5, 0x51, 0x18, 0x96, 0xd6, 0xfd, 0x2d, 0xb6, + 0xdf, 0x56, 0xea, 0xac, 0x45, 0x4e, 0xd4, 0x09, 0xc9, 0x1c, 0x8c, 0x6c, 0xb7, 0x99, 0xd1, 0x29, + 0xdd, 0x22, 0xb6, 0xfa, 0x6d, 0xbd, 0x61, 0x6a, 0x9a, 0x5c, 0x80, 0xd8, 0xa7, 0x2b, 0x88, 0x35, + 0x27, 0xef, 0xb2, 0xa9, 0xdc, 0xee, 0xd4, 0x46, 0xb9, 0x7d, 0x89, 0x72, 0x8b, 0x49, 0x5d, 0x5b, + 0x33, 0x99, 0xca, 0xb3, 0x3e, 0x87, 0x4b, 0xdb, 0xed, 0x90, 0x06, 0x51, 0xa5, 0xdd, 0x6e, 0xb9, + 0x0d, 0x7e, 0x42, 0x86, 0x5e, 0x00, 0x39, 0x58, 0xde, 0x81, 0x21, 0x0e, 0x10, 0xc3, 0x44, 0x8e, + 0xc1, 0x4a, 0xbb, 0x2d, 0x7c, 0x0f, 0x6f, 0xf2, 0x9d, 0x3f, 0xf7, 0x26, 0xd8, 0x82, 0xda, 0xfa, + 0x8d, 0x02, 0x5c, 0xe2, 0x5f, 0x40, 0xae, 0xe8, 0xef, 0xc0, 0x28, 0xc6, 0xbf, 0xb5, 0x9d, 0x86, + 0xfc, 0x26, 0x78, 0x20, 0xa0, 0x04, 0xda, 0x31, 0x5e, 0x8b, 0x2c, 0xec, 0xcb, 0x8f, 0x2c, 0x94, + 0x1f, 0x58, 0x7f, 0xe6, 0x07, 0xf6, 0x19, 0x58, 0xa2, 0x46, 0xad, 0x56, 0xaa, 0x52, 0xe1, 0xf3, + 0xd4, 0xca, 0xfa, 0xef, 0x7d, 0x30, 0x7b, 0x8f, 0x7a, 0x34, 0x70, 0xb0, 0x9d, 0x86, 0x97, 0x4b, + 0x8f, 0x30, 0x2a, 0x74, 0x8d, 0x30, 0x2a, 0x4b, 0xbf, 0x61, 0x1f, 0xfa, 0x0d, 0x53, 0xe1, 0x52, + 0xcc, 0x16, 0xdd, 0xb6, 0x57, 0x44, 0xb3, 0xd0, 0x16, 0xed, 0x04, 0x2e, 0x3f, 0x65, 0x58, 0x89, + 0xa3, 0x93, 0x06, 0x7a, 0xfa, 0x1c, 0xa6, 0x44, 0xb4, 0xc6, 0xb0, 0x88, 0x4e, 0x32, 0x63, 0x92, + 0xd6, 0x61, 0x88, 0xbb, 0x3b, 0xf1, 0x6c, 0x6b, 0x6c, 0xfe, 0x86, 0xf8, 0xa6, 0x72, 0x1a, 0x28, + 0x7c, 0xa3, 0xb8, 0xb0, 0xf3, 0x21, 0x10, 0x21, 0xc0, 0x16, 0x52, 0xe6, 0x3e, 0x83, 0x31, 0x8d, + 0xe4, 0x38, 0x6b, 0xbf, 0x72, 0xbb, 0xb2, 0xed, 0xa8, 0xb7, 0xc7, 0x3d, 0xb8, 0xda, 0xda, 0x6f, + 0x7d, 0x00, 0xa5, 0x74, 0x6d, 0x84, 0xab, 0xad, 0x97, 0x67, 0xcf, 0x5a, 0x84, 0xe9, 0x7b, 0x34, + 0xc2, 0x81, 0x8b, 0x1f, 0x91, 0x16, 0x65, 0x97, 0xf8, 0xce, 0xe4, 0xac, 0x8a, 0x40, 0x36, 0xc0, + 0xb4, 0xaf, 0xb4, 0x06, 0x33, 0x09, 0x29, 0xa2, 0xfc, 0xf7, 0x61, 0x58, 0x80, 0xd4, 0x8c, 0x2a, + 0x42, 0x75, 0xe9, 0xae, 0x40, 0xec, 0xcc, 0xf3, 0x71, 0x2b, 0x24, 0xdb, 0x92, 0xc1, 0xda, 0x87, + 0xb3, 0x6c, 0x99, 0x8d, 0xa5, 0xaa, 0xe1, 0x78, 0x1e, 0x46, 0xdb, 0x6c, 0xa3, 0x10, 0xba, 0x3f, + 0xe2, 0xc3, 0x68, 0xd0, 0x1e, 0x61, 0x80, 0x9a, 0xfb, 0x23, 0x4a, 0x2e, 0x02, 0x20, 0x12, 0x9b, + 0x29, 0x66, 0x01, 0x24, 0xe7, 0xae, 0x4c, 0x02, 0x18, 0xa3, 0xc7, 0xc7, 0x8d, 0x8d, 0x7f, 0x5b, + 0x01, 0xcc, 0xa6, 0x4a, 0x12, 0x0d, 0xb8, 0x05, 0x23, 0x72, 0x7f, 0x9c, 0x38, 0x64, 0xd0, 0x5b, + 0x60, 0x2b, 0x22, 0xf2, 0x2a, 0x9c, 0xf6, 0xe8, 0x37, 0x51, 0x3d, 0x55, 0x87, 0x09, 0x06, 0xde, + 0x94, 0xf5, 0xb0, 0x7e, 0x01, 0x1d, 0xcb, 0x35, 0xcf, 0x7f, 0xfa, 0xa8, 0xe5, 0x3c, 0xa6, 0xa9, + 0x82, 0x3f, 0x82, 0x91, 0x5a, 0xef, 0x82, 0xf9, 0xe7, 0x23, 0x0b, 0xb7, 0x15, 0x8b, 0xd5, 0x82, + 0x39, 0xd6, 0xa4, 0x5a, 0x65, 0x6d, 0x75, 0xa5, 0xb9, 0xf9, 0x6d, 0x2b, 0xf0, 0x09, 0x9c, 0xcf, + 0x2c, 0xed, 0xdb, 0x56, 0xe2, 0x1f, 0x0c, 0xc0, 0x2c, 0x5f, 0x4c, 0xd2, 0x23, 0xf8, 0xf8, 0x53, + 0xcd, 0xcf, 0xe5, 0xbc, 0xf7, 0x76, 0xc6, 0x79, 0x2f, 0xb2, 0xe8, 0xe7, 0xbd, 0xc6, 0x29, 0xef, + 0xbb, 0xd9, 0xa7, 0xbc, 0xe8, 0x84, 0x32, 0x4f, 0x79, 0x93, 0x67, 0xbb, 0x4b, 0xf9, 0x67, 0xbb, + 0x78, 0xf0, 0x94, 0x71, 0xb6, 0x9b, 0x75, 0xa2, 0x9b, 0x08, 0x94, 0x1a, 0x79, 0xb9, 0x81, 0x52, + 0xaf, 0xc2, 0x70, 0xa5, 0xdd, 0xd6, 0x02, 0x0f, 0xb1, 0x7b, 0x9c, 0x76, 0x9b, 0x2b, 0x4f, 0x22, + 0xe5, 0x3c, 0x0f, 0x19, 0xf3, 0xfc, 0x7b, 0x00, 0x0b, 0x78, 0x3d, 0x02, 0x3b, 0x6e, 0x0c, 0x29, + 0x70, 0x87, 0xcf, 0x2f, 0x4d, 0x60, 0xc7, 0xe9, 0xee, 0x95, 0x98, 0x98, 0x6f, 0xec, 0xad, 0x1d, + 0x28, 0xa5, 0x87, 0xcf, 0x4b, 0x98, 0xba, 0x7e, 0xbf, 0x00, 0x17, 0xc5, 0x26, 0x27, 0xf1, 0x81, + 0x9f, 0x7c, 0x74, 0xbe, 0x0d, 0xe3, 0x82, 0x77, 0x2b, 0xfe, 0x10, 0xf8, 0x01, 0xbb, 0x9c, 0x8c, + 0xf9, 0x8c, 0x6e, 0x90, 0x91, 0xb7, 0x61, 0x04, 0xff, 0x88, 0x0f, 0x86, 0x98, 0x66, 0x46, 0x91, + 0xb4, 0x9e, 0x3c, 0x1e, 0x52, 0xa4, 0xd6, 0xd7, 0x70, 0x29, 0xaf, 0xe2, 0x2f, 0x41, 0x2f, 0xff, + 0xa6, 0x00, 0xe7, 0x85, 0x78, 0x63, 0xaa, 0x78, 0xae, 0x55, 0xe7, 0x04, 0xe1, 0xca, 0xf7, 0x61, + 0x8c, 0x15, 0x28, 0xeb, 0xdd, 0x2f, 0x96, 0x56, 0x61, 0x39, 0xc4, 0x98, 0x45, 0x27, 0x72, 0x44, + 0xf8, 0x8d, 0x73, 0xd0, 0x92, 0x9e, 0x11, 0x5b, 0x67, 0xb6, 0xbe, 0x84, 0x0b, 0xd9, 0x4d, 0x78, + 0x09, 0xfa, 0xb9, 0x0f, 0x73, 0x19, 0x8b, 0xc2, 0xf3, 0xad, 0xc9, 0x5f, 0xc0, 0xf9, 0x4c, 0x59, + 0x2f, 0xa1, 0x9a, 0xcb, 0x6c, 0xc7, 0x11, 0xbd, 0x84, 0x2e, 0xb4, 0x1e, 0xc2, 0xb9, 0x0c, 0x49, + 0x2f, 0xa1, 0x8a, 0xf7, 0x60, 0x56, 0xed, 0xb4, 0x5f, 0xa8, 0x86, 0x6b, 0x70, 0x91, 0x0b, 0x7a, + 0x39, 0xbd, 0xf2, 0x00, 0xce, 0x0b, 0x71, 0x2f, 0x41, 0x7b, 0xcb, 0x70, 0x21, 0x36, 0xa8, 0x33, + 0xf6, 0x49, 0xc7, 0x9e, 0x64, 0xac, 0x55, 0xb8, 0x1c, 0x4b, 0xca, 0xd9, 0x34, 0x1c, 0x5f, 0x1a, + 0xdf, 0x0e, 0xc6, 0xbd, 0xf4, 0x52, 0x7a, 0xf4, 0x21, 0x9c, 0x35, 0x84, 0xbe, 0xb4, 0xad, 0xd2, + 0x0a, 0x4c, 0x71, 0xc1, 0xe6, 0xd6, 0x79, 0x5e, 0xdf, 0x3a, 0x8f, 0xcd, 0x9f, 0x89, 0x45, 0x22, + 0x78, 0xe7, 0xcd, 0x8c, 0xdd, 0xf4, 0x1a, 0xee, 0xa6, 0x25, 0x49, 0x5c, 0xc3, 0xb7, 0x61, 0x88, + 0x43, 0x44, 0xfd, 0x32, 0x84, 0x71, 0x63, 0x81, 0xb3, 0x09, 0x62, 0xeb, 0xfb, 0x70, 0x91, 0x5b, + 0xa2, 0xf1, 0x41, 0xa5, 0x69, 0x2d, 0x7e, 0x94, 0x30, 0x44, 0xcf, 0x09, 0xb9, 0x49, 0xfa, 0x1c, + 0x7b, 0x74, 0x57, 0x8e, 0xed, 0x3c, 0xf9, 0xc7, 0xba, 0xba, 0x26, 0x0d, 0xcc, 0xbe, 0x4c, 0x03, + 0xf3, 0x2a, 0x5c, 0x51, 0x06, 0x66, 0xb2, 0x18, 0x39, 0xb4, 0xac, 0x2f, 0xe1, 0x3c, 0x6f, 0xa8, + 0x0c, 0x29, 0x34, 0xab, 0xf1, 0x41, 0xa2, 0x99, 0xb3, 0xa2, 0x99, 0x26, 0x75, 0x4e, 0x23, 0xff, + 0x4e, 0x41, 0x7e, 0x72, 0xd9, 0xc2, 0x7f, 0xde, 0x16, 0xf7, 0x3a, 0x94, 0x95, 0x42, 0xcc, 0x1a, + 0x3d, 0x9f, 0xb9, 0xbd, 0x06, 0x33, 0xba, 0x18, 0xb7, 0x41, 0x77, 0xee, 0xe0, 0x09, 0xd2, 0x5b, + 0xec, 0xb3, 0x40, 0x80, 0x1c, 0x76, 0xa5, 0x0c, 0xbd, 0x21, 0xbd, 0xad, 0x28, 0xad, 0x3a, 0x5c, + 0x48, 0x77, 0x85, 0xdb, 0x90, 0xf7, 0x09, 0xc8, 0x27, 0xec, 0x13, 0x46, 0x88, 0xe8, 0x8c, 0x5c, + 0xa1, 0xf2, 0x3b, 0xe6, 0xec, 0x92, 0xcb, 0xb2, 0xe4, 0x54, 0x93, 0x68, 0x3f, 0x2b, 0x5d, 0x8e, + 0x87, 0x1f, 0x03, 0x91, 0xa8, 0x85, 0x9a, 0x2d, 0x8b, 0x3e, 0x07, 0xfd, 0x0b, 0x35, 0x5b, 0x5c, + 0x64, 0xc2, 0x9d, 0x60, 0x23, 0x0c, 0x6c, 0x06, 0x4b, 0xee, 0xc8, 0xfb, 0x8e, 0xb1, 0x23, 0xbf, + 0x3f, 0x30, 0xd2, 0x5f, 0x1c, 0xb0, 0x49, 0xcd, 0xdd, 0xf3, 0x1e, 0xba, 0xd1, 0xbe, 0x2a, 0xb0, + 0x62, 0x7d, 0x05, 0x53, 0x46, 0xf1, 0xe2, 0x2b, 0xee, 0x7a, 0x03, 0x8b, 0xed, 0x67, 0x17, 0x2a, + 0x18, 0x56, 0x83, 0x2e, 0x8b, 0x71, 0x3e, 0xdf, 0x34, 0x9c, 0x3a, 0x5e, 0xef, 0xb5, 0x25, 0xd2, + 0xfa, 0xdd, 0x01, 0x4d, 0xba, 0x76, 0xaf, 0xad, 0x4b, 0xeb, 0xee, 0x00, 0xf0, 0x11, 0xa2, 0x35, + 0x8e, 0x6d, 0x00, 0xc7, 0x44, 0xb4, 0x0a, 0x9f, 0x92, 0x6d, 0x8d, 0xe8, 0xb8, 0xf7, 0xde, 0x44, + 0xfc, 0x31, 0x67, 0x92, 0x57, 0x3d, 0x55, 0xfc, 0xb1, 0x10, 0x1d, 0xda, 0x3a, 0x11, 0xf9, 0x7e, + 0xf2, 0x72, 0xc6, 0x20, 0x1e, 0x58, 0xbd, 0x22, 0x4f, 0xb0, 0xd3, 0x6d, 0x3b, 0xd9, 0xfd, 0x8c, + 0xa7, 0x30, 0xc3, 0x78, 0xdd, 0x47, 0x68, 0x58, 0x2c, 0x7d, 0x13, 0x51, 0x8f, 0xcf, 0xed, 0x43, + 0x58, 0xce, 0xb5, 0x2e, 0xe5, 0xc4, 0xc4, 0xc2, 0xff, 0x1e, 0xcb, 0xa9, 0x53, 0x85, 0xb3, 0xb3, + 0xe5, 0xe3, 0x20, 0xb2, 0x57, 0x97, 0xbc, 0x66, 0xdb, 0x77, 0x95, 0xc1, 0xc4, 0x07, 0x51, 0xd0, + 0xaa, 0x53, 0x01, 0xb7, 0x75, 0x22, 0xeb, 0xd5, 0xae, 0x51, 0xed, 0x23, 0x30, 0xb0, 0xb5, 0xb0, + 0xb5, 0x5a, 0x2c, 0x58, 0xb7, 0x00, 0xb4, 0x92, 0x00, 0x86, 0xd6, 0x37, 0xec, 0xb5, 0xca, 0x6a, + 0xf1, 0x14, 0x99, 0x81, 0x33, 0x0f, 0x57, 0xd6, 0x17, 0x37, 0x1e, 0xd6, 0xea, 0xb5, 0xb5, 0x8a, + 0xbd, 0xb5, 0x50, 0xb1, 0x17, 0x8b, 0x05, 0xeb, 0x6b, 0x98, 0x36, 0x5b, 0xf8, 0x52, 0x07, 0x61, + 0x04, 0x53, 0x6a, 0x3f, 0x73, 0xff, 0xe1, 0x96, 0x16, 0xd1, 0x2a, 0x8c, 0xbf, 0x64, 0x64, 0x96, + 0x30, 0x13, 0xc5, 0x67, 0xa4, 0x11, 0x91, 0xd7, 0xf9, 0xb6, 0x20, 0x79, 0x73, 0x99, 0x6d, 0x0b, + 0xea, 0xf1, 0xbe, 0x00, 0xa7, 0xbe, 0xef, 0xc1, 0xb4, 0x59, 0xea, 0x71, 0xbd, 0x54, 0xaf, 0x60, + 0xa8, 0xaf, 0x76, 0xad, 0x89, 0x10, 0xfd, 0xd8, 0x40, 0xcc, 0xac, 0xdf, 0x83, 0xa2, 0xa0, 0x8a, + 0x57, 0xde, 0xab, 0xd2, 0x8d, 0x58, 0xc8, 0xb8, 0x84, 0x29, 0x83, 0xd2, 0x7d, 0x28, 0xb2, 0x19, + 0x53, 0x70, 0xf2, 0x02, 0xa6, 0x61, 0x70, 0x35, 0x3e, 0xce, 0xb1, 0xf9, 0x0f, 0xbc, 0xdd, 0x13, + 0x39, 0x41, 0x24, 0xe3, 0xe0, 0x46, 0x6d, 0xf5, 0x9b, 0xbc, 0x0e, 0x43, 0x77, 0xdd, 0x56, 0x24, + 0x5c, 0x23, 0xf1, 0x22, 0xcf, 0xc4, 0x72, 0x84, 0x2d, 0x08, 0x2c, 0x1b, 0xce, 0x68, 0x05, 0x9e, + 0xa0, 0xaa, 0xa4, 0x04, 0xc3, 0xeb, 0xf4, 0x1b, 0xad, 0x7c, 0xf9, 0xd3, 0x7a, 0x07, 0xce, 0x88, + 0x18, 0x43, 0x4d, 0x4d, 0x57, 0xc4, 0x5d, 0xf1, 0x82, 0x71, 0x61, 0x55, 0x88, 0x44, 0x14, 0xe3, + 0xdb, 0x6e, 0x37, 0x9f, 0x93, 0x8f, 0x2d, 0x14, 0x27, 0xe4, 0x7b, 0x4d, 0x9e, 0x02, 0xf5, 0xea, + 0xce, 0xbf, 0xd1, 0x07, 0xa5, 0x84, 0x97, 0x61, 0x61, 0xdf, 0x69, 0xb5, 0xa8, 0xb7, 0x47, 0xc9, + 0x75, 0x18, 0xd8, 0xda, 0xd8, 0xda, 0x14, 0x5e, 0x52, 0x19, 0x5d, 0xc0, 0x40, 0x8a, 0xc6, 0x46, + 0x0a, 0xf2, 0x00, 0xce, 0xc8, 0x28, 0x62, 0x85, 0x12, 0x3d, 0x74, 0xb1, 0x7b, 0x4c, 0x72, 0x9a, + 0x8f, 0xbc, 0x25, 0x5c, 0x22, 0x3f, 0xec, 0xb8, 0x01, 0x6d, 0xa2, 0xe7, 0x27, 0x3e, 0xaa, 0xd7, + 0x30, 0xb6, 0x4e, 0x46, 0xbe, 0x07, 0xe3, 0xb5, 0xda, 0x46, 0x5c, 0xfa, 0xa0, 0x71, 0x42, 0xa4, + 0xa3, 0x6c, 0x83, 0x90, 0x5f, 0x09, 0xb6, 0xfe, 0xa0, 0x00, 0xb3, 0x39, 0xee, 0x16, 0xf2, 0xba, + 0xa1, 0x87, 0x29, 0x4d, 0x0f, 0x92, 0x64, 0xf9, 0x94, 0x50, 0xc4, 0x82, 0x16, 0x93, 0xdd, 0x7f, + 0x82, 0x98, 0xec, 0xe5, 0x53, 0x71, 0x1c, 0x36, 0x79, 0x15, 0xfa, 0x6b, 0xb5, 0x0d, 0xe1, 0x56, + 0x27, 0x71, 0x0b, 0x34, 0x62, 0x46, 0x50, 0x05, 0x18, 0x91, 0x20, 0xeb, 0x34, 0x4c, 0x18, 0x1d, + 0x63, 0x59, 0x30, 0xae, 0xd7, 0x90, 0xf5, 0xfe, 0x82, 0xdf, 0x54, 0xbd, 0xcf, 0xfe, 0xb6, 0x7e, + 0x6c, 0xea, 0x8c, 0x5c, 0x04, 0x90, 0xe7, 0xb5, 0x6e, 0x53, 0x9e, 0xfc, 0x08, 0xc8, 0x4a, 0x93, + 0x5c, 0x81, 0xf1, 0x80, 0x36, 0xdd, 0x80, 0x36, 0xa2, 0x7a, 0x27, 0x10, 0x17, 0x63, 0xec, 0x31, + 0x09, 0xdb, 0x0e, 0x5a, 0xe4, 0x3b, 0x30, 0xc4, 0x0f, 0x92, 0x45, 0xeb, 0xa5, 0x91, 0x50, 0xab, + 0x6d, 0xac, 0xdd, 0xad, 0xf0, 0x83, 0x6e, 0x5b, 0x90, 0x58, 0x55, 0x18, 0xd3, 0x5a, 0xd5, 0xab, + 0xf4, 0x69, 0x18, 0xd4, 0xbd, 0x94, 0xfc, 0x87, 0xf5, 0x9b, 0x05, 0x98, 0xc6, 0x61, 0xb0, 0xe7, + 0xb2, 0xe5, 0x21, 0x6e, 0xcb, 0xbc, 0xd1, 0x69, 0x17, 0x8c, 0x4e, 0x4b, 0xd0, 0xaa, 0xde, 0x7b, + 0x3f, 0xd5, 0x7b, 0x17, 0xb2, 0x7a, 0x0f, 0xa7, 0x00, 0xd7, 0xf7, 0xf4, 0x4e, 0xd3, 0x8f, 0xeb, + 0x7e, 0xbb, 0x00, 0x53, 0x5a, 0x9d, 0x54, 0x03, 0xef, 0x18, 0x55, 0x3a, 0x9f, 0x51, 0xa5, 0xd4, + 0x78, 0xaa, 0xa6, 0x6a, 0xf4, 0x4a, 0xb7, 0x1a, 0x65, 0x0d, 0x27, 0x63, 0x98, 0xfc, 0x79, 0x01, + 0x66, 0x32, 0x75, 0x40, 0xce, 0xb2, 0xfd, 0x7f, 0x23, 0xa0, 0x91, 0xd0, 0xbc, 0xf8, 0xc5, 0xe0, + 0x2b, 0x61, 0xd8, 0xa1, 0x81, 0xd0, 0xbb, 0xf8, 0x45, 0x5e, 0x81, 0x89, 0x4d, 0x1a, 0xb8, 0x7e, + 0x93, 0x5f, 0x4c, 0xe0, 0x11, 0xbf, 0x13, 0xb6, 0x09, 0x24, 0x17, 0x60, 0x54, 0x45, 0xac, 0x72, + 0x1f, 0xae, 0x1d, 0x03, 0x98, 0xec, 0x45, 0x77, 0x8f, 0x1f, 0xfc, 0x30, 0x66, 0xf1, 0x8b, 0x4d, + 0xc0, 0xd2, 0xa3, 0x3a, 0xc4, 0x27, 0x60, 0xe9, 0x2e, 0x3d, 0x0b, 0x43, 0x9f, 0xd9, 0x38, 0x8e, + 0x31, 0xe7, 0x84, 0x2d, 0x7e, 0x91, 0x49, 0x0c, 0x2d, 0xc7, 0x7b, 0x31, 0x18, 0x52, 0xfe, 0x3e, + 0x4c, 0x67, 0xe9, 0x35, 0xeb, 0x2b, 0x10, 0xbc, 0x7d, 0x8a, 0xf7, 0x4b, 0x98, 0xaa, 0x34, 0x9b, + 0xf1, 0x70, 0xe5, 0xbd, 0xca, 0xe7, 0x09, 0xee, 0xd3, 0x14, 0xdb, 0xda, 0x81, 0x15, 0xcf, 0x8d, + 0xec, 0xa9, 0xa5, 0x6f, 0xdc, 0x30, 0x72, 0xbd, 0x3d, 0xcd, 0xf1, 0x6a, 0x9f, 0x5d, 0xa7, 0x4f, + 0x33, 0x86, 0x00, 0xdb, 0x71, 0x98, 0xb2, 0x39, 0x3c, 0x43, 0xf8, 0xb4, 0x26, 0x36, 0x9e, 0xba, + 0x66, 0x4d, 0xb9, 0x31, 0xa2, 0xbf, 0xd2, 0x78, 0x6c, 0x7d, 0x0f, 0xce, 0xf2, 0x69, 0xbf, 0x5b, + 0xe5, 0x45, 0xb5, 0x75, 0x3f, 0xb1, 0xf5, 0xae, 0xf4, 0xe4, 0x74, 0xad, 0x99, 0x3d, 0x6e, 0xd4, + 0x05, 0x8b, 0xfc, 0x6f, 0x05, 0x98, 0x4b, 0xb0, 0xd6, 0x9e, 0x79, 0x0d, 0xb9, 0xe6, 0xbc, 0x9a, + 0x0c, 0xdd, 0xc7, 0xbd, 0x12, 0x77, 0x90, 0xba, 0x4d, 0x15, 0xbd, 0x4f, 0x6e, 0x01, 0x70, 0x66, + 0x6d, 0x8b, 0x83, 0xc7, 0x03, 0x22, 0xca, 0x09, 0x37, 0x39, 0x1a, 0x09, 0xe9, 0x40, 0x96, 0xde, + 0xc5, 0x37, 0xd2, 0xcb, 0x7f, 0x8e, 0x79, 0x56, 0xa8, 0x60, 0xaf, 0xe7, 0x38, 0xd2, 0xb3, 0xe4, + 0x5b, 0x7f, 0xb7, 0x1f, 0x66, 0xf5, 0x0e, 0x7c, 0x9e, 0xb6, 0x6e, 0xc2, 0xd8, 0x82, 0xef, 0x45, + 0xf4, 0x9b, 0x48, 0xcb, 0x73, 0x41, 0x54, 0x34, 0x82, 0xc2, 0x88, 0xed, 0x35, 0x07, 0xd4, 0xd9, + 0x5e, 0xcf, 0x88, 0xd6, 0x8c, 0x09, 0xc9, 0x02, 0x4c, 0xac, 0xd3, 0xa7, 0x29, 0x05, 0x62, 0xc4, + 0xa8, 0x47, 0x9f, 0xd6, 0x35, 0x25, 0xea, 0x61, 0x7c, 0x06, 0x0f, 0xd9, 0x85, 0x49, 0x39, 0xb8, + 0x0c, 0x65, 0xce, 0xe9, 0x2b, 0xaf, 0x39, 0x9c, 0x79, 0x1e, 0x08, 0x56, 0x42, 0x8e, 0x0e, 0x13, + 0x12, 0x59, 0xd3, 0x79, 0x89, 0x3c, 0xb5, 0x81, 0xb9, 0xb4, 0x6b, 0x18, 0x23, 0x1e, 0x37, 0x99, + 0xd2, 0x40, 0x17, 0x61, 0x6d, 0x42, 0x29, 0xdd, 0x1f, 0xa2, 0xb4, 0xb7, 0x60, 0x88, 0x43, 0xc5, + 0x56, 0x49, 0xa6, 0x30, 0x52, 0xd4, 0xdc, 0x97, 0xd1, 0x14, 0xab, 0x12, 0x87, 0x59, 0xcb, 0xe8, + 0x5f, 0x52, 0x34, 0x6a, 0xb3, 0x7a, 0x3b, 0xd9, 0xbd, 0x18, 0xea, 0x2c, 0xbb, 0x57, 0x8f, 0xc5, + 0x91, 0x57, 0x52, 0x16, 0xd0, 0x45, 0xa7, 0x4b, 0x12, 0x15, 0xbb, 0x01, 0xc3, 0x02, 0x94, 0x48, + 0xae, 0x14, 0x7f, 0x7e, 0x92, 0xc0, 0x7a, 0x1f, 0xce, 0xa1, 0xbf, 0xd0, 0xf5, 0xf6, 0x5a, 0x74, + 0x3b, 0x34, 0x2e, 0x95, 0xf4, 0xfa, 0xac, 0x3f, 0x84, 0xb9, 0x2c, 0xde, 0x9e, 0x5f, 0x36, 0x4f, + 0x77, 0xf2, 0xa7, 0x7d, 0x30, 0xbd, 0x12, 0xea, 0x1b, 0x2e, 0x95, 0xf2, 0x24, 0x23, 0x0d, 0x07, + 0xea, 0x64, 0xf9, 0x54, 0x56, 0x9a, 0x8d, 0xb7, 0xb4, 0xeb, 0xae, 0x7d, 0xdd, 0xf2, 0x6b, 0xb0, + 0x65, 0x4b, 0x5d, 0x78, 0x7d, 0x15, 0x06, 0xd6, 0xd9, 0x54, 0xdd, 0x2f, 0xfa, 0x8e, 0x73, 0x30, + 0x10, 0x5e, 0x37, 0x65, 0x4b, 0x24, 0xfb, 0x41, 0xee, 0xa6, 0x2e, 0xb5, 0x0e, 0xf4, 0xce, 0x1f, + 0xb1, 0x7c, 0x2a, 0x75, 0xbf, 0xf5, 0x1d, 0x18, 0xab, 0x34, 0x0f, 0x78, 0x48, 0xa6, 0xef, 0x25, + 0x3e, 0x4b, 0x0d, 0xb3, 0x7c, 0xca, 0xd6, 0x09, 0xc9, 0x35, 0x7e, 0xab, 0x61, 0x28, 0x27, 0xa7, + 0x06, 0xdb, 0xac, 0x55, 0xda, 0xed, 0xea, 0x08, 0x0c, 0xf1, 0x8b, 0x96, 0xd6, 0x97, 0x30, 0x27, + 0x02, 0x79, 0xb8, 0x77, 0x14, 0xc3, 0x7d, 0xc2, 0x38, 0x56, 0xab, 0x5b, 0xf0, 0xcd, 0x25, 0x00, + 0xb4, 0x85, 0x56, 0xbc, 0x26, 0xfd, 0x46, 0x44, 0x12, 0x6a, 0x10, 0xeb, 0x6d, 0x18, 0x55, 0x1a, + 0xc2, 0x0d, 0xbf, 0xb6, 0xd8, 0xa1, 0xb6, 0xa6, 0x8d, 0x5b, 0xbc, 0xf2, 0xea, 0xee, 0x39, 0xa3, + 0xed, 0x22, 0x4b, 0x0e, 0xb7, 0x10, 0x5c, 0x98, 0x49, 0x0c, 0x82, 0x38, 0x09, 0x83, 0xda, 0xa3, + 0xf3, 0x50, 0x47, 0xf5, 0x3b, 0xb9, 0x85, 0xef, 0x3b, 0xd6, 0x16, 0xde, 0xfa, 0x17, 0x7d, 0x68, + 0x5c, 0xa6, 0xf4, 0x91, 0xf0, 0xd3, 0xe9, 0xbe, 0xc2, 0x2a, 0x8c, 0x62, 0xeb, 0x17, 0xe5, 0x85, + 0xc1, 0xee, 0x71, 0x28, 0x23, 0x3f, 0x39, 0x2c, 0x9f, 0xc2, 0xe0, 0x93, 0x98, 0x8d, 0x7c, 0x0c, + 0xc3, 0x4b, 0x5e, 0x13, 0x25, 0xf4, 0x9f, 0x40, 0x82, 0x64, 0x62, 0x7d, 0x82, 0x55, 0xde, 0x62, + 0x9f, 0x30, 0x77, 0xef, 0xd8, 0x1a, 0x24, 0xb6, 0x72, 0x07, 0xf3, 0xac, 0xdc, 0xa1, 0x84, 0x95, + 0x6b, 0xc1, 0xe0, 0x46, 0xd0, 0x14, 0xb9, 0x6d, 0x26, 0xe7, 0xc7, 0x85, 0xe2, 0x10, 0x66, 0x73, + 0x94, 0xf5, 0x3f, 0x0a, 0x30, 0x7b, 0x8f, 0x46, 0x99, 0x63, 0xc8, 0xd0, 0x4a, 0xe1, 0x85, 0xb5, + 0xd2, 0xf7, 0x3c, 0x5a, 0x51, 0xad, 0xee, 0xcf, 0x6b, 0xf5, 0x40, 0x5e, 0xab, 0x07, 0xf3, 0x5b, + 0x7d, 0x0f, 0x86, 0x78, 0x53, 0x99, 0x25, 0xbf, 0x12, 0xd1, 0x83, 0xd8, 0x92, 0xd7, 0xa3, 0xe8, + 0x6c, 0x8e, 0x63, 0x1b, 0xc9, 0x55, 0x27, 0xd4, 0x2d, 0x79, 0xf1, 0xd3, 0xfa, 0x01, 0x5e, 0x35, + 0x5e, 0xf5, 0x1b, 0x8f, 0x35, 0x8f, 0xf0, 0x30, 0xff, 0x42, 0x93, 0x27, 0x08, 0x8c, 0x8a, 0x63, + 0x6c, 0x49, 0x41, 0x2e, 0xc3, 0xd8, 0x8a, 0x77, 0xd7, 0x0f, 0x1a, 0x74, 0xc3, 0x6b, 0x71, 0xe9, + 0x23, 0xb6, 0x0e, 0x12, 0x9e, 0x12, 0x51, 0x42, 0xec, 0x7e, 0x40, 0x40, 0xc2, 0xfd, 0xc0, 0x60, + 0x3b, 0xf3, 0x36, 0xc7, 0x09, 0x47, 0x0c, 0xfb, 0xbb, 0x9b, 0xe5, 0xae, 0x4c, 0xfc, 0x5e, 0x84, + 0xbb, 0x70, 0xce, 0xa6, 0xed, 0x96, 0xc3, 0xf6, 0x74, 0x07, 0x3e, 0xa7, 0x57, 0x6d, 0xbe, 0x9c, + 0x71, 0x4d, 0xd0, 0x8c, 0xa9, 0x50, 0x55, 0xee, 0xeb, 0x52, 0xe5, 0x03, 0xb8, 0x72, 0x8f, 0x46, + 0xe6, 0x84, 0x1a, 0xfb, 0x9b, 0x45, 0xe3, 0x97, 0x61, 0x24, 0x34, 0x7d, 0xe5, 0xf2, 0xda, 0x5b, + 0x26, 0xe3, 0xce, 0x9b, 0xf2, 0x34, 0x49, 0xc8, 0x51, 0x7f, 0x59, 0x9f, 0x40, 0x39, 0xaf, 0xb8, + 0xe3, 0x85, 0xbc, 0xba, 0x70, 0x39, 0x5f, 0x80, 0xa8, 0xee, 0x12, 0x48, 0xbf, 0xba, 0xf8, 0x84, + 0x7a, 0xd5, 0xd6, 0x74, 0xc5, 0x8b, 0x3f, 0xac, 0xaa, 0x0c, 0xfe, 0x7b, 0x81, 0xea, 0xd6, 0xf1, + 0xc8, 0xda, 0x14, 0x10, 0xeb, 0xb5, 0x02, 0x23, 0x12, 0x26, 0xf4, 0x3a, 0x9b, 0x59, 0x53, 0xa9, + 0xd0, 0xa6, 0x14, 0xa0, 0xd8, 0xac, 0x1f, 0xc8, 0xe3, 0x1b, 0x93, 0xe3, 0x78, 0xf7, 0x66, 0x8f, + 0x73, 0x5e, 0x63, 0xf9, 0x70, 0xce, 0x94, 0xad, 0xbb, 0xe5, 0x8b, 0x9a, 0x5b, 0x9e, 0x7b, 0xe3, + 0x2f, 0x9b, 0x6e, 0x62, 0xe1, 0x69, 0xd0, 0x40, 0xe4, 0x92, 0xee, 0x7c, 0x1f, 0x4f, 0x5f, 0xc4, + 0xbd, 0x0d, 0x73, 0x59, 0x05, 0x6a, 0x76, 0xa0, 0xf2, 0xf0, 0x8a, 0xfd, 0xce, 0x22, 0x5c, 0x92, + 0xd9, 0xa5, 0x7c, 0x3f, 0x0a, 0xa3, 0xc0, 0x69, 0xd7, 0x1a, 0x81, 0xdb, 0x8e, 0xb9, 0x2c, 0x18, + 0xe2, 0x10, 0xa1, 0x09, 0x7e, 0x14, 0xc6, 0x69, 0x04, 0xc6, 0xfa, 0x95, 0x02, 0x58, 0x46, 0x9c, + 0x16, 0xf6, 0xf3, 0x66, 0xe0, 0x3f, 0x71, 0x9b, 0xda, 0xf1, 0xd3, 0xeb, 0x86, 0xeb, 0x93, 0xdf, + 0x49, 0x4c, 0x86, 0x88, 0x8b, 0x39, 0xf3, 0x76, 0xc2, 0x1d, 0xc9, 0x37, 0x9e, 0x18, 0xbb, 0x65, + 0x5e, 0x88, 0x50, 0x6e, 0xca, 0xff, 0x55, 0x80, 0xab, 0x5d, 0xeb, 0x20, 0xda, 0xb3, 0x0b, 0xc5, + 0x24, 0x4e, 0x8c, 0xa0, 0xb2, 0x16, 0xb7, 0x91, 0x96, 0xb0, 0x73, 0x87, 0xc7, 0xa1, 0xcb, 0xf8, + 0xa6, 0xb6, 0x92, 0x9c, 0x92, 0x77, 0xf2, 0xda, 0x63, 0xfe, 0x0a, 0x3f, 0x72, 0x5a, 0x0b, 0xe8, + 0x00, 0xe8, 0x8f, 0xef, 0x14, 0x44, 0x0c, 0x5a, 0x4f, 0xa6, 0xc9, 0xd0, 0x88, 0xad, 0x4f, 0xf1, + 0xbb, 0xce, 0xae, 0xf4, 0xf1, 0x3e, 0xb5, 0x05, 0xb8, 0x9a, 0x88, 0x1d, 0x78, 0x0e, 0x21, 0x11, + 0xcc, 0x30, 0xf5, 0xb3, 0xbd, 0xf7, 0xbd, 0xc0, 0xef, 0xb4, 0x7f, 0x3e, 0xbd, 0xfe, 0x87, 0x05, + 0x1e, 0xcc, 0xa9, 0x17, 0x2b, 0x3a, 0x7a, 0x01, 0x20, 0x86, 0x26, 0x82, 0xfa, 0x15, 0x62, 0xe7, + 0x0e, 0x37, 0xb9, 0xf1, 0x54, 0x61, 0x8f, 0x0b, 0xd0, 0xd8, 0x7e, 0xbe, 0x3d, 0xf9, 0x26, 0x06, + 0x0c, 0xa8, 0xd2, 0x8f, 0xa7, 0xf7, 0x77, 0xa4, 0xff, 0xe3, 0x84, 0x7c, 0xfb, 0x30, 0xcd, 0x66, + 0x80, 0x4a, 0x27, 0xda, 0xf7, 0x03, 0x37, 0x92, 0xd7, 0x53, 0xc8, 0xa6, 0xc8, 0x08, 0xc0, 0xb9, + 0x3e, 0xfc, 0xd9, 0x61, 0xf9, 0xdd, 0x93, 0xe4, 0xfd, 0x94, 0x32, 0xb7, 0x54, 0x16, 0x01, 0x6b, + 0x16, 0xfa, 0x17, 0xec, 0x55, 0x9c, 0xf0, 0xec, 0x55, 0x35, 0xe1, 0xd9, 0xab, 0xd6, 0x5f, 0xf4, + 0x41, 0x99, 0xe7, 0x2c, 0xc1, 0x38, 0x93, 0xd8, 0x6b, 0xa1, 0x05, 0xae, 0x1c, 0xd7, 0xc1, 0x90, + 0xc8, 0x49, 0xd2, 0x77, 0x9c, 0x9c, 0x24, 0xbf, 0x04, 0x39, 0x2e, 0xab, 0x63, 0x78, 0x01, 0x5e, + 0x3b, 0x3a, 0x2c, 0x5f, 0x8d, 0xbd, 0x00, 0x1c, 0x9b, 0xe5, 0x0e, 0xc8, 0x29, 0x22, 0xed, 0xbf, + 0x18, 0x78, 0x0e, 0xff, 0xc5, 0x6d, 0x18, 0x46, 0x63, 0x66, 0x65, 0x53, 0x44, 0x7e, 0xe2, 0xf0, + 0xc4, 0x0c, 0x45, 0x75, 0x57, 0x4f, 0x07, 0x28, 0xc9, 0xac, 0x7f, 0xd0, 0x07, 0x97, 0xf3, 0x75, + 0x2e, 0xea, 0xb6, 0x08, 0x10, 0x47, 0xb8, 0x74, 0x8b, 0xa8, 0xc1, 0x6f, 0xe7, 0x29, 0xdd, 0x55, + 0x11, 0x6d, 0x1a, 0x1f, 0xdb, 0xfb, 0xc8, 0x9b, 0xd6, 0x89, 0xe3, 0x14, 0xe3, 0x02, 0xb6, 0xc8, + 0x66, 0x2b, 0x40, 0x46, 0x36, 0x5b, 0x01, 0x23, 0xbb, 0x30, 0xbb, 0x19, 0xb8, 0x4f, 0x9c, 0x88, + 0x3e, 0xa0, 0xcf, 0xf8, 0x65, 0xa1, 0x25, 0x71, 0x43, 0x88, 0x5f, 0x9f, 0xbf, 0x7e, 0x74, 0x58, + 0x7e, 0xa5, 0xcd, 0x49, 0x30, 0x63, 0x19, 0xbf, 0xfb, 0x59, 0x4f, 0x5f, 0x1a, 0xca, 0x13, 0x64, + 0xfd, 0xbb, 0x02, 0x9c, 0xc7, 0x6d, 0xb9, 0x70, 0xbb, 0xca, 0xc2, 0x9f, 0x2b, 0xb0, 0x52, 0x6f, + 0xa0, 0x18, 0x8b, 0x18, 0x58, 0x69, 0xdc, 0x44, 0xb7, 0x0d, 0x32, 0xb2, 0x02, 0x63, 0xe2, 0x37, + 0x7e, 0x7f, 0xfd, 0x68, 0x10, 0xcc, 0x68, 0x13, 0x16, 0x0e, 0x75, 0xee, 0x2a, 0xc2, 0x81, 0x2d, + 0x84, 0xe1, 0x85, 0x4d, 0x5b, 0xe7, 0xb5, 0x7e, 0xda, 0x07, 0x17, 0x76, 0x68, 0xe0, 0x3e, 0x7a, + 0x96, 0xd3, 0x98, 0x0d, 0x98, 0x96, 0x20, 0x9e, 0xb7, 0xc4, 0xf8, 0xc4, 0x78, 0x3e, 0x4b, 0x59, + 0x55, 0x91, 0xf8, 0x44, 0x7e, 0x71, 0x99, 0x8c, 0x27, 0x08, 0x99, 0x7c, 0x0b, 0x46, 0x12, 0x99, + 0x83, 0xb0, 0xff, 0xe5, 0x17, 0x1a, 0x77, 0xd5, 0xf2, 0x29, 0x5b, 0x51, 0x92, 0x5f, 0xcb, 0x3f, + 0xaa, 0x12, 0xae, 0x8f, 0x5e, 0xfe, 0x4f, 0xfc, 0x60, 0xd9, 0xc7, 0xea, 0x68, 0xd8, 0x8c, 0x0f, + 0x76, 0xf9, 0x94, 0x9d, 0x57, 0x52, 0x75, 0x0c, 0x46, 0x2b, 0x78, 0x6e, 0xc7, 0x2c, 0xf7, 0xff, + 0xd9, 0x07, 0x97, 0xe4, 0xc5, 0x9f, 0x1c, 0x35, 0x7f, 0x0e, 0xb3, 0x12, 0x54, 0x69, 0xb3, 0x0d, + 0x03, 0x6d, 0x9a, 0x9a, 0xe6, 0x39, 0x65, 0xa5, 0xa6, 0x1d, 0x41, 0x13, 0x2b, 0x3b, 0x8f, 0xfd, + 0xe5, 0x78, 0x3f, 0x3f, 0xce, 0xca, 0xe3, 0x84, 0x5e, 0x48, 0x7d, 0xce, 0x34, 0x54, 0x63, 0xcc, + 0x9f, 0xcd, 0x94, 0xf7, 0x74, 0xe0, 0x45, 0xbd, 0xa7, 0xcb, 0xa7, 0x92, 0xfe, 0xd3, 0xea, 0x24, + 0x8c, 0xaf, 0xd3, 0xa7, 0xb1, 0xde, 0xff, 0x7a, 0x21, 0x91, 0xea, 0x81, 0xed, 0x30, 0x78, 0xce, + 0x87, 0x42, 0x9c, 0x0a, 0x08, 0x53, 0x3d, 0xe8, 0x3b, 0x0c, 0x4e, 0xba, 0x02, 0xc3, 0xfc, 0x30, + 0xbb, 0x79, 0x0c, 0x0b, 0x5f, 0xdd, 0xe0, 0xe1, 0xd7, 0x2a, 0x9b, 0xdc, 0xd8, 0x17, 0xfc, 0xd6, + 0x03, 0xb8, 0x22, 0x62, 0xbc, 0xcd, 0xce, 0xc7, 0x82, 0x4e, 0xb8, 0x7c, 0x59, 0x0e, 0x5c, 0xba, + 0x47, 0x93, 0x53, 0x8f, 0x71, 0xc3, 0xe9, 0x13, 0x38, 0x6d, 0xc0, 0x95, 0x44, 0xdc, 0x95, 0xaa, + 0x31, 0xa4, 0x44, 0x27, 0xa9, 0xad, 0xcb, 0x59, 0x45, 0xe8, 0x95, 0xb5, 0x28, 0x26, 0x87, 0x0d, + 0xe2, 0x23, 0xb6, 0xf0, 0x04, 0xb3, 0xde, 0x75, 0xed, 0xbb, 0xe6, 0x33, 0x1e, 0xcf, 0x1e, 0x28, + 0x57, 0x5e, 0x85, 0xb5, 0x26, 0x8c, 0xb3, 0x00, 0x6b, 0x12, 0xc6, 0x25, 0xaa, 0x45, 0xc3, 0xd0, + 0xfa, 0xcf, 0x83, 0x60, 0x09, 0xc5, 0x66, 0x9d, 0xd0, 0x4b, 0x7d, 0xec, 0xa6, 0x2a, 0x2b, 0x16, + 0xaa, 0xb3, 0x7a, 0x4e, 0xd2, 0x18, 0xcb, 0x47, 0x1e, 0xee, 0xf3, 0x1a, 0x31, 0xd4, 0x18, 0x79, + 0xa9, 0xd6, 0x7f, 0x95, 0x33, 0x4d, 0xf2, 0x8f, 0x0d, 0xaf, 0x6c, 0xe7, 0x4c, 0x93, 0x86, 0xdc, + 0xec, 0x29, 0xd3, 0x36, 0x8f, 0x44, 0xfa, 0x9f, 0xe7, 0x48, 0x84, 0x7d, 0x91, 0xfa, 0xa1, 0xc8, + 0xb6, 0xa9, 0x4b, 0xf1, 0x3d, 0xca, 0xd3, 0x7b, 0x1d, 0x25, 0x32, 0x2e, 0x68, 0x10, 0x43, 0xaa, + 0x21, 0x86, 0xb8, 0x50, 0xd4, 0x7c, 0x96, 0x0b, 0xfb, 0xb4, 0xf1, 0x58, 0xf8, 0x8a, 0xe5, 0x81, + 0x6e, 0x96, 0xcf, 0x9c, 0xe7, 0xa7, 0xe6, 0xdf, 0x39, 0x47, 0xd4, 0x1b, 0x8c, 0x55, 0xcf, 0x18, + 0x91, 0x14, 0x4b, 0x7e, 0x04, 0x53, 0xaa, 0xab, 0x13, 0x21, 0x5a, 0x63, 0xf3, 0xaf, 0xc4, 0xa9, + 0x4c, 0x0f, 0x1e, 0x39, 0x37, 0x9f, 0xdc, 0xb9, 0x99, 0x41, 0xcb, 0x13, 0x11, 0x34, 0x24, 0x42, + 0x8b, 0xcf, 0xd2, 0x0f, 0xba, 0x32, 0x18, 0xc9, 0x17, 0x30, 0x5d, 0xab, 0x6d, 0xf0, 0xcb, 0x1c, + 0xb6, 0x3c, 0xe0, 0xb7, 0x57, 0x45, 0xc0, 0x16, 0x76, 0x77, 0x18, 0xfa, 0x75, 0x71, 0x09, 0x44, + 0x0f, 0x0b, 0xd0, 0x53, 0x31, 0x64, 0x89, 0xd0, 0x4f, 0xca, 0xff, 0xbe, 0xba, 0xab, 0xc0, 0xb6, + 0x22, 0x6e, 0x8b, 0x8a, 0x4b, 0x47, 0x72, 0x60, 0xe7, 0x9c, 0xf2, 0x15, 0xbe, 0xe5, 0x53, 0xbe, + 0xdf, 0xeb, 0x93, 0x37, 0x34, 0xd2, 0x07, 0xad, 0x27, 0x3e, 0xec, 0xcb, 0x6c, 0xc1, 0xb1, 0xd6, + 0xe9, 0xcc, 0xca, 0x91, 0xaa, 0x3c, 0x2a, 0x55, 0xc9, 0xca, 0x26, 0xd5, 0xb1, 0x43, 0x8c, 0x30, + 0x4e, 0x4f, 0x71, 0x57, 0xa4, 0x71, 0x25, 0xcf, 0xe1, 0xfa, 0x5f, 0xfc, 0x1c, 0xee, 0xc7, 0x30, + 0x23, 0xaf, 0x46, 0x2d, 0x50, 0x2f, 0xa2, 0x81, 0x3c, 0xb1, 0x9f, 0x8c, 0x93, 0xbe, 0x61, 0x7a, + 0xbf, 0x22, 0xf4, 0x57, 0xec, 0x75, 0xe1, 0xd1, 0x61, 0x7f, 0x92, 0xcb, 0x66, 0x40, 0x1c, 0xbf, + 0xf3, 0x66, 0x84, 0xbf, 0x5d, 0x66, 0xd5, 0xe5, 0x7e, 0x16, 0x57, 0xa6, 0xea, 0xb3, 0x75, 0x90, + 0xb5, 0x00, 0xe7, 0xcd, 0xe2, 0x37, 0x69, 0x70, 0xe0, 0xe2, 0xde, 0xbb, 0x46, 0x23, 0x59, 0x68, + 0x21, 0x2e, 0x94, 0xe8, 0x01, 0xd5, 0xc2, 0x0c, 0xfc, 0x3f, 0x7d, 0x50, 0xce, 0x6c, 0x44, 0x25, + 0x0c, 0xdd, 0x3d, 0x0f, 0x33, 0x68, 0x5c, 0x80, 0x81, 0x07, 0xae, 0xd7, 0xd4, 0x0d, 0xc9, 0xc7, + 0xae, 0xd7, 0xb4, 0x11, 0xca, 0x6c, 0x90, 0x5a, 0x67, 0x17, 0x09, 0x34, 0x13, 0x39, 0xec, 0xec, + 0xd6, 0x19, 0x91, 0x6e, 0x83, 0x08, 0x32, 0x72, 0x0d, 0x86, 0x65, 0xb6, 0xb5, 0xfe, 0xd8, 0x7b, + 0x26, 0xd3, 0xac, 0x49, 0x1c, 0xf9, 0x08, 0x46, 0xd6, 0x68, 0xe4, 0x34, 0x9d, 0xc8, 0x11, 0x63, + 0x47, 0x3e, 0x84, 0x21, 0xc1, 0xd5, 0xa2, 0x58, 0xa1, 0x47, 0x0e, 0x04, 0xc4, 0x56, 0x2c, 0xa8, + 0x40, 0x37, 0x6c, 0xb7, 0x9c, 0x67, 0x2a, 0x98, 0x94, 0x29, 0x30, 0x06, 0x91, 0x77, 0xcc, 0x90, + 0x8b, 0xf8, 0xf8, 0x2c, 0x53, 0x21, 0x71, 0x40, 0xc6, 0x32, 0x86, 0x81, 0xc4, 0xaa, 0x16, 0xd9, + 0x04, 0xad, 0x4c, 0x6e, 0x83, 0xd2, 0x36, 0x19, 0xad, 0xdf, 0x1a, 0x83, 0x33, 0x9b, 0xce, 0x9e, + 0xeb, 0xb1, 0x1d, 0x85, 0x4d, 0x43, 0xbf, 0x13, 0x34, 0x28, 0xa9, 0xc0, 0xa4, 0x19, 0xc0, 0xdd, + 0x23, 0x3c, 0x9d, 0x6d, 0x9a, 0x4c, 0x18, 0x99, 0x87, 0x51, 0x75, 0x69, 0x5c, 0xec, 0x74, 0x32, + 0x2e, 0x93, 0x2f, 0x9f, 0xb2, 0x63, 0x32, 0xf2, 0x9e, 0x71, 0xf8, 0x78, 0x5a, 0xe5, 0x3f, 0x40, + 0xda, 0x79, 0x1e, 0x61, 0xeb, 0xf9, 0x4d, 0x73, 0xb7, 0xc6, 0x4f, 0xd8, 0x7e, 0x90, 0x3a, 0x8f, + 0x1c, 0x34, 0x6a, 0x9c, 0x72, 0xca, 0xe2, 0x46, 0x35, 0x37, 0x7b, 0x7d, 0xc6, 0x49, 0xe5, 0x97, + 0x30, 0xf6, 0xa0, 0xb3, 0x4b, 0xe5, 0xc9, 0xeb, 0x90, 0xd8, 0xbc, 0x25, 0xaf, 0x25, 0x08, 0xfc, + 0xce, 0x9b, 0xfc, 0x2b, 0x7e, 0xdc, 0xd9, 0xa5, 0xe9, 0x67, 0x11, 0xd8, 0xaa, 0xa9, 0x09, 0x23, + 0xfb, 0x50, 0x4c, 0xde, 0x20, 0x10, 0x5d, 0xda, 0xe5, 0xde, 0x03, 0x26, 0xfa, 0xd1, 0x1e, 0x5f, + 0xe0, 0x71, 0xcd, 0x46, 0x21, 0x29, 0xa9, 0xe4, 0xc7, 0x30, 0x93, 0xe9, 0x12, 0x57, 0x77, 0x20, + 0xbb, 0x7b, 0xdb, 0x71, 0x09, 0x4a, 0x68, 0x4d, 0x5e, 0xb8, 0x34, 0x4a, 0xce, 0x2e, 0x85, 0x34, + 0xe1, 0x74, 0x22, 0x32, 0x5e, 0xbc, 0x30, 0x93, 0x1f, 0x6b, 0x8f, 0xbb, 0x26, 0x99, 0xa4, 0x39, + 0xb3, 0xac, 0xa4, 0x48, 0xb2, 0x0a, 0xa3, 0xca, 0x17, 0x25, 0x72, 0xf3, 0x65, 0xf9, 0xdd, 0x4a, + 0x47, 0x87, 0xe5, 0xe9, 0xd8, 0xef, 0x66, 0xc8, 0x8c, 0x05, 0x90, 0x5f, 0x86, 0x2b, 0x6a, 0x88, + 0x6e, 0x04, 0xd9, 0x1e, 0x4a, 0xf1, 0xb8, 0xc3, 0x8d, 0xe4, 0x08, 0xcf, 0xa3, 0xdf, 0xb9, 0x53, + 0xed, 0x2b, 0x15, 0x96, 0x4f, 0xd9, 0xbd, 0x45, 0x93, 0x5f, 0x2d, 0xc0, 0xd9, 0x9c, 0x52, 0xc7, + 0xb1, 0xd4, 0x9e, 0x6e, 0x63, 0xb4, 0x3c, 0xf1, 0xde, 0x9f, 0xdb, 0x8c, 0xef, 0xc7, 0x4a, 0xff, + 0xb1, 0xd1, 0xee, 0x9c, 0x92, 0xc8, 0x6d, 0x80, 0x3d, 0x37, 0x12, 0x63, 0x0c, 0xd3, 0xd4, 0xa5, + 0x3f, 0x50, 0xa6, 0xb6, 0x3d, 0x37, 0x12, 0x23, 0xed, 0x77, 0x0b, 0x3d, 0xe7, 0x75, 0xcc, 0x5e, + 0x37, 0x36, 0xff, 0x6a, 0xb7, 0x49, 0x2f, 0xa6, 0xae, 0xde, 0x3e, 0x3a, 0x2c, 0xbf, 0xa1, 0x52, + 0xa0, 0x35, 0x90, 0x4a, 0xde, 0xf2, 0xad, 0x3b, 0x8a, 0xce, 0x68, 0x4f, 0xcf, 0xa5, 0xe5, 0x0d, + 0x18, 0x42, 0xcf, 0x54, 0x58, 0x9a, 0x40, 0xdb, 0x0d, 0x13, 0x77, 0xa1, 0xff, 0x4a, 0xdf, 0xad, + 0x09, 0x1a, 0xb2, 0xcc, 0x6c, 0x20, 0xdc, 0x2d, 0x4a, 0x9b, 0x45, 0xa4, 0xf9, 0x13, 0x76, 0x34, + 0x47, 0xc9, 0xfc, 0x3b, 0xc6, 0xf3, 0x24, 0x26, 0x5b, 0x15, 0x60, 0x24, 0x10, 0xd3, 0xed, 0xfd, + 0x81, 0x91, 0x81, 0xe2, 0x20, 0x9f, 0x11, 0xe4, 0x5d, 0x92, 0x5f, 0x1f, 0xe1, 0x17, 0xcf, 0xb7, + 0x3d, 0xf7, 0x91, 0x1b, 0xcf, 0xcc, 0xba, 0x4f, 0x3b, 0x7e, 0x27, 0x4c, 0x58, 0x9c, 0x39, 0x2f, + 0x82, 0x29, 0xf7, 0x77, 0x5f, 0x4f, 0xf7, 0xf7, 0x9b, 0xda, 0x41, 0xb1, 0x96, 0xce, 0x97, 0x5b, + 0x16, 0xa6, 0xbb, 0x39, 0x3e, 0x41, 0xfe, 0x1a, 0x86, 0x30, 0x03, 0x2f, 0x3f, 0x85, 0x1f, 0x9b, + 0xbf, 0x29, 0xba, 0xb3, 0x4b, 0xf5, 0x79, 0xca, 0x5e, 0x91, 0x4c, 0x82, 0x6b, 0x1c, 0x01, 0x86, + 0xc6, 0x11, 0x42, 0xb6, 0x60, 0x6a, 0x93, 0x6d, 0x74, 0xf9, 0x8d, 0x86, 0x76, 0x20, 0x5c, 0x82, + 0xdc, 0xd9, 0x88, 0x1b, 0xed, 0xb6, 0x44, 0xd7, 0xa9, 0xc2, 0xeb, 0x7b, 0xcd, 0x0c, 0x76, 0xb2, + 0x04, 0x93, 0x35, 0xea, 0x04, 0x8d, 0xfd, 0x07, 0xf4, 0x19, 0x33, 0x32, 0x8c, 0xa7, 0x71, 0x42, + 0xc4, 0xb0, 0xf6, 0x22, 0x4a, 0x8f, 0xac, 0x32, 0x99, 0xc8, 0xa7, 0x30, 0x54, 0xf3, 0x83, 0xa8, + 0xfa, 0x4c, 0xcc, 0xd6, 0xf2, 0x9c, 0x96, 0x03, 0xab, 0xe7, 0xe4, 0xf3, 0x40, 0xa1, 0x1f, 0x44, + 0xf5, 0x5d, 0x23, 0x13, 0x1c, 0x27, 0x21, 0xcf, 0x60, 0xda, 0x9c, 0x29, 0x45, 0xa0, 0xfd, 0x88, + 0x30, 0x6e, 0xb2, 0xa6, 0x63, 0x4e, 0x52, 0xbd, 0x2e, 0xa4, 0x5f, 0x4e, 0xce, 0xc7, 0x8f, 0x10, + 0xaf, 0x5b, 0x04, 0x59, 0xfc, 0x64, 0x0d, 0xdf, 0x55, 0xe2, 0x2d, 0xaa, 0x84, 0x3c, 0x40, 0x7f, + 0x34, 0xce, 0x35, 0xd8, 0xc1, 0xd9, 0x16, 0x35, 0xe1, 0x84, 0xc9, 0xc7, 0xb8, 0xec, 0x14, 0x2b, + 0xd9, 0x84, 0x33, 0xdb, 0x21, 0xdd, 0x0c, 0xe8, 0x13, 0x97, 0x3e, 0x95, 0xf2, 0x20, 0x4e, 0xcc, + 0xc6, 0xe4, 0xb5, 0x39, 0x36, 0x4b, 0x60, 0x9a, 0x99, 0xbc, 0x07, 0xb0, 0xe9, 0x7a, 0x1e, 0x6d, + 0xe2, 0x61, 0xff, 0x18, 0x8a, 0xc2, 0x83, 0x8c, 0x36, 0x42, 0xeb, 0xbe, 0xd7, 0xd2, 0x55, 0xaa, + 0x11, 0x93, 0x2a, 0x4c, 0xac, 0x78, 0x8d, 0x56, 0x47, 0x04, 0xe5, 0x84, 0x38, 0x53, 0x8a, 0x84, + 0x91, 0x2e, 0x47, 0xd4, 0x53, 0x1f, 0xb9, 0xc9, 0x42, 0x1e, 0x00, 0x11, 0x00, 0x31, 0x6a, 0x9d, + 0xdd, 0x16, 0x15, 0x9f, 0x3b, 0x3a, 0x28, 0xa5, 0x20, 0x1c, 0xee, 0x46, 0x1e, 0xc6, 0x14, 0xdb, + 0xdc, 0x7b, 0x30, 0xa6, 0x8d, 0xf9, 0x8c, 0xec, 0x28, 0xd3, 0x7a, 0x76, 0x94, 0x51, 0x3d, 0x0b, + 0xca, 0x3f, 0x2d, 0xc0, 0x85, 0xec, 0x6f, 0x49, 0xd8, 0x26, 0x1b, 0x30, 0xaa, 0x80, 0xea, 0x3e, + 0x9c, 0x34, 0xb8, 0x13, 0x5b, 0x3b, 0xfe, 0x41, 0xcb, 0x99, 0x47, 0x6f, 0x7d, 0x2c, 0xe3, 0x39, + 0x4e, 0xc1, 0xfe, 0xe6, 0x08, 0x4c, 0xe3, 0xbd, 0x8f, 0xe4, 0x3c, 0xf5, 0x09, 0x66, 0x39, 0x42, + 0x98, 0x76, 0xa8, 0x23, 0xfc, 0xbb, 0x1c, 0x9e, 0xcc, 0xf7, 0x67, 0x30, 0x90, 0xb7, 0xf5, 0x48, + 0xa4, 0x3e, 0xed, 0x1d, 0x27, 0x09, 0xd4, 0x9b, 0x10, 0x87, 0x28, 0xbd, 0x6e, 0x04, 0xc2, 0x1c, + 0x7b, 0xd2, 0x1b, 0x38, 0xee, 0xa4, 0xb7, 0xad, 0x26, 0x3d, 0x9e, 0x3d, 0xe7, 0x35, 0x6d, 0xd2, + 0x7b, 0xf9, 0xb3, 0xdd, 0xd0, 0xcb, 0x9e, 0xed, 0x86, 0x5f, 0x6c, 0xb6, 0x1b, 0x79, 0xce, 0xd9, + 0xee, 0x2e, 0x4c, 0xae, 0x53, 0xda, 0xd4, 0x8e, 0x27, 0x47, 0xe3, 0xd5, 0xd3, 0xa3, 0xe8, 0x78, + 0xce, 0x3a, 0xa3, 0x4c, 0x70, 0xe5, 0xce, 0x9a, 0xf0, 0x57, 0x33, 0x6b, 0x8e, 0xbd, 0xe4, 0x59, + 0x73, 0xfc, 0x45, 0x66, 0xcd, 0xd4, 0xd4, 0x37, 0x71, 0xe2, 0xa9, 0xef, 0x45, 0x66, 0xab, 0x8f, + 0x31, 0x90, 0xb7, 0x56, 0x5b, 0x16, 0x31, 0x5b, 0x5a, 0x90, 0xd4, 0xb2, 0x1f, 0xca, 0x7b, 0x0e, + 0xf8, 0x37, 0x83, 0xe1, 0x6b, 0x19, 0xc2, 0x1d, 0xc0, 0xfe, 0xb6, 0xaa, 0x18, 0xbe, 0xab, 0xf3, + 0xab, 0xfb, 0x40, 0xc3, 0xe2, 0x32, 0xb1, 0x98, 0xe3, 0x92, 0xdb, 0x4f, 0x5b, 0xe2, 0xad, 0x3f, + 0x2d, 0xf0, 0x50, 0x80, 0xff, 0x17, 0xa7, 0xca, 0x17, 0x39, 0x9e, 0xff, 0xb5, 0x38, 0xc9, 0x88, + 0x48, 0x88, 0x12, 0x38, 0x8d, 0xc7, 0x71, 0x7c, 0xc4, 0xf7, 0xd9, 0x77, 0xae, 0x23, 0xc4, 0x46, + 0x7d, 0x56, 0x69, 0x4a, 0x47, 0xee, 0xdc, 0x91, 0x13, 0x80, 0xc8, 0xb5, 0xc2, 0xc1, 0xe6, 0x04, + 0xa0, 0x33, 0x60, 0x84, 0xea, 0x69, 0xcb, 0xe6, 0x39, 0x32, 0x32, 0x6b, 0xf0, 0x4e, 0x3a, 0xcb, + 0x03, 0x5a, 0x59, 0x71, 0x96, 0x07, 0x5d, 0x8d, 0x71, 0xbe, 0x87, 0x6d, 0x38, 0x6f, 0xd3, 0x03, + 0xff, 0x09, 0x7d, 0xb9, 0x62, 0xbf, 0x82, 0x73, 0xa6, 0x40, 0x7e, 0x1f, 0x90, 0x3f, 0x5e, 0xf1, + 0x71, 0xf6, 0x93, 0x17, 0x82, 0x81, 0x3f, 0x79, 0xc1, 0x33, 0xe7, 0xb3, 0x3f, 0xf5, 0x75, 0x03, + 0x71, 0x96, 0x0f, 0x17, 0x4c, 0xe1, 0x95, 0x66, 0x13, 0x5f, 0xcd, 0x6d, 0xb8, 0x6d, 0xc7, 0x8b, + 0xc8, 0x06, 0x8c, 0x69, 0x3f, 0x13, 0x3e, 0x10, 0x0d, 0x23, 0xf6, 0x34, 0x31, 0xc0, 0xc8, 0x3c, + 0x1c, 0x83, 0x2d, 0x0a, 0xe5, 0xa4, 0x7a, 0x98, 0xca, 0xf4, 0x32, 0xab, 0x30, 0xa1, 0xfd, 0x54, + 0x07, 0x05, 0xf8, 0xf1, 0x6b, 0x25, 0x98, 0x0a, 0x33, 0x59, 0xac, 0x06, 0xcc, 0x65, 0x29, 0x8d, + 0xa7, 0xa8, 0x27, 0x4b, 0x71, 0x06, 0xba, 0xde, 0x31, 0xae, 0xa7, 0xf3, 0xb2, 0xcf, 0x59, 0x7f, + 0x6f, 0x00, 0xce, 0x8b, 0xce, 0x78, 0x99, 0x3d, 0x4e, 0x7e, 0x00, 0x63, 0x5a, 0x1f, 0x0b, 0xa5, + 0x5f, 0x96, 0xb7, 0xf9, 0xf2, 0xc6, 0x02, 0xf7, 0xd5, 0x74, 0x10, 0x50, 0x4f, 0x74, 0xf7, 0xf2, + 0x29, 0x5b, 0x17, 0x49, 0x5a, 0x30, 0x69, 0x76, 0xb4, 0x70, 0x57, 0x5d, 0xcd, 0x2c, 0xc4, 0x24, + 0x95, 0xf9, 0xeb, 0x9b, 0xf5, 0xcc, 0xee, 0x5e, 0x3e, 0x65, 0x27, 0x64, 0x93, 0x6f, 0xe0, 0x4c, + 0xaa, 0x97, 0x85, 0x2f, 0xf2, 0xd5, 0xcc, 0x02, 0x53, 0xd4, 0xfc, 0x10, 0x24, 0x40, 0x70, 0x6e, + 0xb1, 0xe9, 0x42, 0x48, 0x13, 0xc6, 0xf5, 0x8e, 0x17, 0xfe, 0xb4, 0x2b, 0x5d, 0x54, 0xc9, 0x09, + 0xf9, 0xe6, 0x4e, 0xe8, 0x12, 0xfb, 0xfe, 0x99, 0x79, 0xb0, 0x63, 0x10, 0x8f, 0xc0, 0x10, 0xff, + 0x6d, 0xfd, 0x5e, 0x01, 0xce, 0x6f, 0x06, 0x34, 0xa4, 0x5e, 0x83, 0x1a, 0xf7, 0x22, 0x5e, 0x70, + 0x44, 0xe4, 0x9d, 0xa9, 0xf4, 0xbd, 0xf0, 0x99, 0x8a, 0xf5, 0x6f, 0x0b, 0x50, 0xca, 0xaa, 0x72, + 0x8d, 0x7a, 0x4d, 0xb2, 0x09, 0xc5, 0x64, 0x1b, 0xc4, 0x17, 0x63, 0xa9, 0xf4, 0xe3, 0xb9, 0xad, + 0x5d, 0x3e, 0x65, 0xa7, 0xb8, 0xc9, 0x3a, 0x9c, 0xd1, 0x60, 0xe2, 0x4c, 0xa3, 0xef, 0x38, 0x67, + 0x1a, 0xac, 0x87, 0x53, 0xac, 0xfa, 0x91, 0xd0, 0x32, 0xae, 0xba, 0x8b, 0xfe, 0x81, 0xe3, 0x7a, + 0x6c, 0x13, 0xad, 0x25, 0xb8, 0x83, 0x18, 0x2a, 0xd4, 0xce, 0x0f, 0x39, 0x10, 0x2a, 0xaf, 0x88, + 0x29, 0x12, 0xeb, 0x43, 0x5c, 0x1d, 0x84, 0x63, 0x93, 0x5f, 0xca, 0x57, 0xc2, 0x2e, 0xc3, 0xe0, + 0xd6, 0x6a, 0x6d, 0xa1, 0x22, 0xae, 0xf8, 0xf3, 0xc4, 0x30, 0xad, 0xb0, 0xde, 0x70, 0x6c, 0x8e, + 0xb0, 0x3e, 0x00, 0x72, 0x8f, 0x46, 0xe2, 0xfd, 0x0b, 0xc5, 0x77, 0x0d, 0x86, 0x05, 0x48, 0x70, + 0xa2, 0xbb, 0x5e, 0xbc, 0xa6, 0x61, 0x4b, 0x9c, 0xb5, 0x29, 0x6d, 0x90, 0x16, 0x75, 0x42, 0x6d, + 0xd1, 0x7f, 0x17, 0x46, 0x02, 0x01, 0x13, 0x6b, 0xfe, 0xa4, 0x7a, 0xde, 0x08, 0xc1, 0xfc, 0x18, + 0x49, 0xd2, 0xd8, 0xea, 0x2f, 0x6b, 0x15, 0x93, 0x38, 0x6d, 0xac, 0x2c, 0x2e, 0x30, 0xad, 0x0a, + 0x65, 0xc9, 0xee, 0xb8, 0x85, 0xb7, 0x42, 0x22, 0xaa, 0x5f, 0xf0, 0x47, 0xd5, 0xe0, 0x04, 0x22, + 0x52, 0x97, 0x69, 0x24, 0xd6, 0x9b, 0x2a, 0x25, 0x54, 0x86, 0xb4, 0xbc, 0x67, 0x7a, 0xd6, 0x31, + 0xd9, 0xd5, 0x3d, 0x0c, 0x80, 0x7b, 0x19, 0x95, 0x70, 0x60, 0x8e, 0x6f, 0x21, 0x58, 0xab, 0xc4, + 0x23, 0xa5, 0xbe, 0x9a, 0x76, 0x17, 0x60, 0x54, 0xc1, 0xd4, 0x69, 0x36, 0xd7, 0x95, 0x41, 0xbf, + 0xf3, 0x26, 0xcf, 0x85, 0xd0, 0x50, 0x02, 0x62, 0x3e, 0x56, 0x04, 0xff, 0xa6, 0xbf, 0xe5, 0x22, + 0x42, 0x1a, 0x44, 0xdf, 0x6a, 0x11, 0x71, 0x36, 0xb4, 0x93, 0x14, 0x61, 0xd0, 0xef, 0xcc, 0x1f, + 0x47, 0x51, 0xdf, 0x72, 0x11, 0x4c, 0x51, 0xdf, 0x5e, 0x11, 0x54, 0xa6, 0x8d, 0xe3, 0x83, 0x34, + 0x55, 0xc8, 0x52, 0xba, 0x10, 0xe9, 0xed, 0x4f, 0x70, 0x74, 0xed, 0x0f, 0x0a, 0x17, 0xb8, 0xb2, + 0x7e, 0x0e, 0xc5, 0x30, 0x85, 0x7d, 0xbb, 0xc5, 0xfc, 0xc3, 0x02, 0x4f, 0x62, 0x57, 0xdb, 0xd0, + 0x9e, 0x07, 0xf6, 0x1e, 0xf9, 0x5a, 0xb0, 0x8d, 0xf6, 0xb5, 0x6b, 0x87, 0x9f, 0x18, 0x6c, 0xe3, + 0x74, 0xa2, 0x7d, 0x95, 0xe4, 0x1d, 0x4f, 0x42, 0x93, 0xd4, 0xe4, 0x3d, 0x98, 0xd0, 0x40, 0x6a, + 0x27, 0xc8, 0x9f, 0xe1, 0xd1, 0xd9, 0xdd, 0xa6, 0x6d, 0x52, 0x5a, 0x7f, 0x59, 0x80, 0xa9, 0x8c, + 0x87, 0xeb, 0xd1, 0x51, 0x82, 0x16, 0x96, 0x9a, 0xa8, 0xc4, 0xc3, 0x79, 0x98, 0x4f, 0xc7, 0x58, + 0x7f, 0x15, 0x21, 0x3e, 0x40, 0xa2, 0x3d, 0xb2, 0xdf, 0xa7, 0x3d, 0x07, 0x99, 0xfd, 0xb0, 0xbe, + 0x4e, 0x4e, 0x42, 0x80, 0xb8, 0x26, 0xc2, 0x25, 0x5d, 0x63, 0xdb, 0x65, 0xed, 0x85, 0xfe, 0x98, + 0xf7, 0x67, 0x87, 0xe5, 0x77, 0x4e, 0x12, 0x2a, 0x1c, 0x8b, 0xb6, 0xb5, 0x62, 0xac, 0x5f, 0xeb, + 0x83, 0xb3, 0x19, 0xed, 0xaf, 0xd1, 0xe8, 0xaf, 0x42, 0x05, 0x4f, 0x60, 0x2c, 0xae, 0x4c, 0x58, + 0xea, 0x47, 0xcf, 0xcd, 0x16, 0xbe, 0x97, 0x11, 0xeb, 0x20, 0x7c, 0x29, 0x4a, 0xd0, 0x0b, 0xb2, + 0xfe, 0xa8, 0x0f, 0xce, 0x6e, 0xb7, 0x43, 0xbc, 0x33, 0xb9, 0xe2, 0x3d, 0xa1, 0x5e, 0xe4, 0x07, + 0xcf, 0xf0, 0x9e, 0x17, 0x79, 0x1b, 0x06, 0x97, 0x69, 0xab, 0xe5, 0x8b, 0xf1, 0x7f, 0x51, 0xc6, + 0x3b, 0x25, 0xa9, 0x91, 0x68, 0xf9, 0x94, 0xcd, 0xa9, 0xc9, 0x7b, 0x30, 0xba, 0x4c, 0x9d, 0x20, + 0xda, 0xa5, 0x8e, 0x34, 0x87, 0xe4, 0xe3, 0x40, 0x1a, 0x8b, 0x20, 0x58, 0x3e, 0x65, 0xc7, 0xd4, + 0x64, 0x1e, 0x06, 0x36, 0x7d, 0x6f, 0x4f, 0xe5, 0x87, 0xc8, 0x29, 0x90, 0xd1, 0x2c, 0x9f, 0xb2, + 0x91, 0x96, 0xac, 0xc1, 0x44, 0x65, 0x8f, 0x7a, 0x51, 0xe2, 0x08, 0xff, 0x5a, 0x1e, 0xb3, 0x41, + 0xbc, 0x7c, 0xca, 0x36, 0xb9, 0xc9, 0x07, 0x30, 0x7c, 0xcf, 0xf7, 0x9b, 0xbb, 0xcf, 0x64, 0x96, + 0x93, 0x72, 0x9e, 0x20, 0x41, 0xb6, 0x7c, 0xca, 0x96, 0x1c, 0xd5, 0x41, 0xe8, 0x5f, 0x0b, 0xf7, + 0xac, 0xc3, 0x02, 0x94, 0x16, 0xfd, 0xa7, 0x5e, 0xa6, 0x56, 0xbf, 0x67, 0x6a, 0x55, 0x8a, 0xcf, + 0xa0, 0x4f, 0xe8, 0xf5, 0x2d, 0x18, 0xd8, 0x74, 0xbd, 0xbd, 0xc4, 0x56, 0x30, 0x83, 0x8f, 0x51, + 0xa1, 0x7a, 0x5c, 0x6f, 0x8f, 0xac, 0xca, 0xfd, 0xbd, 0xf0, 0x63, 0xf6, 0x1b, 0x46, 0x45, 0x06, + 0xb7, 0x4e, 0x1d, 0xef, 0xe3, 0xf9, 0x6f, 0xd9, 0xc0, 0xd7, 0x61, 0x36, 0xa7, 0x5c, 0x2d, 0x24, + 0x65, 0x00, 0x37, 0x36, 0x7f, 0xab, 0x00, 0x33, 0x99, 0x1d, 0x98, 0xa4, 0x64, 0x36, 0x1d, 0x1f, + 0x98, 0x0b, 0x2d, 0xbf, 0xf1, 0xf8, 0x18, 0x61, 0x93, 0x96, 0x7c, 0x50, 0x5f, 0x7c, 0x21, 0x0d, + 0xc6, 0x97, 0x78, 0x34, 0x51, 0x17, 0x69, 0xfd, 0xf3, 0xac, 0xb1, 0xce, 0x95, 0x5b, 0x8a, 0x43, + 0x45, 0xb8, 0xeb, 0x4a, 0x45, 0x87, 0xcc, 0x69, 0x73, 0x81, 0xcc, 0x98, 0x24, 0x3f, 0xf9, 0x1d, + 0x2d, 0x43, 0x1d, 0xff, 0x62, 0xdf, 0x7f, 0x81, 0xef, 0x52, 0xc9, 0x62, 0x65, 0x2e, 0xfb, 0x61, + 0xe4, 0xa9, 0x70, 0x7d, 0x5b, 0xfd, 0x26, 0x37, 0xa0, 0x28, 0x1f, 0xe1, 0x11, 0xaf, 0x7d, 0x05, + 0x22, 0xe6, 0x24, 0x05, 0x27, 0xef, 0xc2, 0x6c, 0x12, 0x26, 0x5b, 0xc9, 0xaf, 0xc5, 0xe6, 0xa1, + 0xad, 0x3f, 0xe9, 0xc3, 0x47, 0x04, 0xba, 0x7c, 0x3a, 0xac, 0xff, 0x36, 0x6a, 0x32, 0xf8, 0x68, + 0xa3, 0x46, 0x2e, 0xc0, 0xe8, 0x46, 0xcd, 0x78, 0xdd, 0xd0, 0x8e, 0x01, 0xac, 0xda, 0xac, 0x09, + 0x95, 0xa0, 0xb1, 0xef, 0x46, 0xb4, 0x11, 0x75, 0x02, 0x19, 0x8d, 0x94, 0x82, 0x13, 0x0b, 0xc6, + 0xef, 0xb5, 0xdc, 0xdd, 0x86, 0x14, 0xc6, 0x55, 0x60, 0xc0, 0xc8, 0xab, 0x30, 0xb9, 0xe2, 0x85, + 0x91, 0xd3, 0x6a, 0xad, 0xd1, 0x68, 0xdf, 0x6f, 0x8a, 0xb7, 0x9b, 0xed, 0x04, 0x94, 0x95, 0xbb, + 0xe0, 0x7b, 0x91, 0xe3, 0x7a, 0x34, 0xb0, 0x3b, 0x5e, 0xe4, 0x1e, 0x50, 0xd1, 0xf6, 0x14, 0x9c, + 0xbc, 0x05, 0x33, 0x0a, 0xb6, 0x11, 0x34, 0xf6, 0x69, 0x18, 0x05, 0xf8, 0xe6, 0x29, 0x06, 0xe6, + 0xd9, 0xd9, 0x48, 0x2c, 0xa1, 0xe5, 0x77, 0x9a, 0x4b, 0xde, 0x13, 0x37, 0xf0, 0xf9, 0x89, 0xf7, + 0x88, 0x28, 0x21, 0x01, 0xb7, 0x7e, 0x67, 0x24, 0x73, 0x66, 0x78, 0x91, 0x31, 0xf8, 0x05, 0x8c, + 0x2f, 0x38, 0x6d, 0x67, 0xd7, 0x6d, 0xb9, 0x91, 0xab, 0x1e, 0x87, 0x7c, 0xbb, 0xc7, 0xb4, 0x22, + 0x9f, 0x65, 0xa2, 0x4d, 0x9d, 0xd9, 0x36, 0x44, 0xcd, 0xfd, 0xc5, 0x10, 0xcc, 0x64, 0xd2, 0x91, + 0xeb, 0xe2, 0x15, 0x49, 0x35, 0x75, 0x8b, 0x27, 0x0a, 0xed, 0x24, 0x98, 0xf5, 0x25, 0x82, 0x16, + 0x5a, 0xd4, 0xf1, 0x3a, 0xe2, 0x81, 0x42, 0xdb, 0x80, 0xb1, 0xbe, 0x64, 0x5b, 0x13, 0x4d, 0x18, + 0xde, 0xb6, 0xb0, 0x13, 0x50, 0x0c, 0x66, 0xeb, 0x44, 0xfb, 0x52, 0xd4, 0x00, 0xbf, 0x17, 0xac, + 0x81, 0x98, 0xa4, 0x75, 0xbf, 0x49, 0x35, 0x49, 0x83, 0x5c, 0x92, 0x09, 0x65, 0x92, 0x18, 0x44, + 0x4a, 0x1a, 0xe2, 0x92, 0x34, 0x10, 0x79, 0x05, 0x26, 0x2a, 0xed, 0xb6, 0x26, 0x08, 0x5f, 0x26, + 0xb4, 0x4d, 0x20, 0xb9, 0x04, 0x50, 0x69, 0xb7, 0xa5, 0x18, 0x7c, 0x75, 0xd0, 0xd6, 0x20, 0xe4, + 0x66, 0x9c, 0x07, 0x52, 0x13, 0x85, 0xa7, 0x21, 0x76, 0x06, 0x86, 0xe9, 0x55, 0x25, 0xcd, 0x13, + 0x42, 0x81, 0xeb, 0x35, 0x01, 0x26, 0x1f, 0xc2, 0xb9, 0x44, 0x3c, 0x8c, 0x56, 0x00, 0x9e, 0x54, + 0xd8, 0xf9, 0x04, 0xe4, 0x1d, 0x38, 0x9b, 0x40, 0xca, 0xe2, 0xf0, 0x50, 0xc2, 0xce, 0xc1, 0x92, + 0xf7, 0xa1, 0x94, 0xc8, 0xf5, 0x10, 0x17, 0x8a, 0x07, 0x10, 0x76, 0x2e, 0x9e, 0x7d, 0x5d, 0x89, + 0x4b, 0xa3, 0xa2, 0x48, 0x3c, 0x6b, 0xb5, 0xb3, 0x91, 0x64, 0x19, 0xca, 0x99, 0x31, 0x46, 0x5a, + 0xc1, 0xf8, 0x9a, 0xa2, 0xdd, 0x8b, 0x8c, 0x54, 0xe1, 0x42, 0x26, 0x89, 0xac, 0x06, 0xbe, 0xb1, + 0x68, 0x77, 0xa5, 0x21, 0xf3, 0x30, 0x1d, 0xc7, 0x5a, 0x69, 0x55, 0xc0, 0xe7, 0x15, 0xed, 0x4c, + 0x1c, 0x79, 0xc3, 0xcc, 0xe8, 0xc1, 0x0b, 0xc3, 0xd7, 0x15, 0xed, 0x34, 0xc2, 0x3a, 0x2a, 0xc0, + 0x85, 0xcc, 0xb5, 0x58, 0x9a, 0x0c, 0x73, 0xc9, 0xbd, 0xa9, 0x36, 0x17, 0xdc, 0x10, 0x01, 0x94, + 0xdc, 0xd5, 0x2d, 0x03, 0xd4, 0x91, 0x9f, 0x8b, 0x7a, 0x10, 0x87, 0x53, 0xde, 0x53, 0x47, 0x9b, + 0xfd, 0xe8, 0x2c, 0xb9, 0x95, 0xdc, 0xa3, 0x65, 0x14, 0xae, 0x1f, 0x71, 0xca, 0xc3, 0xcc, 0x17, + 0x39, 0x45, 0xfa, 0x93, 0x02, 0x94, 0x7b, 0x6c, 0x41, 0x54, 0x9b, 0x0a, 0xc7, 0x68, 0xd3, 0x7d, + 0xd5, 0x26, 0x7e, 0xa1, 0x7e, 0xfe, 0x78, 0xdb, 0x9c, 0x97, 0xdd, 0xac, 0xbf, 0x2c, 0x00, 0x49, + 0x6f, 0x75, 0xc9, 0x77, 0x61, 0xb4, 0x56, 0x5b, 0x36, 0x22, 0x2d, 0x53, 0x87, 0x5b, 0x31, 0x05, + 0xb9, 0x7d, 0xac, 0xd0, 0x4a, 0x3d, 0xb0, 0xf2, 0x93, 0x54, 0x3c, 0x67, 0x7f, 0xd7, 0x78, 0xce, + 0x54, 0x34, 0xe7, 0x52, 0x46, 0x80, 0xe2, 0x40, 0x8f, 0x00, 0xc5, 0x74, 0xf4, 0xa1, 0xb5, 0x08, + 0xa5, 0xbc, 0xdd, 0x32, 0xce, 0x70, 0x3c, 0x7b, 0xa2, 0x76, 0x40, 0xc7, 0x67, 0x38, 0x13, 0x6c, + 0xbd, 0x03, 0x67, 0x15, 0x37, 0x7f, 0x96, 0x49, 0x4b, 0x5b, 0x22, 0x4c, 0x6c, 0x95, 0x1e, 0x25, + 0x06, 0x58, 0x7f, 0x3c, 0x90, 0x62, 0xac, 0x75, 0x0e, 0x0e, 0x9c, 0xe0, 0x19, 0xa9, 0x98, 0x8c, + 0xfd, 0x3d, 0xad, 0x9a, 0xea, 0x00, 0xdb, 0x63, 0x6a, 0xd2, 0xd9, 0xba, 0x80, 0x3b, 0x0c, 0xaf, + 0x41, 0xf9, 0xd1, 0x5e, 0x1f, 0x4f, 0xcd, 0x66, 0x00, 0xc9, 0x0e, 0x4c, 0x88, 0xb5, 0x1b, 0x7f, + 0xcb, 0x6f, 0xec, 0x76, 0xf2, 0x1b, 0x33, 0xaa, 0x77, 0xd3, 0x60, 0xe1, 0xa3, 0xd1, 0x14, 0x43, + 0xbe, 0x80, 0x49, 0xb9, 0x53, 0x13, 0x82, 0x79, 0x30, 0xd6, 0x9d, 0xee, 0x82, 0x4d, 0x1e, 0x2e, + 0x39, 0x21, 0x88, 0x55, 0x59, 0x4e, 0x76, 0x5c, 0xf2, 0xe0, 0x71, 0xaa, 0x6c, 0xb0, 0x88, 0x2a, + 0x1b, 0xb0, 0xb9, 0x4f, 0x81, 0xa4, 0xdb, 0xd5, 0xeb, 0x73, 0x9a, 0xd0, 0x3e, 0xa7, 0xb9, 0x0a, + 0x4c, 0x65, 0x34, 0xe0, 0x44, 0x22, 0x3e, 0x05, 0x92, 0xae, 0xe9, 0x49, 0x24, 0x58, 0xd7, 0xe1, + 0x55, 0xa5, 0x02, 0x35, 0x1a, 0x0c, 0x99, 0xd2, 0xc9, 0xfe, 0x2b, 0x7d, 0x50, 0xee, 0x41, 0x4a, + 0xfe, 0x71, 0x21, 0xa9, 0x6d, 0x3e, 0x1a, 0xdf, 0x4b, 0x6a, 0x3b, 0x9b, 0x3f, 0x43, 0xed, 0xd5, + 0xf7, 0x7f, 0xf5, 0xcf, 0x9e, 0xdb, 0xf2, 0x48, 0x77, 0xd9, 0xc9, 0xb5, 0x35, 0xa0, 0x6b, 0x6b, + 0x07, 0xa6, 0x0d, 0xb3, 0xf0, 0x38, 0x8b, 0x97, 0x05, 0x20, 0x5e, 0x88, 0x5e, 0xf5, 0xf7, 0xc4, + 0x43, 0xd6, 0x7d, 0xa5, 0x82, 0xad, 0x41, 0xad, 0xbb, 0x30, 0x93, 0x90, 0x2b, 0x9c, 0xff, 0xdf, + 0x05, 0x95, 0xa2, 0x02, 0x05, 0xf7, 0x57, 0xcf, 0xfc, 0xec, 0xb0, 0x3c, 0xc1, 0xb6, 0xf5, 0x37, + 0xe3, 0x57, 0x42, 0xe4, 0x5f, 0xd6, 0x9a, 0x7e, 0x7c, 0x51, 0x69, 0xe9, 0xa9, 0xbb, 0xc8, 0x1d, + 0x18, 0xe2, 0x90, 0x44, 0x2e, 0x7e, 0x9d, 0x5a, 0xcc, 0x0b, 0x82, 0xd0, 0x9a, 0xc1, 0x0b, 0xf5, + 0xf8, 0xa3, 0x12, 0x27, 0x80, 0xb1, 0xb6, 0xf9, 0xdb, 0x54, 0x31, 0x58, 0xe5, 0xfb, 0x1f, 0xa8, + 0xc4, 0x89, 0x6a, 0x64, 0x1c, 0x8b, 0xa4, 0xf3, 0xfc, 0xa7, 0x2d, 0xda, 0xe4, 0x8f, 0x8a, 0x56, + 0xc7, 0x85, 0x8d, 0x3b, 0xe0, 0x30, 0x01, 0xc8, 0x66, 0x7d, 0x02, 0x33, 0x6c, 0xb7, 0x10, 0x24, + 0xcb, 0xc3, 0x17, 0x69, 0x18, 0xcc, 0xbc, 0x37, 0xe3, 0x30, 0x10, 0xde, 0x9b, 0x11, 0x48, 0x6b, + 0x15, 0xce, 0x71, 0xe7, 0xa7, 0xde, 0xa4, 0xf8, 0xa8, 0x61, 0x10, 0x7f, 0x27, 0xae, 0x63, 0x67, + 0xb4, 0x9e, 0xd3, 0x59, 0x1f, 0xe3, 0x7d, 0x3f, 0x31, 0x50, 0x5d, 0xdf, 0x8b, 0x3d, 0x9d, 0xc7, + 0x4b, 0x10, 0xf0, 0xff, 0xc3, 0x85, 0x4a, 0xbb, 0x4d, 0xbd, 0x66, 0xcc, 0xb8, 0x15, 0x38, 0xc7, + 0x4c, 0xdf, 0x42, 0x2a, 0x30, 0x88, 0xd4, 0xea, 0x0c, 0x58, 0x54, 0x37, 0xa3, 0x3a, 0x48, 0x27, + 0x92, 0x33, 0x63, 0x01, 0x9c, 0xd3, 0x6a, 0xc2, 0x6c, 0xad, 0xb3, 0x7b, 0xe0, 0x46, 0x78, 0xdb, + 0x06, 0x53, 0x20, 0xc9, 0xb2, 0x57, 0xe4, 0x73, 0x82, 0x5c, 0x19, 0xd7, 0xe3, 0x7b, 0x61, 0x78, + 0x61, 0x47, 0xa4, 0x45, 0x7a, 0x72, 0xe7, 0x66, 0xcc, 0x8a, 0x5e, 0x1e, 0x5e, 0x0a, 0xa2, 0xc5, + 0x93, 0x83, 0xd6, 0x14, 0x9c, 0xd1, 0xcf, 0xbc, 0xf8, 0x08, 0x99, 0x81, 0x29, 0xf3, 0x2c, 0x8b, + 0x83, 0xbf, 0x86, 0x69, 0xee, 0x6b, 0xe7, 0x8f, 0x2b, 0xcc, 0xc7, 0xef, 0x08, 0xf4, 0xed, 0xcc, + 0x27, 0x2e, 0x69, 0x60, 0xec, 0xb6, 0x7a, 0x36, 0x67, 0x67, 0x9e, 0xdf, 0xd9, 0x7e, 0x32, 0x6f, + 0x9c, 0xc6, 0xf6, 0xed, 0xcc, 0x57, 0x87, 0x45, 0x92, 0x6a, 0x26, 0x9d, 0x77, 0xff, 0xb7, 0x22, + 0x7d, 0x1e, 0xd3, 0x84, 0x2c, 0x53, 0x07, 0xaf, 0xf4, 0x65, 0x27, 0x5b, 0x98, 0x84, 0x3e, 0x95, + 0x85, 0xb6, 0xcf, 0x6d, 0x5a, 0xbf, 0x5f, 0x80, 0xeb, 0x7c, 0x43, 0x96, 0xcd, 0x87, 0x07, 0x5b, + 0x39, 0xcc, 0xe4, 0x5d, 0x18, 0x0c, 0xb5, 0x00, 0x0f, 0x4b, 0xd4, 0xbc, 0x9b, 0x24, 0xce, 0x40, + 0x2a, 0x30, 0xae, 0xdf, 0x5c, 0x3b, 0x5e, 0x82, 0x4b, 0x7b, 0xec, 0xe0, 0x91, 0xa3, 0x6e, 0xb3, + 0x3d, 0x86, 0xf3, 0x4b, 0xdf, 0xb0, 0x01, 0x21, 0x56, 0x28, 0x61, 0x3d, 0xc4, 0x97, 0xf9, 0x4f, + 0x6f, 0x89, 0x11, 0x63, 0x9a, 0xf6, 0x49, 0x30, 0xb3, 0x93, 0xe5, 0x22, 0x17, 0x5f, 0x71, 0xb2, + 0x0d, 0x98, 0xf5, 0xc7, 0x05, 0xb8, 0x90, 0x5d, 0x9a, 0x98, 0x58, 0x56, 0xe0, 0xcc, 0x82, 0xe3, + 0xf9, 0x9e, 0xdb, 0x70, 0x5a, 0xb5, 0xc6, 0x3e, 0x6d, 0x76, 0x54, 0x2a, 0x6b, 0x35, 0xcb, 0xec, + 0x51, 0x4f, 0xb2, 0x4b, 0x12, 0x3b, 0xcd, 0xc5, 0x2c, 0x44, 0xbc, 0xba, 0xc2, 0xe7, 0xde, 0x16, + 0x0d, 0x94, 0x3c, 0x5e, 0xb3, 0x1c, 0x2c, 0xb9, 0x2d, 0x0f, 0x15, 0x9a, 0xdb, 0x9e, 0x1b, 0x29, + 0x26, 0xee, 0xea, 0xc9, 0x42, 0x59, 0xff, 0xa1, 0x00, 0xe7, 0xf0, 0xf5, 0x3a, 0xe3, 0x3d, 0xdc, + 0x38, 0xa3, 0xbb, 0x4c, 0x4a, 0x5e, 0x30, 0xae, 0xe2, 0x18, 0xd4, 0x66, 0x76, 0x72, 0xf2, 0x06, + 0x0c, 0xd4, 0x64, 0xc0, 0xd9, 0x64, 0xe2, 0x25, 0x73, 0xc1, 0xc1, 0xf0, 0x36, 0x52, 0x31, 0x1b, + 0x7e, 0x91, 0x86, 0x0d, 0xea, 0xe1, 0x93, 0xf3, 0xdc, 0xf3, 0xa0, 0x41, 0xe2, 0x64, 0x6b, 0x03, + 0x79, 0xc9, 0xd6, 0x06, 0xcd, 0x64, 0x6b, 0xd6, 0x13, 0xfe, 0x76, 0x5d, 0xb2, 0x41, 0xa2, 0x93, + 0x3e, 0x4e, 0xbd, 0x50, 0xcf, 0xd7, 0x81, 0xb3, 0x59, 0x2d, 0x63, 0x9b, 0xf4, 0xc4, 0xe3, 0xf3, + 0xf9, 0x19, 0xd4, 0x37, 0xe1, 0x15, 0x83, 0xb6, 0xd2, 0x6a, 0xf9, 0x4f, 0x69, 0x73, 0x33, 0xf0, + 0x0f, 0xfc, 0xc8, 0x78, 0xbb, 0xeb, 0xb4, 0xa3, 0xd3, 0xa9, 0xc5, 0x38, 0x09, 0xb6, 0xfe, 0x3f, + 0xb8, 0xd6, 0x43, 0xa2, 0x68, 0x54, 0x0d, 0xce, 0x38, 0x09, 0x9c, 0x8c, 0x1c, 0xba, 0x96, 0xd5, + 0xae, 0xa4, 0xa0, 0xd0, 0x4e, 0xf3, 0xdf, 0xd8, 0x32, 0x5e, 0x75, 0x27, 0x25, 0x98, 0xde, 0xb4, + 0x37, 0x16, 0xb7, 0x17, 0xb6, 0xea, 0x5b, 0x5f, 0x6c, 0x2e, 0xd5, 0xb7, 0xd7, 0x1f, 0xac, 0x6f, + 0x3c, 0x5c, 0xe7, 0x4f, 0x10, 0x18, 0x98, 0xad, 0xa5, 0xca, 0x5a, 0xb1, 0x40, 0xa6, 0xa1, 0x68, + 0x80, 0x97, 0xb6, 0xab, 0xc5, 0xbe, 0x1b, 0x5f, 0x1b, 0xaf, 0x95, 0x93, 0x0b, 0x50, 0xaa, 0x6d, + 0x6f, 0x6e, 0x6e, 0xd8, 0x4a, 0xaa, 0xfe, 0x00, 0xc2, 0x0c, 0x9c, 0x31, 0xb0, 0x77, 0xed, 0xa5, + 0xa5, 0x62, 0x81, 0x55, 0xc5, 0x00, 0x6f, 0xda, 0x4b, 0x6b, 0x2b, 0xdb, 0x6b, 0xc5, 0xbe, 0x1b, + 0x75, 0xfd, 0x06, 0x29, 0x39, 0x0f, 0xb3, 0x8b, 0x4b, 0x3b, 0x2b, 0x0b, 0x4b, 0x59, 0xb2, 0xa7, + 0xa1, 0xa8, 0x23, 0xb7, 0x36, 0xb6, 0x36, 0xb9, 0x68, 0x1d, 0xfa, 0x70, 0xa9, 0x5a, 0xd9, 0xde, + 0x5a, 0x5e, 0x2f, 0xf6, 0x5b, 0x03, 0x23, 0x7d, 0xc5, 0xbe, 0x1b, 0x3f, 0x30, 0xae, 0x97, 0xb2, + 0xea, 0x0b, 0xf2, 0xed, 0x5a, 0xe5, 0x5e, 0x7e, 0x11, 0x1c, 0xbb, 0x76, 0xb7, 0x52, 0x2c, 0x90, + 0x8b, 0x70, 0xce, 0x80, 0x6e, 0x56, 0x6a, 0xb5, 0x87, 0x1b, 0xf6, 0xe2, 0xea, 0x52, 0xad, 0x56, + 0xec, 0xbb, 0xb1, 0x63, 0x24, 0x98, 0x64, 0x25, 0xac, 0xdd, 0xad, 0xd4, 0xed, 0xa5, 0xcf, 0xb6, + 0x57, 0xec, 0xa5, 0xc5, 0x74, 0x09, 0x06, 0xf6, 0x8b, 0xa5, 0x5a, 0xb1, 0x40, 0xa6, 0xe0, 0xb4, + 0x01, 0x5d, 0xdf, 0x28, 0xf6, 0xdd, 0x78, 0x55, 0xe4, 0x20, 0x24, 0x93, 0x00, 0x8b, 0x4b, 0xb5, + 0x85, 0xa5, 0xf5, 0xc5, 0x95, 0xf5, 0x7b, 0xc5, 0x53, 0x64, 0x02, 0x46, 0x2b, 0xea, 0x67, 0xe1, + 0xc6, 0xfb, 0x70, 0x3a, 0x61, 0xde, 0x33, 0x0a, 0x65, 0x18, 0x17, 0x4f, 0xa1, 0xfa, 0xe5, 0x4f, + 0xf4, 0xb1, 0x72, 0x4b, 0xbd, 0x58, 0xb8, 0x51, 0x95, 0x0f, 0x5c, 0x6b, 0xdf, 0x39, 0x19, 0x83, + 0xe1, 0xc5, 0xa5, 0xbb, 0x95, 0xed, 0xd5, 0xad, 0xe2, 0x29, 0xf6, 0x63, 0xc1, 0x5e, 0xaa, 0x6c, + 0x2d, 0x2d, 0x16, 0x0b, 0x64, 0x14, 0x06, 0x6b, 0x5b, 0x95, 0xad, 0xa5, 0x62, 0x1f, 0x19, 0x81, + 0x81, 0xed, 0xda, 0x92, 0x5d, 0xec, 0x9f, 0xff, 0xd7, 0xff, 0xa8, 0xc0, 0x1d, 0x8d, 0xf2, 0xa2, + 0xd9, 0xd7, 0x9a, 0x41, 0x29, 0xa6, 0x3c, 0xf1, 0x9a, 0x6f, 0xae, 0xf5, 0x88, 0xbb, 0x80, 0xb9, + 0x2e, 0x87, 0x3b, 0x48, 0x70, 0xbd, 0x70, 0xbb, 0x40, 0x6c, 0x0c, 0x86, 0x49, 0xd8, 0x57, 0x4a, + 0x72, 0xb6, 0x09, 0x3c, 0x77, 0xb1, 0xab, 0x59, 0x46, 0x7e, 0x09, 0x2c, 0x5d, 0x66, 0x8e, 0x15, + 0xf2, 0xdd, 0xe3, 0x59, 0x1b, 0xb2, 0xcc, 0x57, 0x8f, 0x47, 0x4e, 0xee, 0xc3, 0x04, 0xdb, 0x9b, + 0x2b, 0x32, 0x72, 0x3e, 0xc9, 0xa8, 0x99, 0x04, 0x73, 0x17, 0xb2, 0x91, 0xea, 0xc1, 0xad, 0x71, + 0x6c, 0x08, 0x37, 0xae, 0x43, 0x22, 0xf3, 0xd4, 0x48, 0x08, 0x9f, 0xf1, 0xe7, 0xce, 0x24, 0xc0, + 0x3b, 0x77, 0x6e, 0x17, 0x48, 0x0d, 0x93, 0x44, 0x1a, 0x9b, 0x7c, 0x22, 0x6f, 0x3e, 0xa6, 0x77, + 0xff, 0xbc, 0x36, 0x65, 0xf5, 0x3c, 0x6e, 0x8e, 0x75, 0xb0, 0x0e, 0x24, 0xbd, 0x77, 0x26, 0x97, + 0xe3, 0x71, 0x90, 0xbd, 0xad, 0x9e, 0x3b, 0x9b, 0x3a, 0xc8, 0x5a, 0x62, 0xbb, 0x27, 0xb2, 0x04, + 0x93, 0x22, 0x09, 0x85, 0xd8, 0xcd, 0x93, 0x6e, 0xf6, 0x40, 0xae, 0x98, 0x7b, 0xa8, 0x27, 0x65, + 0x11, 0x90, 0xb9, 0xb8, 0x1d, 0x49, 0x33, 0x61, 0xee, 0x7c, 0x26, 0x4e, 0xb4, 0xef, 0x2e, 0x4c, + 0x9a, 0xc6, 0x05, 0x91, 0x1d, 0x94, 0x69, 0x73, 0xe4, 0x56, 0xa8, 0x0e, 0xb3, 0x6b, 0x8e, 0x8b, + 0xe7, 0x25, 0x22, 0x48, 0x4f, 0xc6, 0xc1, 0x91, 0x72, 0x97, 0xc0, 0xb8, 0x1a, 0xf5, 0x9a, 0xaa, + 0x13, 0xf2, 0x1e, 0xcf, 0xc0, 0xcf, 0xa6, 0x26, 0xf7, 0xc8, 0x66, 0x8c, 0x22, 0xb1, 0xcc, 0x27, + 0xcf, 0xb3, 0xc2, 0x4e, 0xe7, 0xf2, 0x22, 0xa5, 0xc9, 0x1a, 0x6e, 0xd2, 0x13, 0x12, 0xb5, 0x31, + 0x71, 0x62, 0x71, 0x25, 0x4c, 0x85, 0x12, 0xb9, 0xc9, 0x90, 0xe7, 0x90, 0xe4, 0x28, 0x2e, 0x57, + 0xd8, 0xed, 0x02, 0xf9, 0x1a, 0xbf, 0xea, 0x4c, 0x71, 0x0f, 0xdd, 0x68, 0x5f, 0xec, 0x7e, 0xce, + 0x67, 0x0a, 0x10, 0x1f, 0x4a, 0x17, 0xe9, 0x36, 0x4c, 0x67, 0x05, 0x67, 0x2b, 0x85, 0x76, 0x89, + 0xdc, 0xce, 0x1d, 0x05, 0x36, 0x33, 0x35, 0x9a, 0xf9, 0x9d, 0xd4, 0x25, 0x36, 0x38, 0x57, 0xe6, + 0x87, 0x30, 0xc9, 0x46, 0xc9, 0x03, 0x4a, 0xdb, 0x95, 0x96, 0xfb, 0x84, 0x86, 0x44, 0x66, 0xf8, + 0x56, 0xa0, 0x3c, 0xde, 0xeb, 0x05, 0xf2, 0x1d, 0x18, 0x7b, 0xe8, 0x44, 0x8d, 0x7d, 0x91, 0xe9, + 0x56, 0x26, 0xc2, 0x45, 0xd8, 0x9c, 0xfc, 0x85, 0xc8, 0xdb, 0x05, 0xf2, 0x11, 0x0c, 0xdf, 0xa3, + 0x11, 0xde, 0x3c, 0xbf, 0xa2, 0x62, 0x09, 0xb9, 0x7f, 0x72, 0xc5, 0x53, 0xb7, 0x90, 0x64, 0x85, + 0x93, 0xce, 0x5c, 0x72, 0x0b, 0x80, 0x4f, 0x08, 0x28, 0x21, 0x89, 0x9e, 0x4b, 0x55, 0x9b, 0xdc, + 0x63, 0x9b, 0x87, 0x16, 0x8d, 0xe8, 0x71, 0x8b, 0xcc, 0xd3, 0xd1, 0x2a, 0x4c, 0xaa, 0x37, 0xca, + 0xd6, 0x31, 0x21, 0x91, 0x95, 0x10, 0x16, 0x9e, 0x40, 0xda, 0xfb, 0xec, 0xab, 0xe0, 0x0f, 0x74, + 0x63, 0xe6, 0x1a, 0x9c, 0x49, 0x67, 0xf5, 0xf4, 0x37, 0xfa, 0x14, 0x2a, 0x95, 0xc8, 0xc9, 0x34, + 0xde, 0x65, 0x3f, 0x8c, 0x4c, 0x5e, 0x05, 0xc9, 0xe6, 0xfd, 0x45, 0x98, 0xd3, 0xcb, 0x35, 0x53, + 0xad, 0xc7, 0x73, 0x6e, 0x5e, 0x06, 0xf7, 0xb9, 0x2b, 0x5d, 0x28, 0x84, 0xfd, 0xd6, 0xff, 0xeb, + 0x7d, 0x05, 0x9c, 0x4e, 0x16, 0x61, 0x4a, 0x96, 0xb5, 0xd1, 0xa6, 0x5e, 0xad, 0xb6, 0x8c, 0xef, + 0x51, 0xc9, 0xc8, 0x15, 0x0d, 0x26, 0xa5, 0x93, 0x34, 0x8a, 0x2d, 0x7d, 0x46, 0x86, 0x1a, 0xd2, + 0x2d, 0x6f, 0x4d, 0xbc, 0xf4, 0x65, 0xe6, 0x00, 0x7f, 0xc0, 0x9d, 0x4a, 0xc6, 0xe6, 0x7f, 0x67, + 0x9e, 0x74, 0x31, 0x80, 0xe6, 0x72, 0x4c, 0x88, 0xdb, 0x05, 0xf2, 0x05, 0x90, 0xb4, 0x49, 0xa2, + 0x54, 0x98, 0x6b, 0x7e, 0x29, 0x15, 0x76, 0xb1, 0x67, 0xee, 0xc1, 0x8c, 0xca, 0x4f, 0xa5, 0x95, + 0x3a, 0x4f, 0x72, 0x6a, 0x93, 0x57, 0x4b, 0xf2, 0x09, 0x4c, 0x89, 0x41, 0xab, 0x23, 0x48, 0x51, + 0xcd, 0x3f, 0xc2, 0x2a, 0xc9, 0x1d, 0xa7, 0xf7, 0x61, 0xa6, 0x96, 0xd0, 0x18, 0x0f, 0xe6, 0x3f, + 0x67, 0x8a, 0x40, 0x60, 0x8d, 0x46, 0x5c, 0x65, 0xd9, 0xb2, 0x1e, 0x00, 0xe1, 0x4e, 0x21, 0x29, + 0xee, 0x89, 0x4b, 0x9f, 0x92, 0x8b, 0x89, 0xaa, 0x33, 0x20, 0x92, 0xe1, 0x04, 0x96, 0xdb, 0xb2, + 0x2d, 0xfe, 0xbc, 0x3c, 0x42, 0x8d, 0x73, 0xf4, 0xcb, 0x06, 0x83, 0x71, 0x14, 0x2f, 0x3a, 0xe0, + 0x5c, 0x2e, 0x05, 0xf9, 0x65, 0x4c, 0x0c, 0xdd, 0xdd, 0xac, 0x22, 0xdf, 0xc9, 0xb2, 0x7e, 0x73, + 0x0c, 0xc3, 0xb9, 0x37, 0x8e, 0x47, 0xac, 0x0c, 0xd9, 0x89, 0x7b, 0x34, 0xda, 0x6c, 0x75, 0xf6, + 0x5c, 0x7c, 0x78, 0x98, 0x28, 0xa7, 0x91, 0x02, 0x89, 0x71, 0x29, 0xf3, 0x31, 0xc6, 0x88, 0x1a, + 0xfd, 0x21, 0x59, 0x81, 0x22, 0x9f, 0xff, 0x35, 0x11, 0x17, 0x53, 0x22, 0x04, 0x89, 0x13, 0x38, + 0x07, 0x61, 0x6e, 0x6f, 0xdd, 0xe2, 0xb1, 0x51, 0x44, 0x7e, 0x93, 0xfa, 0x06, 0x73, 0xca, 0x80, + 0xa9, 0xc7, 0x32, 0x58, 0x8f, 0xd8, 0x34, 0xa4, 0x91, 0xcc, 0x40, 0xc5, 0x9f, 0x9d, 0xbe, 0x1a, + 0x2f, 0xf6, 0x69, 0x6c, 0xfc, 0xe9, 0x27, 0xb2, 0x25, 0xee, 0xbc, 0x49, 0xd4, 0x53, 0xdc, 0x19, + 0x42, 0x5f, 0x35, 0xf6, 0x24, 0x27, 0x93, 0xfb, 0x16, 0xae, 0x41, 0x98, 0x75, 0x6b, 0x26, 0xae, + 0x1b, 0xfb, 0x2d, 0xb9, 0x26, 0x34, 0xae, 0x9d, 0x79, 0x9c, 0xd2, 0xd8, 0x22, 0xc9, 0xb6, 0xb0, + 0x9d, 0x20, 0xa0, 0x1e, 0x67, 0xce, 0xdb, 0x6f, 0x64, 0x71, 0x7f, 0x8c, 0x53, 0x8f, 0xc6, 0xcd, + 0xef, 0x1c, 0xf6, 0x12, 0xc1, 0x9f, 0x49, 0xbb, 0x5d, 0x20, 0xef, 0xc2, 0x88, 0xa8, 0x23, 0x63, + 0x32, 0x2a, 0x1d, 0x76, 0xa9, 0x35, 0x72, 0x02, 0x57, 0x12, 0xd6, 0xd9, 0xa4, 0xc9, 0xeb, 0x7d, + 0x5e, 0xe7, 0x77, 0xd9, 0x62, 0xdb, 0x7c, 0x1e, 0xce, 0x05, 0xb9, 0xea, 0x22, 0x67, 0x49, 0x65, + 0x6a, 0x92, 0xa0, 0x1e, 0xcb, 0x23, 0x17, 0xc2, 0xf6, 0xcd, 0x98, 0xee, 0x54, 0x65, 0x2d, 0x54, + 0xfb, 0x66, 0x03, 0xdc, 0x6b, 0xad, 0x5d, 0x81, 0x62, 0xa5, 0x81, 0x2b, 0x41, 0x8d, 0x1e, 0x38, + 0xed, 0x7d, 0x3f, 0xa0, 0xca, 0x68, 0x49, 0x22, 0xa4, 0xac, 0x19, 0xb5, 0xb3, 0x10, 0x88, 0x55, + 0xea, 0x60, 0x4e, 0xf8, 0x59, 0xb5, 0xb5, 0x48, 0xa0, 0xb2, 0x39, 0xba, 0x18, 0x29, 0xd3, 0x0b, + 0xcc, 0xac, 0x6a, 0xbd, 0x98, 0x98, 0xf7, 0x71, 0xc2, 0x50, 0xc4, 0xa1, 0x5a, 0x21, 0x14, 0x48, + 0x99, 0x73, 0xf2, 0xfa, 0x91, 0x22, 0xad, 0xc8, 0x73, 0xe3, 0x58, 0x2d, 0x79, 0xdc, 0x79, 0xc5, + 0x7f, 0x0f, 0x26, 0x97, 0xd8, 0x84, 0xde, 0x69, 0xba, 0xfc, 0x1d, 0x0c, 0x62, 0x3e, 0x6c, 0x90, + 0xcb, 0xb8, 0x2c, 0x5f, 0x26, 0x44, 0x56, 0x61, 0xfa, 0xcb, 0x35, 0x45, 0x83, 0xc9, 0xfe, 0x98, + 0x96, 0x62, 0xc5, 0x53, 0x24, 0x68, 0x9a, 0x0b, 0x5b, 0x7f, 0x96, 0xef, 0x08, 0x2b, 0xed, 0x76, + 0x4b, 0xba, 0xa4, 0xf9, 0xd9, 0xfb, 0x35, 0xc3, 0x84, 0x4c, 0xe1, 0xa5, 0xec, 0xf4, 0xa6, 0xf1, + 0x73, 0xed, 0xa5, 0xf0, 0x1c, 0x99, 0x39, 0xf8, 0x5e, 0x63, 0x51, 0x65, 0xae, 0xaf, 0xb4, 0x5a, + 0x29, 0xe6, 0x90, 0xbc, 0x6e, 0x4a, 0xcf, 0xa2, 0xe9, 0x55, 0x02, 0x9a, 0xe8, 0x7c, 0xd7, 0x55, + 0x69, 0xb7, 0xf9, 0x64, 0x79, 0x49, 0x4d, 0x18, 0x26, 0x22, 0x6d, 0xa2, 0x27, 0xf1, 0x62, 0x6e, + 0xbf, 0x8f, 0xc3, 0x2c, 0x7e, 0x4e, 0x9c, 0xe8, 0x06, 0x6f, 0xf2, 0x35, 0x75, 0xb5, 0x09, 0x4b, + 0x20, 0xd5, 0x3a, 0x71, 0x1a, 0xb7, 0x3e, 0xf1, 0xdb, 0xe4, 0xca, 0x33, 0x93, 0x80, 0x4b, 0x79, + 0x97, 0xf2, 0xd0, 0xca, 0x53, 0x5a, 0x14, 0x83, 0x29, 0xae, 0xe0, 0x25, 0x63, 0x7d, 0x48, 0xd7, + 0xb1, 0x9c, 0x8b, 0x57, 0x4d, 0x2e, 0x26, 0x5f, 0x8b, 0x57, 0x42, 0x73, 0x9e, 0x91, 0xcf, 0xed, + 0x93, 0xbb, 0x30, 0xad, 0xf7, 0xa8, 0x6a, 0x77, 0xde, 0xec, 0x9f, 0x27, 0x67, 0x0b, 0x66, 0x32, + 0x1f, 0x77, 0x57, 0x4b, 0x6c, 0xb7, 0xa7, 0xdf, 0x73, 0xa5, 0x52, 0x38, 0x2b, 0x2c, 0xfb, 0xc4, + 0x73, 0xf6, 0xe4, 0x15, 0xd3, 0xf0, 0xcf, 0x7e, 0xed, 0x7e, 0xee, 0x5a, 0x0f, 0x2a, 0xa1, 0xd0, + 0xaf, 0x71, 0x05, 0x4c, 0x95, 0x71, 0x45, 0x73, 0x05, 0xe4, 0x14, 0x60, 0x75, 0x23, 0x51, 0x63, + 0x60, 0x3a, 0x03, 0x9d, 0xaf, 0xe2, 0xab, 0xf9, 0x32, 0xe3, 0x81, 0xb5, 0x23, 0x13, 0xb4, 0xe7, + 0x6a, 0x26, 0x1b, 0xdd, 0xdb, 0x96, 0x9c, 0x53, 0xe3, 0xe1, 0xf8, 0x55, 0xce, 0x93, 0xd6, 0x54, + 0x6e, 0x1b, 0xe3, 0x91, 0xfe, 0xa4, 0xdb, 0xc6, 0x40, 0xca, 0x1a, 0x5e, 0xed, 0x4a, 0xa3, 0x59, + 0x74, 0xe4, 0x2b, 0xee, 0xc7, 0x31, 0x8b, 0xd0, 0xfd, 0x38, 0x99, 0xf2, 0x2f, 0xe7, 0x13, 0xe8, + 0xc2, 0x1d, 0x7e, 0x68, 0x6b, 0x92, 0x84, 0x44, 0x37, 0x95, 0x12, 0xb8, 0xe4, 0xd8, 0xc8, 0x24, + 0xd1, 0x8b, 0x78, 0x28, 0xbf, 0xc1, 0x1c, 0x2d, 0x65, 0x21, 0x8f, 0xb5, 0x4d, 0xd9, 0x80, 0x52, + 0xdc, 0x99, 0x89, 0x06, 0x9c, 0xb0, 0x2b, 0xa5, 0x32, 0xce, 0xc5, 0xdf, 0x71, 0x52, 0xe2, 0x6b, + 0xa9, 0x2f, 0x3d, 0x47, 0x31, 0x5d, 0x8b, 0xe0, 0xf3, 0xb9, 0x96, 0xf0, 0xfd, 0x7c, 0xec, 0xc4, + 0x8d, 0xa1, 0x19, 0xf3, 0xb9, 0x8e, 0x54, 0xc6, 0xea, 0xa4, 0x81, 0xc8, 0x6f, 0xf5, 0xc5, 0x2c, + 0x39, 0x61, 0x7a, 0xc6, 0xd5, 0xea, 0x25, 0xf7, 0x69, 0x49, 0xc4, 0x49, 0x66, 0xdc, 0xe3, 0x54, + 0x2d, 0x4f, 0xce, 0x22, 0x8c, 0xf1, 0xda, 0xf2, 0x85, 0xf4, 0x9c, 0xa1, 0x26, 0x63, 0x0d, 0x9d, + 0x33, 0x1a, 0x67, 0x2e, 0x9f, 0x0b, 0xe8, 0x4a, 0x96, 0xe0, 0xfc, 0x5a, 0x9c, 0x4f, 0xcb, 0x30, + 0xdc, 0xc8, 0x4a, 0x0b, 0xbc, 0x36, 0x17, 0x92, 0xca, 0x31, 0x2a, 0x94, 0xdf, 0x24, 0xa2, 0xab, + 0xa6, 0x47, 0x95, 0xf2, 0xf7, 0xaf, 0x53, 0xe2, 0x89, 0x68, 0x7c, 0xa5, 0x49, 0xe6, 0x63, 0x3c, + 0xab, 0x7c, 0x62, 0x1a, 0x14, 0x1d, 0x14, 0xd9, 0x62, 0x36, 0xf1, 0xfa, 0x08, 0x0d, 0xa2, 0x54, + 0xbe, 0xc5, 0x57, 0x8c, 0xcd, 0x5b, 0x12, 0x9d, 0xbf, 0x77, 0x53, 0x73, 0x76, 0xae, 0xc4, 0x6c, + 0x74, 0x2f, 0xb5, 0x7d, 0x5f, 0x9b, 0xb3, 0x93, 0xbc, 0x21, 0xb9, 0x9e, 0xdc, 0xb8, 0xa5, 0x48, + 0x7a, 0xaf, 0x09, 0x22, 0x84, 0x24, 0x11, 0x40, 0x6a, 0x19, 0x7a, 0x30, 0x91, 0xf9, 0x5a, 0xb0, + 0xe5, 0xf8, 0xcf, 0x91, 0x96, 0x85, 0xec, 0x55, 0xc3, 0x2f, 0xb5, 0x89, 0xce, 0xe4, 0x0c, 0x95, + 0x39, 0x9e, 0x47, 0xd0, 0x4b, 0xf6, 0x3a, 0x5e, 0x69, 0x4a, 0x34, 0xd0, 0x6d, 0x50, 0xb5, 0xb3, + 0xc9, 0xc4, 0xe6, 0xb7, 0xff, 0x9e, 0xdc, 0x29, 0x25, 0xe5, 0x9d, 0x4d, 0x38, 0x6d, 0x7b, 0x55, + 0xec, 0x6b, 0x39, 0x19, 0x27, 0xda, 0x84, 0x97, 0x8a, 0x5e, 0xeb, 0xd6, 0x6a, 0xed, 0x31, 0xce, + 0x2e, 0x66, 0xd0, 0xe9, 0x9a, 0xbb, 0xe7, 0xa9, 0x9b, 0x08, 0x35, 0x5b, 0x19, 0x41, 0x1a, 0x2c, + 0x39, 0xc5, 0x18, 0x28, 0x95, 0x9f, 0x67, 0x5a, 0xee, 0xde, 0x15, 0x9a, 0x06, 0x11, 0x49, 0xf1, + 0x68, 0xee, 0xd6, 0xf3, 0x99, 0xb8, 0xb4, 0x40, 0xfd, 0x81, 0x7e, 0x25, 0xd0, 0x7c, 0xb5, 0xdf, + 0x14, 0x98, 0xf9, 0xa2, 0xff, 0x2d, 0xf4, 0xba, 0xd8, 0x7e, 0x8b, 0xea, 0x5e, 0x17, 0xed, 0xc5, + 0xf7, 0x84, 0xd3, 0x83, 0x7c, 0x0c, 0xa3, 0xea, 0x45, 0x7c, 0xe5, 0xdf, 0x4e, 0x3e, 0xca, 0x3f, + 0x57, 0x4a, 0x23, 0x44, 0x81, 0x6f, 0x4b, 0xc7, 0x07, 0x96, 0x59, 0x32, 0x1d, 0x46, 0xf9, 0xc5, + 0xbe, 0x2d, 0xbd, 0x1e, 0x06, 0x5b, 0xea, 0x3d, 0xfc, 0x24, 0xdb, 0xf7, 0x60, 0x3c, 0x7e, 0xfb, + 0x7e, 0x67, 0x5e, 0x63, 0x4c, 0x3c, 0x88, 0x9f, 0x64, 0x7c, 0x57, 0x1e, 0x69, 0x60, 0x79, 0x26, + 0xb2, 0xfb, 0x2a, 0xfe, 0xb1, 0xf4, 0xb2, 0x18, 0x35, 0x4d, 0xbd, 0xa4, 0xdf, 0x65, 0xf2, 0x1d, + 0xd7, 0x1f, 0xa3, 0x55, 0x5d, 0x9b, 0xf1, 0x9c, 0xb4, 0xea, 0xda, 0xac, 0xe7, 0xa0, 0x63, 0x97, + 0xff, 0x17, 0xd2, 0xa5, 0x10, 0x0b, 0xbd, 0x68, 0x54, 0x2b, 0x25, 0xf7, 0x52, 0x1e, 0x3a, 0x29, + 0xba, 0x06, 0xc5, 0xe4, 0xcb, 0xb9, 0xca, 0x1e, 0xcb, 0x79, 0xe2, 0x58, 0x19, 0x79, 0xb9, 0x4f, + 0xee, 0x6e, 0x4a, 0xff, 0xb8, 0x29, 0xf7, 0x4a, 0x76, 0xa5, 0x74, 0xd1, 0xf9, 0x0e, 0xf3, 0x09, + 0xe3, 0x11, 0x5d, 0xdd, 0x52, 0x4e, 0x3d, 0xd2, 0xab, 0xef, 0xac, 0x32, 0xde, 0xdd, 0x75, 0x65, + 0xd2, 0xaa, 0xcc, 0x23, 0x5b, 0xe5, 0x2c, 0xe8, 0xfd, 0xe2, 0x42, 0xcf, 0xe3, 0x5f, 0xf2, 0x0b, + 0x30, 0x9b, 0x93, 0x41, 0x9e, 0x5c, 0x4b, 0x78, 0x5a, 0xb3, 0x33, 0xcc, 0xab, 0x01, 0x92, 0xf9, + 0xba, 0xfd, 0x1a, 0xc6, 0x0d, 0x18, 0x29, 0x24, 0x52, 0x67, 0x71, 0x0f, 0xdd, 0x68, 0x9f, 0x3f, + 0xe2, 0xae, 0x4d, 0x9b, 0x99, 0xb9, 0x27, 0x48, 0x0d, 0x6d, 0x11, 0x03, 0x9a, 0x71, 0x1c, 0x97, + 0x21, 0x70, 0x2e, 0x5b, 0x20, 0x9b, 0x3b, 0xd8, 0x58, 0xc8, 0xc8, 0xef, 0xa1, 0xc6, 0x42, 0x7e, + 0xee, 0x8f, 0xdc, 0x6a, 0x6e, 0xca, 0x3d, 0x52, 0xb6, 0xc4, 0xfc, 0x54, 0x1f, 0xb9, 0x12, 0xef, + 0x33, 0x89, 0xa9, 0xec, 0x1d, 0x24, 0x87, 0xbc, 0xfb, 0xec, 0x61, 0xcb, 0x25, 0xd7, 0xe4, 0x9a, + 0xd7, 0xea, 0x97, 0x97, 0x27, 0x24, 0xb7, 0x7e, 0x4b, 0xf2, 0x7b, 0xca, 0xae, 0xdf, 0x71, 0x17, + 0x5d, 0x75, 0xfe, 0x95, 0x48, 0x20, 0x63, 0x34, 0x54, 0x83, 0xcf, 0xe5, 0xc0, 0xc9, 0x3a, 0x06, + 0x02, 0x25, 0xa1, 0x9a, 0x51, 0x9a, 0x9d, 0xa1, 0x26, 0x57, 0x1e, 0x1f, 0xc7, 0x46, 0x86, 0x8f, + 0x93, 0x8c, 0xe3, 0x44, 0x6a, 0x10, 0x31, 0x8e, 0x0d, 0xe8, 0xc9, 0xc6, 0x71, 0x42, 0xa0, 0x39, + 0x8e, 0x93, 0xd5, 0x4c, 0x5a, 0xfa, 0xb9, 0xbd, 0x9a, 0xac, 0xa6, 0x1a, 0xc7, 0xd9, 0x12, 0xf3, + 0x33, 0xb1, 0xe4, 0x4a, 0x54, 0xe3, 0xd8, 0x94, 0x98, 0x43, 0x7e, 0xcc, 0x71, 0x9c, 0x2c, 0xc4, + 0x1c, 0xc7, 0x27, 0xaa, 0x9f, 0x1a, 0xc7, 0xd9, 0xf5, 0x3b, 0xf1, 0x38, 0x4e, 0xa4, 0x2e, 0x32, + 0x1a, 0x9a, 0x35, 0x8e, 0x93, 0xf4, 0x7c, 0x1c, 0x27, 0xa1, 0x09, 0xe7, 0x4a, 0x97, 0x71, 0x9c, + 0xe4, 0xfc, 0x0c, 0xe5, 0x25, 0xd2, 0xae, 0x1c, 0x67, 0x24, 0xe7, 0x66, 0x6c, 0x21, 0x0f, 0xd1, + 0xbd, 0x97, 0x80, 0x1f, 0x6f, 0x34, 0x5f, 0xc8, 0x13, 0x8a, 0xe3, 0x79, 0x47, 0x2a, 0x31, 0x59, + 0x5d, 0xd3, 0x77, 0x95, 0x9d, 0x75, 0xa6, 0x4b, 0x85, 0x77, 0xd8, 0xb8, 0x69, 0x76, 0x91, 0xdb, + 0x2d, 0x69, 0x4e, 0x17, 0xb9, 0xca, 0x94, 0x49, 0xca, 0xcd, 0x65, 0xe9, 0x3e, 0xbe, 0x3f, 0x97, + 0x07, 0x1c, 0x49, 0xbe, 0xf9, 0x84, 0x71, 0x74, 0xe2, 0x9a, 0x2a, 0x23, 0x29, 0x59, 0xd3, 0x93, + 0x8e, 0xf3, 0x35, 0xb9, 0x7b, 0x48, 0x65, 0xdb, 0x4a, 0x34, 0x5a, 0x1f, 0xeb, 0xb9, 0x18, 0xb2, + 0x85, 0xbe, 0xdc, 0x34, 0x5c, 0xf3, 0x03, 0xe7, 0xa5, 0xf5, 0xea, 0x29, 0x35, 0x95, 0x37, 0x48, + 0x97, 0x9a, 0x97, 0x54, 0x48, 0x49, 0x4d, 0x73, 0x7f, 0x82, 0xde, 0x2f, 0x71, 0xe3, 0xca, 0x7b, + 0xe4, 0xe7, 0x7b, 0x52, 0xa6, 0x8c, 0x60, 0x25, 0x46, 0x8b, 0x31, 0x62, 0x1f, 0x8a, 0x13, 0x3c, + 0x09, 0xcc, 0x55, 0x7e, 0x16, 0x3f, 0xf9, 0x04, 0x8a, 0x62, 0x7a, 0x8b, 0x05, 0x64, 0x11, 0xe6, + 0x76, 0x5d, 0x55, 0x3a, 0xdd, 0x8e, 0x51, 0x83, 0xe3, 0x38, 0xdb, 0x8e, 0xa3, 0x89, 0x7c, 0xcf, + 0x14, 0x5b, 0x0e, 0xb7, 0x82, 0x4e, 0x18, 0xd1, 0x66, 0xda, 0xa3, 0x64, 0x56, 0x46, 0x46, 0x46, + 0x98, 0xe4, 0x3b, 0xf3, 0x64, 0x05, 0xe7, 0x36, 0x13, 0xdc, 0xcd, 0xe5, 0x96, 0x2d, 0x06, 0xa7, + 0x9e, 0x65, 0x75, 0xad, 0xc7, 0xac, 0x53, 0x5e, 0xd9, 0xf9, 0x95, 0x52, 0x2a, 0x3a, 0x66, 0xeb, + 0xf2, 0x54, 0xf4, 0x01, 0x86, 0x01, 0x70, 0xf7, 0x5f, 0x2f, 0xcd, 0x24, 0x2f, 0x1a, 0x91, 0x4f, + 0x61, 0x54, 0x32, 0xf7, 0x56, 0x48, 0x92, 0x1b, 0x15, 0xb2, 0x08, 0x13, 0xc6, 0x2d, 0x2a, 0x65, + 0xdd, 0x64, 0xdd, 0xad, 0xea, 0xd2, 0xcf, 0x13, 0xc6, 0x6d, 0x29, 0x25, 0x25, 0xeb, 0x0e, 0x55, + 0xae, 0x94, 0x8f, 0x60, 0x4c, 0xa8, 0xb4, 0xab, 0x36, 0xf2, 0xfd, 0x6d, 0x33, 0x5a, 0x44, 0x72, + 0xa7, 0xe9, 0x46, 0x0b, 0xbe, 0xf7, 0xc8, 0xdd, 0xeb, 0xa9, 0x98, 0x34, 0xcb, 0xce, 0x3c, 0xf9, + 0x0a, 0x9f, 0x3c, 0x97, 0x0f, 0xd1, 0xd3, 0xe8, 0xa9, 0x1f, 0x3c, 0x76, 0xbd, 0xbd, 0x1e, 0x22, + 0x2f, 0x9b, 0x22, 0x93, 0x7c, 0x32, 0x76, 0xe4, 0x2b, 0x98, 0xab, 0xe5, 0x0b, 0xef, 0x29, 0xa4, + 0xfb, 0xf2, 0x52, 0x83, 0x0b, 0x18, 0x3d, 0x73, 0xd2, 0xba, 0x77, 0x15, 0xfa, 0x05, 0x4f, 0xd8, + 0x28, 0x7d, 0xf5, 0x0d, 0x3f, 0x68, 0xf6, 0x96, 0x58, 0x36, 0x03, 0x69, 0x13, 0x6c, 0x52, 0x19, + 0x5f, 0xc0, 0xb9, 0x5a, 0xae, 0xe8, 0x5e, 0x22, 0x7a, 0xed, 0x24, 0xcf, 0xa3, 0x2a, 0x4e, 0x58, + 0xef, 0xae, 0x32, 0x57, 0x70, 0x4e, 0x63, 0xeb, 0xd0, 0x66, 0x40, 0x1f, 0xd1, 0x00, 0xc3, 0xb5, + 0x7b, 0x05, 0x2a, 0x9b, 0xe4, 0xb2, 0xe5, 0x2b, 0x70, 0xa6, 0x96, 0x12, 0x95, 0xc7, 0xd2, 0xeb, + 0xfc, 0x67, 0x0a, 0x5b, 0x7a, 0xcc, 0x7a, 0xf5, 0x88, 0x12, 0x1a, 0xbb, 0x47, 0xa3, 0xed, 0x95, + 0x1e, 0x5a, 0x92, 0xf7, 0x09, 0x24, 0xe1, 0xce, 0x1d, 0xc6, 0x59, 0xd3, 0x38, 0xd3, 0x14, 0xb9, + 0x1f, 0xef, 0xa7, 0xf2, 0x2c, 0xa4, 0x67, 0xb1, 0x79, 0x12, 0xde, 0xc4, 0xb9, 0x50, 0x84, 0x2c, + 0xcf, 0xc6, 0x5b, 0x00, 0x0e, 0x89, 0x5d, 0x75, 0x5a, 0xf4, 0x72, 0x48, 0x2a, 0xdc, 0xfc, 0xe3, + 0xc3, 0x43, 0xc0, 0x2e, 0xa5, 0x42, 0xd9, 0xbb, 0x8a, 0xe0, 0x5e, 0xd0, 0x55, 0xbf, 0xf1, 0x58, + 0xf7, 0x82, 0xb2, 0xdf, 0x49, 0xf7, 0x20, 0x83, 0xed, 0xcc, 0x8b, 0x19, 0x9f, 0xfd, 0x30, 0x02, + 0xbf, 0x10, 0x10, 0xcf, 0xf8, 0x49, 0xb8, 0xf0, 0x20, 0xbd, 0x29, 0x7d, 0x8b, 0x58, 0xa0, 0x29, + 0x39, 0x57, 0x35, 0xca, 0xad, 0x88, 0x4c, 0xa6, 0x5b, 0x51, 0xaf, 0x68, 0xbe, 0x2f, 0x9f, 0xd8, + 0xb4, 0xdd, 0xc2, 0x28, 0xe8, 0x03, 0x9f, 0xf3, 0xc4, 0x81, 0xb1, 0x69, 0x54, 0xef, 0xf8, 0xad, + 0x29, 0x11, 0xf5, 0x63, 0x28, 0x5e, 0x25, 0x54, 0x4e, 0xe3, 0x62, 0x55, 0xea, 0xc1, 0x48, 0xb7, + 0x0b, 0x64, 0x1d, 0xce, 0xde, 0xa3, 0x91, 0x98, 0xe3, 0x6c, 0x1a, 0x46, 0x81, 0xdb, 0x88, 0xba, + 0x1e, 0x0c, 0x4a, 0xdb, 0x24, 0x83, 0x67, 0xe7, 0x2d, 0x26, 0xaf, 0x96, 0x2d, 0xaf, 0x2b, 0x5f, + 0x97, 0x10, 0x59, 0x71, 0xda, 0x70, 0x92, 0x2a, 0xe6, 0x0f, 0xf1, 0x61, 0x1e, 0x81, 0x93, 0xcf, + 0x5a, 0x8c, 0xb3, 0x9f, 0x08, 0x6b, 0xeb, 0x26, 0x0c, 0x71, 0xa6, 0xdc, 0x05, 0x75, 0x5c, 0xe7, + 0x21, 0x77, 0x60, 0x54, 0x85, 0xd0, 0x10, 0x03, 0x95, 0x5b, 0xaf, 0x3b, 0x30, 0xca, 0x4d, 0xab, + 0xe3, 0xb3, 0x7c, 0x00, 0xa3, 0x2a, 0xe6, 0xe6, 0xc4, 0x2b, 0xfd, 0x27, 0x30, 0xa1, 0x47, 0xdf, + 0x9c, 0x5c, 0x91, 0x1f, 0xe1, 0xf1, 0xad, 0x3c, 0x25, 0xc9, 0xe7, 0x9f, 0x49, 0x24, 0x85, 0x11, + 0x2a, 0xe5, 0x13, 0xa4, 0x04, 0xe6, 0x56, 0xff, 0x4c, 0x8a, 0x9b, 0x7c, 0x20, 0x6f, 0x32, 0x29, + 0xe6, 0x34, 0x51, 0x17, 0x9d, 0x4d, 0x72, 0x35, 0x3f, 0x0f, 0xb3, 0x9a, 0x60, 0x7b, 0x56, 0xfb, + 0x38, 0xc7, 0xcc, 0xbd, 0x55, 0x97, 0x27, 0x65, 0x03, 0x77, 0x69, 0xa9, 0x47, 0x02, 0xf3, 0x05, + 0x5d, 0xca, 0x7f, 0x57, 0x10, 0x3b, 0xe3, 0x3e, 0x5a, 0x81, 0x29, 0x6c, 0x6e, 0xf3, 0xba, 0xbc, + 0x53, 0x18, 0x9b, 0xbd, 0x69, 0x71, 0x5d, 0xd8, 0xba, 0x59, 0xd1, 0xe2, 0x7e, 0xe6, 0x4b, 0x11, + 0xb7, 0x22, 0x83, 0x18, 0x8f, 0xdf, 0xd8, 0xfc, 0x9a, 0x9d, 0xcf, 0x38, 0xd8, 0xee, 0xd9, 0x17, + 0x79, 0xe2, 0x7e, 0x01, 0x77, 0x87, 0x99, 0x59, 0xc1, 0xf2, 0x85, 0x5d, 0xd7, 0x62, 0x23, 0x32, + 0x39, 0xd5, 0xa2, 0xf7, 0x18, 0xaf, 0x88, 0x65, 0x3f, 0xa3, 0xf8, 0x6a, 0x0f, 0x29, 0x52, 0x13, + 0xaf, 0xf5, 0xa4, 0x53, 0xc7, 0xa4, 0xe7, 0xf9, 0x0a, 0x9b, 0x5d, 0x5e, 0x8f, 0x67, 0x21, 0x33, + 0x4e, 0xae, 0x55, 0x84, 0x68, 0xb6, 0x40, 0x33, 0x42, 0xb4, 0x6b, 0x1b, 0xf2, 0xd4, 0xff, 0x19, + 0x94, 0xe3, 0x00, 0x90, 0x93, 0x75, 0x42, 0x7e, 0x60, 0x22, 0x49, 0x69, 0x2a, 0x24, 0xdd, 0x9e, + 0x13, 0x9a, 0xbb, 0x92, 0xa7, 0x61, 0xfd, 0x1a, 0x8c, 0x08, 0x6c, 0x4b, 0x3c, 0x28, 0x9a, 0xf7, + 0x34, 0x69, 0x17, 0x3f, 0xac, 0xb8, 0x33, 0xf7, 0x52, 0x04, 0xa5, 0x7b, 0xfb, 0xe4, 0x82, 0x54, + 0x7c, 0x46, 0x42, 0x90, 0xd5, 0xa5, 0x7b, 0x7b, 0x1f, 0x3d, 0x96, 0x72, 0xfa, 0xf5, 0xe4, 0x1d, + 0xea, 0xc4, 0xf7, 0xc4, 0x12, 0x49, 0x04, 0xf5, 0xbb, 0xb9, 0x69, 0x54, 0xf2, 0x92, 0x53, 0x16, + 0x85, 0x0a, 0x8a, 0x2a, 0xc9, 0x22, 0x18, 0x9c, 0x99, 0x22, 0x7e, 0xe0, 0x46, 0xcf, 0x16, 0xec, + 0xd5, 0xd8, 0xad, 0xa0, 0x23, 0xa4, 0x6c, 0x90, 0x48, 0x7b, 0x95, 0x7c, 0x89, 0x53, 0x89, 0x10, + 0x5f, 0xf5, 0xfd, 0x28, 0x8c, 0x02, 0xa7, 0x5d, 0xc3, 0x87, 0x96, 0x73, 0x1b, 0x1d, 0xc7, 0x70, + 0x67, 0xb1, 0x69, 0x21, 0xa5, 0x22, 0x8f, 0x7d, 0x56, 0xe6, 0x1b, 0x75, 0xad, 0x26, 0x0b, 0xd9, + 0xc5, 0x72, 0xa9, 0xc9, 0xcc, 0xf5, 0x2f, 0x53, 0x68, 0x1d, 0x66, 0x73, 0xf2, 0x05, 0xa9, 0xd3, + 0xdb, 0xee, 0xf9, 0x84, 0xe6, 0xba, 0x17, 0x4c, 0xbe, 0x82, 0x99, 0xcc, 0x84, 0x42, 0xca, 0x03, + 0xdd, 0x2d, 0xdd, 0x50, 0x2f, 0xe1, 0x8f, 0xa1, 0xc4, 0x2f, 0x74, 0x60, 0xdc, 0xb2, 0x91, 0x5b, + 0x26, 0xbe, 0xe6, 0x93, 0x43, 0x90, 0x9c, 0xaf, 0xf3, 0xe9, 0xd4, 0x65, 0xf3, 0x69, 0x4c, 0x2a, + 0x22, 0x5f, 0x86, 0x16, 0xcf, 0xfb, 0xab, 0x0f, 0x2f, 0x0b, 0xd9, 0xed, 0x2e, 0xd1, 0x26, 0xcc, + 0xec, 0xd0, 0xc0, 0x7d, 0xf4, 0x2c, 0x29, 0x50, 0x6a, 0x26, 0x13, 0xdb, 0x4d, 0xe2, 0xe7, 0x30, + 0xbb, 0xe0, 0x1f, 0xb4, 0xc5, 0xad, 0x3d, 0x43, 0xa6, 0x3a, 0x8a, 0xcf, 0xc6, 0xf7, 0x8e, 0x65, + 0x9a, 0x53, 0xd7, 0x0a, 0x75, 0xbe, 0x05, 0xbc, 0xce, 0x7a, 0xdd, 0x0c, 0x27, 0xc8, 0x20, 0x89, + 0x2f, 0x63, 0x48, 0x53, 0x4e, 0xe7, 0xdf, 0xc2, 0x41, 0x98, 0xe0, 0xe3, 0xbe, 0x39, 0x6d, 0x10, + 0x66, 0xe1, 0xbb, 0xdf, 0x01, 0xcb, 0x90, 0xca, 0x0b, 0xcc, 0x97, 0x7a, 0x8c, 0xda, 0xae, 0xcb, + 0xb5, 0xc5, 0x7c, 0xc9, 0x3f, 0x11, 0x34, 0x9d, 0xf9, 0xcc, 0x7f, 0x66, 0x3d, 0xb5, 0xac, 0x0a, + 0xad, 0x56, 0x97, 0x2d, 0x16, 0xd1, 0xd3, 0x2a, 0x30, 0x4a, 0x74, 0xe2, 0x4f, 0xe8, 0xbc, 0xdd, + 0x66, 0xeb, 0x14, 0x33, 0x6e, 0x6a, 0xdf, 0x87, 0xf1, 0x9a, 0x5e, 0x78, 0x46, 0x21, 0xb9, 0x83, + 0x42, 0xdd, 0x02, 0xea, 0x5d, 0xf7, 0x2e, 0xb1, 0xa0, 0x6a, 0xe1, 0x39, 0x56, 0x2b, 0x72, 0x43, + 0x67, 0x8c, 0xb7, 0xe7, 0xd4, 0x2a, 0x90, 0xf5, 0x34, 0xa4, 0x0a, 0x9d, 0xc9, 0x7e, 0xae, 0xae, + 0xce, 0x5f, 0xb4, 0x49, 0xbe, 0xfc, 0x49, 0xac, 0xde, 0x4f, 0xec, 0xaa, 0x98, 0xf8, 0xae, 0x4f, + 0x87, 0xf2, 0x38, 0x9f, 0xf8, 0xb5, 0x3d, 0x3d, 0xce, 0x27, 0xf5, 0x86, 0x9f, 0x1e, 0xe7, 0x93, + 0xf1, 0x40, 0xdf, 0x12, 0xca, 0x8a, 0x9f, 0x02, 0xea, 0xe2, 0x8c, 0x50, 0x62, 0x32, 0x5e, 0x1c, + 0x7a, 0xa0, 0x27, 0xe7, 0xe0, 0x0f, 0x08, 0x75, 0xf1, 0xb5, 0x26, 0x93, 0x72, 0x24, 0x5e, 0x1c, + 0xba, 0x0b, 0x45, 0xfe, 0x96, 0x42, 0x9c, 0xd3, 0x30, 0x0e, 0xfd, 0x4b, 0x3f, 0xf1, 0xd0, 0xa5, + 0x53, 0x8b, 0xc9, 0x4c, 0x70, 0xca, 0x65, 0x96, 0x93, 0x22, 0xae, 0xcb, 0x50, 0x85, 0x38, 0xdf, + 0x9b, 0x72, 0x4c, 0xa5, 0x52, 0xc0, 0xcd, 0x9d, 0xcb, 0xc0, 0xa8, 0x2d, 0xe5, 0xb8, 0x9e, 0x1d, + 0x4e, 0x35, 0x29, 0x23, 0x65, 0xdc, 0xdc, 0xf9, 0x4c, 0x9c, 0x10, 0x14, 0xf1, 0x57, 0xa6, 0xb3, + 0x1f, 0xfd, 0x8e, 0x2f, 0x72, 0x75, 0xa1, 0x91, 0xc5, 0xdc, 0x38, 0x0e, 0xa9, 0x28, 0x95, 0xaa, + 0x87, 0x90, 0x32, 0x5e, 0x1a, 0x7f, 0x2d, 0xe3, 0xae, 0x85, 0x41, 0x11, 0x47, 0x83, 0x75, 0x7f, + 0xf6, 0x9c, 0x3c, 0x94, 0x0f, 0xd3, 0xe4, 0x94, 0xd4, 0x4b, 0x40, 0x6e, 0x0f, 0x3e, 0x94, 0x4f, + 0xd1, 0xbc, 0x6c, 0xc1, 0xbb, 0x70, 0x21, 0x71, 0x81, 0xc3, 0x14, 0x7c, 0x23, 0xfb, 0x96, 0x47, + 0xa6, 0x7a, 0xf2, 0xf7, 0xec, 0x97, 0xd3, 0x17, 0x3d, 0x12, 0xfd, 0x7e, 0xd2, 0x39, 0x6f, 0x0d, + 0x26, 0x71, 0x9a, 0x91, 0x6f, 0xe6, 0xc7, 0xb9, 0x61, 0x4c, 0x70, 0x32, 0x49, 0x51, 0x12, 0xab, + 0xee, 0x8f, 0x8f, 0x8b, 0x4b, 0xc1, 0xfc, 0x05, 0xfe, 0x39, 0xf3, 0xa6, 0x30, 0x02, 0xb3, 0x56, + 0x31, 0xf1, 0xb0, 0x3f, 0xf9, 0x08, 0x4e, 0xc7, 0x77, 0x85, 0xb9, 0x88, 0x0c, 0xb2, 0x2e, 0x8e, + 0xb2, 0xd3, 0xf1, 0x85, 0xe1, 0x93, 0xb3, 0x2f, 0xcb, 0xa5, 0x28, 0x66, 0xbf, 0x98, 0xba, 0xee, + 0x62, 0xb4, 0xe1, 0x38, 0x2b, 0x92, 0xa6, 0xdb, 0x93, 0xf6, 0x4e, 0x03, 0x3f, 0xb7, 0xec, 0xb4, + 0x87, 0xfa, 0xe7, 0xd6, 0x35, 0x35, 0xa3, 0xda, 0xfe, 0xe6, 0xc8, 0x59, 0x83, 0xab, 0x98, 0x2a, + 0x65, 0x93, 0x27, 0xc7, 0xcb, 0xa6, 0xca, 0xaf, 0x7b, 0x32, 0xc1, 0x4a, 0x0b, 0xae, 0xf4, 0xcc, + 0xfb, 0x48, 0x6e, 0x19, 0x21, 0x2e, 0xbd, 0x33, 0x44, 0x76, 0xb1, 0x3c, 0xa6, 0xb3, 0xd2, 0x27, + 0xaa, 0x75, 0xb6, 0x4b, 0x26, 0x47, 0xb5, 0xce, 0x76, 0xcd, 0xbf, 0xf8, 0x39, 0xbe, 0xf6, 0x24, + 0xd6, 0x28, 0x4c, 0x7f, 0x44, 0x3d, 0x9e, 0x14, 0xba, 0xeb, 0xb1, 0xcf, 0x15, 0xf3, 0x50, 0x34, + 0xc5, 0x88, 0x36, 0xcd, 0x25, 0x61, 0x89, 0xe5, 0x09, 0xef, 0x2d, 0xa4, 0x4b, 0x68, 0xf5, 0x25, + 0x3e, 0x00, 0x4f, 0x5c, 0xf3, 0x1c, 0x78, 0x75, 0xf1, 0x27, 0xff, 0xf5, 0x52, 0xe1, 0x27, 0x3f, + 0xbd, 0x54, 0xf8, 0x8f, 0x3f, 0xbd, 0x54, 0xf8, 0x2f, 0x3f, 0xbd, 0x54, 0xf8, 0x72, 0xfe, 0x78, + 0xa9, 0x89, 0xf9, 0xfb, 0x8c, 0xb7, 0xb8, 0xb8, 0x21, 0xfc, 0xef, 0xcd, 0xff, 0x1b, 0x00, 0x00, + 0xff, 0xff, 0x6f, 0x43, 0x95, 0x44, 0x34, 0xef, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -35158,6 +35446,191 @@ func (m *CreateRegisterChallengeRequest) MarshalToSizedBuffer(dAtA []byte) (int, return len(dAtA) - i, nil } +func (m *IdentityCenterAccount) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *IdentityCenterAccount) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *IdentityCenterAccount) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.XXX_unrecognized != nil { + i -= len(m.XXX_unrecognized) + copy(dAtA[i:], m.XXX_unrecognized) + } + if len(m.Description) > 0 { + i -= len(m.Description) + copy(dAtA[i:], m.Description) + i = encodeVarintAuthservice(dAtA, i, uint64(len(m.Description))) + i-- + dAtA[i] = 0x22 + } + if len(m.AccountName) > 0 { + i -= len(m.AccountName) + copy(dAtA[i:], m.AccountName) + i = encodeVarintAuthservice(dAtA, i, uint64(len(m.AccountName))) + i-- + dAtA[i] = 0x1a + } + if len(m.ARN) > 0 { + i -= len(m.ARN) + copy(dAtA[i:], m.ARN) + i = encodeVarintAuthservice(dAtA, i, uint64(len(m.ARN))) + i-- + dAtA[i] = 0x12 + } + if len(m.ID) > 0 { + i -= len(m.ID) + copy(dAtA[i:], m.ID) + i = encodeVarintAuthservice(dAtA, i, uint64(len(m.ID))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *IdentityCenterPermissionSet) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *IdentityCenterPermissionSet) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *IdentityCenterPermissionSet) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.XXX_unrecognized != nil { + i -= len(m.XXX_unrecognized) + copy(dAtA[i:], m.XXX_unrecognized) + } + if len(m.Name) > 0 { + i -= len(m.Name) + copy(dAtA[i:], m.Name) + i = encodeVarintAuthservice(dAtA, i, uint64(len(m.Name))) + i-- + dAtA[i] = 0x12 + } + if len(m.ARN) > 0 { + i -= len(m.ARN) + copy(dAtA[i:], m.ARN) + i = encodeVarintAuthservice(dAtA, i, uint64(len(m.ARN))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *IdentityCenterAccountAssignment) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *IdentityCenterAccountAssignment) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *IdentityCenterAccountAssignment) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.XXX_unrecognized != nil { + i -= len(m.XXX_unrecognized) + copy(dAtA[i:], m.XXX_unrecognized) + } + if m.PermissionSet != nil { + { + size, err := m.PermissionSet.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintAuthservice(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x3a + } + if m.Account != nil { + { + size, err := m.Account.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintAuthservice(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x32 + } + if len(m.DisplayName) > 0 { + i -= len(m.DisplayName) + copy(dAtA[i:], m.DisplayName) + i = encodeVarintAuthservice(dAtA, i, uint64(len(m.DisplayName))) + i-- + dAtA[i] = 0x2a + } + { + size, err := m.Metadata.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintAuthservice(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x22 + if len(m.Version) > 0 { + i -= len(m.Version) + copy(dAtA[i:], m.Version) + i = encodeVarintAuthservice(dAtA, i, uint64(len(m.Version))) + i-- + dAtA[i] = 0x1a + } + if len(m.SubKind) > 0 { + i -= len(m.SubKind) + copy(dAtA[i:], m.SubKind) + i = encodeVarintAuthservice(dAtA, i, uint64(len(m.SubKind))) + i-- + dAtA[i] = 0x12 + } + if len(m.Kind) > 0 { + i -= len(m.Kind) + copy(dAtA[i:], m.Kind) + i = encodeVarintAuthservice(dAtA, i, uint64(len(m.Kind))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + func (m *PaginatedResource) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -35182,6 +35655,15 @@ func (m *PaginatedResource) MarshalToSizedBuffer(dAtA []byte) (int, error) { i -= len(m.XXX_unrecognized) copy(dAtA[i:], m.XXX_unrecognized) } + if m.Resource != nil { + { + size := m.Resource.Size() + i -= size + if _, err := m.Resource.MarshalTo(dAtA[i:]); err != nil { + return 0, err + } + } + } if m.RequiresRequest { i-- if m.RequiresRequest { @@ -35201,15 +35683,6 @@ func (m *PaginatedResource) MarshalToSizedBuffer(dAtA []byte) (int, error) { dAtA[i] = 0x6a } } - if m.Resource != nil { - { - size := m.Resource.Size() - i -= size - if _, err := m.Resource.MarshalTo(dAtA[i:]); err != nil { - return 0, err - } - } - } return len(dAtA) - i, nil } @@ -35444,6 +35917,50 @@ func (m *PaginatedResource_SAMLIdPServiceProvider) MarshalToSizedBuffer(dAtA []b } return len(dAtA) - i, nil } +func (m *PaginatedResource_GitServer) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *PaginatedResource_GitServer) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + if m.GitServer != nil { + { + size, err := m.GitServer.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintAuthservice(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x7a + } + return len(dAtA) - i, nil +} +func (m *PaginatedResource_IdentityCenterAccountAssignment) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *PaginatedResource_IdentityCenterAccountAssignment) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + if m.IdentityCenterAccountAssignment != nil { + { + size, err := m.IdentityCenterAccountAssignment.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintAuthservice(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x1 + i-- + dAtA[i] = 0x82 + } + return len(dAtA) - i, nil +} func (m *ListUnifiedResourcesRequest) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -36165,12 +36682,12 @@ func (m *SessionTrackerUpdateExpiry) MarshalToSizedBuffer(dAtA []byte) (int, err copy(dAtA[i:], m.XXX_unrecognized) } if m.Expires != nil { - n102, err102 := github_com_gogo_protobuf_types.StdTimeMarshalTo(*m.Expires, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(*m.Expires):]) - if err102 != nil { - return 0, err102 + n107, err107 := github_com_gogo_protobuf_types.StdTimeMarshalTo(*m.Expires, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(*m.Expires):]) + if err107 != nil { + return 0, err107 } - i -= n102 - i = encodeVarintAuthservice(dAtA, i, uint64(n102)) + i -= n107 + i = encodeVarintAuthservice(dAtA, i, uint64(n107)) i-- dAtA[i] = 0xa } @@ -37454,12 +37971,12 @@ func (m *UpstreamInventoryPong) MarshalToSizedBuffer(dAtA []byte) (int, error) { i -= len(m.XXX_unrecognized) copy(dAtA[i:], m.XXX_unrecognized) } - n126, err126 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.SystemClock, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.SystemClock):]) - if err126 != nil { - return 0, err126 + n131, err131 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.SystemClock, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.SystemClock):]) + if err131 != nil { + return 0, err131 } - i -= n126 - i = encodeVarintAuthservice(dAtA, i, uint64(n126)) + i -= n131 + i = encodeVarintAuthservice(dAtA, i, uint64(n131)) i-- dAtA[i] = 0x12 if m.ID != 0 { @@ -42826,6 +43343,92 @@ func (m *CreateRegisterChallengeRequest) Size() (n int) { return n } +func (m *IdentityCenterAccount) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.ID) + if l > 0 { + n += 1 + l + sovAuthservice(uint64(l)) + } + l = len(m.ARN) + if l > 0 { + n += 1 + l + sovAuthservice(uint64(l)) + } + l = len(m.AccountName) + if l > 0 { + n += 1 + l + sovAuthservice(uint64(l)) + } + l = len(m.Description) + if l > 0 { + n += 1 + l + sovAuthservice(uint64(l)) + } + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} + +func (m *IdentityCenterPermissionSet) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.ARN) + if l > 0 { + n += 1 + l + sovAuthservice(uint64(l)) + } + l = len(m.Name) + if l > 0 { + n += 1 + l + sovAuthservice(uint64(l)) + } + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} + +func (m *IdentityCenterAccountAssignment) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Kind) + if l > 0 { + n += 1 + l + sovAuthservice(uint64(l)) + } + l = len(m.SubKind) + if l > 0 { + n += 1 + l + sovAuthservice(uint64(l)) + } + l = len(m.Version) + if l > 0 { + n += 1 + l + sovAuthservice(uint64(l)) + } + l = m.Metadata.Size() + n += 1 + l + sovAuthservice(uint64(l)) + l = len(m.DisplayName) + if l > 0 { + n += 1 + l + sovAuthservice(uint64(l)) + } + if m.Account != nil { + l = m.Account.Size() + n += 1 + l + sovAuthservice(uint64(l)) + } + if m.PermissionSet != nil { + l = m.PermissionSet.Size() + n += 1 + l + sovAuthservice(uint64(l)) + } + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} + func (m *PaginatedResource) Size() (n int) { if m == nil { return 0 @@ -42982,6 +43585,30 @@ func (m *PaginatedResource_SAMLIdPServiceProvider) Size() (n int) { } return n } +func (m *PaginatedResource_GitServer) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.GitServer != nil { + l = m.GitServer.Size() + n += 1 + l + sovAuthservice(uint64(l)) + } + return n +} +func (m *PaginatedResource_IdentityCenterAccountAssignment) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.IdentityCenterAccountAssignment != nil { + l = m.IdentityCenterAccountAssignment.Size() + n += 2 + l + sovAuthservice(uint64(l)) + } + return n +} func (m *ListUnifiedResourcesRequest) Size() (n int) { if m == nil { return 0 @@ -63953,7 +64580,430 @@ func (m *CreateAuthenticateChallengeRequest) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.SSOClientRedirectURL = string(dAtA[iNdEx:postIndex]) + m.SSOClientRedirectURL = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipAuthservice(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthAuthservice + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *CreatePrivilegeTokenRequest) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAuthservice + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: CreatePrivilegeTokenRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: CreatePrivilegeTokenRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ExistingMFAResponse", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAuthservice + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthAuthservice + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthAuthservice + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.ExistingMFAResponse == nil { + m.ExistingMFAResponse = &MFAAuthenticateResponse{} + } + if err := m.ExistingMFAResponse.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipAuthservice(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthAuthservice + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *CreateRegisterChallengeRequest) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAuthservice + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: CreateRegisterChallengeRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: CreateRegisterChallengeRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field TokenID", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAuthservice + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthAuthservice + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthAuthservice + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.TokenID = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field DeviceType", wireType) + } + m.DeviceType = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAuthservice + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.DeviceType |= DeviceType(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field DeviceUsage", wireType) + } + m.DeviceUsage = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAuthservice + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.DeviceUsage |= DeviceUsage(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ExistingMFAResponse", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAuthservice + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthAuthservice + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthAuthservice + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.ExistingMFAResponse == nil { + m.ExistingMFAResponse = &MFAAuthenticateResponse{} + } + if err := m.ExistingMFAResponse.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipAuthservice(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthAuthservice + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *IdentityCenterAccount) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAuthservice + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: IdentityCenterAccount: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: IdentityCenterAccount: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ID", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAuthservice + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthAuthservice + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthAuthservice + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ID = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ARN", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAuthservice + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthAuthservice + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthAuthservice + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ARN = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field AccountName", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAuthservice + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthAuthservice + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthAuthservice + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.AccountName = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Description", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAuthservice + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthAuthservice + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthAuthservice + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Description = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex default: iNdEx = preIndex @@ -63977,7 +65027,7 @@ func (m *CreateAuthenticateChallengeRequest) Unmarshal(dAtA []byte) error { } return nil } -func (m *CreatePrivilegeTokenRequest) Unmarshal(dAtA []byte) error { +func (m *IdentityCenterPermissionSet) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -64000,17 +65050,17 @@ func (m *CreatePrivilegeTokenRequest) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: CreatePrivilegeTokenRequest: wiretype end group for non-group") + return fmt.Errorf("proto: IdentityCenterPermissionSet: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: CreatePrivilegeTokenRequest: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: IdentityCenterPermissionSet: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ExistingMFAResponse", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field ARN", wireType) } - var msglen int + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowAuthservice @@ -64020,27 +65070,55 @@ func (m *CreatePrivilegeTokenRequest) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - msglen |= int(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } - if msglen < 0 { + intStringLen := int(stringLen) + if intStringLen < 0 { return ErrInvalidLengthAuthservice } - postIndex := iNdEx + msglen + postIndex := iNdEx + intStringLen if postIndex < 0 { return ErrInvalidLengthAuthservice } if postIndex > l { return io.ErrUnexpectedEOF } - if m.ExistingMFAResponse == nil { - m.ExistingMFAResponse = &MFAAuthenticateResponse{} + m.ARN = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) } - if err := m.ExistingMFAResponse.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAuthservice + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthAuthservice + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthAuthservice + } + if postIndex > l { + return io.ErrUnexpectedEOF } + m.Name = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex default: iNdEx = preIndex @@ -64064,7 +65142,7 @@ func (m *CreatePrivilegeTokenRequest) Unmarshal(dAtA []byte) error { } return nil } -func (m *CreateRegisterChallengeRequest) Unmarshal(dAtA []byte) error { +func (m *IdentityCenterAccountAssignment) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -64087,15 +65165,15 @@ func (m *CreateRegisterChallengeRequest) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: CreateRegisterChallengeRequest: wiretype end group for non-group") + return fmt.Errorf("proto: IdentityCenterAccountAssignment: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: CreateRegisterChallengeRequest: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: IdentityCenterAccountAssignment: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field TokenID", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Kind", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -64123,13 +65201,13 @@ func (m *CreateRegisterChallengeRequest) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.TokenID = string(dAtA[iNdEx:postIndex]) + m.Kind = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 2: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field DeviceType", wireType) + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field SubKind", wireType) } - m.DeviceType = 0 + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowAuthservice @@ -64139,16 +65217,29 @@ func (m *CreateRegisterChallengeRequest) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - m.DeviceType |= DeviceType(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthAuthservice + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthAuthservice + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.SubKind = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex case 3: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field DeviceUsage", wireType) + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Version", wireType) } - m.DeviceUsage = 0 + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowAuthservice @@ -64158,14 +65249,27 @@ func (m *CreateRegisterChallengeRequest) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - m.DeviceUsage |= DeviceUsage(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthAuthservice + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthAuthservice + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Version = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex case 4: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ExistingMFAResponse", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Metadata", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -64192,10 +65296,111 @@ func (m *CreateRegisterChallengeRequest) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if m.ExistingMFAResponse == nil { - m.ExistingMFAResponse = &MFAAuthenticateResponse{} + if err := m.Metadata.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err } - if err := m.ExistingMFAResponse.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + iNdEx = postIndex + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field DisplayName", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAuthservice + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthAuthservice + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthAuthservice + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.DisplayName = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 6: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Account", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAuthservice + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthAuthservice + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthAuthservice + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Account == nil { + m.Account = &IdentityCenterAccount{} + } + if err := m.Account.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 7: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field PermissionSet", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAuthservice + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthAuthservice + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthAuthservice + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.PermissionSet == nil { + m.PermissionSet = &IdentityCenterPermissionSet{} + } + if err := m.PermissionSet.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex @@ -64687,6 +65892,76 @@ func (m *PaginatedResource) Unmarshal(dAtA []byte) error { } } m.RequiresRequest = bool(v != 0) + case 15: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field GitServer", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAuthservice + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthAuthservice + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthAuthservice + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + v := &types.ServerV2{} + if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + m.Resource = &PaginatedResource_GitServer{v} + iNdEx = postIndex + case 16: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field IdentityCenterAccountAssignment", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAuthservice + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthAuthservice + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthAuthservice + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + v := &IdentityCenterAccountAssignment{} + if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + m.Resource = &PaginatedResource_IdentityCenterAccountAssignment{v} + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipAuthservice(dAtA[iNdEx:]) diff --git a/api/client/proto/event.pb.go b/api/client/proto/event.pb.go index ac3157f00894e..8ae0a290064fe 100644 --- a/api/client/proto/event.pb.go +++ b/api/client/proto/event.pb.go @@ -37,6 +37,7 @@ import ( v11 "github.com/gravitational/teleport/api/gen/proto/go/teleport/userloginstate/v1" v2 "github.com/gravitational/teleport/api/gen/proto/go/teleport/userprovisioning/v2" v112 "github.com/gravitational/teleport/api/gen/proto/go/teleport/usertasks/v1" + v115 "github.com/gravitational/teleport/api/gen/proto/go/teleport/workloadidentity/v1" types "github.com/gravitational/teleport/api/types" protoreflect "google.golang.org/protobuf/reflect/protoreflect" protoimpl "google.golang.org/protobuf/runtime/protoimpl" @@ -187,6 +188,7 @@ type Event struct { // *Event_IdentityCenterPrincipalAssignment // *Event_IdentityCenterAccountAssignment // *Event_PluginStaticCredentials + // *Event_WorkloadIdentity Resource isEvent_Resource `protobuf_oneof:"Resource"` } @@ -724,6 +726,13 @@ func (x *Event) GetPluginStaticCredentials() *types.PluginStaticCredentialsV1 { return nil } +func (x *Event) GetWorkloadIdentity() *v115.WorkloadIdentity { + if x, ok := x.GetResource().(*Event_WorkloadIdentity); ok { + return x.WorkloadIdentity + } + return nil +} + type isEvent_Resource interface { isEvent_Resource() } @@ -1084,6 +1093,11 @@ type Event_PluginStaticCredentials struct { PluginStaticCredentials *types.PluginStaticCredentialsV1 `protobuf:"bytes,75,opt,name=PluginStaticCredentials,proto3,oneof"` } +type Event_WorkloadIdentity struct { + // WorkloadIdentity is a resource for workload identity. + WorkloadIdentity *v115.WorkloadIdentity `protobuf:"bytes,76,opt,name=WorkloadIdentity,proto3,oneof"` +} + func (*Event_ResourceHeader) isEvent_Resource() {} func (*Event_CertAuthority) isEvent_Resource() {} @@ -1224,6 +1238,8 @@ func (*Event_IdentityCenterAccountAssignment) isEvent_Resource() {} func (*Event_PluginStaticCredentials) isEvent_Resource() {} +func (*Event_WorkloadIdentity) isEvent_Resource() {} + var File_teleport_legacy_client_proto_event_proto protoreflect.FileDescriptor var file_teleport_legacy_client_proto_event_proto_rawDesc = []byte{ @@ -1282,344 +1298,353 @@ var file_teleport_legacy_client_proto_event_proto_rawDesc = []byte{ 0x65, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x26, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x75, 0x73, 0x65, 0x72, 0x74, 0x61, 0x73, 0x6b, 0x73, 0x2f, 0x76, 0x31, 0x2f, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x74, 0x61, 0x73, 0x6b, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x22, 0xad, 0x29, 0x0a, 0x05, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x24, 0x0a, 0x04, 0x54, 0x79, - 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x10, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x2e, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x04, 0x54, 0x79, 0x70, 0x65, - 0x12, 0x3f, 0x0a, 0x0e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x48, 0x65, 0x61, 0x64, - 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, - 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x48, - 0x00, 0x52, 0x0e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x48, 0x65, 0x61, 0x64, 0x65, - 0x72, 0x12, 0x3e, 0x0a, 0x0d, 0x43, 0x65, 0x72, 0x74, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, - 0x74, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, - 0x2e, 0x43, 0x65, 0x72, 0x74, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x56, 0x32, - 0x48, 0x00, 0x52, 0x0d, 0x43, 0x65, 0x72, 0x74, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, - 0x79, 0x12, 0x3b, 0x0a, 0x0c, 0x53, 0x74, 0x61, 0x74, 0x69, 0x63, 0x54, 0x6f, 0x6b, 0x65, 0x6e, - 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, - 0x53, 0x74, 0x61, 0x74, 0x69, 0x63, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x56, 0x32, 0x48, 0x00, - 0x52, 0x0c, 0x53, 0x74, 0x61, 0x74, 0x69, 0x63, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x12, 0x41, - 0x0a, 0x0e, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x54, 0x6f, 0x6b, 0x65, 0x6e, - 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x50, - 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x56, 0x32, 0x48, - 0x00, 0x52, 0x0e, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x54, 0x6f, 0x6b, 0x65, - 0x6e, 0x12, 0x38, 0x0a, 0x0b, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, - 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x43, - 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x56, 0x32, 0x48, 0x00, 0x52, 0x0b, - 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x23, 0x0a, 0x04, 0x55, - 0x73, 0x65, 0x72, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x74, 0x79, 0x70, 0x65, - 0x73, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x56, 0x32, 0x48, 0x00, 0x52, 0x04, 0x55, 0x73, 0x65, 0x72, - 0x12, 0x23, 0x0a, 0x04, 0x52, 0x6f, 0x6c, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, - 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x52, 0x6f, 0x6c, 0x65, 0x56, 0x36, 0x48, 0x00, 0x52, - 0x04, 0x52, 0x6f, 0x6c, 0x65, 0x12, 0x30, 0x0a, 0x09, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, - 0x63, 0x65, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, - 0x2e, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x48, 0x00, 0x52, 0x09, 0x4e, 0x61, - 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x29, 0x0a, 0x06, 0x53, 0x65, 0x72, 0x76, 0x65, - 0x72, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, - 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x56, 0x32, 0x48, 0x00, 0x52, 0x06, 0x53, 0x65, 0x72, 0x76, - 0x65, 0x72, 0x12, 0x3e, 0x0a, 0x0d, 0x52, 0x65, 0x76, 0x65, 0x72, 0x73, 0x65, 0x54, 0x75, 0x6e, - 0x6e, 0x65, 0x6c, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x74, 0x79, 0x70, 0x65, - 0x73, 0x2e, 0x52, 0x65, 0x76, 0x65, 0x72, 0x73, 0x65, 0x54, 0x75, 0x6e, 0x6e, 0x65, 0x6c, 0x56, - 0x32, 0x48, 0x00, 0x52, 0x0d, 0x52, 0x65, 0x76, 0x65, 0x72, 0x73, 0x65, 0x54, 0x75, 0x6e, 0x6e, - 0x65, 0x6c, 0x12, 0x47, 0x0a, 0x10, 0x54, 0x75, 0x6e, 0x6e, 0x65, 0x6c, 0x43, 0x6f, 0x6e, 0x6e, - 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x74, - 0x79, 0x70, 0x65, 0x73, 0x2e, 0x54, 0x75, 0x6e, 0x6e, 0x65, 0x6c, 0x43, 0x6f, 0x6e, 0x6e, 0x65, - 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x56, 0x32, 0x48, 0x00, 0x52, 0x10, 0x54, 0x75, 0x6e, 0x6e, 0x65, - 0x6c, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x3e, 0x0a, 0x0d, 0x41, - 0x63, 0x63, 0x65, 0x73, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x18, 0x0e, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x41, 0x63, 0x63, 0x65, 0x73, - 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x56, 0x33, 0x48, 0x00, 0x52, 0x0d, 0x41, 0x63, - 0x63, 0x65, 0x73, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x35, 0x0a, 0x0a, 0x41, - 0x70, 0x70, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x13, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x57, 0x65, 0x62, 0x53, 0x65, 0x73, 0x73, 0x69, - 0x6f, 0x6e, 0x56, 0x32, 0x48, 0x00, 0x52, 0x0a, 0x41, 0x70, 0x70, 0x53, 0x65, 0x73, 0x73, 0x69, - 0x6f, 0x6e, 0x12, 0x3e, 0x0a, 0x0d, 0x52, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x43, 0x6c, 0x75, 0x73, - 0x74, 0x65, 0x72, 0x18, 0x10, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x74, 0x79, 0x70, 0x65, - 0x73, 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x56, - 0x33, 0x48, 0x00, 0x52, 0x0d, 0x52, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x43, 0x6c, 0x75, 0x73, 0x74, - 0x65, 0x72, 0x12, 0x41, 0x0a, 0x0e, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x53, 0x65, - 0x72, 0x76, 0x65, 0x72, 0x18, 0x11, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x74, 0x79, 0x70, - 0x65, 0x73, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x53, 0x65, 0x72, 0x76, 0x65, - 0x72, 0x56, 0x33, 0x48, 0x00, 0x52, 0x0e, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x53, - 0x65, 0x72, 0x76, 0x65, 0x72, 0x12, 0x35, 0x0a, 0x0a, 0x57, 0x65, 0x62, 0x53, 0x65, 0x73, 0x73, - 0x69, 0x6f, 0x6e, 0x18, 0x12, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x74, 0x79, 0x70, 0x65, - 0x73, 0x2e, 0x57, 0x65, 0x62, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x56, 0x32, 0x48, 0x00, - 0x52, 0x0a, 0x57, 0x65, 0x62, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x2f, 0x0a, 0x08, - 0x57, 0x65, 0x62, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x13, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, - 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x57, 0x65, 0x62, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x56, - 0x33, 0x48, 0x00, 0x52, 0x08, 0x57, 0x65, 0x62, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x5c, 0x0a, + 0x1a, 0x2b, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x77, 0x6f, 0x72, 0x6b, 0x6c, + 0x6f, 0x61, 0x64, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x2f, 0x76, 0x31, 0x2f, 0x72, + 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x8b, 0x2a, + 0x0a, 0x05, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x24, 0x0a, 0x04, 0x54, 0x79, 0x70, 0x65, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x10, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x4f, 0x70, + 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x04, 0x54, 0x79, 0x70, 0x65, 0x12, 0x3f, 0x0a, + 0x0e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x52, 0x65, + 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x48, 0x00, 0x52, 0x0e, + 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x12, 0x3e, + 0x0a, 0x0d, 0x43, 0x65, 0x72, 0x74, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x43, 0x65, + 0x72, 0x74, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x56, 0x32, 0x48, 0x00, 0x52, + 0x0d, 0x43, 0x65, 0x72, 0x74, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x12, 0x3b, + 0x0a, 0x0c, 0x53, 0x74, 0x61, 0x74, 0x69, 0x63, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x18, 0x04, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x53, 0x74, 0x61, + 0x74, 0x69, 0x63, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x56, 0x32, 0x48, 0x00, 0x52, 0x0c, 0x53, + 0x74, 0x61, 0x74, 0x69, 0x63, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x12, 0x41, 0x0a, 0x0e, 0x50, + 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x05, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x50, 0x72, 0x6f, 0x76, + 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x56, 0x32, 0x48, 0x00, 0x52, 0x0e, + 0x50, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x38, + 0x0a, 0x0b, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x06, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x43, 0x6c, 0x75, 0x73, + 0x74, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x56, 0x32, 0x48, 0x00, 0x52, 0x0b, 0x43, 0x6c, 0x75, + 0x73, 0x74, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x23, 0x0a, 0x04, 0x55, 0x73, 0x65, 0x72, + 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x55, + 0x73, 0x65, 0x72, 0x56, 0x32, 0x48, 0x00, 0x52, 0x04, 0x55, 0x73, 0x65, 0x72, 0x12, 0x23, 0x0a, + 0x04, 0x52, 0x6f, 0x6c, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x74, 0x79, + 0x70, 0x65, 0x73, 0x2e, 0x52, 0x6f, 0x6c, 0x65, 0x56, 0x36, 0x48, 0x00, 0x52, 0x04, 0x52, 0x6f, + 0x6c, 0x65, 0x12, 0x30, 0x0a, 0x09, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, + 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x4e, 0x61, + 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x48, 0x00, 0x52, 0x09, 0x4e, 0x61, 0x6d, 0x65, 0x73, + 0x70, 0x61, 0x63, 0x65, 0x12, 0x29, 0x0a, 0x06, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x18, 0x0b, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x53, 0x65, 0x72, + 0x76, 0x65, 0x72, 0x56, 0x32, 0x48, 0x00, 0x52, 0x06, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x12, + 0x3e, 0x0a, 0x0d, 0x52, 0x65, 0x76, 0x65, 0x72, 0x73, 0x65, 0x54, 0x75, 0x6e, 0x6e, 0x65, 0x6c, + 0x18, 0x0c, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x52, + 0x65, 0x76, 0x65, 0x72, 0x73, 0x65, 0x54, 0x75, 0x6e, 0x6e, 0x65, 0x6c, 0x56, 0x32, 0x48, 0x00, + 0x52, 0x0d, 0x52, 0x65, 0x76, 0x65, 0x72, 0x73, 0x65, 0x54, 0x75, 0x6e, 0x6e, 0x65, 0x6c, 0x12, + 0x47, 0x0a, 0x10, 0x54, 0x75, 0x6e, 0x6e, 0x65, 0x6c, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x74, 0x79, 0x70, 0x65, + 0x73, 0x2e, 0x54, 0x75, 0x6e, 0x6e, 0x65, 0x6c, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x56, 0x32, 0x48, 0x00, 0x52, 0x10, 0x54, 0x75, 0x6e, 0x6e, 0x65, 0x6c, 0x43, 0x6f, + 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x3e, 0x0a, 0x0d, 0x41, 0x63, 0x63, 0x65, + 0x73, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x16, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x56, 0x33, 0x48, 0x00, 0x52, 0x0d, 0x41, 0x63, 0x63, 0x65, 0x73, + 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x35, 0x0a, 0x0a, 0x41, 0x70, 0x70, 0x53, + 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x74, + 0x79, 0x70, 0x65, 0x73, 0x2e, 0x57, 0x65, 0x62, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x56, + 0x32, 0x48, 0x00, 0x52, 0x0a, 0x41, 0x70, 0x70, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, + 0x3e, 0x0a, 0x0d, 0x52, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, + 0x18, 0x10, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x52, + 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x56, 0x33, 0x48, 0x00, + 0x52, 0x0d, 0x52, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x12, + 0x41, 0x0a, 0x0e, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x53, 0x65, 0x72, 0x76, 0x65, + 0x72, 0x18, 0x11, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, + 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x56, 0x33, + 0x48, 0x00, 0x52, 0x0e, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x53, 0x65, 0x72, 0x76, + 0x65, 0x72, 0x12, 0x35, 0x0a, 0x0a, 0x57, 0x65, 0x62, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, + 0x18, 0x12, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x57, + 0x65, 0x62, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x56, 0x32, 0x48, 0x00, 0x52, 0x0a, 0x57, + 0x65, 0x62, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x2f, 0x0a, 0x08, 0x57, 0x65, 0x62, + 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x13, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x74, 0x79, + 0x70, 0x65, 0x73, 0x2e, 0x57, 0x65, 0x62, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x56, 0x33, 0x48, 0x00, + 0x52, 0x08, 0x57, 0x65, 0x62, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x5c, 0x0a, 0x17, 0x43, 0x6c, + 0x75, 0x73, 0x74, 0x65, 0x72, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x69, 0x6e, 0x67, 0x43, + 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x14, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x74, 0x79, + 0x70, 0x65, 0x73, 0x2e, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x4e, 0x65, 0x74, 0x77, 0x6f, + 0x72, 0x6b, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x56, 0x32, 0x48, 0x00, 0x52, 0x17, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x69, - 0x6e, 0x67, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x14, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x20, - 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x4e, 0x65, - 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x56, 0x32, - 0x48, 0x00, 0x52, 0x17, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x4e, 0x65, 0x74, 0x77, 0x6f, - 0x72, 0x6b, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x59, 0x0a, 0x16, 0x53, - 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x67, 0x43, - 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x15, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x74, 0x79, - 0x70, 0x65, 0x73, 0x2e, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x63, 0x6f, 0x72, - 0x64, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x56, 0x32, 0x48, 0x00, 0x52, 0x16, - 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x67, - 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x41, 0x0a, 0x0e, 0x41, 0x75, 0x74, 0x68, 0x50, 0x72, - 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x18, 0x16, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, - 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x41, 0x75, 0x74, 0x68, 0x50, 0x72, 0x65, 0x66, 0x65, - 0x72, 0x65, 0x6e, 0x63, 0x65, 0x56, 0x32, 0x48, 0x00, 0x52, 0x0e, 0x41, 0x75, 0x74, 0x68, 0x50, - 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x12, 0x4d, 0x0a, 0x12, 0x43, 0x6c, 0x75, - 0x73, 0x74, 0x65, 0x72, 0x41, 0x75, 0x64, 0x69, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, - 0x17, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x43, 0x6c, - 0x75, 0x73, 0x74, 0x65, 0x72, 0x41, 0x75, 0x64, 0x69, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, - 0x56, 0x32, 0x48, 0x00, 0x52, 0x12, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x41, 0x75, 0x64, - 0x69, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x23, 0x0a, 0x04, 0x4c, 0x6f, 0x63, 0x6b, - 0x18, 0x18, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x4c, - 0x6f, 0x63, 0x6b, 0x56, 0x32, 0x48, 0x00, 0x52, 0x04, 0x4c, 0x6f, 0x63, 0x6b, 0x12, 0x50, 0x0a, - 0x13, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x52, 0x65, 0x73, 0x74, 0x72, 0x69, 0x63, 0x74, - 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x19, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x74, 0x79, 0x70, - 0x65, 0x73, 0x2e, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x52, 0x65, 0x73, 0x74, 0x72, 0x69, - 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x56, 0x34, 0x48, 0x00, 0x52, 0x13, 0x4e, 0x65, 0x74, 0x77, - 0x6f, 0x72, 0x6b, 0x52, 0x65, 0x73, 0x74, 0x72, 0x69, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, - 0x56, 0x0a, 0x15, 0x57, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x73, 0x44, 0x65, 0x73, 0x6b, 0x74, 0x6f, - 0x70, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x18, 0x1a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, - 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x57, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x73, 0x44, 0x65, - 0x73, 0x6b, 0x74, 0x6f, 0x70, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x56, 0x33, 0x48, 0x00, - 0x52, 0x15, 0x57, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x73, 0x44, 0x65, 0x73, 0x6b, 0x74, 0x6f, 0x70, - 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x41, 0x0a, 0x0e, 0x57, 0x69, 0x6e, 0x64, 0x6f, - 0x77, 0x73, 0x44, 0x65, 0x73, 0x6b, 0x74, 0x6f, 0x70, 0x18, 0x1b, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x17, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x57, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x73, 0x44, - 0x65, 0x73, 0x6b, 0x74, 0x6f, 0x70, 0x56, 0x33, 0x48, 0x00, 0x52, 0x0e, 0x57, 0x69, 0x6e, 0x64, - 0x6f, 0x77, 0x73, 0x44, 0x65, 0x73, 0x6b, 0x74, 0x6f, 0x70, 0x12, 0x2f, 0x0a, 0x08, 0x44, 0x61, - 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x18, 0x1c, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x74, - 0x79, 0x70, 0x65, 0x73, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x56, 0x33, 0x48, - 0x00, 0x52, 0x08, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x12, 0x32, 0x0a, 0x09, 0x41, - 0x70, 0x70, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x18, 0x1d, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, - 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x41, 0x70, 0x70, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, - 0x56, 0x33, 0x48, 0x00, 0x52, 0x09, 0x41, 0x70, 0x70, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x12, - 0x20, 0x0a, 0x03, 0x41, 0x70, 0x70, 0x18, 0x1e, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x74, - 0x79, 0x70, 0x65, 0x73, 0x2e, 0x41, 0x70, 0x70, 0x56, 0x33, 0x48, 0x00, 0x52, 0x03, 0x41, 0x70, - 0x70, 0x12, 0x41, 0x0a, 0x10, 0x53, 0x6e, 0x6f, 0x77, 0x66, 0x6c, 0x61, 0x6b, 0x65, 0x53, 0x65, - 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x1f, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x74, 0x79, - 0x70, 0x65, 0x73, 0x2e, 0x57, 0x65, 0x62, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x56, 0x32, - 0x48, 0x00, 0x52, 0x10, 0x53, 0x6e, 0x6f, 0x77, 0x66, 0x6c, 0x61, 0x6b, 0x65, 0x53, 0x65, 0x73, - 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x47, 0x0a, 0x10, 0x4b, 0x75, 0x62, 0x65, 0x72, 0x6e, 0x65, 0x74, - 0x65, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x18, 0x20, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, - 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x4b, 0x75, 0x62, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x65, - 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x56, 0x33, 0x48, 0x00, 0x52, 0x10, 0x4b, 0x75, 0x62, - 0x65, 0x72, 0x6e, 0x65, 0x74, 0x65, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x12, 0x4a, 0x0a, - 0x11, 0x4b, 0x75, 0x62, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x65, 0x73, 0x43, 0x6c, 0x75, 0x73, 0x74, - 0x65, 0x72, 0x18, 0x21, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, - 0x2e, 0x4b, 0x75, 0x62, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x65, 0x73, 0x43, 0x6c, 0x75, 0x73, 0x74, - 0x65, 0x72, 0x56, 0x33, 0x48, 0x00, 0x52, 0x11, 0x4b, 0x75, 0x62, 0x65, 0x72, 0x6e, 0x65, 0x74, - 0x65, 0x73, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x12, 0x32, 0x0a, 0x09, 0x49, 0x6e, 0x73, - 0x74, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x18, 0x22, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x74, - 0x79, 0x70, 0x65, 0x73, 0x2e, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x56, 0x31, - 0x48, 0x00, 0x52, 0x09, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x12, 0x44, 0x0a, + 0x6e, 0x67, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x59, 0x0a, 0x16, 0x53, 0x65, 0x73, 0x73, + 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6e, 0x66, + 0x69, 0x67, 0x18, 0x15, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, + 0x2e, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x69, 0x6e, + 0x67, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x56, 0x32, 0x48, 0x00, 0x52, 0x16, 0x53, 0x65, 0x73, + 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6e, + 0x66, 0x69, 0x67, 0x12, 0x41, 0x0a, 0x0e, 0x41, 0x75, 0x74, 0x68, 0x50, 0x72, 0x65, 0x66, 0x65, + 0x72, 0x65, 0x6e, 0x63, 0x65, 0x18, 0x16, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x74, 0x79, + 0x70, 0x65, 0x73, 0x2e, 0x41, 0x75, 0x74, 0x68, 0x50, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, + 0x63, 0x65, 0x56, 0x32, 0x48, 0x00, 0x52, 0x0e, 0x41, 0x75, 0x74, 0x68, 0x50, 0x72, 0x65, 0x66, + 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x12, 0x4d, 0x0a, 0x12, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, + 0x72, 0x41, 0x75, 0x64, 0x69, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x17, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x43, 0x6c, 0x75, 0x73, 0x74, + 0x65, 0x72, 0x41, 0x75, 0x64, 0x69, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x56, 0x32, 0x48, + 0x00, 0x52, 0x12, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x41, 0x75, 0x64, 0x69, 0x74, 0x43, + 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x23, 0x0a, 0x04, 0x4c, 0x6f, 0x63, 0x6b, 0x18, 0x18, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x4c, 0x6f, 0x63, 0x6b, + 0x56, 0x32, 0x48, 0x00, 0x52, 0x04, 0x4c, 0x6f, 0x63, 0x6b, 0x12, 0x50, 0x0a, 0x13, 0x4e, 0x65, + 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x52, 0x65, 0x73, 0x74, 0x72, 0x69, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x73, 0x18, 0x19, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, + 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x52, 0x65, 0x73, 0x74, 0x72, 0x69, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x73, 0x56, 0x34, 0x48, 0x00, 0x52, 0x13, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, + 0x52, 0x65, 0x73, 0x74, 0x72, 0x69, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x56, 0x0a, 0x15, + 0x57, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x73, 0x44, 0x65, 0x73, 0x6b, 0x74, 0x6f, 0x70, 0x53, 0x65, + 0x72, 0x76, 0x69, 0x63, 0x65, 0x18, 0x1a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x74, 0x79, + 0x70, 0x65, 0x73, 0x2e, 0x57, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x73, 0x44, 0x65, 0x73, 0x6b, 0x74, + 0x6f, 0x70, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x56, 0x33, 0x48, 0x00, 0x52, 0x15, 0x57, + 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x73, 0x44, 0x65, 0x73, 0x6b, 0x74, 0x6f, 0x70, 0x53, 0x65, 0x72, + 0x76, 0x69, 0x63, 0x65, 0x12, 0x41, 0x0a, 0x0e, 0x57, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x73, 0x44, + 0x65, 0x73, 0x6b, 0x74, 0x6f, 0x70, 0x18, 0x1b, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x74, + 0x79, 0x70, 0x65, 0x73, 0x2e, 0x57, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x73, 0x44, 0x65, 0x73, 0x6b, + 0x74, 0x6f, 0x70, 0x56, 0x33, 0x48, 0x00, 0x52, 0x0e, 0x57, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x73, + 0x44, 0x65, 0x73, 0x6b, 0x74, 0x6f, 0x70, 0x12, 0x2f, 0x0a, 0x08, 0x44, 0x61, 0x74, 0x61, 0x62, + 0x61, 0x73, 0x65, 0x18, 0x1c, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x74, 0x79, 0x70, 0x65, + 0x73, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x56, 0x33, 0x48, 0x00, 0x52, 0x08, + 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x12, 0x32, 0x0a, 0x09, 0x41, 0x70, 0x70, 0x53, + 0x65, 0x72, 0x76, 0x65, 0x72, 0x18, 0x1d, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x74, 0x79, + 0x70, 0x65, 0x73, 0x2e, 0x41, 0x70, 0x70, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x56, 0x33, 0x48, + 0x00, 0x52, 0x09, 0x41, 0x70, 0x70, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x12, 0x20, 0x0a, 0x03, + 0x41, 0x70, 0x70, 0x18, 0x1e, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x74, 0x79, 0x70, 0x65, + 0x73, 0x2e, 0x41, 0x70, 0x70, 0x56, 0x33, 0x48, 0x00, 0x52, 0x03, 0x41, 0x70, 0x70, 0x12, 0x41, + 0x0a, 0x10, 0x53, 0x6e, 0x6f, 0x77, 0x66, 0x6c, 0x61, 0x6b, 0x65, 0x53, 0x65, 0x73, 0x73, 0x69, + 0x6f, 0x6e, 0x18, 0x1f, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, + 0x2e, 0x57, 0x65, 0x62, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x56, 0x32, 0x48, 0x00, 0x52, + 0x10, 0x53, 0x6e, 0x6f, 0x77, 0x66, 0x6c, 0x61, 0x6b, 0x65, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, + 0x6e, 0x12, 0x47, 0x0a, 0x10, 0x4b, 0x75, 0x62, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x65, 0x73, 0x53, + 0x65, 0x72, 0x76, 0x65, 0x72, 0x18, 0x20, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x74, 0x79, + 0x70, 0x65, 0x73, 0x2e, 0x4b, 0x75, 0x62, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x65, 0x73, 0x53, 0x65, + 0x72, 0x76, 0x65, 0x72, 0x56, 0x33, 0x48, 0x00, 0x52, 0x10, 0x4b, 0x75, 0x62, 0x65, 0x72, 0x6e, + 0x65, 0x74, 0x65, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x12, 0x4a, 0x0a, 0x11, 0x4b, 0x75, + 0x62, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x65, 0x73, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x18, + 0x21, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x4b, 0x75, + 0x62, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x65, 0x73, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x56, + 0x33, 0x48, 0x00, 0x52, 0x11, 0x4b, 0x75, 0x62, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x65, 0x73, 0x43, + 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x12, 0x32, 0x0a, 0x09, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6c, + 0x6c, 0x65, 0x72, 0x18, 0x22, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x74, 0x79, 0x70, 0x65, + 0x73, 0x2e, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x56, 0x31, 0x48, 0x00, 0x52, + 0x09, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x12, 0x44, 0x0a, 0x0f, 0x44, 0x61, + 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x18, 0x23, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x44, 0x61, 0x74, 0x61, + 0x62, 0x61, 0x73, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x56, 0x31, 0x48, 0x00, 0x52, 0x0f, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, - 0x18, 0x23, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x44, - 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x56, 0x31, - 0x48, 0x00, 0x52, 0x0f, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x53, 0x65, 0x72, 0x76, - 0x69, 0x63, 0x65, 0x12, 0x59, 0x0a, 0x16, 0x53, 0x41, 0x4d, 0x4c, 0x49, 0x64, 0x50, 0x53, 0x65, - 0x72, 0x76, 0x69, 0x63, 0x65, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x18, 0x24, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x53, 0x41, 0x4d, 0x4c, - 0x49, 0x64, 0x50, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, - 0x65, 0x72, 0x56, 0x31, 0x48, 0x00, 0x52, 0x16, 0x53, 0x41, 0x4d, 0x4c, 0x49, 0x64, 0x50, 0x53, - 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x12, 0x3d, - 0x0a, 0x0e, 0x53, 0x41, 0x4d, 0x4c, 0x49, 0x64, 0x50, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, - 0x18, 0x25, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x57, - 0x65, 0x62, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x56, 0x32, 0x48, 0x00, 0x52, 0x0e, 0x53, - 0x41, 0x4d, 0x4c, 0x49, 0x64, 0x50, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x32, 0x0a, - 0x09, 0x55, 0x73, 0x65, 0x72, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x18, 0x26, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x12, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x47, 0x72, 0x6f, - 0x75, 0x70, 0x56, 0x31, 0x48, 0x00, 0x52, 0x09, 0x55, 0x73, 0x65, 0x72, 0x47, 0x72, 0x6f, 0x75, - 0x70, 0x12, 0x2f, 0x0a, 0x08, 0x55, 0x49, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x27, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x55, 0x49, 0x43, 0x6f, - 0x6e, 0x66, 0x69, 0x67, 0x56, 0x31, 0x48, 0x00, 0x52, 0x08, 0x55, 0x49, 0x43, 0x6f, 0x6e, 0x66, - 0x69, 0x67, 0x12, 0x41, 0x0a, 0x0e, 0x4f, 0x6b, 0x74, 0x61, 0x49, 0x6d, 0x70, 0x6f, 0x72, 0x74, - 0x52, 0x75, 0x6c, 0x65, 0x18, 0x28, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x74, 0x79, 0x70, - 0x65, 0x73, 0x2e, 0x4f, 0x6b, 0x74, 0x61, 0x49, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x75, 0x6c, - 0x65, 0x56, 0x31, 0x48, 0x00, 0x52, 0x0e, 0x4f, 0x6b, 0x74, 0x61, 0x49, 0x6d, 0x70, 0x6f, 0x72, - 0x74, 0x52, 0x75, 0x6c, 0x65, 0x12, 0x41, 0x0a, 0x0e, 0x4f, 0x6b, 0x74, 0x61, 0x41, 0x73, 0x73, - 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x18, 0x29, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, - 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x4f, 0x6b, 0x74, 0x61, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, - 0x6d, 0x65, 0x6e, 0x74, 0x56, 0x31, 0x48, 0x00, 0x52, 0x0e, 0x4f, 0x6b, 0x74, 0x61, 0x41, 0x73, - 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x38, 0x0a, 0x0b, 0x49, 0x6e, 0x74, 0x65, - 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x2a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, - 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x49, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x56, 0x31, 0x48, 0x00, 0x52, 0x0b, 0x49, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x12, 0x38, 0x0a, 0x0b, 0x57, 0x61, 0x74, 0x63, 0x68, 0x53, 0x74, 0x61, 0x74, 0x75, - 0x73, 0x18, 0x2b, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, - 0x57, 0x61, 0x74, 0x63, 0x68, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x56, 0x31, 0x48, 0x00, 0x52, - 0x0b, 0x57, 0x61, 0x74, 0x63, 0x68, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x57, 0x0a, 0x16, - 0x48, 0x65, 0x61, 0x64, 0x6c, 0x65, 0x73, 0x73, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, - 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x2c, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x74, - 0x79, 0x70, 0x65, 0x73, 0x2e, 0x48, 0x65, 0x61, 0x64, 0x6c, 0x65, 0x73, 0x73, 0x41, 0x75, 0x74, - 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x48, 0x00, 0x52, 0x16, 0x48, - 0x65, 0x61, 0x64, 0x6c, 0x65, 0x73, 0x73, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x44, 0x0a, 0x0a, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, - 0x69, 0x73, 0x74, 0x18, 0x2d, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x74, 0x65, 0x6c, 0x65, + 0x12, 0x59, 0x0a, 0x16, 0x53, 0x41, 0x4d, 0x4c, 0x49, 0x64, 0x50, 0x53, 0x65, 0x72, 0x76, 0x69, + 0x63, 0x65, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x18, 0x24, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x1f, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x53, 0x41, 0x4d, 0x4c, 0x49, 0x64, 0x50, + 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x56, + 0x31, 0x48, 0x00, 0x52, 0x16, 0x53, 0x41, 0x4d, 0x4c, 0x49, 0x64, 0x50, 0x53, 0x65, 0x72, 0x76, + 0x69, 0x63, 0x65, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x12, 0x3d, 0x0a, 0x0e, 0x53, + 0x41, 0x4d, 0x4c, 0x49, 0x64, 0x50, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x25, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x57, 0x65, 0x62, 0x53, + 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x56, 0x32, 0x48, 0x00, 0x52, 0x0e, 0x53, 0x41, 0x4d, 0x4c, + 0x49, 0x64, 0x50, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x32, 0x0a, 0x09, 0x55, 0x73, + 0x65, 0x72, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x18, 0x26, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, + 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x56, + 0x31, 0x48, 0x00, 0x52, 0x09, 0x55, 0x73, 0x65, 0x72, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x12, 0x2f, + 0x0a, 0x08, 0x55, 0x49, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x27, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x11, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x55, 0x49, 0x43, 0x6f, 0x6e, 0x66, 0x69, + 0x67, 0x56, 0x31, 0x48, 0x00, 0x52, 0x08, 0x55, 0x49, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, + 0x41, 0x0a, 0x0e, 0x4f, 0x6b, 0x74, 0x61, 0x49, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x75, 0x6c, + 0x65, 0x18, 0x28, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, + 0x4f, 0x6b, 0x74, 0x61, 0x49, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x75, 0x6c, 0x65, 0x56, 0x31, + 0x48, 0x00, 0x52, 0x0e, 0x4f, 0x6b, 0x74, 0x61, 0x49, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x75, + 0x6c, 0x65, 0x12, 0x41, 0x0a, 0x0e, 0x4f, 0x6b, 0x74, 0x61, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, + 0x6d, 0x65, 0x6e, 0x74, 0x18, 0x29, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x74, 0x79, 0x70, + 0x65, 0x73, 0x2e, 0x4f, 0x6b, 0x74, 0x61, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, + 0x74, 0x56, 0x31, 0x48, 0x00, 0x52, 0x0e, 0x4f, 0x6b, 0x74, 0x61, 0x41, 0x73, 0x73, 0x69, 0x67, + 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x38, 0x0a, 0x0b, 0x49, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x2a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x74, 0x79, 0x70, + 0x65, 0x73, 0x2e, 0x49, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x56, 0x31, + 0x48, 0x00, 0x52, 0x0b, 0x49, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, + 0x38, 0x0a, 0x0b, 0x57, 0x61, 0x74, 0x63, 0x68, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x2b, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x57, 0x61, 0x74, + 0x63, 0x68, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x56, 0x31, 0x48, 0x00, 0x52, 0x0b, 0x57, 0x61, + 0x74, 0x63, 0x68, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x57, 0x0a, 0x16, 0x48, 0x65, 0x61, + 0x64, 0x6c, 0x65, 0x73, 0x73, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x18, 0x2c, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x74, 0x79, 0x70, 0x65, + 0x73, 0x2e, 0x48, 0x65, 0x61, 0x64, 0x6c, 0x65, 0x73, 0x73, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6e, + 0x74, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x48, 0x00, 0x52, 0x16, 0x48, 0x65, 0x61, 0x64, + 0x6c, 0x65, 0x73, 0x73, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x12, 0x44, 0x0a, 0x0a, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, + 0x18, 0x2d, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, + 0x74, 0x2e, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x6c, 0x69, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, + 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x48, 0x00, 0x52, 0x0a, 0x41, 0x63, + 0x63, 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x54, 0x0a, 0x0e, 0x55, 0x73, 0x65, 0x72, + 0x4c, 0x6f, 0x67, 0x69, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x18, 0x2e, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x2a, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x75, 0x73, 0x65, 0x72, + 0x6c, 0x6f, 0x67, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x73, + 0x65, 0x72, 0x4c, 0x6f, 0x67, 0x69, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x48, 0x00, 0x52, 0x0e, + 0x55, 0x73, 0x65, 0x72, 0x4c, 0x6f, 0x67, 0x69, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x4c, + 0x0a, 0x10, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x65, 0x6d, 0x62, + 0x65, 0x72, 0x18, 0x2f, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, + 0x6f, 0x72, 0x74, 0x2e, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x6c, 0x69, 0x73, 0x74, 0x2e, 0x76, + 0x31, 0x2e, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x48, 0x00, 0x52, 0x10, 0x41, 0x63, 0x63, 0x65, + 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x12, 0x58, 0x0a, 0x0f, + 0x44, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x79, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, + 0x30, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2c, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, + 0x2e, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x79, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, + 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x79, 0x43, 0x6f, 0x6e, + 0x66, 0x69, 0x67, 0x48, 0x00, 0x52, 0x0f, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x79, + 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x44, 0x0a, 0x0a, 0x41, 0x75, 0x64, 0x69, 0x74, 0x51, + 0x75, 0x65, 0x72, 0x79, 0x18, 0x32, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x74, 0x65, 0x6c, + 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x73, 0x65, 0x63, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x73, + 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x75, 0x64, 0x69, 0x74, 0x51, 0x75, 0x65, 0x72, 0x79, 0x48, 0x00, + 0x52, 0x0a, 0x41, 0x75, 0x64, 0x69, 0x74, 0x51, 0x75, 0x65, 0x72, 0x79, 0x12, 0x38, 0x0a, 0x06, + 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x33, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x74, + 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x73, 0x65, 0x63, 0x72, 0x65, 0x70, 0x6f, 0x72, + 0x74, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x48, 0x00, 0x52, 0x06, + 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x12, 0x47, 0x0a, 0x0b, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, + 0x53, 0x74, 0x61, 0x74, 0x65, 0x18, 0x34, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x74, 0x65, + 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x73, 0x65, 0x63, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, + 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, + 0x48, 0x00, 0x52, 0x0b, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, + 0x4c, 0x0a, 0x10, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x76, + 0x69, 0x65, 0x77, 0x18, 0x35, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x6c, 0x69, 0x73, 0x74, 0x2e, - 0x76, 0x31, 0x2e, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x48, 0x00, 0x52, - 0x0a, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x54, 0x0a, 0x0e, 0x55, - 0x73, 0x65, 0x72, 0x4c, 0x6f, 0x67, 0x69, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x18, 0x2e, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x2a, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x75, - 0x73, 0x65, 0x72, 0x6c, 0x6f, 0x67, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x76, 0x31, - 0x2e, 0x55, 0x73, 0x65, 0x72, 0x4c, 0x6f, 0x67, 0x69, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x48, - 0x00, 0x52, 0x0e, 0x55, 0x73, 0x65, 0x72, 0x4c, 0x6f, 0x67, 0x69, 0x6e, 0x53, 0x74, 0x61, 0x74, - 0x65, 0x12, 0x4c, 0x0a, 0x10, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x4d, - 0x65, 0x6d, 0x62, 0x65, 0x72, 0x18, 0x2f, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x74, 0x65, - 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x6c, 0x69, 0x73, - 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x48, 0x00, 0x52, 0x10, 0x41, - 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x12, - 0x58, 0x0a, 0x0f, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x79, 0x43, 0x6f, 0x6e, 0x66, - 0x69, 0x67, 0x18, 0x30, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2c, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, - 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x79, 0x63, 0x6f, 0x6e, - 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x79, - 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x48, 0x00, 0x52, 0x0f, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x76, - 0x65, 0x72, 0x79, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x44, 0x0a, 0x0a, 0x41, 0x75, 0x64, - 0x69, 0x74, 0x51, 0x75, 0x65, 0x72, 0x79, 0x18, 0x32, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, - 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x73, 0x65, 0x63, 0x72, 0x65, 0x70, 0x6f, - 0x72, 0x74, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x75, 0x64, 0x69, 0x74, 0x51, 0x75, 0x65, 0x72, - 0x79, 0x48, 0x00, 0x52, 0x0a, 0x41, 0x75, 0x64, 0x69, 0x74, 0x51, 0x75, 0x65, 0x72, 0x79, 0x12, - 0x38, 0x0a, 0x06, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x33, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x1e, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x73, 0x65, 0x63, 0x72, 0x65, - 0x70, 0x6f, 0x72, 0x74, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x48, - 0x00, 0x52, 0x06, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x12, 0x47, 0x0a, 0x0b, 0x52, 0x65, 0x70, - 0x6f, 0x72, 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, 0x18, 0x34, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, - 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x73, 0x65, 0x63, 0x72, 0x65, 0x70, - 0x6f, 0x72, 0x74, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x53, 0x74, - 0x61, 0x74, 0x65, 0x48, 0x00, 0x52, 0x0b, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x53, 0x74, 0x61, - 0x74, 0x65, 0x12, 0x4c, 0x0a, 0x10, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, - 0x52, 0x65, 0x76, 0x69, 0x65, 0x77, 0x18, 0x35, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x74, - 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x6c, 0x69, - 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x76, 0x69, 0x65, 0x77, 0x48, 0x00, 0x52, 0x10, - 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x76, 0x69, 0x65, 0x77, - 0x12, 0x6d, 0x0a, 0x14, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, - 0x72, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x18, 0x36, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x37, - 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, - 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x72, 0x75, 0x6c, 0x65, 0x73, 0x2e, - 0x76, 0x31, 0x2e, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, - 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x48, 0x00, 0x52, 0x14, 0x41, 0x63, 0x63, 0x65, 0x73, - 0x73, 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x12, - 0x7e, 0x0a, 0x1a, 0x4b, 0x75, 0x62, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x65, 0x73, 0x57, 0x61, 0x69, - 0x74, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x18, 0x37, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x3c, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x6b, - 0x75, 0x62, 0x65, 0x77, 0x61, 0x69, 0x74, 0x69, 0x6e, 0x67, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, - 0x6e, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x4b, 0x75, 0x62, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x65, - 0x73, 0x57, 0x61, 0x69, 0x74, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, - 0x72, 0x48, 0x00, 0x52, 0x1a, 0x4b, 0x75, 0x62, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x65, 0x73, 0x57, - 0x61, 0x69, 0x74, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x12, - 0x55, 0x0a, 0x10, 0x55, 0x73, 0x65, 0x72, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x18, 0x38, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x74, 0x65, 0x6c, 0x65, - 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x6e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x48, 0x00, 0x52, 0x10, 0x55, 0x73, 0x65, 0x72, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x69, - 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x5f, 0x0a, 0x12, 0x47, 0x6c, 0x6f, 0x62, 0x61, 0x6c, - 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x39, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x2d, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x6e, 0x6f, - 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x47, - 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x48, 0x00, 0x52, 0x12, 0x47, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x4e, 0x6f, 0x74, 0x69, 0x66, - 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x44, 0x0a, 0x0a, 0x43, 0x72, 0x6f, 0x77, 0x6e, - 0x4a, 0x65, 0x77, 0x65, 0x6c, 0x18, 0x3a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x74, 0x65, - 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x63, 0x72, 0x6f, 0x77, 0x6e, 0x6a, 0x65, 0x77, 0x65, - 0x6c, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x6f, 0x77, 0x6e, 0x4a, 0x65, 0x77, 0x65, 0x6c, 0x48, - 0x00, 0x52, 0x0a, 0x43, 0x72, 0x6f, 0x77, 0x6e, 0x4a, 0x65, 0x77, 0x65, 0x6c, 0x12, 0x4e, 0x0a, - 0x0e, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x18, - 0x3b, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, - 0x2e, 0x64, 0x62, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x61, 0x74, - 0x61, 0x62, 0x61, 0x73, 0x65, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x48, 0x00, 0x52, 0x0e, 0x44, - 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x46, 0x0a, - 0x0b, 0x42, 0x6f, 0x74, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x18, 0x3c, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x6d, 0x61, - 0x63, 0x68, 0x69, 0x6e, 0x65, 0x69, 0x64, 0x2e, 0x76, 0x31, 0x2e, 0x42, 0x6f, 0x74, 0x49, 0x6e, - 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x48, 0x00, 0x52, 0x0b, 0x42, 0x6f, 0x74, 0x49, 0x6e, 0x73, - 0x74, 0x61, 0x6e, 0x63, 0x65, 0x12, 0x62, 0x0a, 0x13, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x47, - 0x72, 0x61, 0x70, 0x68, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x18, 0x3d, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x2e, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x63, 0x6c, - 0x75, 0x73, 0x74, 0x65, 0x72, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x41, - 0x63, 0x63, 0x65, 0x73, 0x73, 0x47, 0x72, 0x61, 0x70, 0x68, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, - 0x67, 0x73, 0x48, 0x00, 0x52, 0x13, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x47, 0x72, 0x61, 0x70, - 0x68, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x12, 0x55, 0x0a, 0x10, 0x53, 0x50, 0x49, - 0x46, 0x46, 0x45, 0x46, 0x65, 0x64, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x3e, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x6d, - 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x69, 0x64, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x50, 0x49, 0x46, - 0x46, 0x45, 0x46, 0x65, 0x64, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x48, 0x00, 0x52, 0x10, - 0x53, 0x50, 0x49, 0x46, 0x46, 0x45, 0x46, 0x65, 0x64, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x12, 0x56, 0x0a, 0x10, 0x41, 0x75, 0x74, 0x6f, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x43, 0x6f, - 0x6e, 0x66, 0x69, 0x67, 0x18, 0x40, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x28, 0x2e, 0x74, 0x65, 0x6c, - 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x61, 0x75, 0x74, 0x6f, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, - 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x75, 0x74, 0x6f, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x43, 0x6f, - 0x6e, 0x66, 0x69, 0x67, 0x48, 0x00, 0x52, 0x10, 0x41, 0x75, 0x74, 0x6f, 0x55, 0x70, 0x64, 0x61, - 0x74, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x59, 0x0a, 0x11, 0x41, 0x75, 0x74, 0x6f, - 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x41, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x61, - 0x75, 0x74, 0x6f, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x75, 0x74, - 0x6f, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x48, 0x00, - 0x52, 0x11, 0x41, 0x75, 0x74, 0x6f, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x56, 0x65, 0x72, 0x73, - 0x69, 0x6f, 0x6e, 0x12, 0x5a, 0x0a, 0x10, 0x53, 0x74, 0x61, 0x74, 0x69, 0x63, 0x48, 0x6f, 0x73, - 0x74, 0x55, 0x73, 0x65, 0x72, 0x56, 0x32, 0x18, 0x42, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2c, 0x2e, - 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x70, 0x72, 0x6f, - 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x32, 0x2e, 0x53, 0x74, 0x61, - 0x74, 0x69, 0x63, 0x48, 0x6f, 0x73, 0x74, 0x55, 0x73, 0x65, 0x72, 0x48, 0x00, 0x52, 0x10, 0x53, - 0x74, 0x61, 0x74, 0x69, 0x63, 0x48, 0x6f, 0x73, 0x74, 0x55, 0x73, 0x65, 0x72, 0x56, 0x32, 0x12, - 0x3d, 0x0a, 0x08, 0x55, 0x73, 0x65, 0x72, 0x54, 0x61, 0x73, 0x6b, 0x18, 0x43, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x1f, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x75, 0x73, 0x65, - 0x72, 0x74, 0x61, 0x73, 0x6b, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x54, 0x61, - 0x73, 0x6b, 0x48, 0x00, 0x52, 0x08, 0x55, 0x73, 0x65, 0x72, 0x54, 0x61, 0x73, 0x6b, 0x12, 0x56, - 0x0a, 0x15, 0x44, 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x57, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x73, - 0x44, 0x65, 0x73, 0x6b, 0x74, 0x6f, 0x70, 0x18, 0x45, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, - 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x44, 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x57, 0x69, 0x6e, - 0x64, 0x6f, 0x77, 0x73, 0x44, 0x65, 0x73, 0x6b, 0x74, 0x6f, 0x70, 0x56, 0x31, 0x48, 0x00, 0x52, - 0x15, 0x44, 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x57, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x73, 0x44, - 0x65, 0x73, 0x6b, 0x74, 0x6f, 0x70, 0x12, 0x6a, 0x0a, 0x1a, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x73, - 0x69, 0x6f, 0x6e, 0x69, 0x6e, 0x67, 0x50, 0x72, 0x69, 0x6e, 0x63, 0x69, 0x70, 0x61, 0x6c, 0x53, - 0x74, 0x61, 0x74, 0x65, 0x18, 0x46, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x28, 0x2e, 0x74, 0x65, 0x6c, - 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x69, - 0x6e, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x72, 0x69, 0x6e, 0x63, 0x69, 0x70, 0x61, 0x6c, 0x53, - 0x74, 0x61, 0x74, 0x65, 0x48, 0x00, 0x52, 0x1a, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, - 0x6e, 0x69, 0x6e, 0x67, 0x50, 0x72, 0x69, 0x6e, 0x63, 0x69, 0x70, 0x61, 0x6c, 0x53, 0x74, 0x61, - 0x74, 0x65, 0x12, 0x68, 0x0a, 0x16, 0x41, 0x75, 0x74, 0x6f, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, - 0x41, 0x67, 0x65, 0x6e, 0x74, 0x52, 0x6f, 0x6c, 0x6c, 0x6f, 0x75, 0x74, 0x18, 0x47, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x2e, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x61, 0x75, - 0x74, 0x6f, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x75, 0x74, 0x6f, - 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x52, 0x6f, 0x6c, 0x6c, 0x6f, - 0x75, 0x74, 0x48, 0x00, 0x52, 0x16, 0x41, 0x75, 0x74, 0x6f, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, - 0x41, 0x67, 0x65, 0x6e, 0x74, 0x52, 0x6f, 0x6c, 0x6c, 0x6f, 0x75, 0x74, 0x12, 0x5b, 0x0a, 0x15, - 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x43, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x41, 0x63, - 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x48, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x74, 0x65, - 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x63, - 0x65, 0x6e, 0x74, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, - 0x48, 0x00, 0x52, 0x15, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x43, 0x65, 0x6e, 0x74, - 0x65, 0x72, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x7f, 0x0a, 0x21, 0x49, 0x64, 0x65, - 0x6e, 0x74, 0x69, 0x74, 0x79, 0x43, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x50, 0x72, 0x69, 0x6e, 0x63, - 0x69, 0x70, 0x61, 0x6c, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x18, 0x49, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2f, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, - 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x2e, 0x76, - 0x31, 0x2e, 0x50, 0x72, 0x69, 0x6e, 0x63, 0x69, 0x70, 0x61, 0x6c, 0x41, 0x73, 0x73, 0x69, 0x67, - 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x21, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, - 0x79, 0x43, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x50, 0x72, 0x69, 0x6e, 0x63, 0x69, 0x70, 0x61, 0x6c, - 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x79, 0x0a, 0x1f, 0x49, 0x64, - 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x43, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x41, 0x63, 0x63, 0x6f, - 0x75, 0x6e, 0x74, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x18, 0x4a, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x2d, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x69, - 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x2e, 0x76, 0x31, - 0x2e, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, - 0x6e, 0x74, 0x48, 0x00, 0x52, 0x1f, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x43, 0x65, - 0x6e, 0x74, 0x65, 0x72, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x41, 0x73, 0x73, 0x69, 0x67, - 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x5c, 0x0a, 0x17, 0x50, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x53, - 0x74, 0x61, 0x74, 0x69, 0x63, 0x43, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x73, - 0x18, 0x4b, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x50, - 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x69, 0x63, 0x43, 0x72, 0x65, 0x64, 0x65, - 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x73, 0x56, 0x31, 0x48, 0x00, 0x52, 0x17, 0x50, 0x6c, 0x75, 0x67, + 0x76, 0x31, 0x2e, 0x52, 0x65, 0x76, 0x69, 0x65, 0x77, 0x48, 0x00, 0x52, 0x10, 0x41, 0x63, 0x63, + 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x76, 0x69, 0x65, 0x77, 0x12, 0x6d, 0x0a, + 0x14, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, + 0x67, 0x52, 0x75, 0x6c, 0x65, 0x18, 0x36, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x37, 0x2e, 0x74, 0x65, + 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x6d, 0x6f, 0x6e, + 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x72, 0x75, 0x6c, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x2e, + 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, + 0x52, 0x75, 0x6c, 0x65, 0x48, 0x00, 0x52, 0x14, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4d, 0x6f, + 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x12, 0x7e, 0x0a, 0x1a, + 0x4b, 0x75, 0x62, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x65, 0x73, 0x57, 0x61, 0x69, 0x74, 0x69, 0x6e, + 0x67, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x18, 0x37, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x3c, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x6b, 0x75, 0x62, 0x65, + 0x77, 0x61, 0x69, 0x74, 0x69, 0x6e, 0x67, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, + 0x2e, 0x76, 0x31, 0x2e, 0x4b, 0x75, 0x62, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x65, 0x73, 0x57, 0x61, + 0x69, 0x74, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x48, 0x00, + 0x52, 0x1a, 0x4b, 0x75, 0x62, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x65, 0x73, 0x57, 0x61, 0x69, 0x74, + 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x12, 0x55, 0x0a, 0x10, + 0x55, 0x73, 0x65, 0x72, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x18, 0x38, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, + 0x74, 0x2e, 0x6e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, + 0x76, 0x31, 0x2e, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x48, + 0x00, 0x52, 0x10, 0x55, 0x73, 0x65, 0x72, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x12, 0x5f, 0x0a, 0x12, 0x47, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x4e, 0x6f, 0x74, + 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x39, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x2d, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x6e, 0x6f, 0x74, 0x69, 0x66, + 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x6c, 0x6f, 0x62, + 0x61, 0x6c, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x48, 0x00, + 0x52, 0x12, 0x47, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x44, 0x0a, 0x0a, 0x43, 0x72, 0x6f, 0x77, 0x6e, 0x4a, 0x65, 0x77, + 0x65, 0x6c, 0x18, 0x3a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, + 0x6f, 0x72, 0x74, 0x2e, 0x63, 0x72, 0x6f, 0x77, 0x6e, 0x6a, 0x65, 0x77, 0x65, 0x6c, 0x2e, 0x76, + 0x31, 0x2e, 0x43, 0x72, 0x6f, 0x77, 0x6e, 0x4a, 0x65, 0x77, 0x65, 0x6c, 0x48, 0x00, 0x52, 0x0a, + 0x43, 0x72, 0x6f, 0x77, 0x6e, 0x4a, 0x65, 0x77, 0x65, 0x6c, 0x12, 0x4e, 0x0a, 0x0e, 0x44, 0x61, + 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x18, 0x3b, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x62, + 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, + 0x73, 0x65, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x48, 0x00, 0x52, 0x0e, 0x44, 0x61, 0x74, 0x61, + 0x62, 0x61, 0x73, 0x65, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x46, 0x0a, 0x0b, 0x42, 0x6f, + 0x74, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x18, 0x3c, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x22, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x6d, 0x61, 0x63, 0x68, 0x69, + 0x6e, 0x65, 0x69, 0x64, 0x2e, 0x76, 0x31, 0x2e, 0x42, 0x6f, 0x74, 0x49, 0x6e, 0x73, 0x74, 0x61, + 0x6e, 0x63, 0x65, 0x48, 0x00, 0x52, 0x0b, 0x42, 0x6f, 0x74, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, + 0x63, 0x65, 0x12, 0x62, 0x0a, 0x13, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x47, 0x72, 0x61, 0x70, + 0x68, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x18, 0x3d, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x2e, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x63, 0x6c, 0x75, 0x73, 0x74, + 0x65, 0x72, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x63, 0x63, 0x65, + 0x73, 0x73, 0x47, 0x72, 0x61, 0x70, 0x68, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x48, + 0x00, 0x52, 0x13, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x47, 0x72, 0x61, 0x70, 0x68, 0x53, 0x65, + 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x12, 0x55, 0x0a, 0x10, 0x53, 0x50, 0x49, 0x46, 0x46, 0x45, + 0x46, 0x65, 0x64, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x3e, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x27, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x6d, 0x61, 0x63, 0x68, + 0x69, 0x6e, 0x65, 0x69, 0x64, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x50, 0x49, 0x46, 0x46, 0x45, 0x46, + 0x65, 0x64, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x48, 0x00, 0x52, 0x10, 0x53, 0x50, 0x49, + 0x46, 0x46, 0x45, 0x46, 0x65, 0x64, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x56, 0x0a, + 0x10, 0x41, 0x75, 0x74, 0x6f, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, + 0x67, 0x18, 0x40, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x28, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, + 0x72, 0x74, 0x2e, 0x61, 0x75, 0x74, 0x6f, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x2e, 0x76, 0x31, + 0x2e, 0x41, 0x75, 0x74, 0x6f, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, + 0x67, 0x48, 0x00, 0x52, 0x10, 0x41, 0x75, 0x74, 0x6f, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x43, + 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x59, 0x0a, 0x11, 0x41, 0x75, 0x74, 0x6f, 0x55, 0x70, 0x64, + 0x61, 0x74, 0x65, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x41, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x29, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x61, 0x75, 0x74, 0x6f, + 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x75, 0x74, 0x6f, 0x55, 0x70, + 0x64, 0x61, 0x74, 0x65, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x48, 0x00, 0x52, 0x11, 0x41, + 0x75, 0x74, 0x6f, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, + 0x12, 0x5a, 0x0a, 0x10, 0x53, 0x74, 0x61, 0x74, 0x69, 0x63, 0x48, 0x6f, 0x73, 0x74, 0x55, 0x73, + 0x65, 0x72, 0x56, 0x32, 0x18, 0x42, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2c, 0x2e, 0x74, 0x65, 0x6c, + 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, + 0x69, 0x6f, 0x6e, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x32, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x69, 0x63, + 0x48, 0x6f, 0x73, 0x74, 0x55, 0x73, 0x65, 0x72, 0x48, 0x00, 0x52, 0x10, 0x53, 0x74, 0x61, 0x74, + 0x69, 0x63, 0x48, 0x6f, 0x73, 0x74, 0x55, 0x73, 0x65, 0x72, 0x56, 0x32, 0x12, 0x3d, 0x0a, 0x08, + 0x55, 0x73, 0x65, 0x72, 0x54, 0x61, 0x73, 0x6b, 0x18, 0x43, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, + 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x74, 0x61, + 0x73, 0x6b, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x54, 0x61, 0x73, 0x6b, 0x48, + 0x00, 0x52, 0x08, 0x55, 0x73, 0x65, 0x72, 0x54, 0x61, 0x73, 0x6b, 0x12, 0x56, 0x0a, 0x15, 0x44, + 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x57, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x73, 0x44, 0x65, 0x73, + 0x6b, 0x74, 0x6f, 0x70, 0x18, 0x45, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x74, 0x79, 0x70, + 0x65, 0x73, 0x2e, 0x44, 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x57, 0x69, 0x6e, 0x64, 0x6f, 0x77, + 0x73, 0x44, 0x65, 0x73, 0x6b, 0x74, 0x6f, 0x70, 0x56, 0x31, 0x48, 0x00, 0x52, 0x15, 0x44, 0x79, + 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x57, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x73, 0x44, 0x65, 0x73, 0x6b, + 0x74, 0x6f, 0x70, 0x12, 0x6a, 0x0a, 0x1a, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, + 0x69, 0x6e, 0x67, 0x50, 0x72, 0x69, 0x6e, 0x63, 0x69, 0x70, 0x61, 0x6c, 0x53, 0x74, 0x61, 0x74, + 0x65, 0x18, 0x46, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x28, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, + 0x72, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x69, 0x6e, 0x67, 0x2e, + 0x76, 0x31, 0x2e, 0x50, 0x72, 0x69, 0x6e, 0x63, 0x69, 0x70, 0x61, 0x6c, 0x53, 0x74, 0x61, 0x74, + 0x65, 0x48, 0x00, 0x52, 0x1a, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x69, 0x6e, + 0x67, 0x50, 0x72, 0x69, 0x6e, 0x63, 0x69, 0x70, 0x61, 0x6c, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, + 0x68, 0x0a, 0x16, 0x41, 0x75, 0x74, 0x6f, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x41, 0x67, 0x65, + 0x6e, 0x74, 0x52, 0x6f, 0x6c, 0x6c, 0x6f, 0x75, 0x74, 0x18, 0x47, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x2e, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x61, 0x75, 0x74, 0x6f, 0x75, + 0x70, 0x64, 0x61, 0x74, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x75, 0x74, 0x6f, 0x55, 0x70, 0x64, + 0x61, 0x74, 0x65, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x52, 0x6f, 0x6c, 0x6c, 0x6f, 0x75, 0x74, 0x48, + 0x00, 0x52, 0x16, 0x41, 0x75, 0x74, 0x6f, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x41, 0x67, 0x65, + 0x6e, 0x74, 0x52, 0x6f, 0x6c, 0x6c, 0x6f, 0x75, 0x74, 0x12, 0x5b, 0x0a, 0x15, 0x49, 0x64, 0x65, + 0x6e, 0x74, 0x69, 0x74, 0x79, 0x43, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x41, 0x63, 0x63, 0x6f, 0x75, + 0x6e, 0x74, 0x18, 0x48, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, + 0x6f, 0x72, 0x74, 0x2e, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x63, 0x65, 0x6e, 0x74, + 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x48, 0x00, 0x52, + 0x15, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x43, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x41, + 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x7f, 0x0a, 0x21, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, + 0x74, 0x79, 0x43, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x50, 0x72, 0x69, 0x6e, 0x63, 0x69, 0x70, 0x61, + 0x6c, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x18, 0x49, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x2f, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x69, 0x64, 0x65, + 0x6e, 0x74, 0x69, 0x74, 0x79, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x50, + 0x72, 0x69, 0x6e, 0x63, 0x69, 0x70, 0x61, 0x6c, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, + 0x6e, 0x74, 0x48, 0x00, 0x52, 0x21, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x43, 0x65, + 0x6e, 0x74, 0x65, 0x72, 0x50, 0x72, 0x69, 0x6e, 0x63, 0x69, 0x70, 0x61, 0x6c, 0x41, 0x73, 0x73, + 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x79, 0x0a, 0x1f, 0x49, 0x64, 0x65, 0x6e, 0x74, + 0x69, 0x74, 0x79, 0x43, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, + 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x18, 0x4a, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x2d, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x69, 0x64, 0x65, 0x6e, + 0x74, 0x69, 0x74, 0x79, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x63, + 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x48, + 0x00, 0x52, 0x1f, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x43, 0x65, 0x6e, 0x74, 0x65, + 0x72, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, + 0x6e, 0x74, 0x12, 0x5c, 0x0a, 0x17, 0x50, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x53, 0x74, 0x61, 0x74, + 0x69, 0x63, 0x43, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x73, 0x18, 0x4b, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x50, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x69, 0x63, 0x43, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, - 0x61, 0x6c, 0x73, 0x42, 0x0a, 0x0a, 0x08, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4a, - 0x04, 0x08, 0x07, 0x10, 0x08, 0x4a, 0x04, 0x08, 0x31, 0x10, 0x32, 0x4a, 0x04, 0x08, 0x3f, 0x10, - 0x40, 0x4a, 0x04, 0x08, 0x44, 0x10, 0x45, 0x52, 0x12, 0x45, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, - 0x6c, 0x43, 0x6c, 0x6f, 0x75, 0x64, 0x41, 0x75, 0x64, 0x69, 0x74, 0x52, 0x0e, 0x53, 0x74, 0x61, - 0x74, 0x69, 0x63, 0x48, 0x6f, 0x73, 0x74, 0x55, 0x73, 0x65, 0x72, 0x52, 0x13, 0x41, 0x75, 0x74, - 0x6f, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x50, 0x6c, 0x61, 0x6e, - 0x2a, 0x2a, 0x0a, 0x09, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x08, 0x0a, - 0x04, 0x49, 0x4e, 0x49, 0x54, 0x10, 0x00, 0x12, 0x07, 0x0a, 0x03, 0x50, 0x55, 0x54, 0x10, 0x01, - 0x12, 0x0a, 0x0a, 0x06, 0x44, 0x45, 0x4c, 0x45, 0x54, 0x45, 0x10, 0x02, 0x42, 0x34, 0x5a, 0x32, - 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x72, 0x61, 0x76, 0x69, - 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x2f, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, - 0x74, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x2f, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x61, 0x6c, 0x73, 0x56, 0x31, 0x48, 0x00, 0x52, 0x17, 0x50, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x53, + 0x74, 0x61, 0x74, 0x69, 0x63, 0x43, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x73, + 0x12, 0x5c, 0x0a, 0x10, 0x57, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x49, 0x64, 0x65, 0x6e, + 0x74, 0x69, 0x74, 0x79, 0x18, 0x4c, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2e, 0x2e, 0x74, 0x65, 0x6c, + 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x77, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x69, 0x64, + 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, + 0x61, 0x64, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x48, 0x00, 0x52, 0x10, 0x57, 0x6f, + 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x42, 0x0a, + 0x0a, 0x08, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4a, 0x04, 0x08, 0x07, 0x10, 0x08, + 0x4a, 0x04, 0x08, 0x31, 0x10, 0x32, 0x4a, 0x04, 0x08, 0x3f, 0x10, 0x40, 0x4a, 0x04, 0x08, 0x44, + 0x10, 0x45, 0x52, 0x12, 0x45, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x43, 0x6c, 0x6f, 0x75, + 0x64, 0x41, 0x75, 0x64, 0x69, 0x74, 0x52, 0x0e, 0x53, 0x74, 0x61, 0x74, 0x69, 0x63, 0x48, 0x6f, + 0x73, 0x74, 0x55, 0x73, 0x65, 0x72, 0x52, 0x13, 0x41, 0x75, 0x74, 0x6f, 0x55, 0x70, 0x64, 0x61, + 0x74, 0x65, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x50, 0x6c, 0x61, 0x6e, 0x2a, 0x2a, 0x0a, 0x09, 0x4f, + 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x08, 0x0a, 0x04, 0x49, 0x4e, 0x49, 0x54, + 0x10, 0x00, 0x12, 0x07, 0x0a, 0x03, 0x50, 0x55, 0x54, 0x10, 0x01, 0x12, 0x0a, 0x0a, 0x06, 0x44, + 0x45, 0x4c, 0x45, 0x54, 0x45, 0x10, 0x02, 0x42, 0x34, 0x5a, 0x32, 0x67, 0x69, 0x74, 0x68, 0x75, + 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x72, 0x61, 0x76, 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x61, 0x6c, 0x2f, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x61, 0x70, 0x69, + 0x2f, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -1706,6 +1731,7 @@ var file_teleport_legacy_client_proto_event_proto_goTypes = []any{ (*v114.PrincipalAssignment)(nil), // 66: teleport.identitycenter.v1.PrincipalAssignment (*v114.AccountAssignment)(nil), // 67: teleport.identitycenter.v1.AccountAssignment (*types.PluginStaticCredentialsV1)(nil), // 68: types.PluginStaticCredentialsV1 + (*v115.WorkloadIdentity)(nil), // 69: teleport.workloadidentity.v1.WorkloadIdentity } var file_teleport_legacy_client_proto_event_proto_depIdxs = []int32{ 0, // 0: proto.Event.Type:type_name -> proto.Operation @@ -1779,11 +1805,12 @@ var file_teleport_legacy_client_proto_event_proto_depIdxs = []int32{ 66, // 68: proto.Event.IdentityCenterPrincipalAssignment:type_name -> teleport.identitycenter.v1.PrincipalAssignment 67, // 69: proto.Event.IdentityCenterAccountAssignment:type_name -> teleport.identitycenter.v1.AccountAssignment 68, // 70: proto.Event.PluginStaticCredentials:type_name -> types.PluginStaticCredentialsV1 - 71, // [71:71] is the sub-list for method output_type - 71, // [71:71] is the sub-list for method input_type - 71, // [71:71] is the sub-list for extension type_name - 71, // [71:71] is the sub-list for extension extendee - 0, // [0:71] is the sub-list for field type_name + 69, // 71: proto.Event.WorkloadIdentity:type_name -> teleport.workloadidentity.v1.WorkloadIdentity + 72, // [72:72] is the sub-list for method output_type + 72, // [72:72] is the sub-list for method input_type + 72, // [72:72] is the sub-list for extension type_name + 72, // [72:72] is the sub-list for extension extendee + 0, // [0:72] is the sub-list for field type_name } func init() { file_teleport_legacy_client_proto_event_proto_init() } @@ -1862,6 +1889,7 @@ func file_teleport_legacy_client_proto_event_proto_init() { (*Event_IdentityCenterPrincipalAssignment)(nil), (*Event_IdentityCenterAccountAssignment)(nil), (*Event_PluginStaticCredentials)(nil), + (*Event_WorkloadIdentity)(nil), } type x struct{} out := protoimpl.TypeBuilder{ diff --git a/api/client/proto/identitycenter.go b/api/client/proto/identitycenter.go new file mode 100644 index 0000000000000..ac0886a6b2772 --- /dev/null +++ b/api/client/proto/identitycenter.go @@ -0,0 +1,61 @@ +// Copyright 2024 Gravitational, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package proto + +import ( + identitycenterv1 "github.com/gravitational/teleport/api/gen/proto/go/teleport/identitycenter/v1" + "github.com/gravitational/teleport/api/types" +) + +// PackICAccountAssignment packs an Identity Center Account Assignment in to its +// wire format. +func PackICAccountAssignment(assignment *identitycenterv1.AccountAssignment) isPaginatedResource_Resource { + return &PaginatedResource_IdentityCenterAccountAssignment{ + IdentityCenterAccountAssignment: &IdentityCenterAccountAssignment{ + Kind: types.KindIdentityCenterAccountAssignment, + Version: assignment.GetVersion(), + Metadata: types.Metadata153ToLegacy(assignment.Metadata), + DisplayName: assignment.GetSpec().GetDisplay(), + Account: &IdentityCenterAccount{ + AccountName: assignment.GetSpec().GetAccountName(), + ID: assignment.GetSpec().GetAccountId(), + }, + PermissionSet: &IdentityCenterPermissionSet{ + ARN: assignment.GetSpec().GetPermissionSet().GetArn(), + Name: assignment.GetSpec().GetPermissionSet().GetName(), + }, + }, + } +} + +// UnpackICAccountAssignment converts a wire-format IdentityCenterAccountAssignment +// resource back into an identitycenterv1.AccountAssignment instance. +func UnpackICAccountAssignment(src *IdentityCenterAccountAssignment) types.ResourceWithLabels { + dst := &identitycenterv1.AccountAssignment{ + Kind: types.KindIdentityCenterAccountAssignment, + Version: src.Version, + Metadata: types.LegacyTo153Metadata(src.Metadata), + Spec: &identitycenterv1.AccountAssignmentSpec{ + AccountId: src.Account.ID, + AccountName: src.Account.AccountName, + Display: src.DisplayName, + PermissionSet: &identitycenterv1.PermissionSetInfo{ + Arn: src.PermissionSet.ARN, + Name: src.PermissionSet.Name, + }, + }, + } + return types.Resource153ToResourceWithLabels(dst) +} diff --git a/api/client/webclient/webclient.go b/api/client/webclient/webclient.go index 6b7d7153a7136..78d4c80c9aebc 100644 --- a/api/client/webclient/webclient.go +++ b/api/client/webclient/webclient.go @@ -47,6 +47,15 @@ import ( "github.com/gravitational/teleport/api/utils/keys" ) +const ( + // AgentUpdateGroupParameter is the parameter used to specify the updater + // group when doing a Ping() or Find() query. + // The proxy server will modulate the auto_update part of the PingResponse + // based on the specified group. e.g. some groups might need to update + // before others. + AgentUpdateGroupParameter = "group" +) + // Config specifies information when building requests with the // webclient. type Config struct { @@ -183,7 +192,7 @@ func findWithClient(cfg *Config, clt *http.Client) (*PingResponse, error) { } if cfg.UpdateGroup != "" { endpoint.RawQuery = url.Values{ - "group": []string{cfg.UpdateGroup}, + AgentUpdateGroupParameter: []string{cfg.UpdateGroup}, }.Encode() } @@ -232,7 +241,7 @@ func pingWithClient(cfg *Config, clt *http.Client) (*PingResponse, error) { } if cfg.UpdateGroup != "" { endpoint.RawQuery = url.Values{ - "group": []string{cfg.UpdateGroup}, + AgentUpdateGroupParameter: []string{cfg.UpdateGroup}, }.Encode() } if cfg.ConnectorName != "" { diff --git a/api/gen/proto/go/teleport/autoupdate/v1/autoupdate.pb.go b/api/gen/proto/go/teleport/autoupdate/v1/autoupdate.pb.go index eab6a3f5830fc..e1fb1f9e34c88 100644 --- a/api/gen/proto/go/teleport/autoupdate/v1/autoupdate.pb.go +++ b/api/gen/proto/go/teleport/autoupdate/v1/autoupdate.pb.go @@ -982,6 +982,12 @@ type AutoUpdateAgentRolloutStatusGroup struct { LastUpdateTime *timestamppb.Timestamp `protobuf:"bytes,4,opt,name=last_update_time,json=lastUpdateTime,proto3" json:"last_update_time,omitempty"` // last_update_reason is the trigger for the last update LastUpdateReason string `protobuf:"bytes,5,opt,name=last_update_reason,json=lastUpdateReason,proto3" json:"last_update_reason,omitempty"` + // config_days when the update can run. Supported values are "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun" and "*" + ConfigDays []string `protobuf:"bytes,6,rep,name=config_days,json=configDays,proto3" json:"config_days,omitempty"` + // config_start_hour to initiate update + ConfigStartHour int32 `protobuf:"varint,7,opt,name=config_start_hour,json=configStartHour,proto3" json:"config_start_hour,omitempty"` + // config_wait_days after last group succeeds before this group can run. This can only be used when the strategy is "halt-on-failure". + ConfigWaitDays int64 `protobuf:"varint,8,opt,name=config_wait_days,json=configWaitDays,proto3" json:"config_wait_days,omitempty"` } func (x *AutoUpdateAgentRolloutStatusGroup) Reset() { @@ -1049,6 +1055,27 @@ func (x *AutoUpdateAgentRolloutStatusGroup) GetLastUpdateReason() string { return "" } +func (x *AutoUpdateAgentRolloutStatusGroup) GetConfigDays() []string { + if x != nil { + return x.ConfigDays + } + return nil +} + +func (x *AutoUpdateAgentRolloutStatusGroup) GetConfigStartHour() int32 { + if x != nil { + return x.ConfigStartHour + } + return 0 +} + +func (x *AutoUpdateAgentRolloutStatusGroup) GetConfigWaitDays() int64 { + if x != nil { + return x.ConfigWaitDays + } + return 0 +} + var File_teleport_autoupdate_v1_autoupdate_proto protoreflect.FileDescriptor var file_teleport_autoupdate_v1_autoupdate_proto_rawDesc = []byte{ @@ -1201,7 +1228,7 @@ var file_teleport_autoupdate_v1_autoupdate_proto_rawDesc = []byte{ 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x61, 0x75, 0x74, 0x6f, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x75, 0x74, 0x6f, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x52, 0x6f, 0x6c, 0x6c, 0x6f, 0x75, 0x74, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, - 0x47, 0x72, 0x6f, 0x75, 0x70, 0x52, 0x06, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x22, 0xaf, 0x02, + 0x47, 0x72, 0x6f, 0x75, 0x70, 0x52, 0x06, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x22, 0xa6, 0x03, 0x0a, 0x21, 0x41, 0x75, 0x74, 0x6f, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x52, 0x6f, 0x6c, 0x6c, 0x6f, 0x75, 0x74, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, @@ -1220,29 +1247,36 @@ var file_teleport_autoupdate_v1_autoupdate_proto_rawDesc = []byte{ 0x70, 0x52, 0x0e, 0x6c, 0x61, 0x73, 0x74, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x2c, 0x0a, 0x12, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, 0x6c, - 0x61, 0x73, 0x74, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x2a, - 0xf7, 0x01, 0x0a, 0x19, 0x41, 0x75, 0x74, 0x6f, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x41, 0x67, - 0x65, 0x6e, 0x74, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x2d, 0x0a, - 0x29, 0x41, 0x55, 0x54, 0x4f, 0x5f, 0x55, 0x50, 0x44, 0x41, 0x54, 0x45, 0x5f, 0x41, 0x47, 0x45, - 0x4e, 0x54, 0x5f, 0x47, 0x52, 0x4f, 0x55, 0x50, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f, 0x55, - 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x2b, 0x0a, 0x27, - 0x41, 0x55, 0x54, 0x4f, 0x5f, 0x55, 0x50, 0x44, 0x41, 0x54, 0x45, 0x5f, 0x41, 0x47, 0x45, 0x4e, - 0x54, 0x5f, 0x47, 0x52, 0x4f, 0x55, 0x50, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f, 0x55, 0x4e, - 0x53, 0x54, 0x41, 0x52, 0x54, 0x45, 0x44, 0x10, 0x01, 0x12, 0x28, 0x0a, 0x24, 0x41, 0x55, 0x54, - 0x4f, 0x5f, 0x55, 0x50, 0x44, 0x41, 0x54, 0x45, 0x5f, 0x41, 0x47, 0x45, 0x4e, 0x54, 0x5f, 0x47, - 0x52, 0x4f, 0x55, 0x50, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f, 0x41, 0x43, 0x54, 0x49, 0x56, - 0x45, 0x10, 0x02, 0x12, 0x26, 0x0a, 0x22, 0x41, 0x55, 0x54, 0x4f, 0x5f, 0x55, 0x50, 0x44, 0x41, + 0x61, 0x73, 0x74, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x12, + 0x1f, 0x0a, 0x0b, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x64, 0x61, 0x79, 0x73, 0x18, 0x06, + 0x20, 0x03, 0x28, 0x09, 0x52, 0x0a, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x44, 0x61, 0x79, 0x73, + 0x12, 0x2a, 0x0a, 0x11, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x73, 0x74, 0x61, 0x72, 0x74, + 0x5f, 0x68, 0x6f, 0x75, 0x72, 0x18, 0x07, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0f, 0x63, 0x6f, 0x6e, + 0x66, 0x69, 0x67, 0x53, 0x74, 0x61, 0x72, 0x74, 0x48, 0x6f, 0x75, 0x72, 0x12, 0x28, 0x0a, 0x10, + 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x77, 0x61, 0x69, 0x74, 0x5f, 0x64, 0x61, 0x79, 0x73, + 0x18, 0x08, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x57, 0x61, + 0x69, 0x74, 0x44, 0x61, 0x79, 0x73, 0x2a, 0xf7, 0x01, 0x0a, 0x19, 0x41, 0x75, 0x74, 0x6f, 0x55, + 0x70, 0x64, 0x61, 0x74, 0x65, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x53, + 0x74, 0x61, 0x74, 0x65, 0x12, 0x2d, 0x0a, 0x29, 0x41, 0x55, 0x54, 0x4f, 0x5f, 0x55, 0x50, 0x44, + 0x41, 0x54, 0x45, 0x5f, 0x41, 0x47, 0x45, 0x4e, 0x54, 0x5f, 0x47, 0x52, 0x4f, 0x55, 0x50, 0x5f, + 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, + 0x44, 0x10, 0x00, 0x12, 0x2b, 0x0a, 0x27, 0x41, 0x55, 0x54, 0x4f, 0x5f, 0x55, 0x50, 0x44, 0x41, 0x54, 0x45, 0x5f, 0x41, 0x47, 0x45, 0x4e, 0x54, 0x5f, 0x47, 0x52, 0x4f, 0x55, 0x50, 0x5f, 0x53, - 0x54, 0x41, 0x54, 0x45, 0x5f, 0x44, 0x4f, 0x4e, 0x45, 0x10, 0x03, 0x12, 0x2c, 0x0a, 0x28, 0x41, - 0x55, 0x54, 0x4f, 0x5f, 0x55, 0x50, 0x44, 0x41, 0x54, 0x45, 0x5f, 0x41, 0x47, 0x45, 0x4e, 0x54, - 0x5f, 0x47, 0x52, 0x4f, 0x55, 0x50, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f, 0x52, 0x4f, 0x4c, - 0x4c, 0x45, 0x44, 0x42, 0x41, 0x43, 0x4b, 0x10, 0x04, 0x42, 0x56, 0x5a, 0x54, 0x67, 0x69, 0x74, - 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x72, 0x61, 0x76, 0x69, 0x74, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x2f, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x61, - 0x70, 0x69, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x6f, 0x2f, - 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x61, 0x75, 0x74, 0x6f, 0x75, 0x70, 0x64, - 0x61, 0x74, 0x65, 0x2f, 0x76, 0x31, 0x3b, 0x61, 0x75, 0x74, 0x6f, 0x75, 0x70, 0x64, 0x61, 0x74, - 0x65, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x54, 0x41, 0x54, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x54, 0x41, 0x52, 0x54, 0x45, 0x44, 0x10, 0x01, + 0x12, 0x28, 0x0a, 0x24, 0x41, 0x55, 0x54, 0x4f, 0x5f, 0x55, 0x50, 0x44, 0x41, 0x54, 0x45, 0x5f, + 0x41, 0x47, 0x45, 0x4e, 0x54, 0x5f, 0x47, 0x52, 0x4f, 0x55, 0x50, 0x5f, 0x53, 0x54, 0x41, 0x54, + 0x45, 0x5f, 0x41, 0x43, 0x54, 0x49, 0x56, 0x45, 0x10, 0x02, 0x12, 0x26, 0x0a, 0x22, 0x41, 0x55, + 0x54, 0x4f, 0x5f, 0x55, 0x50, 0x44, 0x41, 0x54, 0x45, 0x5f, 0x41, 0x47, 0x45, 0x4e, 0x54, 0x5f, + 0x47, 0x52, 0x4f, 0x55, 0x50, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f, 0x44, 0x4f, 0x4e, 0x45, + 0x10, 0x03, 0x12, 0x2c, 0x0a, 0x28, 0x41, 0x55, 0x54, 0x4f, 0x5f, 0x55, 0x50, 0x44, 0x41, 0x54, + 0x45, 0x5f, 0x41, 0x47, 0x45, 0x4e, 0x54, 0x5f, 0x47, 0x52, 0x4f, 0x55, 0x50, 0x5f, 0x53, 0x54, + 0x41, 0x54, 0x45, 0x5f, 0x52, 0x4f, 0x4c, 0x4c, 0x45, 0x44, 0x42, 0x41, 0x43, 0x4b, 0x10, 0x04, + 0x42, 0x56, 0x5a, 0x54, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, + 0x72, 0x61, 0x76, 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x2f, 0x74, 0x65, 0x6c, + 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x6f, 0x2f, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2f, + 0x61, 0x75, 0x74, 0x6f, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x2f, 0x76, 0x31, 0x3b, 0x61, 0x75, + 0x74, 0x6f, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/api/gen/proto/go/teleport/identitycenter/v1/identitycenter.pb.go b/api/gen/proto/go/teleport/identitycenter/v1/identitycenter.pb.go index e9279a3f5446b..9a8580947c5b8 100644 --- a/api/gen/proto/go/teleport/identitycenter/v1/identitycenter.pb.go +++ b/api/gen/proto/go/teleport/identitycenter/v1/identitycenter.pb.go @@ -166,6 +166,9 @@ type PermissionSetInfo struct { // Role is an optional ARN indicating role provisioned to this account. May be // empty if the permission set is not provisioned or is not relevant in the Role string `protobuf:"bytes,3,opt,name=role,proto3" json:"role,omitempty"` + // AssignmentID is the name of a Teleport Account Assignment resource + // representing this permission set assigned to the enclosing Account. + AssignmentId string `protobuf:"bytes,4,opt,name=assignment_id,json=assignmentId,proto3" json:"assignment_id,omitempty"` } func (x *PermissionSetInfo) Reset() { @@ -219,6 +222,13 @@ func (x *PermissionSetInfo) GetRole() string { return "" } +func (x *PermissionSetInfo) GetAssignmentId() string { + if x != nil { + return x.AssignmentId + } + return "" +} + // AccountStatus represents any commonly-changing data about an Identity // Center account. type AccountStatus struct { @@ -257,7 +267,7 @@ func (*AccountStatus) Descriptor() ([]byte, []int) { return file_teleport_identitycenter_v1_identitycenter_proto_rawDescGZIP(), []int{1} } -// Account is an Identity-Ceneter-managed AWS account +// Account is an Identity-Center-managed AWS account type Account struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -1071,177 +1081,180 @@ var file_teleport_identitycenter_v1_identitycenter_proto_rawDesc = []byte{ 0x74, 0x69, 0x74, 0x79, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x1a, 0x21, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x2f, 0x76, 0x31, 0x2f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x22, 0x4d, 0x0a, 0x11, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x65, + 0x22, 0x72, 0x0a, 0x11, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x65, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x10, 0x0a, 0x03, 0x61, 0x72, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x61, 0x72, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x72, - 0x6f, 0x6c, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x72, 0x6f, 0x6c, 0x65, 0x22, - 0x0f, 0x0a, 0x0d, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, - 0x22, 0x8c, 0x02, 0x0a, 0x07, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x12, 0x0a, 0x04, - 0x6b, 0x69, 0x6e, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6b, 0x69, 0x6e, 0x64, - 0x12, 0x19, 0x0a, 0x08, 0x73, 0x75, 0x62, 0x5f, 0x6b, 0x69, 0x6e, 0x64, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x07, 0x73, 0x75, 0x62, 0x4b, 0x69, 0x6e, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x76, - 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x76, 0x65, - 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x38, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, - 0x61, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, - 0x72, 0x74, 0x2e, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x65, 0x74, - 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, - 0x3b, 0x0a, 0x04, 0x73, 0x70, 0x65, 0x63, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27, 0x2e, - 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, - 0x79, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x63, 0x63, 0x6f, 0x75, - 0x6e, 0x74, 0x53, 0x70, 0x65, 0x63, 0x52, 0x04, 0x73, 0x70, 0x65, 0x63, 0x12, 0x41, 0x0a, 0x06, - 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x74, - 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, - 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, - 0x74, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x22, - 0x95, 0x02, 0x0a, 0x0b, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x53, 0x70, 0x65, 0x63, 0x12, - 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, - 0x10, 0x0a, 0x03, 0x61, 0x72, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x61, 0x72, - 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, - 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, - 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1b, 0x0a, 0x09, 0x73, 0x74, 0x61, 0x72, 0x74, - 0x5f, 0x75, 0x72, 0x6c, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x73, 0x74, 0x61, 0x72, - 0x74, 0x55, 0x72, 0x6c, 0x12, 0x5d, 0x0a, 0x13, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, - 0x6f, 0x6e, 0x5f, 0x73, 0x65, 0x74, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x06, 0x20, 0x03, 0x28, - 0x0b, 0x32, 0x2d, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x69, 0x64, 0x65, - 0x6e, 0x74, 0x69, 0x74, 0x79, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x50, - 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x65, 0x74, 0x49, 0x6e, 0x66, 0x6f, - 0x52, 0x11, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x65, 0x74, 0x49, - 0x6e, 0x66, 0x6f, 0x12, 0x32, 0x0a, 0x15, 0x69, 0x73, 0x5f, 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x69, - 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6f, 0x77, 0x6e, 0x65, 0x72, 0x18, 0x07, 0x20, 0x01, - 0x28, 0x08, 0x52, 0x13, 0x69, 0x73, 0x4f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x4f, 0x77, 0x6e, 0x65, 0x72, 0x22, 0xd5, 0x01, 0x0a, 0x0d, 0x50, 0x65, 0x72, 0x6d, - 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x65, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6b, 0x69, 0x6e, - 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6b, 0x69, 0x6e, 0x64, 0x12, 0x19, 0x0a, - 0x08, 0x73, 0x75, 0x62, 0x5f, 0x6b, 0x69, 0x6e, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x07, 0x73, 0x75, 0x62, 0x4b, 0x69, 0x6e, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, - 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, - 0x6f, 0x6e, 0x12, 0x38, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x04, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, - 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, - 0x74, 0x61, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x41, 0x0a, 0x04, - 0x73, 0x70, 0x65, 0x63, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2d, 0x2e, 0x74, 0x65, 0x6c, - 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x63, 0x65, - 0x6e, 0x74, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, - 0x6f, 0x6e, 0x53, 0x65, 0x74, 0x53, 0x70, 0x65, 0x63, 0x52, 0x04, 0x73, 0x70, 0x65, 0x63, 0x22, - 0x5b, 0x0a, 0x11, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x65, 0x74, - 0x53, 0x70, 0x65, 0x63, 0x12, 0x10, 0x0a, 0x03, 0x61, 0x72, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x03, 0x61, 0x72, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, + 0x6f, 0x6c, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x72, 0x6f, 0x6c, 0x65, 0x12, + 0x23, 0x0a, 0x0d, 0x61, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x64, + 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x61, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, + 0x6e, 0x74, 0x49, 0x64, 0x22, 0x0f, 0x0a, 0x0d, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x53, + 0x74, 0x61, 0x74, 0x75, 0x73, 0x22, 0x8c, 0x02, 0x0a, 0x07, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, + 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6b, 0x69, 0x6e, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x04, 0x6b, 0x69, 0x6e, 0x64, 0x12, 0x19, 0x0a, 0x08, 0x73, 0x75, 0x62, 0x5f, 0x6b, 0x69, 0x6e, + 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x73, 0x75, 0x62, 0x4b, 0x69, 0x6e, 0x64, + 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x38, 0x0a, 0x08, 0x6d, 0x65, + 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x74, + 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x2e, 0x76, + 0x31, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, + 0x64, 0x61, 0x74, 0x61, 0x12, 0x3b, 0x0a, 0x04, 0x73, 0x70, 0x65, 0x63, 0x18, 0x05, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x69, 0x64, + 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, + 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x53, 0x70, 0x65, 0x63, 0x52, 0x04, 0x73, 0x70, 0x65, + 0x63, 0x12, 0x41, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x29, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x69, 0x64, 0x65, + 0x6e, 0x74, 0x69, 0x74, 0x79, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x41, + 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, + 0x61, 0x74, 0x75, 0x73, 0x22, 0x95, 0x02, 0x0a, 0x0b, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, + 0x53, 0x70, 0x65, 0x63, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x02, 0x69, 0x64, 0x12, 0x10, 0x0a, 0x03, 0x61, 0x72, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x03, 0x61, 0x72, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, - 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0xdd, 0x01, 0x0a, - 0x11, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, - 0x6e, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6b, 0x69, 0x6e, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x04, 0x6b, 0x69, 0x6e, 0x64, 0x12, 0x19, 0x0a, 0x08, 0x73, 0x75, 0x62, 0x5f, 0x6b, 0x69, - 0x6e, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x73, 0x75, 0x62, 0x4b, 0x69, 0x6e, - 0x64, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x38, 0x0a, 0x08, 0x6d, - 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, - 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x2e, - 0x76, 0x31, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x08, 0x6d, 0x65, 0x74, - 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x45, 0x0a, 0x04, 0x73, 0x70, 0x65, 0x63, 0x18, 0x05, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x31, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x69, - 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x2e, 0x76, 0x31, - 0x2e, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, - 0x6e, 0x74, 0x53, 0x70, 0x65, 0x63, 0x52, 0x04, 0x73, 0x70, 0x65, 0x63, 0x22, 0xc9, 0x01, 0x0a, - 0x15, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, - 0x6e, 0x74, 0x53, 0x70, 0x65, 0x63, 0x12, 0x18, 0x0a, 0x07, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, - 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, - 0x12, 0x54, 0x0a, 0x0e, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x73, - 0x65, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2d, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, + 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1b, 0x0a, 0x09, + 0x73, 0x74, 0x61, 0x72, 0x74, 0x5f, 0x75, 0x72, 0x6c, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x08, 0x73, 0x74, 0x61, 0x72, 0x74, 0x55, 0x72, 0x6c, 0x12, 0x5d, 0x0a, 0x13, 0x70, 0x65, 0x72, + 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x73, 0x65, 0x74, 0x5f, 0x69, 0x6e, 0x66, 0x6f, + 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2d, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, + 0x74, 0x2e, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, + 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x65, + 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x11, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, + 0x6e, 0x53, 0x65, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x32, 0x0a, 0x15, 0x69, 0x73, 0x5f, 0x6f, + 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6f, 0x77, 0x6e, 0x65, + 0x72, 0x18, 0x07, 0x20, 0x01, 0x28, 0x08, 0x52, 0x13, 0x69, 0x73, 0x4f, 0x72, 0x67, 0x61, 0x6e, + 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4f, 0x77, 0x6e, 0x65, 0x72, 0x22, 0xd5, 0x01, 0x0a, + 0x0d, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x65, 0x74, 0x12, 0x12, + 0x0a, 0x04, 0x6b, 0x69, 0x6e, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6b, 0x69, + 0x6e, 0x64, 0x12, 0x19, 0x0a, 0x08, 0x73, 0x75, 0x62, 0x5f, 0x6b, 0x69, 0x6e, 0x64, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x73, 0x75, 0x62, 0x4b, 0x69, 0x6e, 0x64, 0x12, 0x18, 0x0a, + 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, + 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x38, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, + 0x61, 0x74, 0x61, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x74, 0x65, 0x6c, 0x65, + 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x4d, + 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, + 0x61, 0x12, 0x41, 0x0a, 0x04, 0x73, 0x70, 0x65, 0x63, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x2d, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x69, 0x64, 0x65, 0x6e, 0x74, + 0x69, 0x74, 0x79, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x65, 0x72, + 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x65, 0x74, 0x53, 0x70, 0x65, 0x63, 0x52, 0x04, + 0x73, 0x70, 0x65, 0x63, 0x22, 0x5b, 0x0a, 0x11, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, + 0x6f, 0x6e, 0x53, 0x65, 0x74, 0x53, 0x70, 0x65, 0x63, 0x12, 0x10, 0x0a, 0x03, 0x61, 0x72, 0x6e, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x61, 0x72, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x6e, + 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, + 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, + 0x6e, 0x22, 0xdd, 0x01, 0x0a, 0x11, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x41, 0x73, 0x73, + 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6b, 0x69, 0x6e, 0x64, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6b, 0x69, 0x6e, 0x64, 0x12, 0x19, 0x0a, 0x08, 0x73, + 0x75, 0x62, 0x5f, 0x6b, 0x69, 0x6e, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x73, + 0x75, 0x62, 0x4b, 0x69, 0x6e, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, + 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, + 0x12, 0x38, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x04, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x68, 0x65, + 0x61, 0x64, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, + 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x45, 0x0a, 0x04, 0x73, 0x70, + 0x65, 0x63, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x31, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x63, 0x65, 0x6e, 0x74, - 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, - 0x53, 0x65, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x0d, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, - 0x69, 0x6f, 0x6e, 0x53, 0x65, 0x74, 0x12, 0x21, 0x0a, 0x0c, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, - 0x74, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x61, 0x63, - 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x61, 0x63, 0x63, - 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x61, - 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x49, 0x64, 0x22, 0xb0, 0x02, 0x0a, 0x13, 0x50, 0x72, 0x69, - 0x6e, 0x63, 0x69, 0x70, 0x61, 0x6c, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, - 0x12, 0x12, 0x0a, 0x04, 0x6b, 0x69, 0x6e, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, - 0x6b, 0x69, 0x6e, 0x64, 0x12, 0x19, 0x0a, 0x08, 0x73, 0x75, 0x62, 0x5f, 0x6b, 0x69, 0x6e, 0x64, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x73, 0x75, 0x62, 0x4b, 0x69, 0x6e, 0x64, 0x12, - 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x38, 0x0a, 0x08, 0x6d, 0x65, 0x74, - 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x74, 0x65, - 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x2e, 0x76, 0x31, - 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, - 0x61, 0x74, 0x61, 0x12, 0x47, 0x0a, 0x04, 0x73, 0x70, 0x65, 0x63, 0x18, 0x05, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x33, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x69, 0x64, 0x65, + 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x41, 0x73, 0x73, + 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x53, 0x70, 0x65, 0x63, 0x52, 0x04, 0x73, 0x70, 0x65, + 0x63, 0x22, 0xc9, 0x01, 0x0a, 0x15, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x41, 0x73, 0x73, + 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x53, 0x70, 0x65, 0x63, 0x12, 0x18, 0x0a, 0x07, 0x64, + 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x64, 0x69, + 0x73, 0x70, 0x6c, 0x61, 0x79, 0x12, 0x54, 0x0a, 0x0e, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, + 0x69, 0x6f, 0x6e, 0x5f, 0x73, 0x65, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2d, 0x2e, + 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, + 0x79, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x65, 0x72, 0x6d, 0x69, + 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x65, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x0d, 0x70, 0x65, + 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x65, 0x74, 0x12, 0x21, 0x0a, 0x0c, 0x61, + 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x0b, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1d, + 0x0a, 0x0a, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x09, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x49, 0x64, 0x22, 0xb0, 0x02, + 0x0a, 0x13, 0x50, 0x72, 0x69, 0x6e, 0x63, 0x69, 0x70, 0x61, 0x6c, 0x41, 0x73, 0x73, 0x69, 0x67, + 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6b, 0x69, 0x6e, 0x64, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x04, 0x6b, 0x69, 0x6e, 0x64, 0x12, 0x19, 0x0a, 0x08, 0x73, 0x75, 0x62, + 0x5f, 0x6b, 0x69, 0x6e, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x73, 0x75, 0x62, + 0x4b, 0x69, 0x6e, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x38, + 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x1c, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x68, 0x65, 0x61, 0x64, + 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x08, + 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x47, 0x0a, 0x04, 0x73, 0x70, 0x65, 0x63, + 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x33, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, + 0x74, 0x2e, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, + 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x72, 0x69, 0x6e, 0x63, 0x69, 0x70, 0x61, 0x6c, 0x41, 0x73, 0x73, + 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x53, 0x70, 0x65, 0x63, 0x52, 0x04, 0x73, 0x70, 0x65, + 0x63, 0x12, 0x4d, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x35, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x72, 0x69, 0x6e, 0x63, 0x69, 0x70, 0x61, 0x6c, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, - 0x6e, 0x74, 0x53, 0x70, 0x65, 0x63, 0x52, 0x04, 0x73, 0x70, 0x65, 0x63, 0x12, 0x4d, 0x0a, 0x06, - 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x35, 0x2e, 0x74, - 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, - 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x72, 0x69, 0x6e, 0x63, 0x69, - 0x70, 0x61, 0x6c, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x53, 0x74, 0x61, - 0x74, 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x22, 0xdd, 0x01, 0x0a, 0x17, - 0x50, 0x72, 0x69, 0x6e, 0x63, 0x69, 0x70, 0x61, 0x6c, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, - 0x65, 0x6e, 0x74, 0x53, 0x70, 0x65, 0x63, 0x12, 0x50, 0x0a, 0x0e, 0x70, 0x72, 0x69, 0x6e, 0x63, - 0x69, 0x70, 0x61, 0x6c, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, - 0x29, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x69, 0x64, 0x65, 0x6e, 0x74, - 0x69, 0x74, 0x79, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x72, 0x69, - 0x6e, 0x63, 0x69, 0x70, 0x61, 0x6c, 0x54, 0x79, 0x70, 0x65, 0x52, 0x0d, 0x70, 0x72, 0x69, 0x6e, - 0x63, 0x69, 0x70, 0x61, 0x6c, 0x54, 0x79, 0x70, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x70, 0x72, 0x69, - 0x6e, 0x63, 0x69, 0x70, 0x61, 0x6c, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x0b, 0x70, 0x72, 0x69, 0x6e, 0x63, 0x69, 0x70, 0x61, 0x6c, 0x49, 0x64, 0x12, 0x2c, 0x0a, 0x12, - 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x5f, 0x69, 0x64, 0x5f, 0x73, 0x6f, 0x75, 0x72, - 0x63, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, - 0x61, 0x6c, 0x49, 0x64, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x65, 0x78, - 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x5f, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x0a, 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x49, 0x64, 0x22, 0xb6, 0x01, 0x0a, 0x14, - 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, - 0x74, 0x52, 0x65, 0x66, 0x12, 0x1d, 0x0a, 0x0a, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5f, - 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, - 0x74, 0x49, 0x64, 0x12, 0x21, 0x0a, 0x0c, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x6e, - 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x61, 0x63, 0x63, 0x6f, 0x75, - 0x6e, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x2c, 0x0a, 0x12, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, - 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x73, 0x65, 0x74, 0x5f, 0x61, 0x72, 0x6e, 0x18, 0x03, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x10, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x65, - 0x74, 0x41, 0x72, 0x6e, 0x12, 0x2e, 0x0a, 0x13, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, - 0x6f, 0x6e, 0x5f, 0x73, 0x65, 0x74, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x11, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x65, 0x74, - 0x4e, 0x61, 0x6d, 0x65, 0x22, 0x87, 0x02, 0x0a, 0x19, 0x50, 0x72, 0x69, 0x6e, 0x63, 0x69, 0x70, - 0x61, 0x6c, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x53, 0x74, 0x61, 0x74, - 0x75, 0x73, 0x12, 0x5c, 0x0a, 0x12, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x69, - 0x6e, 0x67, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2d, - 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, - 0x74, 0x79, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x76, - 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x69, 0x6e, 0x67, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x11, 0x70, - 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x69, 0x6e, 0x67, 0x53, 0x74, 0x61, 0x74, 0x65, - 0x12, 0x52, 0x0a, 0x0b, 0x61, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x18, - 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x30, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, - 0x2e, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x2e, - 0x76, 0x31, 0x2e, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, - 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x66, 0x52, 0x0b, 0x61, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, - 0x65, 0x6e, 0x74, 0x73, 0x12, 0x22, 0x0a, 0x0c, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0c, 0x61, 0x70, 0x70, 0x6c, - 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, - 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x2a, 0x68, - 0x0a, 0x0d, 0x50, 0x72, 0x69, 0x6e, 0x63, 0x69, 0x70, 0x61, 0x6c, 0x54, 0x79, 0x70, 0x65, 0x12, - 0x1e, 0x0a, 0x1a, 0x50, 0x52, 0x49, 0x4e, 0x43, 0x49, 0x50, 0x41, 0x4c, 0x5f, 0x54, 0x59, 0x50, - 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, - 0x17, 0x0a, 0x13, 0x50, 0x52, 0x49, 0x4e, 0x43, 0x49, 0x50, 0x41, 0x4c, 0x5f, 0x54, 0x59, 0x50, - 0x45, 0x5f, 0x55, 0x53, 0x45, 0x52, 0x10, 0x01, 0x12, 0x1e, 0x0a, 0x1a, 0x50, 0x52, 0x49, 0x4e, - 0x43, 0x49, 0x50, 0x41, 0x4c, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x41, 0x43, 0x43, 0x45, 0x53, - 0x53, 0x5f, 0x4c, 0x49, 0x53, 0x54, 0x10, 0x02, 0x2a, 0x99, 0x01, 0x0a, 0x11, 0x50, 0x72, 0x6f, - 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x69, 0x6e, 0x67, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x22, - 0x0a, 0x1e, 0x50, 0x52, 0x4f, 0x56, 0x49, 0x53, 0x49, 0x4f, 0x4e, 0x49, 0x4e, 0x47, 0x5f, 0x53, - 0x54, 0x41, 0x54, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, - 0x10, 0x00, 0x12, 0x1c, 0x0a, 0x18, 0x50, 0x52, 0x4f, 0x56, 0x49, 0x53, 0x49, 0x4f, 0x4e, 0x49, - 0x4e, 0x47, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f, 0x53, 0x54, 0x41, 0x4c, 0x45, 0x10, 0x01, - 0x12, 0x22, 0x0a, 0x1e, 0x50, 0x52, 0x4f, 0x56, 0x49, 0x53, 0x49, 0x4f, 0x4e, 0x49, 0x4e, 0x47, - 0x5f, 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f, 0x50, 0x52, 0x4f, 0x56, 0x49, 0x53, 0x49, 0x4f, 0x4e, - 0x45, 0x44, 0x10, 0x02, 0x12, 0x1e, 0x0a, 0x1a, 0x50, 0x52, 0x4f, 0x56, 0x49, 0x53, 0x49, 0x4f, - 0x4e, 0x49, 0x4e, 0x47, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f, 0x44, 0x45, 0x4c, 0x45, 0x54, - 0x45, 0x44, 0x10, 0x03, 0x42, 0x60, 0x5a, 0x5e, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, - 0x6f, 0x6d, 0x2f, 0x67, 0x72, 0x61, 0x76, 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, - 0x2f, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x67, 0x65, - 0x6e, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x6f, 0x2f, 0x74, 0x65, 0x6c, 0x65, 0x70, - 0x6f, 0x72, 0x74, 0x2f, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x63, 0x65, 0x6e, 0x74, - 0x65, 0x72, 0x2f, 0x76, 0x31, 0x3b, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x63, 0x65, - 0x6e, 0x74, 0x65, 0x72, 0x76, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x6e, 0x74, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, + 0x22, 0xdd, 0x01, 0x0a, 0x17, 0x50, 0x72, 0x69, 0x6e, 0x63, 0x69, 0x70, 0x61, 0x6c, 0x41, 0x73, + 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x53, 0x70, 0x65, 0x63, 0x12, 0x50, 0x0a, 0x0e, + 0x70, 0x72, 0x69, 0x6e, 0x63, 0x69, 0x70, 0x61, 0x6c, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x0e, 0x32, 0x29, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, + 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x2e, 0x76, + 0x31, 0x2e, 0x50, 0x72, 0x69, 0x6e, 0x63, 0x69, 0x70, 0x61, 0x6c, 0x54, 0x79, 0x70, 0x65, 0x52, + 0x0d, 0x70, 0x72, 0x69, 0x6e, 0x63, 0x69, 0x70, 0x61, 0x6c, 0x54, 0x79, 0x70, 0x65, 0x12, 0x21, + 0x0a, 0x0c, 0x70, 0x72, 0x69, 0x6e, 0x63, 0x69, 0x70, 0x61, 0x6c, 0x5f, 0x69, 0x64, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x70, 0x72, 0x69, 0x6e, 0x63, 0x69, 0x70, 0x61, 0x6c, 0x49, + 0x64, 0x12, 0x2c, 0x0a, 0x12, 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x5f, 0x69, 0x64, + 0x5f, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, 0x65, + 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x49, 0x64, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, + 0x1f, 0x0a, 0x0b, 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x5f, 0x69, 0x64, 0x18, 0x04, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x49, 0x64, + 0x22, 0xb6, 0x01, 0x0a, 0x14, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x41, 0x73, 0x73, 0x69, + 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x66, 0x12, 0x1d, 0x0a, 0x0a, 0x61, 0x63, 0x63, + 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x61, + 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x49, 0x64, 0x12, 0x21, 0x0a, 0x0c, 0x61, 0x63, 0x63, 0x6f, + 0x75, 0x6e, 0x74, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, + 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x2c, 0x0a, 0x12, 0x70, + 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x73, 0x65, 0x74, 0x5f, 0x61, 0x72, + 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, + 0x69, 0x6f, 0x6e, 0x53, 0x65, 0x74, 0x41, 0x72, 0x6e, 0x12, 0x2e, 0x0a, 0x13, 0x70, 0x65, 0x72, + 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x73, 0x65, 0x74, 0x5f, 0x6e, 0x61, 0x6d, 0x65, + 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x11, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, + 0x6f, 0x6e, 0x53, 0x65, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0x87, 0x02, 0x0a, 0x19, 0x50, 0x72, + 0x69, 0x6e, 0x63, 0x69, 0x70, 0x61, 0x6c, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, + 0x74, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x5c, 0x0a, 0x12, 0x70, 0x72, 0x6f, 0x76, 0x69, + 0x73, 0x69, 0x6f, 0x6e, 0x69, 0x6e, 0x67, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x0e, 0x32, 0x2d, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x69, + 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x2e, 0x76, 0x31, + 0x2e, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x69, 0x6e, 0x67, 0x53, 0x74, 0x61, + 0x74, 0x65, 0x52, 0x11, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x69, 0x6e, 0x67, + 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x52, 0x0a, 0x0b, 0x61, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, + 0x65, 0x6e, 0x74, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x30, 0x2e, 0x74, 0x65, 0x6c, + 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x63, 0x65, + 0x6e, 0x74, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x41, + 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x66, 0x52, 0x0b, 0x61, 0x73, + 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x12, 0x22, 0x0a, 0x0c, 0x61, 0x70, 0x70, + 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, + 0x0c, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x14, 0x0a, + 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x72, + 0x72, 0x6f, 0x72, 0x2a, 0x68, 0x0a, 0x0d, 0x50, 0x72, 0x69, 0x6e, 0x63, 0x69, 0x70, 0x61, 0x6c, + 0x54, 0x79, 0x70, 0x65, 0x12, 0x1e, 0x0a, 0x1a, 0x50, 0x52, 0x49, 0x4e, 0x43, 0x49, 0x50, 0x41, + 0x4c, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, + 0x45, 0x44, 0x10, 0x00, 0x12, 0x17, 0x0a, 0x13, 0x50, 0x52, 0x49, 0x4e, 0x43, 0x49, 0x50, 0x41, + 0x4c, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x55, 0x53, 0x45, 0x52, 0x10, 0x01, 0x12, 0x1e, 0x0a, + 0x1a, 0x50, 0x52, 0x49, 0x4e, 0x43, 0x49, 0x50, 0x41, 0x4c, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, + 0x41, 0x43, 0x43, 0x45, 0x53, 0x53, 0x5f, 0x4c, 0x49, 0x53, 0x54, 0x10, 0x02, 0x2a, 0x99, 0x01, + 0x0a, 0x11, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x69, 0x6e, 0x67, 0x53, 0x74, + 0x61, 0x74, 0x65, 0x12, 0x22, 0x0a, 0x1e, 0x50, 0x52, 0x4f, 0x56, 0x49, 0x53, 0x49, 0x4f, 0x4e, + 0x49, 0x4e, 0x47, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, + 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x1c, 0x0a, 0x18, 0x50, 0x52, 0x4f, 0x56, 0x49, + 0x53, 0x49, 0x4f, 0x4e, 0x49, 0x4e, 0x47, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f, 0x53, 0x54, + 0x41, 0x4c, 0x45, 0x10, 0x01, 0x12, 0x22, 0x0a, 0x1e, 0x50, 0x52, 0x4f, 0x56, 0x49, 0x53, 0x49, + 0x4f, 0x4e, 0x49, 0x4e, 0x47, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f, 0x50, 0x52, 0x4f, 0x56, + 0x49, 0x53, 0x49, 0x4f, 0x4e, 0x45, 0x44, 0x10, 0x02, 0x12, 0x1e, 0x0a, 0x1a, 0x50, 0x52, 0x4f, + 0x56, 0x49, 0x53, 0x49, 0x4f, 0x4e, 0x49, 0x4e, 0x47, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f, + 0x44, 0x45, 0x4c, 0x45, 0x54, 0x45, 0x44, 0x10, 0x03, 0x42, 0x60, 0x5a, 0x5e, 0x67, 0x69, 0x74, + 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x72, 0x61, 0x76, 0x69, 0x74, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x2f, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x61, + 0x70, 0x69, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x6f, 0x2f, + 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, + 0x79, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x2f, 0x76, 0x31, 0x3b, 0x69, 0x64, 0x65, 0x6e, 0x74, + 0x69, 0x74, 0x79, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x33, } var ( diff --git a/api/gen/proto/go/teleport/workloadidentity/v1/resource.pb.go b/api/gen/proto/go/teleport/workloadidentity/v1/resource.pb.go new file mode 100644 index 0000000000000..fe09bd6c1039a --- /dev/null +++ b/api/gen/proto/go/teleport/workloadidentity/v1/resource.pb.go @@ -0,0 +1,523 @@ +// Copyright 2024 Gravitational, Inc +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.35.2 +// protoc (unknown) +// source: teleport/workloadidentity/v1/resource.proto + +package workloadidentityv1pb + +import ( + v1 "github.com/gravitational/teleport/api/gen/proto/go/teleport/header/v1" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +// WorkloadIdentity represents a single, or group of similar, workload +// identities and configures the structure of workload identity credentials and +// authorization rules. is a resource that represents the configuration of a trust +// domain federation. +type WorkloadIdentity struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The kind of resource represented. + Kind string `protobuf:"bytes,1,opt,name=kind,proto3" json:"kind,omitempty"` + // Differentiates variations of the same kind. All resources should + // contain one, even if it is never populated. + SubKind string `protobuf:"bytes,2,opt,name=sub_kind,json=subKind,proto3" json:"sub_kind,omitempty"` + // The version of the resource being represented. + Version string `protobuf:"bytes,3,opt,name=version,proto3" json:"version,omitempty"` + // Common metadata that all resources share. + Metadata *v1.Metadata `protobuf:"bytes,4,opt,name=metadata,proto3" json:"metadata,omitempty"` + // The configured properties of the WorkloadIdentity + Spec *WorkloadIdentitySpec `protobuf:"bytes,5,opt,name=spec,proto3" json:"spec,omitempty"` +} + +func (x *WorkloadIdentity) Reset() { + *x = WorkloadIdentity{} + mi := &file_teleport_workloadidentity_v1_resource_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *WorkloadIdentity) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*WorkloadIdentity) ProtoMessage() {} + +func (x *WorkloadIdentity) ProtoReflect() protoreflect.Message { + mi := &file_teleport_workloadidentity_v1_resource_proto_msgTypes[0] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use WorkloadIdentity.ProtoReflect.Descriptor instead. +func (*WorkloadIdentity) Descriptor() ([]byte, []int) { + return file_teleport_workloadidentity_v1_resource_proto_rawDescGZIP(), []int{0} +} + +func (x *WorkloadIdentity) GetKind() string { + if x != nil { + return x.Kind + } + return "" +} + +func (x *WorkloadIdentity) GetSubKind() string { + if x != nil { + return x.SubKind + } + return "" +} + +func (x *WorkloadIdentity) GetVersion() string { + if x != nil { + return x.Version + } + return "" +} + +func (x *WorkloadIdentity) GetMetadata() *v1.Metadata { + if x != nil { + return x.Metadata + } + return nil +} + +func (x *WorkloadIdentity) GetSpec() *WorkloadIdentitySpec { + if x != nil { + return x.Spec + } + return nil +} + +// The individual conditions that make up a rule. +type WorkloadIdentityCondition struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The name of the attribute to evaluate the condition against. + Attribute string `protobuf:"bytes,1,opt,name=attribute,proto3" json:"attribute,omitempty"` + // An exact string that the attribute must match. + Equals string `protobuf:"bytes,2,opt,name=equals,proto3" json:"equals,omitempty"` +} + +func (x *WorkloadIdentityCondition) Reset() { + *x = WorkloadIdentityCondition{} + mi := &file_teleport_workloadidentity_v1_resource_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *WorkloadIdentityCondition) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*WorkloadIdentityCondition) ProtoMessage() {} + +func (x *WorkloadIdentityCondition) ProtoReflect() protoreflect.Message { + mi := &file_teleport_workloadidentity_v1_resource_proto_msgTypes[1] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use WorkloadIdentityCondition.ProtoReflect.Descriptor instead. +func (*WorkloadIdentityCondition) Descriptor() ([]byte, []int) { + return file_teleport_workloadidentity_v1_resource_proto_rawDescGZIP(), []int{1} +} + +func (x *WorkloadIdentityCondition) GetAttribute() string { + if x != nil { + return x.Attribute + } + return "" +} + +func (x *WorkloadIdentityCondition) GetEquals() string { + if x != nil { + return x.Equals + } + return "" +} + +// An individual rule that is evaluated during the issuance of a WorkloadIdentity. +type WorkloadIdentityRule struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The conditions that must be met for this rule to be considered passed. + Conditions []*WorkloadIdentityCondition `protobuf:"bytes,1,rep,name=conditions,proto3" json:"conditions,omitempty"` +} + +func (x *WorkloadIdentityRule) Reset() { + *x = WorkloadIdentityRule{} + mi := &file_teleport_workloadidentity_v1_resource_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *WorkloadIdentityRule) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*WorkloadIdentityRule) ProtoMessage() {} + +func (x *WorkloadIdentityRule) ProtoReflect() protoreflect.Message { + mi := &file_teleport_workloadidentity_v1_resource_proto_msgTypes[2] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use WorkloadIdentityRule.ProtoReflect.Descriptor instead. +func (*WorkloadIdentityRule) Descriptor() ([]byte, []int) { + return file_teleport_workloadidentity_v1_resource_proto_rawDescGZIP(), []int{2} +} + +func (x *WorkloadIdentityRule) GetConditions() []*WorkloadIdentityCondition { + if x != nil { + return x.Conditions + } + return nil +} + +// The rules which are evaluated before the WorkloadIdentity can be issued. +type WorkloadIdentityRules struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // A list of rules used to determine if a WorkloadIdentity can be issued. + // If none are provided, it will be considered a pass. If any are provided, + // then at least one must pass for the rules to be considered passed. + Allow []*WorkloadIdentityRule `protobuf:"bytes,1,rep,name=allow,proto3" json:"allow,omitempty"` +} + +func (x *WorkloadIdentityRules) Reset() { + *x = WorkloadIdentityRules{} + mi := &file_teleport_workloadidentity_v1_resource_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *WorkloadIdentityRules) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*WorkloadIdentityRules) ProtoMessage() {} + +func (x *WorkloadIdentityRules) ProtoReflect() protoreflect.Message { + mi := &file_teleport_workloadidentity_v1_resource_proto_msgTypes[3] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use WorkloadIdentityRules.ProtoReflect.Descriptor instead. +func (*WorkloadIdentityRules) Descriptor() ([]byte, []int) { + return file_teleport_workloadidentity_v1_resource_proto_rawDescGZIP(), []int{3} +} + +func (x *WorkloadIdentityRules) GetAllow() []*WorkloadIdentityRule { + if x != nil { + return x.Allow + } + return nil +} + +// Configuration pertaining to the issuance of SPIFFE-compatible workload +// identity credentials. +type WorkloadIdentitySPIFFE struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The path of the SPIFFE ID that will be issued to the workload. + // + // This should be prefixed with a forward-slash ("/"). + // + // This field supports templating using attributes. + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + // A freeform text field which is provided to workloads along with a + // credential produced by this WorkloadIdentity. This can be used to provide + // additional context that can be used to select between multiple credentials. + Hint string `protobuf:"bytes,2,opt,name=hint,proto3" json:"hint,omitempty"` +} + +func (x *WorkloadIdentitySPIFFE) Reset() { + *x = WorkloadIdentitySPIFFE{} + mi := &file_teleport_workloadidentity_v1_resource_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *WorkloadIdentitySPIFFE) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*WorkloadIdentitySPIFFE) ProtoMessage() {} + +func (x *WorkloadIdentitySPIFFE) ProtoReflect() protoreflect.Message { + mi := &file_teleport_workloadidentity_v1_resource_proto_msgTypes[4] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use WorkloadIdentitySPIFFE.ProtoReflect.Descriptor instead. +func (*WorkloadIdentitySPIFFE) Descriptor() ([]byte, []int) { + return file_teleport_workloadidentity_v1_resource_proto_rawDescGZIP(), []int{4} +} + +func (x *WorkloadIdentitySPIFFE) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +func (x *WorkloadIdentitySPIFFE) GetHint() string { + if x != nil { + return x.Hint + } + return "" +} + +// The spec for the WorkloadIdentity resource. +type WorkloadIdentitySpec struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The rules which are evaluated before the WorkloadIdentity can be issued. + Rules *WorkloadIdentityRules `protobuf:"bytes,1,opt,name=rules,proto3" json:"rules,omitempty"` + // Configuration pertaining to the issuance of SPIFFE-compatible workload + // identity credentials. + Spiffe *WorkloadIdentitySPIFFE `protobuf:"bytes,2,opt,name=spiffe,proto3" json:"spiffe,omitempty"` +} + +func (x *WorkloadIdentitySpec) Reset() { + *x = WorkloadIdentitySpec{} + mi := &file_teleport_workloadidentity_v1_resource_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *WorkloadIdentitySpec) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*WorkloadIdentitySpec) ProtoMessage() {} + +func (x *WorkloadIdentitySpec) ProtoReflect() protoreflect.Message { + mi := &file_teleport_workloadidentity_v1_resource_proto_msgTypes[5] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use WorkloadIdentitySpec.ProtoReflect.Descriptor instead. +func (*WorkloadIdentitySpec) Descriptor() ([]byte, []int) { + return file_teleport_workloadidentity_v1_resource_proto_rawDescGZIP(), []int{5} +} + +func (x *WorkloadIdentitySpec) GetRules() *WorkloadIdentityRules { + if x != nil { + return x.Rules + } + return nil +} + +func (x *WorkloadIdentitySpec) GetSpiffe() *WorkloadIdentitySPIFFE { + if x != nil { + return x.Spiffe + } + return nil +} + +var File_teleport_workloadidentity_v1_resource_proto protoreflect.FileDescriptor + +var file_teleport_workloadidentity_v1_resource_proto_rawDesc = []byte{ + 0x0a, 0x2b, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x77, 0x6f, 0x72, 0x6b, 0x6c, + 0x6f, 0x61, 0x64, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x2f, 0x76, 0x31, 0x2f, 0x72, + 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x1c, 0x74, + 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x77, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, + 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x2e, 0x76, 0x31, 0x1a, 0x21, 0x74, 0x65, 0x6c, + 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x2f, 0x76, 0x31, 0x2f, + 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xdd, + 0x01, 0x0a, 0x10, 0x57, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x49, 0x64, 0x65, 0x6e, 0x74, + 0x69, 0x74, 0x79, 0x12, 0x12, 0x0a, 0x04, 0x6b, 0x69, 0x6e, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x04, 0x6b, 0x69, 0x6e, 0x64, 0x12, 0x19, 0x0a, 0x08, 0x73, 0x75, 0x62, 0x5f, 0x6b, + 0x69, 0x6e, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x73, 0x75, 0x62, 0x4b, 0x69, + 0x6e, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x38, 0x0a, 0x08, + 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, + 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, + 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x08, 0x6d, 0x65, + 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x46, 0x0a, 0x04, 0x73, 0x70, 0x65, 0x63, 0x18, 0x05, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x32, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, + 0x77, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, + 0x2e, 0x76, 0x31, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x49, 0x64, 0x65, 0x6e, + 0x74, 0x69, 0x74, 0x79, 0x53, 0x70, 0x65, 0x63, 0x52, 0x04, 0x73, 0x70, 0x65, 0x63, 0x22, 0x51, + 0x0a, 0x19, 0x57, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, + 0x74, 0x79, 0x43, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1c, 0x0a, 0x09, 0x61, + 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, + 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x65, 0x71, 0x75, + 0x61, 0x6c, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x65, 0x71, 0x75, 0x61, 0x6c, + 0x73, 0x22, 0x6f, 0x0a, 0x14, 0x57, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x49, 0x64, 0x65, + 0x6e, 0x74, 0x69, 0x74, 0x79, 0x52, 0x75, 0x6c, 0x65, 0x12, 0x57, 0x0a, 0x0a, 0x63, 0x6f, 0x6e, + 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x37, 0x2e, + 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x77, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, + 0x64, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x57, 0x6f, 0x72, + 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x43, 0x6f, 0x6e, + 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0a, 0x63, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, + 0x6e, 0x73, 0x22, 0x61, 0x0a, 0x15, 0x57, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x49, 0x64, + 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x12, 0x48, 0x0a, 0x05, 0x61, + 0x6c, 0x6c, 0x6f, 0x77, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x32, 0x2e, 0x74, 0x65, 0x6c, + 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x77, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x69, 0x64, + 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, + 0x61, 0x64, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x05, + 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x22, 0x3c, 0x0a, 0x16, 0x57, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, + 0x64, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x53, 0x50, 0x49, 0x46, 0x46, 0x45, 0x12, + 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, + 0x12, 0x0a, 0x04, 0x68, 0x69, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x68, + 0x69, 0x6e, 0x74, 0x22, 0xaf, 0x01, 0x0a, 0x14, 0x57, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, + 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x53, 0x70, 0x65, 0x63, 0x12, 0x49, 0x0a, 0x05, + 0x72, 0x75, 0x6c, 0x65, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x33, 0x2e, 0x74, 0x65, + 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x77, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x69, + 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x6c, + 0x6f, 0x61, 0x64, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x52, 0x75, 0x6c, 0x65, 0x73, + 0x52, 0x05, 0x72, 0x75, 0x6c, 0x65, 0x73, 0x12, 0x4c, 0x0a, 0x06, 0x73, 0x70, 0x69, 0x66, 0x66, + 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x34, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, + 0x72, 0x74, 0x2e, 0x77, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x69, 0x64, 0x65, 0x6e, 0x74, + 0x69, 0x74, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x49, + 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x53, 0x50, 0x49, 0x46, 0x46, 0x45, 0x52, 0x06, 0x73, + 0x70, 0x69, 0x66, 0x66, 0x65, 0x42, 0x66, 0x5a, 0x64, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, + 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x72, 0x61, 0x76, 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x61, + 0x6c, 0x2f, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x67, + 0x65, 0x6e, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x6f, 0x2f, 0x74, 0x65, 0x6c, 0x65, + 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x77, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x69, 0x64, 0x65, + 0x6e, 0x74, 0x69, 0x74, 0x79, 0x2f, 0x76, 0x31, 0x3b, 0x77, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, + 0x64, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x76, 0x31, 0x70, 0x62, 0x62, 0x06, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_teleport_workloadidentity_v1_resource_proto_rawDescOnce sync.Once + file_teleport_workloadidentity_v1_resource_proto_rawDescData = file_teleport_workloadidentity_v1_resource_proto_rawDesc +) + +func file_teleport_workloadidentity_v1_resource_proto_rawDescGZIP() []byte { + file_teleport_workloadidentity_v1_resource_proto_rawDescOnce.Do(func() { + file_teleport_workloadidentity_v1_resource_proto_rawDescData = protoimpl.X.CompressGZIP(file_teleport_workloadidentity_v1_resource_proto_rawDescData) + }) + return file_teleport_workloadidentity_v1_resource_proto_rawDescData +} + +var file_teleport_workloadidentity_v1_resource_proto_msgTypes = make([]protoimpl.MessageInfo, 6) +var file_teleport_workloadidentity_v1_resource_proto_goTypes = []any{ + (*WorkloadIdentity)(nil), // 0: teleport.workloadidentity.v1.WorkloadIdentity + (*WorkloadIdentityCondition)(nil), // 1: teleport.workloadidentity.v1.WorkloadIdentityCondition + (*WorkloadIdentityRule)(nil), // 2: teleport.workloadidentity.v1.WorkloadIdentityRule + (*WorkloadIdentityRules)(nil), // 3: teleport.workloadidentity.v1.WorkloadIdentityRules + (*WorkloadIdentitySPIFFE)(nil), // 4: teleport.workloadidentity.v1.WorkloadIdentitySPIFFE + (*WorkloadIdentitySpec)(nil), // 5: teleport.workloadidentity.v1.WorkloadIdentitySpec + (*v1.Metadata)(nil), // 6: teleport.header.v1.Metadata +} +var file_teleport_workloadidentity_v1_resource_proto_depIdxs = []int32{ + 6, // 0: teleport.workloadidentity.v1.WorkloadIdentity.metadata:type_name -> teleport.header.v1.Metadata + 5, // 1: teleport.workloadidentity.v1.WorkloadIdentity.spec:type_name -> teleport.workloadidentity.v1.WorkloadIdentitySpec + 1, // 2: teleport.workloadidentity.v1.WorkloadIdentityRule.conditions:type_name -> teleport.workloadidentity.v1.WorkloadIdentityCondition + 2, // 3: teleport.workloadidentity.v1.WorkloadIdentityRules.allow:type_name -> teleport.workloadidentity.v1.WorkloadIdentityRule + 3, // 4: teleport.workloadidentity.v1.WorkloadIdentitySpec.rules:type_name -> teleport.workloadidentity.v1.WorkloadIdentityRules + 4, // 5: teleport.workloadidentity.v1.WorkloadIdentitySpec.spiffe:type_name -> teleport.workloadidentity.v1.WorkloadIdentitySPIFFE + 6, // [6:6] is the sub-list for method output_type + 6, // [6:6] is the sub-list for method input_type + 6, // [6:6] is the sub-list for extension type_name + 6, // [6:6] is the sub-list for extension extendee + 0, // [0:6] is the sub-list for field type_name +} + +func init() { file_teleport_workloadidentity_v1_resource_proto_init() } +func file_teleport_workloadidentity_v1_resource_proto_init() { + if File_teleport_workloadidentity_v1_resource_proto != nil { + return + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_teleport_workloadidentity_v1_resource_proto_rawDesc, + NumEnums: 0, + NumMessages: 6, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_teleport_workloadidentity_v1_resource_proto_goTypes, + DependencyIndexes: file_teleport_workloadidentity_v1_resource_proto_depIdxs, + MessageInfos: file_teleport_workloadidentity_v1_resource_proto_msgTypes, + }.Build() + File_teleport_workloadidentity_v1_resource_proto = out.File + file_teleport_workloadidentity_v1_resource_proto_rawDesc = nil + file_teleport_workloadidentity_v1_resource_proto_goTypes = nil + file_teleport_workloadidentity_v1_resource_proto_depIdxs = nil +} diff --git a/api/gen/proto/go/teleport/workloadidentity/v1/resource_service.pb.go b/api/gen/proto/go/teleport/workloadidentity/v1/resource_service.pb.go new file mode 100644 index 0000000000000..155ff59be6106 --- /dev/null +++ b/api/gen/proto/go/teleport/workloadidentity/v1/resource_service.pb.go @@ -0,0 +1,580 @@ +// Copyright 2024 Gravitational, Inc +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.35.2 +// protoc (unknown) +// source: teleport/workloadidentity/v1/resource_service.proto + +package workloadidentityv1pb + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + emptypb "google.golang.org/protobuf/types/known/emptypb" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +// The request for CreateWorkloadIdentity. +type CreateWorkloadIdentityRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The workload identity to create. + WorkloadIdentity *WorkloadIdentity `protobuf:"bytes,1,opt,name=workload_identity,json=workloadIdentity,proto3" json:"workload_identity,omitempty"` +} + +func (x *CreateWorkloadIdentityRequest) Reset() { + *x = CreateWorkloadIdentityRequest{} + mi := &file_teleport_workloadidentity_v1_resource_service_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *CreateWorkloadIdentityRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CreateWorkloadIdentityRequest) ProtoMessage() {} + +func (x *CreateWorkloadIdentityRequest) ProtoReflect() protoreflect.Message { + mi := &file_teleport_workloadidentity_v1_resource_service_proto_msgTypes[0] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use CreateWorkloadIdentityRequest.ProtoReflect.Descriptor instead. +func (*CreateWorkloadIdentityRequest) Descriptor() ([]byte, []int) { + return file_teleport_workloadidentity_v1_resource_service_proto_rawDescGZIP(), []int{0} +} + +func (x *CreateWorkloadIdentityRequest) GetWorkloadIdentity() *WorkloadIdentity { + if x != nil { + return x.WorkloadIdentity + } + return nil +} + +// The request for UpdateWorkloadIdentity. +type UpdateWorkloadIdentityRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The workload identity to update. + WorkloadIdentity *WorkloadIdentity `protobuf:"bytes,1,opt,name=workload_identity,json=workloadIdentity,proto3" json:"workload_identity,omitempty"` +} + +func (x *UpdateWorkloadIdentityRequest) Reset() { + *x = UpdateWorkloadIdentityRequest{} + mi := &file_teleport_workloadidentity_v1_resource_service_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *UpdateWorkloadIdentityRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UpdateWorkloadIdentityRequest) ProtoMessage() {} + +func (x *UpdateWorkloadIdentityRequest) ProtoReflect() protoreflect.Message { + mi := &file_teleport_workloadidentity_v1_resource_service_proto_msgTypes[1] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use UpdateWorkloadIdentityRequest.ProtoReflect.Descriptor instead. +func (*UpdateWorkloadIdentityRequest) Descriptor() ([]byte, []int) { + return file_teleport_workloadidentity_v1_resource_service_proto_rawDescGZIP(), []int{1} +} + +func (x *UpdateWorkloadIdentityRequest) GetWorkloadIdentity() *WorkloadIdentity { + if x != nil { + return x.WorkloadIdentity + } + return nil +} + +// The request for UpsertWorkloadIdentityRequest. +type UpsertWorkloadIdentityRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The workload identity to upsert. + WorkloadIdentity *WorkloadIdentity `protobuf:"bytes,1,opt,name=workload_identity,json=workloadIdentity,proto3" json:"workload_identity,omitempty"` +} + +func (x *UpsertWorkloadIdentityRequest) Reset() { + *x = UpsertWorkloadIdentityRequest{} + mi := &file_teleport_workloadidentity_v1_resource_service_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *UpsertWorkloadIdentityRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UpsertWorkloadIdentityRequest) ProtoMessage() {} + +func (x *UpsertWorkloadIdentityRequest) ProtoReflect() protoreflect.Message { + mi := &file_teleport_workloadidentity_v1_resource_service_proto_msgTypes[2] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use UpsertWorkloadIdentityRequest.ProtoReflect.Descriptor instead. +func (*UpsertWorkloadIdentityRequest) Descriptor() ([]byte, []int) { + return file_teleport_workloadidentity_v1_resource_service_proto_rawDescGZIP(), []int{2} +} + +func (x *UpsertWorkloadIdentityRequest) GetWorkloadIdentity() *WorkloadIdentity { + if x != nil { + return x.WorkloadIdentity + } + return nil +} + +// The request for GetWorkloadIdentity. +type GetWorkloadIdentityRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The name of the workload identity to retrieve. + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` +} + +func (x *GetWorkloadIdentityRequest) Reset() { + *x = GetWorkloadIdentityRequest{} + mi := &file_teleport_workloadidentity_v1_resource_service_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *GetWorkloadIdentityRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetWorkloadIdentityRequest) ProtoMessage() {} + +func (x *GetWorkloadIdentityRequest) ProtoReflect() protoreflect.Message { + mi := &file_teleport_workloadidentity_v1_resource_service_proto_msgTypes[3] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetWorkloadIdentityRequest.ProtoReflect.Descriptor instead. +func (*GetWorkloadIdentityRequest) Descriptor() ([]byte, []int) { + return file_teleport_workloadidentity_v1_resource_service_proto_rawDescGZIP(), []int{3} +} + +func (x *GetWorkloadIdentityRequest) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +// The request for DeleteWorkloadIdentity. +type DeleteWorkloadIdentityRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The name of the workload identity to delete. + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` +} + +func (x *DeleteWorkloadIdentityRequest) Reset() { + *x = DeleteWorkloadIdentityRequest{} + mi := &file_teleport_workloadidentity_v1_resource_service_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *DeleteWorkloadIdentityRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DeleteWorkloadIdentityRequest) ProtoMessage() {} + +func (x *DeleteWorkloadIdentityRequest) ProtoReflect() protoreflect.Message { + mi := &file_teleport_workloadidentity_v1_resource_service_proto_msgTypes[4] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use DeleteWorkloadIdentityRequest.ProtoReflect.Descriptor instead. +func (*DeleteWorkloadIdentityRequest) Descriptor() ([]byte, []int) { + return file_teleport_workloadidentity_v1_resource_service_proto_rawDescGZIP(), []int{4} +} + +func (x *DeleteWorkloadIdentityRequest) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +// The request for ListWorkloadIdentities. +type ListWorkloadIdentitiesRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The maximum number of items to return. + // The server may impose a different page size at its discretion. + PageSize int32 `protobuf:"varint,1,opt,name=page_size,json=pageSize,proto3" json:"page_size,omitempty"` + // The page_token value returned from a previous ListWorkloadIdentities request, if any. + PageToken string `protobuf:"bytes,2,opt,name=page_token,json=pageToken,proto3" json:"page_token,omitempty"` +} + +func (x *ListWorkloadIdentitiesRequest) Reset() { + *x = ListWorkloadIdentitiesRequest{} + mi := &file_teleport_workloadidentity_v1_resource_service_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ListWorkloadIdentitiesRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListWorkloadIdentitiesRequest) ProtoMessage() {} + +func (x *ListWorkloadIdentitiesRequest) ProtoReflect() protoreflect.Message { + mi := &file_teleport_workloadidentity_v1_resource_service_proto_msgTypes[5] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ListWorkloadIdentitiesRequest.ProtoReflect.Descriptor instead. +func (*ListWorkloadIdentitiesRequest) Descriptor() ([]byte, []int) { + return file_teleport_workloadidentity_v1_resource_service_proto_rawDescGZIP(), []int{5} +} + +func (x *ListWorkloadIdentitiesRequest) GetPageSize() int32 { + if x != nil { + return x.PageSize + } + return 0 +} + +func (x *ListWorkloadIdentitiesRequest) GetPageToken() string { + if x != nil { + return x.PageToken + } + return "" +} + +// The response for ListWorkloadIdentities. +type ListWorkloadIdentitiesResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The page of workload identities that matched the request. + WorkloadIdentities []*WorkloadIdentity `protobuf:"bytes,1,rep,name=workload_identities,json=workloadIdentities,proto3" json:"workload_identities,omitempty"` + // Token to retrieve the next page of results, or empty if there are no + // more results in the list. + NextPageToken string `protobuf:"bytes,2,opt,name=next_page_token,json=nextPageToken,proto3" json:"next_page_token,omitempty"` +} + +func (x *ListWorkloadIdentitiesResponse) Reset() { + *x = ListWorkloadIdentitiesResponse{} + mi := &file_teleport_workloadidentity_v1_resource_service_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ListWorkloadIdentitiesResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListWorkloadIdentitiesResponse) ProtoMessage() {} + +func (x *ListWorkloadIdentitiesResponse) ProtoReflect() protoreflect.Message { + mi := &file_teleport_workloadidentity_v1_resource_service_proto_msgTypes[6] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ListWorkloadIdentitiesResponse.ProtoReflect.Descriptor instead. +func (*ListWorkloadIdentitiesResponse) Descriptor() ([]byte, []int) { + return file_teleport_workloadidentity_v1_resource_service_proto_rawDescGZIP(), []int{6} +} + +func (x *ListWorkloadIdentitiesResponse) GetWorkloadIdentities() []*WorkloadIdentity { + if x != nil { + return x.WorkloadIdentities + } + return nil +} + +func (x *ListWorkloadIdentitiesResponse) GetNextPageToken() string { + if x != nil { + return x.NextPageToken + } + return "" +} + +var File_teleport_workloadidentity_v1_resource_service_proto protoreflect.FileDescriptor + +var file_teleport_workloadidentity_v1_resource_service_proto_rawDesc = []byte{ + 0x0a, 0x33, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x77, 0x6f, 0x72, 0x6b, 0x6c, + 0x6f, 0x61, 0x64, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x2f, 0x76, 0x31, 0x2f, 0x72, + 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x1c, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, + 0x77, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, + 0x2e, 0x76, 0x31, 0x1a, 0x1b, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x65, 0x6d, 0x70, 0x74, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x1a, 0x2b, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x77, 0x6f, 0x72, 0x6b, 0x6c, + 0x6f, 0x61, 0x64, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x2f, 0x76, 0x31, 0x2f, 0x72, + 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x7c, 0x0a, + 0x1d, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x57, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x49, + 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x5b, + 0x0a, 0x11, 0x77, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x5f, 0x69, 0x64, 0x65, 0x6e, 0x74, + 0x69, 0x74, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2e, 0x2e, 0x74, 0x65, 0x6c, 0x65, + 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x77, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x69, 0x64, 0x65, + 0x6e, 0x74, 0x69, 0x74, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, + 0x64, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x52, 0x10, 0x77, 0x6f, 0x72, 0x6b, 0x6c, + 0x6f, 0x61, 0x64, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x22, 0x7c, 0x0a, 0x1d, 0x55, + 0x70, 0x64, 0x61, 0x74, 0x65, 0x57, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x49, 0x64, 0x65, + 0x6e, 0x74, 0x69, 0x74, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x5b, 0x0a, 0x11, + 0x77, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x5f, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, + 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2e, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, + 0x72, 0x74, 0x2e, 0x77, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x69, 0x64, 0x65, 0x6e, 0x74, + 0x69, 0x74, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x49, + 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x52, 0x10, 0x77, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, + 0x64, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x22, 0x7c, 0x0a, 0x1d, 0x55, 0x70, 0x73, + 0x65, 0x72, 0x74, 0x57, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x49, 0x64, 0x65, 0x6e, 0x74, + 0x69, 0x74, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x5b, 0x0a, 0x11, 0x77, 0x6f, + 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x5f, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2e, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, + 0x2e, 0x77, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, + 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x49, 0x64, 0x65, + 0x6e, 0x74, 0x69, 0x74, 0x79, 0x52, 0x10, 0x77, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x49, + 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x22, 0x30, 0x0a, 0x1a, 0x47, 0x65, 0x74, 0x57, 0x6f, + 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x33, 0x0a, 0x1d, 0x44, 0x65, 0x6c, + 0x65, 0x74, 0x65, 0x57, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x49, 0x64, 0x65, 0x6e, 0x74, + 0x69, 0x74, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, + 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x5b, + 0x0a, 0x1d, 0x4c, 0x69, 0x73, 0x74, 0x57, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x49, 0x64, + 0x65, 0x6e, 0x74, 0x69, 0x74, 0x69, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, + 0x1b, 0x0a, 0x09, 0x70, 0x61, 0x67, 0x65, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x05, 0x52, 0x08, 0x70, 0x61, 0x67, 0x65, 0x53, 0x69, 0x7a, 0x65, 0x12, 0x1d, 0x0a, 0x0a, + 0x70, 0x61, 0x67, 0x65, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x09, 0x70, 0x61, 0x67, 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0xa9, 0x01, 0x0a, 0x1e, + 0x4c, 0x69, 0x73, 0x74, 0x57, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x49, 0x64, 0x65, 0x6e, + 0x74, 0x69, 0x74, 0x69, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x5f, + 0x0a, 0x13, 0x77, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x5f, 0x69, 0x64, 0x65, 0x6e, 0x74, + 0x69, 0x74, 0x69, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2e, 0x2e, 0x74, 0x65, + 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x77, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x69, + 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x6c, + 0x6f, 0x61, 0x64, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x52, 0x12, 0x77, 0x6f, 0x72, + 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x69, 0x65, 0x73, 0x12, + 0x26, 0x0a, 0x0f, 0x6e, 0x65, 0x78, 0x74, 0x5f, 0x70, 0x61, 0x67, 0x65, 0x5f, 0x74, 0x6f, 0x6b, + 0x65, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x6e, 0x65, 0x78, 0x74, 0x50, 0x61, + 0x67, 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x32, 0xbf, 0x06, 0x0a, 0x1f, 0x57, 0x6f, 0x72, 0x6b, + 0x6c, 0x6f, 0x61, 0x64, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x52, 0x65, 0x73, 0x6f, + 0x75, 0x72, 0x63, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x85, 0x01, 0x0a, 0x16, + 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x57, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x49, 0x64, + 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x12, 0x3b, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, + 0x74, 0x2e, 0x77, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, + 0x74, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x57, 0x6f, 0x72, 0x6b, + 0x6c, 0x6f, 0x61, 0x64, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x2e, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x77, + 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x2e, + 0x76, 0x31, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x49, 0x64, 0x65, 0x6e, 0x74, + 0x69, 0x74, 0x79, 0x12, 0x85, 0x01, 0x0a, 0x16, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x57, 0x6f, + 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x12, 0x3b, + 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x77, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, + 0x61, 0x64, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x70, + 0x64, 0x61, 0x74, 0x65, 0x57, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x49, 0x64, 0x65, 0x6e, + 0x74, 0x69, 0x74, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2e, 0x2e, 0x74, 0x65, + 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x77, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x69, + 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x6c, + 0x6f, 0x61, 0x64, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x12, 0x85, 0x01, 0x0a, 0x16, + 0x55, 0x70, 0x73, 0x65, 0x72, 0x74, 0x57, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x49, 0x64, + 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x12, 0x3b, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, + 0x74, 0x2e, 0x77, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, + 0x74, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x70, 0x73, 0x65, 0x72, 0x74, 0x57, 0x6f, 0x72, 0x6b, + 0x6c, 0x6f, 0x61, 0x64, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x2e, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x77, + 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x2e, + 0x76, 0x31, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x49, 0x64, 0x65, 0x6e, 0x74, + 0x69, 0x74, 0x79, 0x12, 0x7f, 0x0a, 0x13, 0x47, 0x65, 0x74, 0x57, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, + 0x61, 0x64, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x12, 0x38, 0x2e, 0x74, 0x65, 0x6c, + 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x77, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x69, 0x64, + 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x57, 0x6f, 0x72, + 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2e, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, + 0x77, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, + 0x2e, 0x76, 0x31, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x49, 0x64, 0x65, 0x6e, + 0x74, 0x69, 0x74, 0x79, 0x12, 0x6d, 0x0a, 0x16, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x57, 0x6f, + 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x12, 0x3b, + 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x77, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, + 0x61, 0x64, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, + 0x6c, 0x65, 0x74, 0x65, 0x57, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x49, 0x64, 0x65, 0x6e, + 0x74, 0x69, 0x74, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, + 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, + 0x70, 0x74, 0x79, 0x12, 0x93, 0x01, 0x0a, 0x16, 0x4c, 0x69, 0x73, 0x74, 0x57, 0x6f, 0x72, 0x6b, + 0x6c, 0x6f, 0x61, 0x64, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x69, 0x65, 0x73, 0x12, 0x3b, + 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x77, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, + 0x61, 0x64, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, + 0x73, 0x74, 0x57, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, + 0x74, 0x69, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x3c, 0x2e, 0x74, 0x65, + 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x77, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x69, + 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x57, + 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x69, 0x65, + 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x66, 0x5a, 0x64, 0x67, 0x69, 0x74, + 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x72, 0x61, 0x76, 0x69, 0x74, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x2f, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x61, + 0x70, 0x69, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x6f, 0x2f, + 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x77, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, + 0x64, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x2f, 0x76, 0x31, 0x3b, 0x77, 0x6f, 0x72, + 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x76, 0x31, 0x70, + 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_teleport_workloadidentity_v1_resource_service_proto_rawDescOnce sync.Once + file_teleport_workloadidentity_v1_resource_service_proto_rawDescData = file_teleport_workloadidentity_v1_resource_service_proto_rawDesc +) + +func file_teleport_workloadidentity_v1_resource_service_proto_rawDescGZIP() []byte { + file_teleport_workloadidentity_v1_resource_service_proto_rawDescOnce.Do(func() { + file_teleport_workloadidentity_v1_resource_service_proto_rawDescData = protoimpl.X.CompressGZIP(file_teleport_workloadidentity_v1_resource_service_proto_rawDescData) + }) + return file_teleport_workloadidentity_v1_resource_service_proto_rawDescData +} + +var file_teleport_workloadidentity_v1_resource_service_proto_msgTypes = make([]protoimpl.MessageInfo, 7) +var file_teleport_workloadidentity_v1_resource_service_proto_goTypes = []any{ + (*CreateWorkloadIdentityRequest)(nil), // 0: teleport.workloadidentity.v1.CreateWorkloadIdentityRequest + (*UpdateWorkloadIdentityRequest)(nil), // 1: teleport.workloadidentity.v1.UpdateWorkloadIdentityRequest + (*UpsertWorkloadIdentityRequest)(nil), // 2: teleport.workloadidentity.v1.UpsertWorkloadIdentityRequest + (*GetWorkloadIdentityRequest)(nil), // 3: teleport.workloadidentity.v1.GetWorkloadIdentityRequest + (*DeleteWorkloadIdentityRequest)(nil), // 4: teleport.workloadidentity.v1.DeleteWorkloadIdentityRequest + (*ListWorkloadIdentitiesRequest)(nil), // 5: teleport.workloadidentity.v1.ListWorkloadIdentitiesRequest + (*ListWorkloadIdentitiesResponse)(nil), // 6: teleport.workloadidentity.v1.ListWorkloadIdentitiesResponse + (*WorkloadIdentity)(nil), // 7: teleport.workloadidentity.v1.WorkloadIdentity + (*emptypb.Empty)(nil), // 8: google.protobuf.Empty +} +var file_teleport_workloadidentity_v1_resource_service_proto_depIdxs = []int32{ + 7, // 0: teleport.workloadidentity.v1.CreateWorkloadIdentityRequest.workload_identity:type_name -> teleport.workloadidentity.v1.WorkloadIdentity + 7, // 1: teleport.workloadidentity.v1.UpdateWorkloadIdentityRequest.workload_identity:type_name -> teleport.workloadidentity.v1.WorkloadIdentity + 7, // 2: teleport.workloadidentity.v1.UpsertWorkloadIdentityRequest.workload_identity:type_name -> teleport.workloadidentity.v1.WorkloadIdentity + 7, // 3: teleport.workloadidentity.v1.ListWorkloadIdentitiesResponse.workload_identities:type_name -> teleport.workloadidentity.v1.WorkloadIdentity + 0, // 4: teleport.workloadidentity.v1.WorkloadIdentityResourceService.CreateWorkloadIdentity:input_type -> teleport.workloadidentity.v1.CreateWorkloadIdentityRequest + 1, // 5: teleport.workloadidentity.v1.WorkloadIdentityResourceService.UpdateWorkloadIdentity:input_type -> teleport.workloadidentity.v1.UpdateWorkloadIdentityRequest + 2, // 6: teleport.workloadidentity.v1.WorkloadIdentityResourceService.UpsertWorkloadIdentity:input_type -> teleport.workloadidentity.v1.UpsertWorkloadIdentityRequest + 3, // 7: teleport.workloadidentity.v1.WorkloadIdentityResourceService.GetWorkloadIdentity:input_type -> teleport.workloadidentity.v1.GetWorkloadIdentityRequest + 4, // 8: teleport.workloadidentity.v1.WorkloadIdentityResourceService.DeleteWorkloadIdentity:input_type -> teleport.workloadidentity.v1.DeleteWorkloadIdentityRequest + 5, // 9: teleport.workloadidentity.v1.WorkloadIdentityResourceService.ListWorkloadIdentities:input_type -> teleport.workloadidentity.v1.ListWorkloadIdentitiesRequest + 7, // 10: teleport.workloadidentity.v1.WorkloadIdentityResourceService.CreateWorkloadIdentity:output_type -> teleport.workloadidentity.v1.WorkloadIdentity + 7, // 11: teleport.workloadidentity.v1.WorkloadIdentityResourceService.UpdateWorkloadIdentity:output_type -> teleport.workloadidentity.v1.WorkloadIdentity + 7, // 12: teleport.workloadidentity.v1.WorkloadIdentityResourceService.UpsertWorkloadIdentity:output_type -> teleport.workloadidentity.v1.WorkloadIdentity + 7, // 13: teleport.workloadidentity.v1.WorkloadIdentityResourceService.GetWorkloadIdentity:output_type -> teleport.workloadidentity.v1.WorkloadIdentity + 8, // 14: teleport.workloadidentity.v1.WorkloadIdentityResourceService.DeleteWorkloadIdentity:output_type -> google.protobuf.Empty + 6, // 15: teleport.workloadidentity.v1.WorkloadIdentityResourceService.ListWorkloadIdentities:output_type -> teleport.workloadidentity.v1.ListWorkloadIdentitiesResponse + 10, // [10:16] is the sub-list for method output_type + 4, // [4:10] is the sub-list for method input_type + 4, // [4:4] is the sub-list for extension type_name + 4, // [4:4] is the sub-list for extension extendee + 0, // [0:4] is the sub-list for field type_name +} + +func init() { file_teleport_workloadidentity_v1_resource_service_proto_init() } +func file_teleport_workloadidentity_v1_resource_service_proto_init() { + if File_teleport_workloadidentity_v1_resource_service_proto != nil { + return + } + file_teleport_workloadidentity_v1_resource_proto_init() + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_teleport_workloadidentity_v1_resource_service_proto_rawDesc, + NumEnums: 0, + NumMessages: 7, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_teleport_workloadidentity_v1_resource_service_proto_goTypes, + DependencyIndexes: file_teleport_workloadidentity_v1_resource_service_proto_depIdxs, + MessageInfos: file_teleport_workloadidentity_v1_resource_service_proto_msgTypes, + }.Build() + File_teleport_workloadidentity_v1_resource_service_proto = out.File + file_teleport_workloadidentity_v1_resource_service_proto_rawDesc = nil + file_teleport_workloadidentity_v1_resource_service_proto_goTypes = nil + file_teleport_workloadidentity_v1_resource_service_proto_depIdxs = nil +} diff --git a/api/gen/proto/go/teleport/workloadidentity/v1/resource_service_grpc.pb.go b/api/gen/proto/go/teleport/workloadidentity/v1/resource_service_grpc.pb.go new file mode 100644 index 0000000000000..bd3492fee51ec --- /dev/null +++ b/api/gen/proto/go/teleport/workloadidentity/v1/resource_service_grpc.pb.go @@ -0,0 +1,361 @@ +// Copyright 2024 Gravitational, Inc +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Code generated by protoc-gen-go-grpc. DO NOT EDIT. +// versions: +// - protoc-gen-go-grpc v1.5.1 +// - protoc (unknown) +// source: teleport/workloadidentity/v1/resource_service.proto + +package workloadidentityv1pb + +import ( + context "context" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" + emptypb "google.golang.org/protobuf/types/known/emptypb" +) + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +// Requires gRPC-Go v1.64.0 or later. +const _ = grpc.SupportPackageIsVersion9 + +const ( + WorkloadIdentityResourceService_CreateWorkloadIdentity_FullMethodName = "/teleport.workloadidentity.v1.WorkloadIdentityResourceService/CreateWorkloadIdentity" + WorkloadIdentityResourceService_UpdateWorkloadIdentity_FullMethodName = "/teleport.workloadidentity.v1.WorkloadIdentityResourceService/UpdateWorkloadIdentity" + WorkloadIdentityResourceService_UpsertWorkloadIdentity_FullMethodName = "/teleport.workloadidentity.v1.WorkloadIdentityResourceService/UpsertWorkloadIdentity" + WorkloadIdentityResourceService_GetWorkloadIdentity_FullMethodName = "/teleport.workloadidentity.v1.WorkloadIdentityResourceService/GetWorkloadIdentity" + WorkloadIdentityResourceService_DeleteWorkloadIdentity_FullMethodName = "/teleport.workloadidentity.v1.WorkloadIdentityResourceService/DeleteWorkloadIdentity" + WorkloadIdentityResourceService_ListWorkloadIdentities_FullMethodName = "/teleport.workloadidentity.v1.WorkloadIdentityResourceService/ListWorkloadIdentities" +) + +// WorkloadIdentityResourceServiceClient is the client API for WorkloadIdentityResourceService service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. +// +// WorkloadIdentityResourceService provides methods to manage the +// WorkloadIdentity resource. +type WorkloadIdentityResourceServiceClient interface { + // CreateWorkloadIdentity creates a new workload identity, it will refuse to + // create a workload identity if one already exists with the same name. + CreateWorkloadIdentity(ctx context.Context, in *CreateWorkloadIdentityRequest, opts ...grpc.CallOption) (*WorkloadIdentity, error) + // UpdateWorkloadIdentity updates an existing workload identity, it will refuse + // to update a workload identity if one does not already exist with the same name. + // + // ConditionalUpdate semantics are applied, e.g, the update will only succeed + // if the revision of the provided WorkloadIdentity matches the revision of + // the existing WorkloadIdentity. + UpdateWorkloadIdentity(ctx context.Context, in *UpdateWorkloadIdentityRequest, opts ...grpc.CallOption) (*WorkloadIdentity, error) + // UpsertWorkloadIdentity creates or updates a workload identity. You should + // prefer to call Create or Update. + UpsertWorkloadIdentity(ctx context.Context, in *UpsertWorkloadIdentityRequest, opts ...grpc.CallOption) (*WorkloadIdentity, error) + // GetWorkloadIdentity retrieves a workload identity by name. + GetWorkloadIdentity(ctx context.Context, in *GetWorkloadIdentityRequest, opts ...grpc.CallOption) (*WorkloadIdentity, error) + // DeleteWorkloadIdentity deletes a workload identity by name. + DeleteWorkloadIdentity(ctx context.Context, in *DeleteWorkloadIdentityRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) + // ListWorkloadIdentities of all workload identities, pagination semantics are + // applied. + ListWorkloadIdentities(ctx context.Context, in *ListWorkloadIdentitiesRequest, opts ...grpc.CallOption) (*ListWorkloadIdentitiesResponse, error) +} + +type workloadIdentityResourceServiceClient struct { + cc grpc.ClientConnInterface +} + +func NewWorkloadIdentityResourceServiceClient(cc grpc.ClientConnInterface) WorkloadIdentityResourceServiceClient { + return &workloadIdentityResourceServiceClient{cc} +} + +func (c *workloadIdentityResourceServiceClient) CreateWorkloadIdentity(ctx context.Context, in *CreateWorkloadIdentityRequest, opts ...grpc.CallOption) (*WorkloadIdentity, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(WorkloadIdentity) + err := c.cc.Invoke(ctx, WorkloadIdentityResourceService_CreateWorkloadIdentity_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *workloadIdentityResourceServiceClient) UpdateWorkloadIdentity(ctx context.Context, in *UpdateWorkloadIdentityRequest, opts ...grpc.CallOption) (*WorkloadIdentity, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(WorkloadIdentity) + err := c.cc.Invoke(ctx, WorkloadIdentityResourceService_UpdateWorkloadIdentity_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *workloadIdentityResourceServiceClient) UpsertWorkloadIdentity(ctx context.Context, in *UpsertWorkloadIdentityRequest, opts ...grpc.CallOption) (*WorkloadIdentity, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(WorkloadIdentity) + err := c.cc.Invoke(ctx, WorkloadIdentityResourceService_UpsertWorkloadIdentity_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *workloadIdentityResourceServiceClient) GetWorkloadIdentity(ctx context.Context, in *GetWorkloadIdentityRequest, opts ...grpc.CallOption) (*WorkloadIdentity, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(WorkloadIdentity) + err := c.cc.Invoke(ctx, WorkloadIdentityResourceService_GetWorkloadIdentity_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *workloadIdentityResourceServiceClient) DeleteWorkloadIdentity(ctx context.Context, in *DeleteWorkloadIdentityRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(emptypb.Empty) + err := c.cc.Invoke(ctx, WorkloadIdentityResourceService_DeleteWorkloadIdentity_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *workloadIdentityResourceServiceClient) ListWorkloadIdentities(ctx context.Context, in *ListWorkloadIdentitiesRequest, opts ...grpc.CallOption) (*ListWorkloadIdentitiesResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(ListWorkloadIdentitiesResponse) + err := c.cc.Invoke(ctx, WorkloadIdentityResourceService_ListWorkloadIdentities_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +// WorkloadIdentityResourceServiceServer is the server API for WorkloadIdentityResourceService service. +// All implementations must embed UnimplementedWorkloadIdentityResourceServiceServer +// for forward compatibility. +// +// WorkloadIdentityResourceService provides methods to manage the +// WorkloadIdentity resource. +type WorkloadIdentityResourceServiceServer interface { + // CreateWorkloadIdentity creates a new workload identity, it will refuse to + // create a workload identity if one already exists with the same name. + CreateWorkloadIdentity(context.Context, *CreateWorkloadIdentityRequest) (*WorkloadIdentity, error) + // UpdateWorkloadIdentity updates an existing workload identity, it will refuse + // to update a workload identity if one does not already exist with the same name. + // + // ConditionalUpdate semantics are applied, e.g, the update will only succeed + // if the revision of the provided WorkloadIdentity matches the revision of + // the existing WorkloadIdentity. + UpdateWorkloadIdentity(context.Context, *UpdateWorkloadIdentityRequest) (*WorkloadIdentity, error) + // UpsertWorkloadIdentity creates or updates a workload identity. You should + // prefer to call Create or Update. + UpsertWorkloadIdentity(context.Context, *UpsertWorkloadIdentityRequest) (*WorkloadIdentity, error) + // GetWorkloadIdentity retrieves a workload identity by name. + GetWorkloadIdentity(context.Context, *GetWorkloadIdentityRequest) (*WorkloadIdentity, error) + // DeleteWorkloadIdentity deletes a workload identity by name. + DeleteWorkloadIdentity(context.Context, *DeleteWorkloadIdentityRequest) (*emptypb.Empty, error) + // ListWorkloadIdentities of all workload identities, pagination semantics are + // applied. + ListWorkloadIdentities(context.Context, *ListWorkloadIdentitiesRequest) (*ListWorkloadIdentitiesResponse, error) + mustEmbedUnimplementedWorkloadIdentityResourceServiceServer() +} + +// UnimplementedWorkloadIdentityResourceServiceServer must be embedded to have +// forward compatible implementations. +// +// NOTE: this should be embedded by value instead of pointer to avoid a nil +// pointer dereference when methods are called. +type UnimplementedWorkloadIdentityResourceServiceServer struct{} + +func (UnimplementedWorkloadIdentityResourceServiceServer) CreateWorkloadIdentity(context.Context, *CreateWorkloadIdentityRequest) (*WorkloadIdentity, error) { + return nil, status.Errorf(codes.Unimplemented, "method CreateWorkloadIdentity not implemented") +} +func (UnimplementedWorkloadIdentityResourceServiceServer) UpdateWorkloadIdentity(context.Context, *UpdateWorkloadIdentityRequest) (*WorkloadIdentity, error) { + return nil, status.Errorf(codes.Unimplemented, "method UpdateWorkloadIdentity not implemented") +} +func (UnimplementedWorkloadIdentityResourceServiceServer) UpsertWorkloadIdentity(context.Context, *UpsertWorkloadIdentityRequest) (*WorkloadIdentity, error) { + return nil, status.Errorf(codes.Unimplemented, "method UpsertWorkloadIdentity not implemented") +} +func (UnimplementedWorkloadIdentityResourceServiceServer) GetWorkloadIdentity(context.Context, *GetWorkloadIdentityRequest) (*WorkloadIdentity, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetWorkloadIdentity not implemented") +} +func (UnimplementedWorkloadIdentityResourceServiceServer) DeleteWorkloadIdentity(context.Context, *DeleteWorkloadIdentityRequest) (*emptypb.Empty, error) { + return nil, status.Errorf(codes.Unimplemented, "method DeleteWorkloadIdentity not implemented") +} +func (UnimplementedWorkloadIdentityResourceServiceServer) ListWorkloadIdentities(context.Context, *ListWorkloadIdentitiesRequest) (*ListWorkloadIdentitiesResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method ListWorkloadIdentities not implemented") +} +func (UnimplementedWorkloadIdentityResourceServiceServer) mustEmbedUnimplementedWorkloadIdentityResourceServiceServer() { +} +func (UnimplementedWorkloadIdentityResourceServiceServer) testEmbeddedByValue() {} + +// UnsafeWorkloadIdentityResourceServiceServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to WorkloadIdentityResourceServiceServer will +// result in compilation errors. +type UnsafeWorkloadIdentityResourceServiceServer interface { + mustEmbedUnimplementedWorkloadIdentityResourceServiceServer() +} + +func RegisterWorkloadIdentityResourceServiceServer(s grpc.ServiceRegistrar, srv WorkloadIdentityResourceServiceServer) { + // If the following call pancis, it indicates UnimplementedWorkloadIdentityResourceServiceServer was + // embedded by pointer and is nil. This will cause panics if an + // unimplemented method is ever invoked, so we test this at initialization + // time to prevent it from happening at runtime later due to I/O. + if t, ok := srv.(interface{ testEmbeddedByValue() }); ok { + t.testEmbeddedByValue() + } + s.RegisterService(&WorkloadIdentityResourceService_ServiceDesc, srv) +} + +func _WorkloadIdentityResourceService_CreateWorkloadIdentity_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(CreateWorkloadIdentityRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(WorkloadIdentityResourceServiceServer).CreateWorkloadIdentity(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: WorkloadIdentityResourceService_CreateWorkloadIdentity_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(WorkloadIdentityResourceServiceServer).CreateWorkloadIdentity(ctx, req.(*CreateWorkloadIdentityRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _WorkloadIdentityResourceService_UpdateWorkloadIdentity_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(UpdateWorkloadIdentityRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(WorkloadIdentityResourceServiceServer).UpdateWorkloadIdentity(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: WorkloadIdentityResourceService_UpdateWorkloadIdentity_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(WorkloadIdentityResourceServiceServer).UpdateWorkloadIdentity(ctx, req.(*UpdateWorkloadIdentityRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _WorkloadIdentityResourceService_UpsertWorkloadIdentity_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(UpsertWorkloadIdentityRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(WorkloadIdentityResourceServiceServer).UpsertWorkloadIdentity(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: WorkloadIdentityResourceService_UpsertWorkloadIdentity_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(WorkloadIdentityResourceServiceServer).UpsertWorkloadIdentity(ctx, req.(*UpsertWorkloadIdentityRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _WorkloadIdentityResourceService_GetWorkloadIdentity_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetWorkloadIdentityRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(WorkloadIdentityResourceServiceServer).GetWorkloadIdentity(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: WorkloadIdentityResourceService_GetWorkloadIdentity_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(WorkloadIdentityResourceServiceServer).GetWorkloadIdentity(ctx, req.(*GetWorkloadIdentityRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _WorkloadIdentityResourceService_DeleteWorkloadIdentity_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(DeleteWorkloadIdentityRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(WorkloadIdentityResourceServiceServer).DeleteWorkloadIdentity(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: WorkloadIdentityResourceService_DeleteWorkloadIdentity_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(WorkloadIdentityResourceServiceServer).DeleteWorkloadIdentity(ctx, req.(*DeleteWorkloadIdentityRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _WorkloadIdentityResourceService_ListWorkloadIdentities_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ListWorkloadIdentitiesRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(WorkloadIdentityResourceServiceServer).ListWorkloadIdentities(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: WorkloadIdentityResourceService_ListWorkloadIdentities_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(WorkloadIdentityResourceServiceServer).ListWorkloadIdentities(ctx, req.(*ListWorkloadIdentitiesRequest)) + } + return interceptor(ctx, in, info, handler) +} + +// WorkloadIdentityResourceService_ServiceDesc is the grpc.ServiceDesc for WorkloadIdentityResourceService service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var WorkloadIdentityResourceService_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "teleport.workloadidentity.v1.WorkloadIdentityResourceService", + HandlerType: (*WorkloadIdentityResourceServiceServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "CreateWorkloadIdentity", + Handler: _WorkloadIdentityResourceService_CreateWorkloadIdentity_Handler, + }, + { + MethodName: "UpdateWorkloadIdentity", + Handler: _WorkloadIdentityResourceService_UpdateWorkloadIdentity_Handler, + }, + { + MethodName: "UpsertWorkloadIdentity", + Handler: _WorkloadIdentityResourceService_UpsertWorkloadIdentity_Handler, + }, + { + MethodName: "GetWorkloadIdentity", + Handler: _WorkloadIdentityResourceService_GetWorkloadIdentity_Handler, + }, + { + MethodName: "DeleteWorkloadIdentity", + Handler: _WorkloadIdentityResourceService_DeleteWorkloadIdentity_Handler, + }, + { + MethodName: "ListWorkloadIdentities", + Handler: _WorkloadIdentityResourceService_ListWorkloadIdentities_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "teleport/workloadidentity/v1/resource_service.proto", +} diff --git a/api/go.mod b/api/go.mod index 6d69900733e2f..31e931385e11a 100644 --- a/api/go.mod +++ b/api/go.mod @@ -13,20 +13,20 @@ require ( github.com/jonboulle/clockwork v0.4.0 github.com/russellhaering/gosaml2 v0.9.1 github.com/stretchr/testify v1.10.0 - go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.55.0 - go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.55.0 - go.opentelemetry.io/otel v1.30.0 - go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.30.0 - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.30.0 - go.opentelemetry.io/otel/metric v1.30.0 - go.opentelemetry.io/otel/sdk v1.30.0 - go.opentelemetry.io/otel/trace v1.30.0 - go.opentelemetry.io/proto/otlp v1.3.1 + go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.57.0 + go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.57.0 + go.opentelemetry.io/otel v1.32.0 + go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.32.0 + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.32.0 + go.opentelemetry.io/otel/metric v1.32.0 + go.opentelemetry.io/otel/sdk v1.32.0 + go.opentelemetry.io/otel/trace v1.32.0 + go.opentelemetry.io/proto/otlp v1.4.0 golang.org/x/crypto v0.29.0 golang.org/x/exp v0.0.0-20241108190413-2d47ceb2692f golang.org/x/net v0.31.0 golang.org/x/term v0.26.0 - google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1 + google.golang.org/genproto/googleapis/rpc v0.0.0-20241118233622-e639e219e697 google.golang.org/grpc v1.68.0 google.golang.org/protobuf v1.35.2 gopkg.in/yaml.v2 v2.4.0 @@ -41,12 +41,12 @@ require ( github.com/go-logr/stdr v1.2.2 // indirect github.com/gobwas/httphead v0.1.0 // indirect github.com/gobwas/pool v0.2.1 // indirect - github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0 // indirect + github.com/grpc-ecosystem/grpc-gateway/v2 v2.24.0 // indirect github.com/mattermost/xml-roundtrip-validator v0.1.0 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/russellhaering/goxmldsig v1.4.0 // indirect golang.org/x/sys v0.27.0 // indirect golang.org/x/text v0.20.0 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20240903143218-8af14fe29dc1 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20241118233622-e639e219e697 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/api/go.sum b/api/go.sum index 40ba92bdc3a95..8d2982e63ce17 100644 --- a/api/go.sum +++ b/api/go.sum @@ -800,8 +800,8 @@ github.com/gravitational/trace v1.4.0/go.mod h1:g79NZzwCjWS/VVubYowaFAQsTjVTohGi github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= github.com/grpc-ecosystem/grpc-gateway/v2 v2.7.0/go.mod h1:hgWBS7lorOAVIJEQMi4ZsPv9hVvWI6+ch50m39Pf2Ks= github.com/grpc-ecosystem/grpc-gateway/v2 v2.11.3/go.mod h1:o//XUCC/F+yRGJoPO/VU0GSB0f8Nhgmxx0VIRUvaC0w= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0 h1:asbCHRVmodnJTuQ3qamDwqVOIjwqUPTYmYuemVOx+Ys= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0/go.mod h1:ggCgvZ2r7uOoQjOyu2Y1NhHmEPPzzuhWgcza5M1Ji1I= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.24.0 h1:TmHmbvxPmaegwhDubVz0lICL0J5Ka2vwTzhoePEXsGE= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.24.0/go.mod h1:qztMSjm835F2bXf+5HKAPIS5qsmQDqZna/PgVt4rWtI= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/iancoleman/strcase v0.2.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47ZCWhYzw7ho= @@ -861,8 +861,8 @@ github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFR github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE= github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= -github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= -github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= +github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII= +github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o= github.com/russellhaering/gosaml2 v0.9.1 h1:H/whrl8NuSoxyW46Ww5lKPskm+5K+qYLw9afqJ/Zef0= github.com/russellhaering/gosaml2 v0.9.1/go.mod h1:ja+qgbayxm+0mxBRLMSUuX3COqy+sb0RRhIGun/W2kc= github.com/russellhaering/goxmldsig v1.3.0/go.mod h1:gM4MDENBQf7M+V824SGfyIUVFWydB7n0KkEubVJl+Tw= @@ -905,27 +905,27 @@ go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= -go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.55.0 h1:hCq2hNMwsegUvPzI7sPOvtO9cqyy5GbWt/Ybp2xrx8Q= -go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.55.0/go.mod h1:LqaApwGx/oUmzsbqxkzuBvyoPpkxk3JQWnqfVrJ3wCA= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.55.0 h1:ZIg3ZT/aQ7AfKqdwp7ECpOK6vHqquXXuyTjIO8ZdmPs= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.55.0/go.mod h1:DQAwmETtZV00skUwgD6+0U89g80NKsJE3DCKeLLPQMI= -go.opentelemetry.io/otel v1.30.0 h1:F2t8sK4qf1fAmY9ua4ohFS/K+FUuOPemHUIXHtktrts= -go.opentelemetry.io/otel v1.30.0/go.mod h1:tFw4Br9b7fOS+uEao81PJjVMjW/5fvNCbpsDIXqP0pc= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.30.0 h1:lsInsfvhVIfOI6qHVyysXMNDnjO9Npvl7tlDPJFBVd4= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.30.0/go.mod h1:KQsVNh4OjgjTG0G6EiNi1jVpnaeeKsKMRwbLN+f1+8M= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.30.0 h1:m0yTiGDLUvVYaTFbAvCkVYIYcvwKt3G7OLoN77NUs/8= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.30.0/go.mod h1:wBQbT4UekBfegL2nx0Xk1vBcnzyBPsIVm9hRG4fYcr4= -go.opentelemetry.io/otel/metric v1.30.0 h1:4xNulvn9gjzo4hjg+wzIKG7iNFEaBMX00Qd4QIZs7+w= -go.opentelemetry.io/otel/metric v1.30.0/go.mod h1:aXTfST94tswhWEb+5QjlSqG+cZlmyXy/u8jFpor3WqQ= -go.opentelemetry.io/otel/sdk v1.30.0 h1:cHdik6irO49R5IysVhdn8oaiR9m8XluDaJAs4DfOrYE= -go.opentelemetry.io/otel/sdk v1.30.0/go.mod h1:p14X4Ok8S+sygzblytT1nqG98QG2KYKv++HE0LY/mhg= -go.opentelemetry.io/otel/trace v1.30.0 h1:7UBkkYzeg3C7kQX8VAidWh2biiQbtAKjyIML8dQ9wmc= -go.opentelemetry.io/otel/trace v1.30.0/go.mod h1:5EyKqTzzmyqB9bwtCCq6pDLktPK6fmGf/Dph+8VI02o= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.57.0 h1:qtFISDHKolvIxzSs0gIaiPUPR0Cucb0F2coHC7ZLdps= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.57.0/go.mod h1:Y+Pop1Q6hCOnETWTW4NROK/q1hv50hM7yDaUTjG8lp8= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.57.0 h1:DheMAlT6POBP+gh8RUH19EOTnQIor5QE0uSRPtzCpSw= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.57.0/go.mod h1:wZcGmeVO9nzP67aYSLDqXNWK87EZWhi7JWj1v7ZXf94= +go.opentelemetry.io/otel v1.32.0 h1:WnBN+Xjcteh0zdk01SVqV55d/m62NJLJdIyb4y/WO5U= +go.opentelemetry.io/otel v1.32.0/go.mod h1:00DCVSB0RQcnzlwyTfqtxSm+DRr9hpYrHjNGiBHVQIg= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.32.0 h1:IJFEoHiytixx8cMiVAO+GmHR6Frwu+u5Ur8njpFO6Ac= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.32.0/go.mod h1:3rHrKNtLIoS0oZwkY2vxi+oJcwFRWdtUyRII+so45p8= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.32.0 h1:9kV11HXBHZAvuPUZxmMWrH8hZn/6UnHX4K0mu36vNsU= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.32.0/go.mod h1:JyA0FHXe22E1NeNiHmVp7kFHglnexDQ7uRWDiiJ1hKQ= +go.opentelemetry.io/otel/metric v1.32.0 h1:xV2umtmNcThh2/a/aCP+h64Xx5wsj8qqnkYZktzNa0M= +go.opentelemetry.io/otel/metric v1.32.0/go.mod h1:jH7CIbbK6SH2V2wE16W05BHCtIDzauciCRLoc/SyMv8= +go.opentelemetry.io/otel/sdk v1.32.0 h1:RNxepc9vK59A8XsgZQouW8ue8Gkb4jpWtJm9ge5lEG4= +go.opentelemetry.io/otel/sdk v1.32.0/go.mod h1:LqgegDBjKMmb2GC6/PrTnteJG39I8/vJCAP9LlJXEjU= +go.opentelemetry.io/otel/trace v1.32.0 h1:WIC9mYrXf8TmY/EXuULKc8hR17vE+Hjv2cssQDe03fM= +go.opentelemetry.io/otel/trace v1.32.0/go.mod h1:+i4rkvCraA+tG6AzwloGaCtkx53Fa+L+V8e9a7YvhT8= go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= go.opentelemetry.io/proto/otlp v0.15.0/go.mod h1:H7XAot3MsfNsj7EXtrA2q5xSNQ10UqI405h3+duxN4U= go.opentelemetry.io/proto/otlp v0.19.0/go.mod h1:H7XAot3MsfNsj7EXtrA2q5xSNQ10UqI405h3+duxN4U= -go.opentelemetry.io/proto/otlp v1.3.1 h1:TrMUixzpM0yuc/znrFTP9MMRh8trP93mkCiDVeXrui0= -go.opentelemetry.io/proto/otlp v1.3.1/go.mod h1:0X1WI4de4ZsLrrJNLAQbFeLCm3T7yBkR0XqQ7niQU+8= +go.opentelemetry.io/proto/otlp v1.4.0 h1:TA9WRvW6zMwP+Ssb6fLoUIuirti1gGbP28GcKG1jgeg= +go.opentelemetry.io/proto/otlp v1.4.0/go.mod h1:PPBWZIP98o2ElSqI35IHfu7hIhSwvc5N38Jw8pXuGFY= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= @@ -1500,10 +1500,10 @@ google.golang.org/genproto v0.0.0-20230323212658-478b75c54725/go.mod h1:UUQDJDOl google.golang.org/genproto v0.0.0-20230330154414-c0448cd141ea/go.mod h1:UUQDJDOlWu4KYeJZffbWgBkS1YFobzKbLVfK69pe0Ak= google.golang.org/genproto v0.0.0-20230331144136-dcfb400f0633/go.mod h1:UUQDJDOlWu4KYeJZffbWgBkS1YFobzKbLVfK69pe0Ak= google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1/go.mod h1:nKE/iIaLqn2bQwXBg8f1g2Ylh6r5MN5CmZvuzZCgsCU= -google.golang.org/genproto/googleapis/api v0.0.0-20240903143218-8af14fe29dc1 h1:hjSy6tcFQZ171igDaN5QHOw2n6vx40juYbC/x67CEhc= -google.golang.org/genproto/googleapis/api v0.0.0-20240903143218-8af14fe29dc1/go.mod h1:qpvKtACPCQhAdu3PyQgV4l3LMXZEtft7y8QcarRsp9I= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1 h1:pPJltXNxVzT4pK9yD8vR9X75DaWYYmLGMsEvBfFQZzQ= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU= +google.golang.org/genproto/googleapis/api v0.0.0-20241118233622-e639e219e697 h1:pgr/4QbFyktUv9CtQ/Fq4gzEE6/Xs7iCXbktaGzLHbQ= +google.golang.org/genproto/googleapis/api v0.0.0-20241118233622-e639e219e697/go.mod h1:+D9ySVjN8nY8YCVjc5O7PZDIdZporIDY3KaGfJunh88= +google.golang.org/genproto/googleapis/rpc v0.0.0-20241118233622-e639e219e697 h1:LWZqQOEjDyONlF1H6afSWpAL/znlREo2tHfLoe+8LMA= +google.golang.org/genproto/googleapis/rpc v0.0.0-20241118233622-e639e219e697/go.mod h1:5uTbfoYQed2U9p3KIj2/Zzm02PYhndfdmML0qC3q3FU= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= diff --git a/api/proto/teleport/autoupdate/v1/autoupdate.proto b/api/proto/teleport/autoupdate/v1/autoupdate.proto index 5c7527d0177cf..5133f30f9983e 100644 --- a/api/proto/teleport/autoupdate/v1/autoupdate.proto +++ b/api/proto/teleport/autoupdate/v1/autoupdate.proto @@ -178,6 +178,12 @@ message AutoUpdateAgentRolloutStatusGroup { google.protobuf.Timestamp last_update_time = 4; // last_update_reason is the trigger for the last update string last_update_reason = 5; + // config_days when the update can run. Supported values are "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun" and "*" + repeated string config_days = 6; + // config_start_hour to initiate update + int32 config_start_hour = 7; + // config_wait_days after last group succeeds before this group can run. This can only be used when the strategy is "halt-on-failure". + int64 config_wait_days = 8; } // AutoUpdateAgentGroupState represents the agent group state. This state controls whether the agents from this group diff --git a/api/proto/teleport/identitycenter/v1/identitycenter.proto b/api/proto/teleport/identitycenter/v1/identitycenter.proto index 94efabeeb81a4..64c25c13aa27f 100644 --- a/api/proto/teleport/identitycenter/v1/identitycenter.proto +++ b/api/proto/teleport/identitycenter/v1/identitycenter.proto @@ -34,13 +34,17 @@ message PermissionSetInfo { // Role is an optional ARN indicating role provisioned to this account. May be // empty if the permission set is not provisioned or is not relevant in the string role = 3; + + // AssignmentID is the name of a Teleport Account Assignment resource + // representing this permission set assigned to the enclosing Account. + string assignment_id = 4; } // AccountStatus represents any commonly-changing data about an Identity // Center account. message AccountStatus {} -// Account is an Identity-Ceneter-managed AWS account +// Account is an Identity-Center-managed AWS account message Account { string kind = 1; string sub_kind = 2; diff --git a/api/proto/teleport/legacy/client/proto/authservice.proto b/api/proto/teleport/legacy/client/proto/authservice.proto index 9caaaafaee775..79eb5fc2b56d7 100644 --- a/api/proto/teleport/legacy/client/proto/authservice.proto +++ b/api/proto/teleport/legacy/client/proto/authservice.proto @@ -1940,6 +1940,60 @@ message CreateRegisterChallengeRequest { DeviceUsage DeviceUsage = 3 [(gogoproto.jsontag) = "device_usage,omitempty"]; } +// IdentityCenterAccount holds information about an Identity Center account +// within an IdentityCenterAccountAssignment +message IdentityCenterAccount { + // ID is the AWS-assigned account ID + string ID = 1; + + // ARN is the full Amazon Resource Name for the AWS account + string ARN = 2; + + // AccountName is the human-readable name of the account + string AccountName = 3; + + // Description is a free text description of the account + string Description = 4; +} + +// IdentityCenterPermissionSet holds information about an Identity Center +// permission set within an IdentityCenterAccountAssignment +message IdentityCenterPermissionSet { + // ARN is the full Amazon Resource Name for the Permission Set + string ARN = 1; + + // Name is the human readable name for the Permission Set + string Name = 2; +} + +// IdentityCenterAccountAssignment represents a requestable Identity Center +// Account Assignment. This is strictly a wire-format object for use with the +// Unfied resource cache, and the types defined in the `identitycenter` package +// should be used for actual processing. +message IdentityCenterAccountAssignment { + // Kind is the database server resource kind. + string Kind = 1 [(gogoproto.jsontag) = "kind"]; + // SubKind is an optional resource subkind. + string SubKind = 2 [(gogoproto.jsontag) = "sub_kind,omitempty"]; + // Version is the resource version. + string Version = 3 [(gogoproto.jsontag) = "version"]; + // Metadata is the account metadata. + types.Metadata Metadata = 4 [ + (gogoproto.nullable) = false, + (gogoproto.jsontag) = "metadata" + ]; + + // DisplayName is a human-readable name for the Account assignment + string DisplayName = 5; + + // Account is the Identity Center Account this assigment references + IdentityCenterAccount Account = 6; + + // PermissionSet is the Identity Center Permission Set this assignment + // references + IdentityCenterPermissionSet PermissionSet = 7; +} + // PaginatedResource represents one of the supported resources. message PaginatedResource { // Resource is the resource itself. @@ -1968,6 +2022,12 @@ message PaginatedResource { types.AppServerOrSAMLIdPServiceProviderV1 AppServerOrSAMLIdPServiceProvider = 11 [deprecated = true]; // SAMLIdPServiceProvider represents a SAML IdP service provider resource. types.SAMLIdPServiceProviderV1 SAMLIdPServiceProvider = 12 [(gogoproto.jsontag) = "saml_idp_service_provider,omitempty"]; + // GitServer represents a Git server resource. + types.ServerV2 git_server = 15; + + // IdentityCenterAccountAssignment represents a requestable Identity Center + // Account Assignment + IdentityCenterAccountAssignment IdentityCenterAccountAssignment = 16 [(gogoproto.jsontag) = "identity_center_account_assignment,omitempty"]; } // Logins allowed for the included resource. Only to be populated for SSH and Desktops. diff --git a/api/proto/teleport/legacy/client/proto/event.proto b/api/proto/teleport/legacy/client/proto/event.proto index 4c790ce6fdbc3..b8c39fec6054e 100644 --- a/api/proto/teleport/legacy/client/proto/event.proto +++ b/api/proto/teleport/legacy/client/proto/event.proto @@ -34,6 +34,7 @@ import "teleport/secreports/v1/secreports.proto"; import "teleport/userloginstate/v1/userloginstate.proto"; import "teleport/userprovisioning/v2/statichostuser.proto"; import "teleport/usertasks/v1/user_tasks.proto"; +import "teleport/workloadidentity/v1/resource.proto"; option go_package = "github.com/gravitational/teleport/api/client/proto"; @@ -208,5 +209,7 @@ message Event { teleport.identitycenter.v1.AccountAssignment IdentityCenterAccountAssignment = 74; // PluginStaticCredentials is filled in PluginStaticCredentials related events types.PluginStaticCredentialsV1 PluginStaticCredentials = 75; + // WorkloadIdentity is a resource for workload identity. + teleport.workloadidentity.v1.WorkloadIdentity WorkloadIdentity = 76; } } diff --git a/api/proto/teleport/legacy/types/events/events.proto b/api/proto/teleport/legacy/types/events/events.proto index 8b00c1749e45b..0829cd40aef10 100644 --- a/api/proto/teleport/legacy/types/events/events.proto +++ b/api/proto/teleport/legacy/types/events/events.proto @@ -1617,6 +1617,21 @@ message PortForward { // Addr is a target port forwarding address string Addr = 5 [(gogoproto.jsontag) = "addr"]; + + // KubernetesCluster has information about a kubernetes cluster, if + // applicable. + KubernetesClusterMetadata KubernetesCluster = 6 [ + (gogoproto.nullable) = false, + (gogoproto.embed) = true, + (gogoproto.jsontag) = "" + ]; + + // KubernetesPod has information about a kubernetes pod, if applicable. + KubernetesPodMetadata KubernetesPod = 7 [ + (gogoproto.nullable) = false, + (gogoproto.embed) = true, + (gogoproto.jsontag) = "" + ]; } // X11Forward is emitted when a user requests X11 protocol forwarding @@ -4687,6 +4702,11 @@ message OneOf { events.UserTaskUpdate UserTaskUpdate = 189; events.UserTaskDelete UserTaskDelete = 190; events.SFTPSummary SFTPSummary = 191; + events.ContactCreate ContactCreate = 192; + events.ContactDelete ContactDelete = 193; + events.WorkloadIdentityCreate WorkloadIdentityCreate = 194; + events.WorkloadIdentityUpdate WorkloadIdentityUpdate = 195; + events.WorkloadIdentityDelete WorkloadIdentityDelete = 196; } } @@ -7580,3 +7600,203 @@ message UserTaskDelete { (gogoproto.jsontag) = "" ]; } + +// ContactCreate is emitted when a contact is created. +message ContactCreate { + // Metadata is a common event metadata + Metadata Metadata = 1 [ + (gogoproto.nullable) = false, + (gogoproto.embed) = true, + (gogoproto.jsontag) = "" + ]; + + // ResourceMetadata is a common resource event metadata + ResourceMetadata Resource = 2 [ + (gogoproto.nullable) = false, + (gogoproto.embed) = true, + (gogoproto.jsontag) = "" + ]; + + // User is a common user event metadata + UserMetadata User = 3 [ + (gogoproto.nullable) = false, + (gogoproto.embed) = true, + (gogoproto.jsontag) = "" + ]; + + // ConnectionMetadata holds information about the connection + ConnectionMetadata Connection = 4 [ + (gogoproto.nullable) = false, + (gogoproto.embed) = true, + (gogoproto.jsontag) = "" + ]; + + // Status indicates whether the creation was successful. + Status Status = 5 [ + (gogoproto.nullable) = false, + (gogoproto.embed) = true, + (gogoproto.jsontag) = "" + ]; + + // Email is the Email of the contact being deleted + string Email = 6 [(gogoproto.jsontag) = "email"]; + + // ContactType is the type of the contact being deleted ('Business' or 'Security') + ContactType ContactType = 7 [(gogoproto.jsontag) = "contact_type"]; +} + +// ContactDelete is emitted when a contact is deleted. +message ContactDelete { + // Metadata is a common event metadata + Metadata Metadata = 1 [ + (gogoproto.nullable) = false, + (gogoproto.embed) = true, + (gogoproto.jsontag) = "" + ]; + + // ResourceMetadata is a common resource event metadata + ResourceMetadata Resource = 2 [ + (gogoproto.nullable) = false, + (gogoproto.embed) = true, + (gogoproto.jsontag) = "" + ]; + + // User is a common user event metadata + UserMetadata User = 3 [ + (gogoproto.nullable) = false, + (gogoproto.embed) = true, + (gogoproto.jsontag) = "" + ]; + + // ConnectionMetadata holds information about the connection + ConnectionMetadata Connection = 4 [ + (gogoproto.nullable) = false, + (gogoproto.embed) = true, + (gogoproto.jsontag) = "" + ]; + + // Status indicates whether the deletion was successful. + Status Status = 5 [ + (gogoproto.nullable) = false, + (gogoproto.embed) = true, + (gogoproto.jsontag) = "" + ]; + + // Email is the Email of the contact being deleted + string Email = 6 [(gogoproto.jsontag) = "email"]; + + // ContactType is the type of the contact being deleted ('Business' or 'Security') + ContactType ContactType = 7 [(gogoproto.jsontag) = "contact_type"]; +} + +// ContactType is the type of contact being added. +enum ContactType { + CONTACT_TYPE_UNSPECIFIED = 0; + CONTACT_TYPE_BUSINESS = 1; + CONTACT_TYPE_SECURITY = 2; +} + +// WorkloadIdentityCreate is emitted when a WorkloadIdentity is created. +message WorkloadIdentityCreate { + // Metadata is a common event metadata + Metadata Metadata = 1 [ + (gogoproto.nullable) = false, + (gogoproto.embed) = true, + (gogoproto.jsontag) = "" + ]; + + // ResourceMetadata is a common resource event metadata + ResourceMetadata Resource = 2 [ + (gogoproto.nullable) = false, + (gogoproto.embed) = true, + (gogoproto.jsontag) = "" + ]; + + // User is a common user event metadata + UserMetadata User = 3 [ + (gogoproto.nullable) = false, + (gogoproto.embed) = true, + (gogoproto.jsontag) = "" + ]; + + // ConnectionMetadata holds information about the connection + ConnectionMetadata Connection = 4 [ + (gogoproto.nullable) = false, + (gogoproto.embed) = true, + (gogoproto.jsontag) = "" + ]; + + // WorkloadIdentityData is a copy of the WorkloadIdentity resource + google.protobuf.Struct WorkloadIdentityData = 5 [ + (gogoproto.jsontag) = "workload_identity_data,omitempty", + (gogoproto.casttype) = "Struct" + ]; +} + +// WorkloadIdentityUpdate is emitted when a WorkloadIdentity is updated. +message WorkloadIdentityUpdate { + // Metadata is a common event metadata + Metadata Metadata = 1 [ + (gogoproto.nullable) = false, + (gogoproto.embed) = true, + (gogoproto.jsontag) = "" + ]; + + // ResourceMetadata is a common resource event metadata + ResourceMetadata Resource = 2 [ + (gogoproto.nullable) = false, + (gogoproto.embed) = true, + (gogoproto.jsontag) = "" + ]; + + // User is a common user event metadata + UserMetadata User = 3 [ + (gogoproto.nullable) = false, + (gogoproto.embed) = true, + (gogoproto.jsontag) = "" + ]; + + // ConnectionMetadata holds information about the connection + ConnectionMetadata Connection = 4 [ + (gogoproto.nullable) = false, + (gogoproto.embed) = true, + (gogoproto.jsontag) = "" + ]; + + // WorkloadIdentityData is a copy of the WorkloadIdentity resource + google.protobuf.Struct WorkloadIdentityData = 5 [ + (gogoproto.jsontag) = "workload_identity_data,omitempty", + (gogoproto.casttype) = "Struct" + ]; +} + +// WorkloadIdentityDelete is emitted when a WorkloadIdentity is deleted. +message WorkloadIdentityDelete { + // Metadata is a common event metadata + Metadata Metadata = 1 [ + (gogoproto.nullable) = false, + (gogoproto.embed) = true, + (gogoproto.jsontag) = "" + ]; + + // ResourceMetadata is a common resource event metadata + ResourceMetadata Resource = 2 [ + (gogoproto.nullable) = false, + (gogoproto.embed) = true, + (gogoproto.jsontag) = "" + ]; + + // User is a common user event metadata + UserMetadata User = 3 [ + (gogoproto.nullable) = false, + (gogoproto.embed) = true, + (gogoproto.jsontag) = "" + ]; + + // ConnectionMetadata holds information about the connection + ConnectionMetadata Connection = 4 [ + (gogoproto.nullable) = false, + (gogoproto.embed) = true, + (gogoproto.jsontag) = "" + ]; +} diff --git a/api/proto/teleport/legacy/types/types.proto b/api/proto/teleport/legacy/types/types.proto index 47461bb37b53c..530d8315a4bdf 100644 --- a/api/proto/teleport/legacy/types/types.proto +++ b/api/proto/teleport/legacy/types/types.proto @@ -1009,6 +1009,10 @@ message IdentityCenterPermissionSet { // Name is the human-readable name of the Permission Set. string Name = 2 [(gogoproto.jsontag) = "name,omitempty"]; + + // AssignmentID is the ID of the Teelport Account Assignment resource that + // represents this permission being assigned on the enclosing Account. + string AssignmentID = 3 [(gogoproto.jsontag) = "assignment_name,omitempty"]; } // AppIdentityCenter encapsulates information about an AWS Identity Center diff --git a/api/proto/teleport/workloadidentity/v1/resource.proto b/api/proto/teleport/workloadidentity/v1/resource.proto new file mode 100644 index 0000000000000..6bf73e0f07fab --- /dev/null +++ b/api/proto/teleport/workloadidentity/v1/resource.proto @@ -0,0 +1,85 @@ +// Copyright 2024 Gravitational, Inc +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +syntax = "proto3"; + +package teleport.workloadidentity.v1; + +import "teleport/header/v1/metadata.proto"; + +option go_package = "github.com/gravitational/teleport/api/gen/proto/go/teleport/workloadidentity/v1;workloadidentityv1pb"; + +// WorkloadIdentity represents a single, or group of similar, workload +// identities and configures the structure of workload identity credentials and +// authorization rules. is a resource that represents the configuration of a trust +// domain federation. +message WorkloadIdentity { + // The kind of resource represented. + string kind = 1; + // Differentiates variations of the same kind. All resources should + // contain one, even if it is never populated. + string sub_kind = 2; + // The version of the resource being represented. + string version = 3; + // Common metadata that all resources share. + teleport.header.v1.Metadata metadata = 4; + // The configured properties of the WorkloadIdentity + WorkloadIdentitySpec spec = 5; +} + +// The individual conditions that make up a rule. +message WorkloadIdentityCondition { + // The name of the attribute to evaluate the condition against. + string attribute = 1; + // An exact string that the attribute must match. + string equals = 2; +} + +// An individual rule that is evaluated during the issuance of a WorkloadIdentity. +message WorkloadIdentityRule { + // The conditions that must be met for this rule to be considered passed. + repeated WorkloadIdentityCondition conditions = 1; +} + +// The rules which are evaluated before the WorkloadIdentity can be issued. +message WorkloadIdentityRules { + // A list of rules used to determine if a WorkloadIdentity can be issued. + // If none are provided, it will be considered a pass. If any are provided, + // then at least one must pass for the rules to be considered passed. + repeated WorkloadIdentityRule allow = 1; +} + +// Configuration pertaining to the issuance of SPIFFE-compatible workload +// identity credentials. +message WorkloadIdentitySPIFFE { + // The path of the SPIFFE ID that will be issued to the workload. + // + // This should be prefixed with a forward-slash ("/"). + // + // This field supports templating using attributes. + string id = 1; + // A freeform text field which is provided to workloads along with a + // credential produced by this WorkloadIdentity. This can be used to provide + // additional context that can be used to select between multiple credentials. + string hint = 2; +} + +// The spec for the WorkloadIdentity resource. +message WorkloadIdentitySpec { + // The rules which are evaluated before the WorkloadIdentity can be issued. + WorkloadIdentityRules rules = 1; + // Configuration pertaining to the issuance of SPIFFE-compatible workload + // identity credentials. + WorkloadIdentitySPIFFE spiffe = 2; +} diff --git a/api/proto/teleport/workloadidentity/v1/resource_service.proto b/api/proto/teleport/workloadidentity/v1/resource_service.proto new file mode 100644 index 0000000000000..28351aefb6434 --- /dev/null +++ b/api/proto/teleport/workloadidentity/v1/resource_service.proto @@ -0,0 +1,95 @@ +// Copyright 2024 Gravitational, Inc +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +syntax = "proto3"; + +package teleport.workloadidentity.v1; + +import "google/protobuf/empty.proto"; +import "teleport/workloadidentity/v1/resource.proto"; + +option go_package = "github.com/gravitational/teleport/api/gen/proto/go/teleport/workloadidentity/v1;workloadidentityv1pb"; + +// WorkloadIdentityResourceService provides methods to manage the +// WorkloadIdentity resource. +service WorkloadIdentityResourceService { + // CreateWorkloadIdentity creates a new workload identity, it will refuse to + // create a workload identity if one already exists with the same name. + rpc CreateWorkloadIdentity(CreateWorkloadIdentityRequest) returns (WorkloadIdentity); + // UpdateWorkloadIdentity updates an existing workload identity, it will refuse + // to update a workload identity if one does not already exist with the same name. + // + // ConditionalUpdate semantics are applied, e.g, the update will only succeed + // if the revision of the provided WorkloadIdentity matches the revision of + // the existing WorkloadIdentity. + rpc UpdateWorkloadIdentity(UpdateWorkloadIdentityRequest) returns (WorkloadIdentity); + // UpsertWorkloadIdentity creates or updates a workload identity. You should + // prefer to call Create or Update. + rpc UpsertWorkloadIdentity(UpsertWorkloadIdentityRequest) returns (WorkloadIdentity); + // GetWorkloadIdentity retrieves a workload identity by name. + rpc GetWorkloadIdentity(GetWorkloadIdentityRequest) returns (WorkloadIdentity); + // DeleteWorkloadIdentity deletes a workload identity by name. + rpc DeleteWorkloadIdentity(DeleteWorkloadIdentityRequest) returns (google.protobuf.Empty); + // ListWorkloadIdentities of all workload identities, pagination semantics are + // applied. + rpc ListWorkloadIdentities(ListWorkloadIdentitiesRequest) returns (ListWorkloadIdentitiesResponse); +} + +// The request for CreateWorkloadIdentity. +message CreateWorkloadIdentityRequest { + // The workload identity to create. + WorkloadIdentity workload_identity = 1; +} + +// The request for UpdateWorkloadIdentity. +message UpdateWorkloadIdentityRequest { + // The workload identity to update. + WorkloadIdentity workload_identity = 1; +} + +// The request for UpsertWorkloadIdentityRequest. +message UpsertWorkloadIdentityRequest { + // The workload identity to upsert. + WorkloadIdentity workload_identity = 1; +} + +// The request for GetWorkloadIdentity. +message GetWorkloadIdentityRequest { + // The name of the workload identity to retrieve. + string name = 1; +} + +// The request for DeleteWorkloadIdentity. +message DeleteWorkloadIdentityRequest { + // The name of the workload identity to delete. + string name = 1; +} + +// The request for ListWorkloadIdentities. +message ListWorkloadIdentitiesRequest { + // The maximum number of items to return. + // The server may impose a different page size at its discretion. + int32 page_size = 1; + // The page_token value returned from a previous ListWorkloadIdentities request, if any. + string page_token = 2; +} + +// The response for ListWorkloadIdentities. +message ListWorkloadIdentitiesResponse { + // The page of workload identities that matched the request. + repeated WorkloadIdentity workload_identities = 1; + // Token to retrieve the next page of results, or empty if there are no + // more results in the list. + string next_page_token = 2; +} diff --git a/api/types/app.go b/api/types/app.go index 7452d35879815..75b6283d2e514 100644 --- a/api/types/app.go +++ b/api/types/app.go @@ -91,6 +91,8 @@ type Application interface { GetTCPPorts() []*PortRange // SetTCPPorts sets port ranges to which connections can be forwarded to. SetTCPPorts([]*PortRange) + // GetIdentityCenter fetches identity center info for the app, if any. + GetIdentityCenter() *AppIdentityCenter } // NewAppV3 creates a new app resource. @@ -456,6 +458,23 @@ func (a *AppV3) checkTCPPorts() error { return nil } +// GetIdentityCenter returns the Identity Center information for the app, if any. +// May be nil. +func (a *AppV3) GetIdentityCenter() *AppIdentityCenter { + return a.Spec.IdentityCenter +} + +// GetDisplayName fetches a human-readable display name for the App. +func (a *AppV3) GetDisplayName() string { + // Only Identity Center apps have a display name at this point. Returning + // the empty string signals to the caller they should fall back to whatever + // they have been using in the past. + if a.Spec.IdentityCenter == nil { + return "" + } + return a.GetName() +} + // IsEqual determines if two application resources are equivalent to one another. func (a *AppV3) IsEqual(i Application) bool { if other, ok := i.(*AppV3); ok { @@ -509,3 +528,12 @@ func (a Apps) Less(i, j int) bool { return a[i].GetName() < a[j].GetName() } // Swap swaps two apps. func (a Apps) Swap(i, j int) { a[i], a[j] = a[j], a[i] } + +// GetPermissionSets fetches the list of permission sets from the Identity Center +// app information. Handles nil identity center values. +func (a *AppIdentityCenter) GetPermissionSets() []*IdentityCenterPermissionSet { + if a == nil { + return nil + } + return a.PermissionSets +} diff --git a/api/types/appserver.go b/api/types/appserver.go index b3ce94c684697..f2094e25391af 100644 --- a/api/types/appserver.go +++ b/api/types/appserver.go @@ -86,13 +86,15 @@ func NewAppServerV3FromApp(app *AppV3, hostname, hostID string) (*AppServerV3, e // NewAppServerForAWSOIDCIntegration creates a new AppServer that will be used to grant AWS App Access // using the AWSOIDC credentials. -func NewAppServerForAWSOIDCIntegration(integrationName, hostID, publicAddr string) (*AppServerV3, error) { +func NewAppServerForAWSOIDCIntegration(integrationName, hostID, publicAddr string, labels map[string]string) (*AppServerV3, error) { return NewAppServerV3(Metadata{ - Name: integrationName, + Name: integrationName, + Labels: labels, }, AppServerSpecV3{ HostID: hostID, App: &AppV3{Metadata: Metadata{ - Name: integrationName, + Name: integrationName, + Labels: labels, }, Spec: AppSpecV3{ URI: constants.AWSConsoleURL, Integration: integrationName, diff --git a/api/types/appserver_test.go b/api/types/appserver_test.go index 74a0ab661f7dd..25fa31f6d4d63 100644 --- a/api/types/appserver_test.go +++ b/api/types/appserver_test.go @@ -63,6 +63,7 @@ func TestNewAppServerForAWSOIDCIntegration(t *testing.T) { integratioName string hostID string publicAddr string + labels map[string]string expectedApp *AppServerV3 errCheck require.ErrorAssertionFunc }{ @@ -71,12 +72,14 @@ func TestNewAppServerForAWSOIDCIntegration(t *testing.T) { integratioName: "valid", hostID: "my-host-id", publicAddr: "valid.proxy.example.com", + labels: map[string]string{"account_id": "123456789012"}, expectedApp: &AppServerV3{ Kind: KindAppServer, Version: V3, Metadata: Metadata{ Name: "valid", Namespace: "default", + Labels: map[string]string{"account_id": "123456789012"}, }, Spec: AppServerSpecV3{ Version: api.Version, @@ -87,6 +90,7 @@ func TestNewAppServerForAWSOIDCIntegration(t *testing.T) { Metadata: Metadata{ Name: "valid", Namespace: "default", + Labels: map[string]string{"account_id": "123456789012"}, }, Spec: AppSpecV3{ URI: "https://console.aws.amazon.com", @@ -106,7 +110,7 @@ func TestNewAppServerForAWSOIDCIntegration(t *testing.T) { }, } { t.Run(tt.name, func(t *testing.T) { - app, err := NewAppServerForAWSOIDCIntegration(tt.integratioName, tt.hostID, tt.publicAddr) + app, err := NewAppServerForAWSOIDCIntegration(tt.integratioName, tt.hostID, tt.publicAddr, tt.labels) if tt.errCheck != nil { tt.errCheck(t, err) } diff --git a/api/types/constants.go b/api/types/constants.go index e8beb81d0bec0..0035a69dddbde 100644 --- a/api/types/constants.go +++ b/api/types/constants.go @@ -21,6 +21,11 @@ import ( ) const ( + // The `Kind*` constants in this const block identify resource kinds used for + // storage an/or and access control. Please keep these in sync with the + // `ResourceKind` enum in + // `web/packages/teleport/src/services/resources/types.ts`. + // DefaultAPIGroup is a default group of permissions API, // lets us to add different permission types DefaultAPIGroup = "gravitational.io/teleport" @@ -597,6 +602,9 @@ const ( // for Teleport Enterprise customers. KindContact = "contact" + // KindWorkloadIdentity is the WorkloadIdentity resource. + KindWorkloadIdentity = "workload_identity" + // KindGitServer represents a Git server that can proxy git commands. KindGitServer = "git_server" // SubKindGitHub specifies the GitHub subkind of a Git server. diff --git a/api/types/derived.gen.go b/api/types/derived.gen.go index ff9e3f2fe07c0..ee13f9580a399 100644 --- a/api/types/derived.gen.go +++ b/api/types/derived.gen.go @@ -648,5 +648,6 @@ func deriveTeleportEqual_41(this, that *IdentityCenterPermissionSet) bool { return (this == nil && that == nil) || this != nil && that != nil && this.ARN == that.ARN && - this.Name == that.Name + this.Name == that.Name && + this.AssignmentID == that.AssignmentID } diff --git a/api/types/events/events.go b/api/types/events/events.go index 19cc44b5e8981..c4222057a3a18 100644 --- a/api/types/events/events.go +++ b/api/types/events/events.go @@ -2352,3 +2352,53 @@ func (m *AutoUpdateVersionUpdate) TrimToMaxSize(_ int) AuditEvent { func (m *AutoUpdateVersionDelete) TrimToMaxSize(_ int) AuditEvent { return m } + +func (m *ContactCreate) TrimToMaxSize(_ int) AuditEvent { + return m +} + +func (m *ContactDelete) TrimToMaxSize(_ int) AuditEvent { + return m +} + +func (m *WorkloadIdentityCreate) TrimToMaxSize(maxSize int) AuditEvent { + size := m.Size() + if size <= maxSize { + return m + } + + out := utils.CloneProtoMsg(m) + out.WorkloadIdentityData = nil + + maxSize = adjustedMaxSize(out, maxSize) + + customFieldsCount := m.WorkloadIdentityData.nonEmptyStrs() + maxFieldsSize := maxSizePerField(maxSize, customFieldsCount) + + out.WorkloadIdentityData = m.WorkloadIdentityData.trimToMaxSize(maxFieldsSize) + + return out +} + +func (m *WorkloadIdentityUpdate) TrimToMaxSize(maxSize int) AuditEvent { + size := m.Size() + if size <= maxSize { + return m + } + + out := utils.CloneProtoMsg(m) + out.WorkloadIdentityData = nil + + maxSize = adjustedMaxSize(out, maxSize) + + customFieldsCount := m.WorkloadIdentityData.nonEmptyStrs() + maxFieldsSize := maxSizePerField(maxSize, customFieldsCount) + + out.WorkloadIdentityData = m.WorkloadIdentityData.trimToMaxSize(maxFieldsSize) + + return out +} + +func (m *WorkloadIdentityDelete) TrimToMaxSize(_ int) AuditEvent { + return m +} diff --git a/api/types/events/events.pb.go b/api/types/events/events.pb.go index d729768769d0f..a767691de20e0 100644 --- a/api/types/events/events.pb.go +++ b/api/types/events/events.pb.go @@ -350,6 +350,35 @@ func (AdminActionsMFAStatus) EnumDescriptor() ([]byte, []int) { return fileDescriptor_007ba1c3d6266d56, []int{7} } +// ContactType is the type of contact being added. +type ContactType int32 + +const ( + ContactType_CONTACT_TYPE_UNSPECIFIED ContactType = 0 + ContactType_CONTACT_TYPE_BUSINESS ContactType = 1 + ContactType_CONTACT_TYPE_SECURITY ContactType = 2 +) + +var ContactType_name = map[int32]string{ + 0: "CONTACT_TYPE_UNSPECIFIED", + 1: "CONTACT_TYPE_BUSINESS", + 2: "CONTACT_TYPE_SECURITY", +} + +var ContactType_value = map[string]int32{ + "CONTACT_TYPE_UNSPECIFIED": 0, + "CONTACT_TYPE_BUSINESS": 1, + "CONTACT_TYPE_SECURITY": 2, +} + +func (x ContactType) String() string { + return proto.EnumName(ContactType_name, int32(x)) +} + +func (ContactType) EnumDescriptor() ([]byte, []int) { + return fileDescriptor_007ba1c3d6266d56, []int{8} +} + // Operation is the network operation that was performed or attempted type SessionNetwork_NetworkOperation int32 @@ -2976,10 +3005,15 @@ type PortForward struct { // Status contains operation success or failure status Status `protobuf:"bytes,4,opt,name=Status,proto3,embedded=Status" json:""` // Addr is a target port forwarding address - Addr string `protobuf:"bytes,5,opt,name=Addr,proto3" json:"addr"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` + Addr string `protobuf:"bytes,5,opt,name=Addr,proto3" json:"addr"` + // KubernetesCluster has information about a kubernetes cluster, if + // applicable. + KubernetesClusterMetadata `protobuf:"bytes,6,opt,name=KubernetesCluster,proto3,embedded=KubernetesCluster" json:""` + // KubernetesPod has information about a kubernetes pod, if applicable. + KubernetesPodMetadata `protobuf:"bytes,7,opt,name=KubernetesPod,proto3,embedded=KubernetesPod" json:""` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` } func (m *PortForward) Reset() { *m = PortForward{} } @@ -7881,6 +7915,11 @@ type OneOf struct { // *OneOf_UserTaskUpdate // *OneOf_UserTaskDelete // *OneOf_SFTPSummary + // *OneOf_ContactCreate + // *OneOf_ContactDelete + // *OneOf_WorkloadIdentityCreate + // *OneOf_WorkloadIdentityUpdate + // *OneOf_WorkloadIdentityDelete Event isOneOf_Event `protobuf_oneof:"Event"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` @@ -8487,6 +8526,21 @@ type OneOf_UserTaskDelete struct { type OneOf_SFTPSummary struct { SFTPSummary *SFTPSummary `protobuf:"bytes,191,opt,name=SFTPSummary,proto3,oneof" json:"SFTPSummary,omitempty"` } +type OneOf_ContactCreate struct { + ContactCreate *ContactCreate `protobuf:"bytes,192,opt,name=ContactCreate,proto3,oneof" json:"ContactCreate,omitempty"` +} +type OneOf_ContactDelete struct { + ContactDelete *ContactDelete `protobuf:"bytes,193,opt,name=ContactDelete,proto3,oneof" json:"ContactDelete,omitempty"` +} +type OneOf_WorkloadIdentityCreate struct { + WorkloadIdentityCreate *WorkloadIdentityCreate `protobuf:"bytes,194,opt,name=WorkloadIdentityCreate,proto3,oneof" json:"WorkloadIdentityCreate,omitempty"` +} +type OneOf_WorkloadIdentityUpdate struct { + WorkloadIdentityUpdate *WorkloadIdentityUpdate `protobuf:"bytes,195,opt,name=WorkloadIdentityUpdate,proto3,oneof" json:"WorkloadIdentityUpdate,omitempty"` +} +type OneOf_WorkloadIdentityDelete struct { + WorkloadIdentityDelete *WorkloadIdentityDelete `protobuf:"bytes,196,opt,name=WorkloadIdentityDelete,proto3,oneof" json:"WorkloadIdentityDelete,omitempty"` +} func (*OneOf_UserLogin) isOneOf_Event() {} func (*OneOf_UserCreate) isOneOf_Event() {} @@ -8675,6 +8729,11 @@ func (*OneOf_UserTaskCreate) isOneOf_Event() {} func (*OneOf_UserTaskUpdate) isOneOf_Event() {} func (*OneOf_UserTaskDelete) isOneOf_Event() {} func (*OneOf_SFTPSummary) isOneOf_Event() {} +func (*OneOf_ContactCreate) isOneOf_Event() {} +func (*OneOf_ContactDelete) isOneOf_Event() {} +func (*OneOf_WorkloadIdentityCreate) isOneOf_Event() {} +func (*OneOf_WorkloadIdentityUpdate) isOneOf_Event() {} +func (*OneOf_WorkloadIdentityDelete) isOneOf_Event() {} func (m *OneOf) GetEvent() isOneOf_Event { if m != nil { @@ -9992,6 +10051,41 @@ func (m *OneOf) GetSFTPSummary() *SFTPSummary { return nil } +func (m *OneOf) GetContactCreate() *ContactCreate { + if x, ok := m.GetEvent().(*OneOf_ContactCreate); ok { + return x.ContactCreate + } + return nil +} + +func (m *OneOf) GetContactDelete() *ContactDelete { + if x, ok := m.GetEvent().(*OneOf_ContactDelete); ok { + return x.ContactDelete + } + return nil +} + +func (m *OneOf) GetWorkloadIdentityCreate() *WorkloadIdentityCreate { + if x, ok := m.GetEvent().(*OneOf_WorkloadIdentityCreate); ok { + return x.WorkloadIdentityCreate + } + return nil +} + +func (m *OneOf) GetWorkloadIdentityUpdate() *WorkloadIdentityUpdate { + if x, ok := m.GetEvent().(*OneOf_WorkloadIdentityUpdate); ok { + return x.WorkloadIdentityUpdate + } + return nil +} + +func (m *OneOf) GetWorkloadIdentityDelete() *WorkloadIdentityDelete { + if x, ok := m.GetEvent().(*OneOf_WorkloadIdentityDelete); ok { + return x.WorkloadIdentityDelete + } + return nil +} + // XXX_OneofWrappers is for the internal use of the proto package. func (*OneOf) XXX_OneofWrappers() []interface{} { return []interface{}{ @@ -10182,6 +10276,11 @@ func (*OneOf) XXX_OneofWrappers() []interface{} { (*OneOf_UserTaskUpdate)(nil), (*OneOf_UserTaskDelete)(nil), (*OneOf_SFTPSummary)(nil), + (*OneOf_ContactCreate)(nil), + (*OneOf_ContactDelete)(nil), + (*OneOf_WorkloadIdentityCreate)(nil), + (*OneOf_WorkloadIdentityUpdate)(nil), + (*OneOf_WorkloadIdentityDelete)(nil), } } @@ -14925,6 +15024,262 @@ func (m *UserTaskDelete) XXX_DiscardUnknown() { var xxx_messageInfo_UserTaskDelete proto.InternalMessageInfo +// ContactCreate is emitted when a contact is created. +type ContactCreate struct { + // Metadata is a common event metadata + Metadata `protobuf:"bytes,1,opt,name=Metadata,proto3,embedded=Metadata" json:""` + // ResourceMetadata is a common resource event metadata + ResourceMetadata `protobuf:"bytes,2,opt,name=Resource,proto3,embedded=Resource" json:""` + // User is a common user event metadata + UserMetadata `protobuf:"bytes,3,opt,name=User,proto3,embedded=User" json:""` + // ConnectionMetadata holds information about the connection + ConnectionMetadata `protobuf:"bytes,4,opt,name=Connection,proto3,embedded=Connection" json:""` + // Status indicates whether the creation was successful. + Status `protobuf:"bytes,5,opt,name=Status,proto3,embedded=Status" json:""` + // Email is the Email of the contact being deleted + Email string `protobuf:"bytes,6,opt,name=Email,proto3" json:"email"` + // ContactType is the type of the contact being deleted ('Business' or 'Security') + ContactType ContactType `protobuf:"varint,7,opt,name=ContactType,proto3,enum=events.ContactType" json:"contact_type"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *ContactCreate) Reset() { *m = ContactCreate{} } +func (m *ContactCreate) String() string { return proto.CompactTextString(m) } +func (*ContactCreate) ProtoMessage() {} +func (*ContactCreate) Descriptor() ([]byte, []int) { + return fileDescriptor_007ba1c3d6266d56, []int{234} +} +func (m *ContactCreate) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *ContactCreate) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_ContactCreate.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *ContactCreate) XXX_Merge(src proto.Message) { + xxx_messageInfo_ContactCreate.Merge(m, src) +} +func (m *ContactCreate) XXX_Size() int { + return m.Size() +} +func (m *ContactCreate) XXX_DiscardUnknown() { + xxx_messageInfo_ContactCreate.DiscardUnknown(m) +} + +var xxx_messageInfo_ContactCreate proto.InternalMessageInfo + +// ContactDelete is emitted when a contact is deleted. +type ContactDelete struct { + // Metadata is a common event metadata + Metadata `protobuf:"bytes,1,opt,name=Metadata,proto3,embedded=Metadata" json:""` + // ResourceMetadata is a common resource event metadata + ResourceMetadata `protobuf:"bytes,2,opt,name=Resource,proto3,embedded=Resource" json:""` + // User is a common user event metadata + UserMetadata `protobuf:"bytes,3,opt,name=User,proto3,embedded=User" json:""` + // ConnectionMetadata holds information about the connection + ConnectionMetadata `protobuf:"bytes,4,opt,name=Connection,proto3,embedded=Connection" json:""` + // Status indicates whether the deletion was successful. + Status `protobuf:"bytes,5,opt,name=Status,proto3,embedded=Status" json:""` + // Email is the Email of the contact being deleted + Email string `protobuf:"bytes,6,opt,name=Email,proto3" json:"email"` + // ContactType is the type of the contact being deleted ('Business' or 'Security') + ContactType ContactType `protobuf:"varint,7,opt,name=ContactType,proto3,enum=events.ContactType" json:"contact_type"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *ContactDelete) Reset() { *m = ContactDelete{} } +func (m *ContactDelete) String() string { return proto.CompactTextString(m) } +func (*ContactDelete) ProtoMessage() {} +func (*ContactDelete) Descriptor() ([]byte, []int) { + return fileDescriptor_007ba1c3d6266d56, []int{235} +} +func (m *ContactDelete) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *ContactDelete) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_ContactDelete.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *ContactDelete) XXX_Merge(src proto.Message) { + xxx_messageInfo_ContactDelete.Merge(m, src) +} +func (m *ContactDelete) XXX_Size() int { + return m.Size() +} +func (m *ContactDelete) XXX_DiscardUnknown() { + xxx_messageInfo_ContactDelete.DiscardUnknown(m) +} + +var xxx_messageInfo_ContactDelete proto.InternalMessageInfo + +// WorkloadIdentityCreate is emitted when a WorkloadIdentity is created. +type WorkloadIdentityCreate struct { + // Metadata is a common event metadata + Metadata `protobuf:"bytes,1,opt,name=Metadata,proto3,embedded=Metadata" json:""` + // ResourceMetadata is a common resource event metadata + ResourceMetadata `protobuf:"bytes,2,opt,name=Resource,proto3,embedded=Resource" json:""` + // User is a common user event metadata + UserMetadata `protobuf:"bytes,3,opt,name=User,proto3,embedded=User" json:""` + // ConnectionMetadata holds information about the connection + ConnectionMetadata `protobuf:"bytes,4,opt,name=Connection,proto3,embedded=Connection" json:""` + // WorkloadIdentityData is a copy of the WorkloadIdentity resource + WorkloadIdentityData *Struct `protobuf:"bytes,5,opt,name=WorkloadIdentityData,proto3,casttype=Struct" json:"workload_identity_data,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *WorkloadIdentityCreate) Reset() { *m = WorkloadIdentityCreate{} } +func (m *WorkloadIdentityCreate) String() string { return proto.CompactTextString(m) } +func (*WorkloadIdentityCreate) ProtoMessage() {} +func (*WorkloadIdentityCreate) Descriptor() ([]byte, []int) { + return fileDescriptor_007ba1c3d6266d56, []int{236} +} +func (m *WorkloadIdentityCreate) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *WorkloadIdentityCreate) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_WorkloadIdentityCreate.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *WorkloadIdentityCreate) XXX_Merge(src proto.Message) { + xxx_messageInfo_WorkloadIdentityCreate.Merge(m, src) +} +func (m *WorkloadIdentityCreate) XXX_Size() int { + return m.Size() +} +func (m *WorkloadIdentityCreate) XXX_DiscardUnknown() { + xxx_messageInfo_WorkloadIdentityCreate.DiscardUnknown(m) +} + +var xxx_messageInfo_WorkloadIdentityCreate proto.InternalMessageInfo + +// WorkloadIdentityUpdate is emitted when a WorkloadIdentity is updated. +type WorkloadIdentityUpdate struct { + // Metadata is a common event metadata + Metadata `protobuf:"bytes,1,opt,name=Metadata,proto3,embedded=Metadata" json:""` + // ResourceMetadata is a common resource event metadata + ResourceMetadata `protobuf:"bytes,2,opt,name=Resource,proto3,embedded=Resource" json:""` + // User is a common user event metadata + UserMetadata `protobuf:"bytes,3,opt,name=User,proto3,embedded=User" json:""` + // ConnectionMetadata holds information about the connection + ConnectionMetadata `protobuf:"bytes,4,opt,name=Connection,proto3,embedded=Connection" json:""` + // WorkloadIdentityData is a copy of the WorkloadIdentity resource + WorkloadIdentityData *Struct `protobuf:"bytes,5,opt,name=WorkloadIdentityData,proto3,casttype=Struct" json:"workload_identity_data,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *WorkloadIdentityUpdate) Reset() { *m = WorkloadIdentityUpdate{} } +func (m *WorkloadIdentityUpdate) String() string { return proto.CompactTextString(m) } +func (*WorkloadIdentityUpdate) ProtoMessage() {} +func (*WorkloadIdentityUpdate) Descriptor() ([]byte, []int) { + return fileDescriptor_007ba1c3d6266d56, []int{237} +} +func (m *WorkloadIdentityUpdate) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *WorkloadIdentityUpdate) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_WorkloadIdentityUpdate.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *WorkloadIdentityUpdate) XXX_Merge(src proto.Message) { + xxx_messageInfo_WorkloadIdentityUpdate.Merge(m, src) +} +func (m *WorkloadIdentityUpdate) XXX_Size() int { + return m.Size() +} +func (m *WorkloadIdentityUpdate) XXX_DiscardUnknown() { + xxx_messageInfo_WorkloadIdentityUpdate.DiscardUnknown(m) +} + +var xxx_messageInfo_WorkloadIdentityUpdate proto.InternalMessageInfo + +// WorkloadIdentityDelete is emitted when a WorkloadIdentity is deleted. +type WorkloadIdentityDelete struct { + // Metadata is a common event metadata + Metadata `protobuf:"bytes,1,opt,name=Metadata,proto3,embedded=Metadata" json:""` + // ResourceMetadata is a common resource event metadata + ResourceMetadata `protobuf:"bytes,2,opt,name=Resource,proto3,embedded=Resource" json:""` + // User is a common user event metadata + UserMetadata `protobuf:"bytes,3,opt,name=User,proto3,embedded=User" json:""` + // ConnectionMetadata holds information about the connection + ConnectionMetadata `protobuf:"bytes,4,opt,name=Connection,proto3,embedded=Connection" json:""` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *WorkloadIdentityDelete) Reset() { *m = WorkloadIdentityDelete{} } +func (m *WorkloadIdentityDelete) String() string { return proto.CompactTextString(m) } +func (*WorkloadIdentityDelete) ProtoMessage() {} +func (*WorkloadIdentityDelete) Descriptor() ([]byte, []int) { + return fileDescriptor_007ba1c3d6266d56, []int{238} +} +func (m *WorkloadIdentityDelete) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *WorkloadIdentityDelete) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_WorkloadIdentityDelete.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *WorkloadIdentityDelete) XXX_Merge(src proto.Message) { + xxx_messageInfo_WorkloadIdentityDelete.Merge(m, src) +} +func (m *WorkloadIdentityDelete) XXX_Size() int { + return m.Size() +} +func (m *WorkloadIdentityDelete) XXX_DiscardUnknown() { + xxx_messageInfo_WorkloadIdentityDelete.DiscardUnknown(m) +} + +var xxx_messageInfo_WorkloadIdentityDelete proto.InternalMessageInfo + func init() { proto.RegisterEnum("events.UserKind", UserKind_name, UserKind_value) proto.RegisterEnum("events.EventAction", EventAction_name, EventAction_value) @@ -14934,6 +15289,7 @@ func init() { proto.RegisterEnum("events.ElasticsearchCategory", ElasticsearchCategory_name, ElasticsearchCategory_value) proto.RegisterEnum("events.OpenSearchCategory", OpenSearchCategory_name, OpenSearchCategory_value) proto.RegisterEnum("events.AdminActionsMFAStatus", AdminActionsMFAStatus_name, AdminActionsMFAStatus_value) + proto.RegisterEnum("events.ContactType", ContactType_name, ContactType_value) proto.RegisterEnum("events.SessionNetwork_NetworkOperation", SessionNetwork_NetworkOperation_name, SessionNetwork_NetworkOperation_value) proto.RegisterType((*Metadata)(nil), "events.Metadata") proto.RegisterType((*SessionMetadata)(nil), "events.SessionMetadata") @@ -15183,6 +15539,11 @@ func init() { proto.RegisterType((*UserTaskUpdate)(nil), "events.UserTaskUpdate") proto.RegisterType((*UserTaskMetadata)(nil), "events.UserTaskMetadata") proto.RegisterType((*UserTaskDelete)(nil), "events.UserTaskDelete") + proto.RegisterType((*ContactCreate)(nil), "events.ContactCreate") + proto.RegisterType((*ContactDelete)(nil), "events.ContactDelete") + proto.RegisterType((*WorkloadIdentityCreate)(nil), "events.WorkloadIdentityCreate") + proto.RegisterType((*WorkloadIdentityUpdate)(nil), "events.WorkloadIdentityUpdate") + proto.RegisterType((*WorkloadIdentityDelete)(nil), "events.WorkloadIdentityDelete") } func init() { @@ -15190,1069 +15551,1087 @@ func init() { } var fileDescriptor_007ba1c3d6266d56 = []byte{ - // 16990 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xec, 0xbd, 0x69, 0x78, 0x24, 0xc9, - 0x75, 0x20, 0x86, 0x3a, 0x50, 0x00, 0x1e, 0xce, 0x8e, 0xbe, 0xb2, 0x7b, 0x7a, 0x1a, 0x33, 0x39, - 0x64, 0xb3, 0x7b, 0x38, 0x83, 0xe6, 0xf4, 0xf4, 0xcc, 0x70, 0x2e, 0x0e, 0x0b, 0x28, 0xa0, 0x51, - 0xdd, 0x38, 0x6a, 0xb2, 0xd0, 0xdd, 0x1c, 0x52, 0x64, 0x29, 0x51, 0x19, 0x0d, 0xe4, 0x74, 0x55, - 0x66, 0x29, 0x33, 0xab, 0xd1, 0x18, 0x5f, 0xa2, 0xac, 0xd5, 0x4a, 0x2b, 0x8a, 0x4b, 0x53, 0xd6, - 0xb1, 0x87, 0xbd, 0xd4, 0x1e, 0xb6, 0x56, 0xab, 0x15, 0xad, 0xb5, 0x2c, 0x89, 0x92, 0xe8, 0xdd, - 0xb5, 0x7c, 0x70, 0xa5, 0xcf, 0xfa, 0xb4, 0x6b, 0x7b, 0xbf, 0xfd, 0xec, 0x35, 0xb8, 0x96, 0xbd, - 0x7f, 0xf0, 0xd9, 0xfe, 0xf4, 0xd9, 0xfa, 0xbc, 0xf4, 0x7a, 0xed, 0xcf, 0x5f, 0xbc, 0x88, 0xcc, - 0x8c, 0xbc, 0x0a, 0xe7, 0x08, 0x03, 0x36, 0xfe, 0x74, 0xa3, 0xde, 0x7b, 0xf1, 0x22, 0xf2, 0xc5, - 0x8b, 0x88, 0x17, 0x11, 0x2f, 0xde, 0x83, 0x6b, 0x1e, 0x6d, 0xd1, 0x8e, 0xed, 0x78, 0xd7, 0x5b, - 0x74, 0x4d, 0x6f, 0x6e, 0x5e, 0xf7, 0x36, 0x3b, 0xd4, 0xbd, 0x4e, 0x1f, 0x51, 0xcb, 0xf3, 0xff, - 0x9b, 0xea, 0x38, 0xb6, 0x67, 0x93, 0x12, 0xff, 0x75, 0xf1, 0xcc, 0x9a, 0xbd, 0x66, 0x23, 0xe8, - 0x3a, 0xfb, 0x8b, 0x63, 0x2f, 0x5e, 0x5a, 0xb3, 0xed, 0xb5, 0x16, 0xbd, 0x8e, 0xbf, 0x56, 0xbb, - 0x0f, 0xae, 0xbb, 0x9e, 0xd3, 0x6d, 0x7a, 0x02, 0x3b, 0x19, 0xc7, 0x7a, 0x66, 0x9b, 0xba, 0x9e, - 0xde, 0xee, 0x08, 0x82, 0xcb, 0x71, 0x82, 0x0d, 0x47, 0xef, 0x74, 0xa8, 0x23, 0x2a, 0xbf, 0xf8, - 0x89, 0xa0, 0x9d, 0x7a, 0xb3, 0x49, 0x5d, 0xb7, 0x65, 0xba, 0xde, 0xf5, 0x47, 0x2f, 0x49, 0xbf, - 0x04, 0xe1, 0xb3, 0xe9, 0x1f, 0x84, 0xff, 0x0a, 0x92, 0x17, 0xd3, 0x49, 0xfc, 0x1a, 0x63, 0x55, - 0xab, 0x5f, 0xcf, 0xc3, 0xe0, 0x22, 0xf5, 0x74, 0x43, 0xf7, 0x74, 0x72, 0x09, 0xfa, 0xab, 0x96, - 0x41, 0x1f, 0x2b, 0xb9, 0x67, 0x72, 0x57, 0x0b, 0xd3, 0xa5, 0xed, 0xad, 0xc9, 0x3c, 0x35, 0x35, - 0x0e, 0x24, 0x4f, 0x43, 0x71, 0x65, 0xb3, 0x43, 0x95, 0xfc, 0x33, 0xb9, 0xab, 0x43, 0xd3, 0x43, - 0xdb, 0x5b, 0x93, 0xfd, 0x28, 0x34, 0x0d, 0xc1, 0xe4, 0x59, 0xc8, 0x57, 0x2b, 0x4a, 0x01, 0x91, - 0xa7, 0xb6, 0xb7, 0x26, 0x47, 0xbb, 0xa6, 0xf1, 0x82, 0xdd, 0x36, 0x3d, 0xda, 0xee, 0x78, 0x9b, - 0x5a, 0xbe, 0x5a, 0x21, 0x57, 0xa0, 0x38, 0x63, 0x1b, 0x54, 0x29, 0x22, 0x11, 0xd9, 0xde, 0x9a, - 0x1c, 0x6b, 0xda, 0x06, 0x95, 0xa8, 0x10, 0x4f, 0x3e, 0x0b, 0xc5, 0x15, 0xb3, 0x4d, 0x95, 0xfe, - 0x67, 0x72, 0x57, 0x87, 0x6f, 0x5c, 0x9c, 0xe2, 0xe2, 0x9b, 0xf2, 0xc5, 0x37, 0xb5, 0xe2, 0xcb, - 0x77, 0x7a, 0xe2, 0x3b, 0x5b, 0x93, 0x7d, 0xdb, 0x5b, 0x93, 0x45, 0x26, 0xf2, 0xaf, 0x7d, 0x77, - 0x32, 0xa7, 0x61, 0x49, 0xf2, 0x16, 0x0c, 0xcf, 0xb4, 0xba, 0xae, 0x47, 0x9d, 0x25, 0xbd, 0x4d, - 0x95, 0x12, 0x56, 0x78, 0x71, 0x7b, 0x6b, 0xf2, 0x5c, 0x93, 0x83, 0x1b, 0x96, 0xde, 0x96, 0x2b, - 0x96, 0xc9, 0xd5, 0xdf, 0xcc, 0xc1, 0x78, 0x9d, 0xba, 0xae, 0x69, 0x5b, 0x81, 0x6c, 0x3e, 0x0e, - 0x43, 0x02, 0x54, 0xad, 0xa0, 0x7c, 0x86, 0xa6, 0x07, 0xb6, 0xb7, 0x26, 0x0b, 0xae, 0x69, 0x68, - 0x21, 0x86, 0x7c, 0x0a, 0x06, 0xee, 0x9b, 0xde, 0xfa, 0xe2, 0x5c, 0x59, 0xc8, 0xe9, 0xdc, 0xf6, - 0xd6, 0x24, 0xd9, 0x30, 0xbd, 0xf5, 0x46, 0xfb, 0x81, 0x2e, 0x55, 0xe8, 0x93, 0x91, 0x05, 0x98, - 0xa8, 0x39, 0xe6, 0x23, 0xdd, 0xa3, 0x77, 0xe8, 0x66, 0xcd, 0x6e, 0x99, 0xcd, 0x4d, 0x21, 0xc5, - 0x67, 0xb6, 0xb7, 0x26, 0x2f, 0x75, 0x38, 0xae, 0xf1, 0x90, 0x6e, 0x36, 0x3a, 0x88, 0x95, 0x98, - 0x24, 0x4a, 0xaa, 0xbf, 0x55, 0x82, 0x91, 0xbb, 0x2e, 0x75, 0x82, 0x76, 0x5f, 0x81, 0x22, 0xfb, - 0x2d, 0x9a, 0x8c, 0x32, 0xef, 0xba, 0xd4, 0x91, 0x65, 0xce, 0xf0, 0xe4, 0x1a, 0xf4, 0x2f, 0xd8, - 0x6b, 0xa6, 0x25, 0x9a, 0x7d, 0x7a, 0x7b, 0x6b, 0x72, 0xbc, 0xc5, 0x00, 0x12, 0x25, 0xa7, 0x20, - 0x9f, 0x81, 0x91, 0x6a, 0x9b, 0xe9, 0x90, 0x6d, 0xe9, 0x9e, 0xed, 0x88, 0xd6, 0xa2, 0x74, 0x4d, - 0x09, 0x2e, 0x15, 0x8c, 0xd0, 0x93, 0x37, 0x00, 0xca, 0xf7, 0xeb, 0x9a, 0xdd, 0xa2, 0x65, 0x6d, - 0x49, 0x28, 0x03, 0x96, 0xd6, 0x37, 0xdc, 0x86, 0x63, 0xb7, 0x68, 0x43, 0x77, 0xe4, 0x6a, 0x25, - 0x6a, 0x32, 0x0b, 0x63, 0x65, 0x1c, 0x15, 0x1a, 0xfd, 0xa1, 0x2e, 0x75, 0x3d, 0x57, 0xe9, 0x7f, - 0xa6, 0x70, 0x75, 0x68, 0xfa, 0xe9, 0xed, 0xad, 0xc9, 0x0b, 0x7c, 0xbc, 0x34, 0x1c, 0x81, 0x92, - 0x58, 0xc4, 0x0a, 0x91, 0x69, 0x18, 0x2d, 0x7f, 0xd0, 0x75, 0x68, 0xd5, 0xa0, 0x96, 0x67, 0x7a, - 0x9b, 0x42, 0x43, 0x2e, 0x6d, 0x6f, 0x4d, 0x2a, 0x3a, 0x43, 0x34, 0x4c, 0x81, 0x91, 0x98, 0x44, - 0x8b, 0x90, 0x65, 0x38, 0x75, 0x6b, 0xa6, 0x56, 0xa7, 0xce, 0x23, 0xb3, 0x49, 0xcb, 0xcd, 0xa6, - 0xdd, 0xb5, 0x3c, 0x65, 0x00, 0xf9, 0x3c, 0xbb, 0xbd, 0x35, 0xf9, 0xf4, 0x5a, 0xb3, 0xd3, 0x70, - 0x39, 0xb6, 0xa1, 0x73, 0xb4, 0xc4, 0x2c, 0x59, 0x96, 0x7c, 0x1e, 0x46, 0x57, 0x1c, 0xa6, 0x85, - 0x46, 0x85, 0x32, 0xb8, 0x32, 0x88, 0xfa, 0x7f, 0x6e, 0x4a, 0xcc, 0x54, 0x1c, 0xea, 0xf7, 0x2c, - 0x6f, 0xac, 0xc7, 0x0b, 0x34, 0x0c, 0xc4, 0xc9, 0x8d, 0x8d, 0xb0, 0x22, 0x14, 0x14, 0xf6, 0xf1, - 0xa6, 0x43, 0x8d, 0x84, 0xb6, 0x0d, 0x61, 0x9b, 0xaf, 0x6d, 0x6f, 0x4d, 0x7e, 0xdc, 0x11, 0x34, - 0x8d, 0x9e, 0x6a, 0x97, 0xc9, 0x8a, 0xcc, 0xc2, 0x20, 0xd3, 0xa6, 0x3b, 0xa6, 0x65, 0x28, 0xf0, - 0x4c, 0xee, 0xea, 0xd8, 0x8d, 0x09, 0xbf, 0xf5, 0x3e, 0x7c, 0xfa, 0xfc, 0xf6, 0xd6, 0xe4, 0x69, - 0xa6, 0x83, 0x8d, 0x87, 0xa6, 0x25, 0x4f, 0x11, 0x41, 0x51, 0x36, 0x8a, 0xa6, 0x6d, 0x0f, 0x87, - 0xee, 0x70, 0x38, 0x8a, 0x56, 0x6d, 0x2f, 0x3e, 0x6c, 0x7d, 0x32, 0x32, 0x03, 0xa3, 0xd3, 0xb6, - 0x57, 0xb5, 0x5c, 0x4f, 0xb7, 0x9a, 0xb4, 0x5a, 0x51, 0x46, 0xb0, 0x1c, 0xaa, 0x05, 0x2b, 0x67, - 0x0a, 0x4c, 0x23, 0x32, 0x29, 0x45, 0xcb, 0xa8, 0xff, 0xa2, 0x08, 0x63, 0xac, 0x4f, 0xa4, 0xe1, - 0x53, 0x66, 0x33, 0x01, 0x83, 0xb0, 0x5a, 0xdc, 0x8e, 0xde, 0xa4, 0x62, 0x24, 0xe1, 0x57, 0x58, - 0x3e, 0x50, 0xe2, 0x19, 0xa7, 0x27, 0xd7, 0x60, 0x90, 0x83, 0xaa, 0x15, 0x31, 0xb8, 0x46, 0xb7, - 0xb7, 0x26, 0x87, 0x5c, 0x84, 0x35, 0x4c, 0x43, 0x0b, 0xd0, 0x4c, 0xbb, 0xf9, 0xdf, 0xf3, 0xb6, - 0xeb, 0x31, 0xe6, 0x62, 0x6c, 0xe1, 0x67, 0x88, 0x02, 0xeb, 0x02, 0x25, 0x6b, 0x77, 0xb4, 0x10, - 0x79, 0x1d, 0x80, 0x43, 0xca, 0x86, 0xe1, 0x88, 0x01, 0x76, 0x61, 0x7b, 0x6b, 0xf2, 0xac, 0x60, - 0xa1, 0x1b, 0x86, 0x3c, 0x3a, 0x25, 0x62, 0xd2, 0x86, 0x11, 0xfe, 0x6b, 0x41, 0x5f, 0xa5, 0x2d, - 0x3e, 0xba, 0x86, 0x6f, 0x5c, 0xf5, 0x3b, 0x31, 0x2a, 0x9d, 0x29, 0x99, 0x74, 0xd6, 0xf2, 0x9c, - 0xcd, 0xe9, 0x49, 0x31, 0x21, 0x9f, 0x17, 0x55, 0xb5, 0x10, 0x27, 0x4f, 0x05, 0x72, 0x19, 0x36, - 0x4f, 0xcf, 0xd9, 0xce, 0x86, 0xee, 0x18, 0xd4, 0x98, 0xde, 0x94, 0xe7, 0xe9, 0x07, 0x3e, 0xb8, - 0xb1, 0x2a, 0xab, 0x9e, 0x4c, 0xce, 0x3a, 0x9d, 0x73, 0xab, 0x77, 0x57, 0x51, 0xe5, 0x06, 0x12, - 0xd2, 0x72, 0xbb, 0xab, 0x71, 0x35, 0x8b, 0x96, 0x61, 0x53, 0x01, 0x07, 0xdc, 0xa3, 0x0e, 0x9b, - 0xc4, 0x71, 0xd4, 0x89, 0xa9, 0x40, 0x30, 0x79, 0xc4, 0x31, 0x49, 0x1e, 0xa2, 0xc8, 0xc5, 0x77, - 0xe0, 0x54, 0x42, 0x14, 0x64, 0x02, 0x0a, 0x0f, 0xe9, 0x26, 0x57, 0x17, 0x8d, 0xfd, 0x49, 0xce, - 0x40, 0xff, 0x23, 0xbd, 0xd5, 0x15, 0x4b, 0xa8, 0xc6, 0x7f, 0xbc, 0x91, 0xff, 0x74, 0x8e, 0xad, - 0x38, 0x64, 0xc6, 0xb6, 0x2c, 0xda, 0xf4, 0xe4, 0x45, 0xe7, 0x55, 0x18, 0x5a, 0xb0, 0x9b, 0x7a, - 0x0b, 0xfb, 0x91, 0xeb, 0x9d, 0xb2, 0xbd, 0x35, 0x79, 0x86, 0x75, 0xe0, 0x54, 0x8b, 0x61, 0xa4, - 0x36, 0x85, 0xa4, 0x4c, 0x01, 0x34, 0xda, 0xb6, 0x3d, 0x8a, 0x05, 0xf3, 0xa1, 0x02, 0x60, 0x41, - 0x07, 0x51, 0xb2, 0x02, 0x84, 0xc4, 0xe4, 0x3a, 0x0c, 0xd6, 0xd8, 0x3a, 0xdb, 0xb4, 0x5b, 0x42, - 0xf9, 0x70, 0x29, 0xc0, 0xb5, 0x57, 0x1e, 0xab, 0x3e, 0x91, 0x3a, 0x0f, 0x63, 0x33, 0x2d, 0x93, - 0x5a, 0x9e, 0xdc, 0x6a, 0x36, 0x92, 0xcb, 0x6b, 0xd4, 0xf2, 0xe4, 0x56, 0xe3, 0x98, 0xd7, 0x19, - 0x54, 0x6e, 0x75, 0x40, 0xaa, 0xfe, 0x41, 0x01, 0x2e, 0xdc, 0xe9, 0xae, 0x52, 0xc7, 0xa2, 0x1e, - 0x75, 0xc5, 0x82, 0x1c, 0x70, 0x5d, 0x82, 0x53, 0x09, 0xa4, 0xe0, 0x8e, 0x0b, 0xe5, 0xc3, 0x00, - 0xd9, 0x10, 0x6b, 0xbc, 0x3c, 0xdb, 0x26, 0x8a, 0x92, 0x79, 0x18, 0x0f, 0x81, 0xac, 0x11, 0xae, - 0x92, 0xc7, 0xa5, 0xe4, 0xf2, 0xf6, 0xd6, 0xe4, 0x45, 0x89, 0x1b, 0x6b, 0xb6, 0xac, 0xc1, 0xf1, - 0x62, 0xe4, 0x0e, 0x4c, 0x84, 0xa0, 0x5b, 0x8e, 0xdd, 0xed, 0xb8, 0x4a, 0x01, 0x59, 0x4d, 0x6e, - 0x6f, 0x4d, 0x3e, 0x25, 0xb1, 0x5a, 0x43, 0xa4, 0xbc, 0x80, 0xc7, 0x0b, 0x92, 0x1f, 0xcd, 0xc9, - 0xdc, 0xc4, 0x28, 0x2c, 0xe2, 0x28, 0x7c, 0xcd, 0x1f, 0x85, 0x99, 0x42, 0x9a, 0x8a, 0x97, 0x14, - 0x83, 0x32, 0xd6, 0x8c, 0xc4, 0xa0, 0x4c, 0xd4, 0x78, 0x71, 0x06, 0xce, 0xa6, 0xf2, 0xda, 0x93, - 0x56, 0xff, 0xf3, 0x82, 0xcc, 0xa5, 0x66, 0x1b, 0x41, 0x67, 0x2e, 0xcb, 0x9d, 0x59, 0xb3, 0x0d, - 0x9c, 0xea, 0x73, 0xe1, 0xda, 0x29, 0x35, 0xb6, 0x63, 0x1b, 0xf1, 0x59, 0x3f, 0x59, 0x96, 0x7c, - 0x09, 0xce, 0x25, 0x80, 0x7c, 0xba, 0xe6, 0xda, 0x7f, 0x65, 0x7b, 0x6b, 0x52, 0x4d, 0xe1, 0x1a, - 0x9f, 0xbd, 0x33, 0xb8, 0x10, 0x1d, 0xce, 0x4b, 0x52, 0xb7, 0x2d, 0x4f, 0x37, 0x2d, 0x61, 0x5c, - 0xf2, 0x51, 0xf2, 0x89, 0xed, 0xad, 0xc9, 0xe7, 0x64, 0x1d, 0xf4, 0x69, 0xe2, 0x8d, 0xcf, 0xe2, - 0x43, 0x0c, 0x50, 0x52, 0x50, 0xd5, 0xb6, 0xbe, 0xe6, 0x5b, 0xcc, 0x57, 0xb7, 0xb7, 0x26, 0x3f, - 0x96, 0x5a, 0x87, 0xc9, 0xa8, 0xe4, 0x15, 0x3a, 0x8b, 0x13, 0xd1, 0x80, 0x84, 0xb8, 0x25, 0xdb, - 0xa0, 0xf8, 0x0d, 0xfd, 0xc8, 0x5f, 0xdd, 0xde, 0x9a, 0xbc, 0x2c, 0xf1, 0xb7, 0x6c, 0x83, 0xc6, - 0x9b, 0x9f, 0x52, 0x5a, 0xfd, 0xcd, 0x02, 0x5c, 0xae, 0x97, 0x17, 0x17, 0xaa, 0x86, 0x6f, 0xd2, - 0xd4, 0x1c, 0xfb, 0x91, 0x69, 0x48, 0xa3, 0x77, 0x15, 0xce, 0xc7, 0x50, 0xb3, 0x68, 0x45, 0x05, - 0xc6, 0x34, 0x7e, 0x9b, 0x6f, 0x2e, 0x75, 0x04, 0x4d, 0x83, 0x9b, 0x5a, 0xd1, 0x45, 0x3b, 0x8b, - 0x11, 0xeb, 0xa3, 0x18, 0xaa, 0xbe, 0x6e, 0x3b, 0x5e, 0xb3, 0xeb, 0x09, 0x25, 0xc0, 0x3e, 0x4a, - 0xd4, 0xe1, 0x0a, 0xa2, 0x1e, 0x55, 0xf8, 0x7c, 0xc8, 0x4f, 0xe4, 0x60, 0xa2, 0xec, 0x79, 0x8e, - 0xb9, 0xda, 0xf5, 0xe8, 0xa2, 0xde, 0xe9, 0x98, 0xd6, 0x1a, 0x8e, 0xf5, 0xe1, 0x1b, 0x6f, 0x05, - 0x6b, 0x64, 0x4f, 0x49, 0x4c, 0xc5, 0x8b, 0x4b, 0x43, 0x54, 0xf7, 0x51, 0x8d, 0x36, 0xc7, 0xc9, - 0x43, 0x34, 0x5e, 0x8e, 0x0d, 0xd1, 0x54, 0x5e, 0x7b, 0x1a, 0xa2, 0x5f, 0x2f, 0xc0, 0xa5, 0xe5, - 0x87, 0x9e, 0xae, 0x51, 0xd7, 0xee, 0x3a, 0x4d, 0xea, 0xde, 0xed, 0x18, 0xba, 0x47, 0xc3, 0x91, - 0x3a, 0x09, 0xfd, 0x65, 0xc3, 0xa0, 0x06, 0xb2, 0xeb, 0xe7, 0xdb, 0x3e, 0x9d, 0x01, 0x34, 0x0e, - 0x27, 0x1f, 0x87, 0x01, 0x51, 0x06, 0xb9, 0xf7, 0x4f, 0x0f, 0x6f, 0x6f, 0x4d, 0x0e, 0x74, 0x39, - 0x48, 0xf3, 0x71, 0x8c, 0xac, 0x42, 0x5b, 0x94, 0x91, 0x15, 0x42, 0x32, 0x83, 0x83, 0x34, 0x1f, - 0x47, 0xde, 0x85, 0x31, 0x64, 0x1b, 0xb4, 0x47, 0xcc, 0x7d, 0x67, 0x7c, 0xe9, 0xca, 0x8d, 0xe5, - 0x4b, 0x13, 0xb6, 0xa6, 0xe1, 0xf8, 0x05, 0xb4, 0x18, 0x03, 0x72, 0x1f, 0x26, 0x44, 0x23, 0x42, - 0xa6, 0xfd, 0x3d, 0x98, 0x9e, 0xdd, 0xde, 0x9a, 0x3c, 0x25, 0xda, 0x2f, 0xb1, 0x4d, 0x30, 0x61, - 0x8c, 0x45, 0xb3, 0x43, 0xc6, 0xa5, 0x9d, 0x18, 0x8b, 0x2f, 0x96, 0x19, 0xc7, 0x99, 0xa8, 0xef, - 0xc1, 0x88, 0x5c, 0x90, 0x9c, 0xc3, 0xad, 0x35, 0x1f, 0x27, 0xb8, 0x29, 0x37, 0x0d, 0xdc, 0x4f, - 0xbf, 0x04, 0xc3, 0x15, 0xea, 0x36, 0x1d, 0xb3, 0xc3, 0xac, 0x06, 0xa1, 0xe4, 0xe3, 0xdb, 0x5b, - 0x93, 0xc3, 0x46, 0x08, 0xd6, 0x64, 0x1a, 0xf5, 0xff, 0xca, 0xc1, 0x39, 0xc6, 0xbb, 0xec, 0xba, - 0xe6, 0x9a, 0xd5, 0x96, 0x97, 0xed, 0x17, 0xa0, 0x54, 0xc7, 0xfa, 0x44, 0x4d, 0x67, 0xb6, 0xb7, - 0x26, 0x27, 0x78, 0x0b, 0x24, 0x3d, 0x14, 0x34, 0xc1, 0xbe, 0x32, 0xbf, 0xc3, 0xbe, 0x92, 0x99, - 0xb4, 0x9e, 0xee, 0x78, 0xa6, 0xb5, 0x56, 0xf7, 0x74, 0xaf, 0xeb, 0x46, 0x4c, 0x5a, 0x81, 0x69, - 0xb8, 0x88, 0x8a, 0x98, 0xb4, 0x91, 0x42, 0xe4, 0x1d, 0x18, 0x99, 0xb5, 0x8c, 0x90, 0x09, 0x9f, - 0x10, 0x9f, 0x62, 0x96, 0x26, 0x45, 0x78, 0x92, 0x45, 0xa4, 0x80, 0xfa, 0xb7, 0x73, 0xa0, 0xf0, - 0x4d, 0xe0, 0x82, 0xe9, 0x7a, 0x8b, 0xb4, 0xbd, 0x2a, 0xcd, 0x4e, 0x73, 0xfe, 0xae, 0x92, 0xe1, - 0xa4, 0xb5, 0x08, 0x4d, 0x01, 0xb1, 0xab, 0x6c, 0x99, 0x6e, 0x62, 0xfb, 0x11, 0x2b, 0x45, 0xaa, - 0x30, 0xc0, 0x39, 0x73, 0x5b, 0x62, 0xf8, 0x86, 0xe2, 0x2b, 0x42, 0xbc, 0x6a, 0xae, 0x0c, 0x6d, - 0x4e, 0x2c, 0x6f, 0x68, 0x44, 0x79, 0xf5, 0x1b, 0x05, 0x98, 0x88, 0x17, 0x22, 0xf7, 0x61, 0xf0, - 0xb6, 0x6d, 0x5a, 0xd4, 0x58, 0xb6, 0xb0, 0x85, 0xbd, 0x0f, 0x47, 0x7c, 0x5b, 0xfc, 0xf4, 0xfb, - 0x58, 0xa6, 0x21, 0x5b, 0xb0, 0x78, 0x56, 0x12, 0x30, 0x23, 0x9f, 0x87, 0x21, 0x66, 0x03, 0x3e, - 0x42, 0xce, 0xf9, 0x1d, 0x39, 0x3f, 0x23, 0x38, 0x9f, 0x71, 0x78, 0xa1, 0x24, 0xeb, 0x90, 0x1d, - 0xd3, 0x2b, 0x8d, 0xea, 0xae, 0x6d, 0x89, 0x9e, 0x47, 0xbd, 0x72, 0x10, 0x22, 0xeb, 0x15, 0xa7, - 0x61, 0xa6, 0x2b, 0xff, 0x58, 0xec, 0x06, 0x69, 0xef, 0xc2, 0x65, 0x15, 0xef, 0x01, 0x89, 0x98, - 0x58, 0x30, 0x2e, 0x04, 0xba, 0x6e, 0x76, 0xd0, 0xea, 0xc7, 0x75, 0x6d, 0xec, 0xc6, 0x95, 0x29, - 0xff, 0x50, 0x6c, 0x4a, 0x3a, 0x52, 0x7b, 0xf4, 0xd2, 0xd4, 0x62, 0x40, 0x8e, 0x3b, 0x53, 0xd4, - 0xc9, 0x18, 0x0b, 0xb9, 0xb7, 0xdb, 0x11, 0x72, 0xf5, 0xc7, 0xf2, 0xf0, 0x62, 0xd8, 0x45, 0x1a, - 0x7d, 0x64, 0xd2, 0x8d, 0x90, 0xa3, 0xd8, 0x23, 0xb3, 0x21, 0xe6, 0xce, 0xac, 0xeb, 0xd6, 0x1a, - 0x35, 0xc8, 0x35, 0xe8, 0xd7, 0xec, 0x16, 0x75, 0x95, 0x1c, 0x9a, 0x87, 0x38, 0x7d, 0x39, 0x0c, - 0x20, 0x1f, 0xb2, 0x20, 0x05, 0xb1, 0xa1, 0xb4, 0xe2, 0xe8, 0xa6, 0xe7, 0x6b, 0x52, 0x39, 0xa9, - 0x49, 0xbb, 0xa8, 0x71, 0x8a, 0xf3, 0xe0, 0x6b, 0x0c, 0x0a, 0xde, 0x43, 0x80, 0x2c, 0x78, 0x4e, - 0x72, 0xf1, 0x75, 0x18, 0x96, 0x88, 0xf7, 0xb4, 0x88, 0x7c, 0xab, 0x28, 0x8f, 0x2d, 0xbf, 0x59, - 0x62, 0x6c, 0x5d, 0x67, 0x63, 0xc2, 0x75, 0x99, 0x15, 0xc3, 0x07, 0x95, 0xd0, 0x7c, 0x04, 0x45, - 0x35, 0x1f, 0x41, 0xe4, 0x65, 0x18, 0xe4, 0x2c, 0x82, 0xfd, 0x32, 0xee, 0xb5, 0x1d, 0x84, 0x45, - 0x4d, 0x81, 0x80, 0x90, 0xfc, 0x52, 0x0e, 0x9e, 0xee, 0x29, 0x09, 0x54, 0xbe, 0xe1, 0x1b, 0xaf, - 0xec, 0x4b, 0x8c, 0xd3, 0x2f, 0x6e, 0x6f, 0x4d, 0x5e, 0x93, 0x34, 0xc3, 0x91, 0x68, 0x1a, 0x4d, - 0x4e, 0x24, 0xb5, 0xab, 0x77, 0x53, 0x98, 0xb1, 0xca, 0x2b, 0x9d, 0xc3, 0xa3, 0x2a, 0xab, 0xb9, - 0xe9, 0x37, 0xb2, 0x18, 0x1a, 0xab, 0xe2, 0x7b, 0x1f, 0xf8, 0x24, 0x29, 0xd5, 0x64, 0x70, 0x21, - 0x4d, 0x38, 0xcf, 0x31, 0x15, 0x7d, 0x73, 0xf9, 0xc1, 0xa2, 0x6d, 0x79, 0xeb, 0x7e, 0x05, 0xfd, - 0xf2, 0x59, 0x0f, 0x56, 0x60, 0xe8, 0x9b, 0x0d, 0xfb, 0x41, 0xa3, 0xcd, 0xa8, 0x52, 0xea, 0xc8, - 0xe2, 0xc4, 0x26, 0x76, 0x31, 0xc6, 0xfd, 0x29, 0xaf, 0x14, 0x9e, 0xc4, 0xf9, 0xf3, 0x42, 0x72, - 0x82, 0x8b, 0x15, 0x52, 0xab, 0x30, 0xb2, 0x60, 0x37, 0x1f, 0x06, 0xea, 0xf2, 0x3a, 0x94, 0x56, - 0x74, 0x67, 0x8d, 0x7a, 0x28, 0x8b, 0xe1, 0x1b, 0xa7, 0xa6, 0xf8, 0xe9, 0x36, 0x23, 0xe2, 0x88, - 0xe9, 0x31, 0x31, 0xfb, 0x94, 0x3c, 0xfc, 0xad, 0x89, 0x02, 0xea, 0x77, 0xfb, 0x61, 0x44, 0x9c, - 0xc4, 0xe2, 0xea, 0x41, 0xde, 0x08, 0xcf, 0xb6, 0xc5, 0x74, 0x19, 0x9c, 0x46, 0x05, 0xa7, 0x68, - 0x23, 0x8c, 0xd9, 0x1f, 0x6e, 0x4d, 0xe6, 0xb6, 0xb7, 0x26, 0xfb, 0xb4, 0x41, 0x69, 0x13, 0x1b, - 0xae, 0x6f, 0xd2, 0x82, 0x2e, 0x9f, 0xad, 0xc6, 0xca, 0xf2, 0xf5, 0xee, 0x1d, 0x18, 0x10, 0x6d, - 0x10, 0x1a, 0x77, 0x3e, 0x3c, 0x3b, 0x89, 0x9c, 0x28, 0xc7, 0x4a, 0xfb, 0xa5, 0xc8, 0x5b, 0x50, - 0xe2, 0x67, 0x09, 0x42, 0x00, 0xe7, 0xd2, 0xcf, 0x5e, 0x62, 0xc5, 0x45, 0x19, 0x32, 0x0f, 0x10, - 0x9e, 0x23, 0x04, 0x07, 0xe8, 0x82, 0x43, 0xf2, 0x84, 0x21, 0xc6, 0x45, 0x2a, 0x4b, 0x5e, 0x85, - 0x91, 0x15, 0xea, 0xb4, 0x4d, 0x4b, 0x6f, 0xd5, 0xcd, 0x0f, 0xfc, 0x33, 0x74, 0x5c, 0xe8, 0x5d, - 0xf3, 0x03, 0x79, 0xe4, 0x46, 0xe8, 0xc8, 0x17, 0xd3, 0xf6, 0xe9, 0x03, 0xd8, 0x90, 0x67, 0x77, - 0xdc, 0xc0, 0xc6, 0xda, 0x93, 0xb2, 0x6d, 0x7f, 0x17, 0x46, 0x23, 0x5b, 0x34, 0x71, 0x48, 0xfa, - 0x74, 0x92, 0xb5, 0xb4, 0xdf, 0x8c, 0xb1, 0x8d, 0x72, 0x60, 0x9a, 0x5c, 0xb5, 0x4c, 0xcf, 0xd4, - 0x5b, 0x33, 0x76, 0xbb, 0xad, 0x5b, 0x86, 0x32, 0x14, 0x6a, 0xb2, 0xc9, 0x31, 0x8d, 0x26, 0x47, - 0xc9, 0x9a, 0x1c, 0x2d, 0x44, 0xee, 0xc0, 0x84, 0xe8, 0x43, 0x8d, 0x36, 0x6d, 0x87, 0xd9, 0x1e, - 0x78, 0x06, 0x2a, 0x8e, 0x01, 0x5c, 0x8e, 0x6b, 0x38, 0x3e, 0x52, 0x36, 0xee, 0xe3, 0x05, 0x6f, - 0x17, 0x07, 0x87, 0x27, 0x46, 0xe2, 0xc7, 0xd6, 0xea, 0xdf, 0x2c, 0xc0, 0xb0, 0x20, 0x65, 0x4b, - 0xf7, 0x89, 0x82, 0x1f, 0x44, 0xc1, 0x53, 0x15, 0xb5, 0x74, 0x58, 0x8a, 0xaa, 0x7e, 0x25, 0x1f, - 0xcc, 0x46, 0x35, 0xc7, 0xb4, 0x0e, 0x36, 0x1b, 0x5d, 0x01, 0x98, 0x59, 0xef, 0x5a, 0x0f, 0xf9, - 0xf5, 0x5c, 0x3e, 0xbc, 0x9e, 0x6b, 0x9a, 0x9a, 0x84, 0x21, 0x4f, 0x43, 0xb1, 0xc2, 0xf8, 0xb3, - 0x9e, 0x19, 0x99, 0x1e, 0xfa, 0x0e, 0xe7, 0x94, 0x7b, 0x51, 0x43, 0x30, 0xdb, 0xcc, 0x4d, 0x6f, - 0x7a, 0x94, 0x9b, 0xcf, 0x05, 0xbe, 0x99, 0x5b, 0x65, 0x00, 0x8d, 0xc3, 0xc9, 0x4d, 0x38, 0x55, - 0xa1, 0x2d, 0x7d, 0x73, 0xd1, 0x6c, 0xb5, 0x4c, 0x97, 0x36, 0x6d, 0xcb, 0x70, 0x51, 0xc8, 0xa2, - 0xba, 0xb6, 0xab, 0x25, 0x09, 0x88, 0x0a, 0xa5, 0xe5, 0x07, 0x0f, 0x5c, 0xea, 0xa1, 0xf8, 0x0a, - 0xd3, 0xc0, 0x26, 0x67, 0x1b, 0x21, 0x9a, 0xc0, 0xa8, 0xdf, 0xcc, 0xb1, 0xdd, 0x92, 0xfb, 0xd0, - 0xb3, 0x3b, 0x81, 0x96, 0x1f, 0x48, 0x24, 0xd7, 0x42, 0xbb, 0x22, 0x8f, 0x5f, 0x3b, 0x2e, 0xbe, - 0x76, 0x40, 0xd8, 0x16, 0xa1, 0x45, 0x91, 0xfa, 0x55, 0x85, 0x1d, 0xbe, 0x4a, 0xfd, 0xe3, 0x3c, - 0x9c, 0x17, 0x2d, 0x9e, 0x69, 0x99, 0x9d, 0x55, 0x5b, 0x77, 0x0c, 0x8d, 0x36, 0xa9, 0xf9, 0x88, - 0x1e, 0xcf, 0x81, 0x17, 0x1d, 0x3a, 0xc5, 0x03, 0x0c, 0x9d, 0x1b, 0xb8, 0xf1, 0x64, 0x92, 0xc1, - 0x03, 0x66, 0x6e, 0x54, 0x4c, 0x6c, 0x6f, 0x4d, 0x8e, 0x18, 0x1c, 0x8c, 0x57, 0x0c, 0x9a, 0x4c, - 0xc4, 0x94, 0x64, 0x81, 0x5a, 0x6b, 0xde, 0x3a, 0x2a, 0x49, 0x3f, 0x57, 0x92, 0x16, 0x42, 0x34, - 0x81, 0x51, 0xff, 0xb7, 0x3c, 0x9c, 0x89, 0x8b, 0xbc, 0x4e, 0x2d, 0xe3, 0x44, 0xde, 0x1f, 0x8e, - 0xbc, 0xff, 0xa4, 0x00, 0x4f, 0x89, 0x32, 0xf5, 0x75, 0xdd, 0xa1, 0x46, 0xc5, 0x74, 0x68, 0xd3, - 0xb3, 0x9d, 0xcd, 0x63, 0x6c, 0x40, 0x1d, 0x9e, 0xd8, 0x6f, 0x42, 0x49, 0x1c, 0x37, 0xf0, 0x75, - 0x66, 0x2c, 0x68, 0x09, 0x42, 0x13, 0x2b, 0x14, 0x3f, 0xaa, 0x88, 0x75, 0x56, 0x69, 0x37, 0x9d, - 0xf5, 0x69, 0x18, 0x0d, 0x44, 0x8f, 0x1b, 0xdf, 0x81, 0xd0, 0xda, 0x32, 0x7c, 0x04, 0xee, 0x7d, - 0xb5, 0x28, 0x21, 0xd6, 0xe6, 0x03, 0xaa, 0x15, 0xb4, 0x86, 0x46, 0x45, 0x6d, 0x41, 0x39, 0xd3, - 0xd0, 0x64, 0x22, 0x75, 0xab, 0x08, 0x17, 0xd3, 0xbb, 0x5d, 0xa3, 0xba, 0x71, 0xd2, 0xeb, 0xdf, - 0x97, 0xbd, 0x4e, 0x9e, 0x85, 0x62, 0x4d, 0xf7, 0xd6, 0xc5, 0x75, 0x3f, 0xde, 0x41, 0x3f, 0x30, - 0x5b, 0xb4, 0xd1, 0xd1, 0xbd, 0x75, 0x0d, 0x51, 0xd2, 0x9c, 0x01, 0xc8, 0x31, 0x65, 0xce, 0x90, - 0x16, 0xfb, 0xe1, 0x67, 0x72, 0x57, 0x8b, 0xa9, 0x8b, 0xfd, 0x77, 0x8b, 0x59, 0xf3, 0xca, 0x7d, - 0xc7, 0xf4, 0xe8, 0x89, 0x86, 0x9d, 0x68, 0xd8, 0x01, 0x35, 0xec, 0x1f, 0xe5, 0x61, 0x34, 0xd8, - 0x34, 0xbd, 0x4f, 0x9b, 0x47, 0xb3, 0x56, 0x85, 0x5b, 0x99, 0xc2, 0x81, 0xb7, 0x32, 0x07, 0x51, - 0x28, 0x35, 0x38, 0x62, 0xe5, 0xa6, 0x01, 0x4a, 0x8c, 0x1f, 0xb1, 0x06, 0x07, 0xab, 0xcf, 0xc2, - 0xc0, 0xa2, 0xfe, 0xd8, 0x6c, 0x77, 0xdb, 0xc2, 0x4a, 0x47, 0xf7, 0xb5, 0xb6, 0xfe, 0x58, 0xf3, - 0xe1, 0xea, 0x7f, 0x9b, 0x83, 0x31, 0x21, 0x54, 0xc1, 0xfc, 0x40, 0x52, 0x0d, 0xa5, 0x93, 0x3f, - 0xb0, 0x74, 0x0a, 0xfb, 0x97, 0x8e, 0xfa, 0x97, 0x0b, 0xa0, 0xcc, 0x99, 0x2d, 0xba, 0xe2, 0xe8, - 0x96, 0xfb, 0x80, 0x3a, 0x62, 0x3b, 0x3d, 0xcb, 0x58, 0x1d, 0xe8, 0x03, 0xa5, 0x29, 0x25, 0xbf, - 0xaf, 0x29, 0xe5, 0x93, 0x30, 0x24, 0x1a, 0x13, 0xb8, 0x4e, 0xe2, 0xa8, 0x71, 0x7c, 0xa0, 0x16, - 0xe2, 0x19, 0x71, 0xb9, 0xd3, 0x71, 0xec, 0x47, 0xd4, 0xe1, 0xb7, 0x62, 0x82, 0x58, 0xf7, 0x81, - 0x5a, 0x88, 0x97, 0x38, 0x53, 0xdf, 0x5e, 0x94, 0x39, 0x53, 0x47, 0x0b, 0xf1, 0xe4, 0x2a, 0x0c, - 0x2e, 0xd8, 0x4d, 0x1d, 0x05, 0xcd, 0xa7, 0x95, 0x91, 0xed, 0xad, 0xc9, 0xc1, 0x96, 0x80, 0x69, - 0x01, 0x96, 0x51, 0x56, 0xec, 0x0d, 0xab, 0x65, 0xeb, 0xdc, 0xd9, 0x66, 0x90, 0x53, 0x1a, 0x02, - 0xa6, 0x05, 0x58, 0x46, 0xc9, 0x64, 0x8e, 0x4e, 0x4c, 0x83, 0x21, 0xcf, 0x07, 0x02, 0xa6, 0x05, - 0x58, 0xf5, 0x9b, 0x45, 0xa6, 0xbd, 0xae, 0xf9, 0xc1, 0x13, 0xbf, 0x2e, 0x84, 0x03, 0xa6, 0x7f, - 0x1f, 0x03, 0xe6, 0x89, 0x39, 0xb0, 0x53, 0xff, 0xc5, 0x00, 0x80, 0x90, 0xfe, 0xec, 0xc9, 0xe6, - 0xf0, 0x60, 0x5a, 0x53, 0x81, 0x53, 0xb3, 0xd6, 0xba, 0x6e, 0x35, 0xa9, 0x11, 0x1e, 0x5b, 0x96, - 0x70, 0x68, 0xa3, 0xd3, 0x25, 0x15, 0xc8, 0xf0, 0xdc, 0x52, 0x4b, 0x16, 0x20, 0x2f, 0xc1, 0x70, - 0xd5, 0xf2, 0xa8, 0xa3, 0x37, 0x3d, 0xf3, 0x11, 0x15, 0x53, 0x03, 0xde, 0x44, 0x9b, 0x21, 0x58, - 0x93, 0x69, 0xc8, 0x4d, 0x18, 0xa9, 0xe9, 0x8e, 0x67, 0x36, 0xcd, 0x8e, 0x6e, 0x79, 0xae, 0x32, - 0x88, 0x33, 0x1a, 0x5a, 0x18, 0x1d, 0x09, 0xae, 0x45, 0xa8, 0xc8, 0x17, 0x61, 0x08, 0xb7, 0xa6, - 0xe8, 0x1f, 0x3e, 0xb4, 0xe3, 0x45, 0xe5, 0x73, 0xa1, 0x3b, 0x22, 0x3f, 0x7d, 0xc5, 0x1b, 0xe7, - 0xf8, 0x5d, 0x65, 0xc0, 0x91, 0x7c, 0x0e, 0x06, 0x66, 0x2d, 0x03, 0x99, 0xc3, 0x8e, 0xcc, 0x55, - 0xc1, 0xfc, 0x5c, 0xc8, 0xdc, 0xee, 0xc4, 0x78, 0xfb, 0xec, 0xd2, 0x47, 0xd9, 0xf0, 0x87, 0x37, - 0xca, 0x46, 0x3e, 0x84, 0x63, 0xf1, 0xd1, 0xc3, 0x3a, 0x16, 0x1f, 0xdb, 0xe7, 0xb1, 0xb8, 0xfa, - 0x01, 0x0c, 0x4f, 0xd7, 0xe6, 0x82, 0xd1, 0x7b, 0x01, 0x0a, 0x35, 0xe1, 0x19, 0x51, 0xe4, 0xf6, - 0x4c, 0xc7, 0x34, 0x34, 0x06, 0x23, 0xd7, 0x60, 0x70, 0x06, 0xdd, 0xed, 0xc4, 0x2d, 0x62, 0x91, - 0xaf, 0x7f, 0x4d, 0x84, 0xa1, 0xd7, 0xad, 0x8f, 0x26, 0x1f, 0x87, 0x81, 0x9a, 0x63, 0xaf, 0x39, - 0x7a, 0x5b, 0xac, 0xc1, 0xe8, 0x9a, 0xd2, 0xe1, 0x20, 0xcd, 0xc7, 0xa9, 0x3f, 0x9d, 0xf3, 0xcd, - 0x76, 0x56, 0xa2, 0xde, 0xc5, 0xa3, 0x79, 0xac, 0x7b, 0x90, 0x97, 0x70, 0x39, 0x48, 0xf3, 0x71, - 0xe4, 0x1a, 0xf4, 0xcf, 0x3a, 0x8e, 0xed, 0xc8, 0x3e, 0xf5, 0x94, 0x01, 0xe4, 0xeb, 0x5e, 0xa4, - 0x20, 0xaf, 0xc1, 0x30, 0x9f, 0x73, 0xf8, 0x89, 0x66, 0xa1, 0xd7, 0x4d, 0xa9, 0x4c, 0xa9, 0xfe, - 0x6e, 0x41, 0xb2, 0xd9, 0xb8, 0xc4, 0x9f, 0xc0, 0x5b, 0x81, 0x97, 0xa1, 0x30, 0x5d, 0x9b, 0x13, - 0x13, 0xe0, 0x69, 0xbf, 0xa8, 0xa4, 0x2a, 0xb1, 0x72, 0x8c, 0x9a, 0x5c, 0x82, 0x62, 0x8d, 0xa9, - 0x4f, 0x09, 0xd5, 0x63, 0x70, 0x7b, 0x6b, 0xb2, 0xd8, 0x61, 0xfa, 0x83, 0x50, 0xc4, 0xb2, 0xcd, - 0x0c, 0xdf, 0x31, 0x71, 0x6c, 0xb8, 0x8f, 0xb9, 0x04, 0xc5, 0xb2, 0xb3, 0xf6, 0x48, 0xcc, 0x5a, - 0x88, 0xd5, 0x9d, 0xb5, 0x47, 0x1a, 0x42, 0xc9, 0x75, 0x00, 0x8d, 0x7a, 0x5d, 0xc7, 0xc2, 0xe7, - 0x2e, 0x43, 0x78, 0xfe, 0x86, 0xb3, 0xa1, 0x83, 0xd0, 0x46, 0xd3, 0x36, 0xa8, 0x26, 0x91, 0xa8, - 0x7f, 0x23, 0xbc, 0xd8, 0xa9, 0x98, 0xee, 0xc3, 0x93, 0x2e, 0xdc, 0x43, 0x17, 0xea, 0xe2, 0x88, - 0x33, 0xd9, 0x49, 0x93, 0xd0, 0x3f, 0xd7, 0xd2, 0xd7, 0x5c, 0xec, 0x43, 0xe1, 0xbb, 0xf6, 0x80, - 0x01, 0x34, 0x0e, 0x8f, 0xf5, 0xd3, 0xe0, 0xce, 0xfd, 0xf4, 0x73, 0xfd, 0xc1, 0x68, 0x5b, 0xa2, - 0xde, 0x86, 0xed, 0x9c, 0x74, 0xd5, 0x6e, 0xbb, 0xea, 0x0a, 0x0c, 0xd4, 0x9d, 0xa6, 0x74, 0x74, - 0x81, 0xfb, 0x01, 0xd7, 0x69, 0xf2, 0x63, 0x0b, 0x1f, 0xc9, 0xe8, 0x2a, 0xae, 0x87, 0x74, 0x03, - 0x21, 0x9d, 0xe1, 0x7a, 0x82, 0x4e, 0x20, 0x05, 0x5d, 0xcd, 0x76, 0x3c, 0xd1, 0x71, 0x01, 0x5d, - 0xc7, 0x76, 0x3c, 0xcd, 0x47, 0x92, 0x4f, 0x02, 0xac, 0xcc, 0xd4, 0x7c, 0xe7, 0xfe, 0xa1, 0xd0, - 0xf7, 0x50, 0x78, 0xf5, 0x6b, 0x12, 0x9a, 0xac, 0xc0, 0xd0, 0x72, 0x87, 0x3a, 0x7c, 0x2b, 0xc4, - 0x1f, 0xb0, 0x7c, 0x22, 0x26, 0x5a, 0xd1, 0xef, 0x53, 0xe2, 0xff, 0x80, 0x9c, 0xaf, 0x2f, 0xb6, - 0xff, 0x53, 0x0b, 0x19, 0x91, 0xd7, 0xa0, 0x54, 0xe6, 0x76, 0xde, 0x30, 0xb2, 0x0c, 0x44, 0x86, - 0x5b, 0x50, 0x8e, 0xe2, 0x7b, 0x76, 0x1d, 0xff, 0xd6, 0x04, 0xb9, 0x7a, 0x0d, 0x26, 0xe2, 0xd5, - 0x90, 0x61, 0x18, 0x98, 0x59, 0x5e, 0x5a, 0x9a, 0x9d, 0x59, 0x99, 0xe8, 0x23, 0x83, 0x50, 0xac, - 0xcf, 0x2e, 0x55, 0x26, 0x72, 0xea, 0x2f, 0x4b, 0x33, 0x08, 0x53, 0xad, 0x93, 0xab, 0xe1, 0x03, - 0xdd, 0xb7, 0x4c, 0xe0, 0x7d, 0x28, 0x9e, 0x18, 0xb4, 0x4d, 0xcf, 0xa3, 0x86, 0x58, 0x25, 0xf0, - 0xbe, 0xd0, 0x7b, 0xac, 0x25, 0xf0, 0xe4, 0x05, 0x18, 0x45, 0x98, 0xb8, 0x22, 0xe4, 0xfb, 0x63, - 0x51, 0xc0, 0x79, 0xac, 0x45, 0x91, 0xea, 0xef, 0x87, 0xb7, 0xc3, 0x0b, 0x54, 0x3f, 0xae, 0x37, - 0x8a, 0x1f, 0x91, 0xfe, 0x52, 0xff, 0x55, 0x91, 0x3f, 0x39, 0xe1, 0xef, 0x13, 0x8f, 0x42, 0x94, - 0xe1, 0x91, 0x6e, 0x61, 0x0f, 0x47, 0xba, 0x2f, 0x40, 0x69, 0x91, 0x7a, 0xeb, 0xb6, 0xef, 0xf8, - 0x85, 0x1e, 0x7a, 0x6d, 0x84, 0xc8, 0x1e, 0x7a, 0x9c, 0x86, 0x3c, 0x04, 0xe2, 0x3f, 0x3e, 0x0c, - 0x1c, 0xbf, 0xfd, 0x23, 0xe4, 0xf3, 0x89, 0x7d, 0x4a, 0x1d, 0x9f, 0x28, 0xa3, 0x4f, 0xff, 0x99, - 0xc0, 0xb1, 0x5c, 0xf2, 0xc4, 0xfa, 0x97, 0x5b, 0x93, 0x25, 0x4e, 0xa3, 0xa5, 0xb0, 0x25, 0xef, - 0xc2, 0xd0, 0xe2, 0x5c, 0x59, 0x3c, 0x44, 0xe4, 0x5e, 0x11, 0x17, 0x02, 0x29, 0xfa, 0x88, 0x40, - 0x24, 0xf8, 0xbe, 0xa7, 0xfd, 0x40, 0x4f, 0xbe, 0x43, 0x0c, 0xb9, 0x30, 0x6d, 0xe1, 0x2f, 0x85, - 0xc4, 0xe9, 0x42, 0xa0, 0x2d, 0xd1, 0xf7, 0x43, 0x71, 0x59, 0x71, 0x6c, 0x4c, 0x5b, 0x06, 0x0f, - 0x30, 0xba, 0x97, 0xe1, 0x54, 0xb9, 0xd3, 0x69, 0x99, 0xd4, 0x40, 0x7d, 0xd1, 0xba, 0x2d, 0xea, - 0x0a, 0x97, 0x1f, 0x7c, 0x7c, 0xa2, 0x73, 0x64, 0x03, 0x9f, 0xbf, 0x36, 0x9c, 0x6e, 0xd4, 0x3f, - 0x33, 0x59, 0x56, 0xfd, 0xd9, 0x3c, 0x9c, 0x9b, 0x71, 0xa8, 0xee, 0xd1, 0xc5, 0xb9, 0x72, 0xb9, - 0x8b, 0x3e, 0x72, 0xad, 0x16, 0xb5, 0xd6, 0x8e, 0x66, 0x58, 0xbf, 0x09, 0x63, 0x41, 0x03, 0xea, - 0x4d, 0xbb, 0x43, 0xe5, 0x87, 0x5c, 0x4d, 0x1f, 0xd3, 0x70, 0x19, 0x4a, 0x8b, 0x91, 0x92, 0x3b, - 0x70, 0x3a, 0x80, 0x94, 0x5b, 0x2d, 0x7b, 0x43, 0xa3, 0x5d, 0x97, 0x3b, 0xe2, 0x0e, 0x72, 0x47, - 0xdc, 0x90, 0x83, 0xce, 0xf0, 0x0d, 0x87, 0x11, 0x68, 0x69, 0xa5, 0xd4, 0x6f, 0x14, 0xe0, 0xfc, - 0x3d, 0xbd, 0x65, 0x1a, 0xa1, 0x68, 0x34, 0xea, 0x76, 0x6c, 0xcb, 0xa5, 0xc7, 0x68, 0x94, 0x46, - 0x86, 0x42, 0xf1, 0x50, 0x86, 0x42, 0xb2, 0x8b, 0xfa, 0x0f, 0xdc, 0x45, 0xa5, 0x7d, 0x75, 0xd1, - 0xff, 0x9a, 0x83, 0x09, 0xff, 0xa1, 0x81, 0xfc, 0x68, 0x5c, 0xf2, 0x82, 0xc7, 0x23, 0xc4, 0x98, - 0xdf, 0x35, 0xe2, 0x49, 0x1d, 0x06, 0x66, 0x1f, 0x77, 0x4c, 0x87, 0xba, 0xbb, 0x70, 0x1a, 0x7f, - 0x5a, 0x1c, 0x97, 0x9c, 0xa2, 0xbc, 0x48, 0xe2, 0xa4, 0x84, 0x83, 0xf1, 0xf9, 0x20, 0x7f, 0x6a, - 0x31, 0xed, 0xbf, 0x84, 0xe7, 0xcf, 0x07, 0xc5, 0x93, 0x8c, 0xc8, 0x7b, 0xd0, 0x90, 0x94, 0x3c, - 0x07, 0x85, 0x95, 0x95, 0x05, 0x31, 0x93, 0x62, 0x04, 0x02, 0xcf, 0x93, 0xdf, 0x47, 0x32, 0xac, - 0xfa, 0x4f, 0xf3, 0x00, 0x4c, 0x15, 0xf8, 0x70, 0x3d, 0x12, 0x25, 0x9c, 0x86, 0x41, 0x5f, 0xe0, - 0x42, 0x0d, 0x83, 0x57, 0x02, 0xf1, 0x8e, 0x88, 0xd7, 0x1d, 0xbc, 0x08, 0x99, 0xf4, 0x1d, 0xc9, - 0xf9, 0x3d, 0x00, 0xee, 0x6c, 0xd0, 0x91, 0xdc, 0x77, 0x1f, 0xff, 0x24, 0x0c, 0x89, 0x19, 0xcf, - 0x8e, 0x9c, 0xff, 0x37, 0x7d, 0xa0, 0x16, 0xe2, 0x63, 0x53, 0x6b, 0xe9, 0x00, 0x0b, 0xb1, 0x2f, - 0x5e, 0xde, 0x2b, 0x27, 0xe2, 0x3d, 0x64, 0xf1, 0x7e, 0x55, 0x88, 0x97, 0xbf, 0x18, 0x3a, 0xb6, - 0xe2, 0x3d, 0xb4, 0xb3, 0x6f, 0xf5, 0x1f, 0xe5, 0x80, 0xb0, 0x66, 0xd5, 0x74, 0xd7, 0xdd, 0xb0, - 0x1d, 0x83, 0x3b, 0xa7, 0x1f, 0x89, 0x60, 0x0e, 0xef, 0xbe, 0xf2, 0x77, 0x07, 0xe1, 0x74, 0xc4, - 0xf1, 0xf7, 0x98, 0x4f, 0x56, 0xd7, 0xa2, 0xa3, 0xa9, 0xd7, 0xab, 0x97, 0x8f, 0xc9, 0x17, 0xa2, - 0xfd, 0x91, 0x07, 0x6f, 0xd2, 0x4d, 0xe8, 0x8b, 0x30, 0x22, 0x7e, 0xb0, 0x15, 0xda, 0xbf, 0xe9, - 0xc2, 0x51, 0xea, 0x32, 0x80, 0x16, 0x41, 0x93, 0x57, 0x60, 0x88, 0x0d, 0x98, 0x35, 0x0c, 0x56, - 0x32, 0x10, 0xbe, 0x28, 0x31, 0x7c, 0xa0, 0xbc, 0x9e, 0x04, 0x94, 0xd2, 0xbb, 0xa5, 0xc1, 0x5d, - 0xbc, 0x5b, 0xfa, 0x12, 0x0c, 0x97, 0x2d, 0xcb, 0xf6, 0x70, 0x93, 0xee, 0x8a, 0xab, 0x89, 0x4c, - 0xab, 0xfc, 0x39, 0x7c, 0x8c, 0x1f, 0xd2, 0xa7, 0x9a, 0xe5, 0x32, 0x43, 0x72, 0xc3, 0x7f, 0x15, - 0x43, 0x1d, 0xe1, 0x55, 0x8e, 0xd7, 0x33, 0x8e, 0x80, 0x25, 0x1f, 0xc5, 0x60, 0xe7, 0x8d, 0xd6, - 0x1c, 0xbb, 0x63, 0xbb, 0xd4, 0xe0, 0x82, 0x1a, 0x0e, 0x43, 0x1b, 0x74, 0x04, 0x02, 0xdf, 0xcd, - 0x45, 0x02, 0x87, 0x44, 0x8a, 0x90, 0x07, 0x70, 0xc6, 0xbf, 0x28, 0x0e, 0x5e, 0x28, 0x56, 0x2b, - 0xae, 0x32, 0x82, 0xaf, 0x92, 0x48, 0x5c, 0x19, 0xaa, 0x95, 0xe9, 0xcb, 0xfe, 0xb5, 0x88, 0xff, - 0xc4, 0xb1, 0x61, 0x1a, 0x72, 0x57, 0xa7, 0xf2, 0x23, 0x3f, 0x08, 0xc3, 0x8b, 0xfa, 0xe3, 0x4a, - 0x57, 0x9c, 0xbd, 0x8c, 0xee, 0xfe, 0xf6, 0xa5, 0xad, 0x3f, 0x6e, 0x18, 0xa2, 0x5c, 0xcc, 0xa6, - 0x90, 0x59, 0x92, 0x06, 0x9c, 0xab, 0x39, 0x76, 0xdb, 0xf6, 0xa8, 0x11, 0x7b, 0xec, 0x37, 0x1e, - 0xbe, 0x0e, 0xee, 0x08, 0x8a, 0x46, 0x8f, 0x57, 0x7f, 0x19, 0x6c, 0x48, 0x1b, 0xc6, 0xcb, 0xae, - 0xdb, 0x6d, 0xd3, 0xf0, 0x86, 0x6a, 0x62, 0xc7, 0xcf, 0xf8, 0x84, 0xf0, 0x5a, 0x7e, 0x4a, 0xc7, - 0xa2, 0xfc, 0x82, 0xaa, 0xe1, 0x99, 0x72, 0x8d, 0xf8, 0x2d, 0x71, 0xde, 0xb7, 0x8b, 0x83, 0x63, - 0x13, 0xe3, 0xda, 0xf9, 0x64, 0x63, 0x56, 0x4c, 0xaf, 0x45, 0xd5, 0x6f, 0xe7, 0x00, 0x42, 0x01, - 0x93, 0x17, 0xa3, 0x11, 0x91, 0x72, 0xe1, 0x45, 0x87, 0x88, 0x96, 0x10, 0x09, 0x81, 0x44, 0x2e, - 0x41, 0x11, 0x23, 0x6a, 0xe4, 0xc3, 0x83, 0xd5, 0x87, 0xa6, 0x65, 0x68, 0x08, 0x65, 0x58, 0xe9, - 0xe9, 0x3b, 0x62, 0xf1, 0x52, 0x9f, 0x5b, 0x85, 0x15, 0x18, 0xaf, 0x77, 0x57, 0xfd, 0xba, 0xa5, - 0x77, 0x7c, 0x18, 0xd8, 0xc3, 0xed, 0xae, 0x06, 0x8f, 0x5f, 0x23, 0x61, 0x53, 0xa2, 0x45, 0xd4, - 0x6f, 0xe6, 0x62, 0xb3, 0xe0, 0x11, 0x2e, 0x7a, 0x1f, 0x4b, 0xfa, 0x69, 0x24, 0xa7, 0x25, 0xf5, - 0xaf, 0xe4, 0x61, 0xb8, 0x66, 0x3b, 0x9e, 0x08, 0x51, 0x72, 0xbc, 0x57, 0x21, 0x69, 0xaf, 0x54, - 0xdc, 0xc3, 0x5e, 0xe9, 0x12, 0x14, 0x25, 0x17, 0x65, 0x7e, 0x2f, 0x62, 0x18, 0x8e, 0x86, 0x50, - 0xf5, 0x87, 0xf3, 0x00, 0x9f, 0x7b, 0xe9, 0xa5, 0x27, 0x58, 0x40, 0xea, 0x5f, 0xca, 0xc1, 0xb8, - 0xb8, 0xa8, 0x93, 0x62, 0x8b, 0x0d, 0xf8, 0x57, 0xac, 0xf2, 0xb8, 0xe4, 0x20, 0xcd, 0xc7, 0xb1, - 0x25, 0x60, 0xf6, 0xb1, 0xe9, 0xe1, 0x5d, 0x85, 0x14, 0x5c, 0x8c, 0x0a, 0x98, 0xbc, 0x04, 0xf8, - 0x74, 0xe4, 0x45, 0xff, 0x0a, 0xb2, 0x10, 0xae, 0x7b, 0xac, 0xc0, 0x6c, 0xea, 0x35, 0xa4, 0xfa, - 0xeb, 0x45, 0x28, 0xce, 0x3e, 0xa6, 0xcd, 0x63, 0xde, 0x35, 0xd2, 0xc1, 0x66, 0xf1, 0x80, 0x07, - 0x9b, 0xfb, 0xf1, 0xa9, 0x78, 0x27, 0xec, 0xcf, 0x52, 0xb4, 0xfa, 0x58, 0xcf, 0xc7, 0xab, 0xf7, - 0x7b, 0xfa, 0xf8, 0xb9, 0xe4, 0xfc, 0x17, 0x05, 0x28, 0xd4, 0x67, 0x6a, 0x27, 0x7a, 0x73, 0xa4, - 0x7a, 0xd3, 0xfb, 0xce, 0x5a, 0x0d, 0xae, 0xa1, 0x06, 0x43, 0x2f, 0xd1, 0xd8, 0x8d, 0xd3, 0x9f, - 0x14, 0x60, 0xac, 0x3e, 0xb7, 0x52, 0x93, 0x4e, 0x82, 0xef, 0x70, 0x4f, 0x3e, 0xf4, 0x29, 0xe3, - 0x5d, 0x7a, 0x29, 0x61, 0xcf, 0xdc, 0xad, 0x5a, 0xde, 0xab, 0x37, 0xef, 0xe9, 0xad, 0x2e, 0xc5, - 0xa3, 0x17, 0xee, 0xf7, 0xeb, 0x9a, 0x1f, 0xd0, 0x6f, 0x60, 0xa0, 0x01, 0x9f, 0x01, 0x79, 0x13, - 0x0a, 0x77, 0x85, 0x47, 0x46, 0x16, 0x9f, 0x97, 0x6f, 0x70, 0x3e, 0x6c, 0x12, 0x2c, 0x74, 0x4d, - 0x03, 0x39, 0xb0, 0x52, 0xac, 0xf0, 0x2d, 0xb1, 0x00, 0xef, 0xaa, 0xf0, 0x9a, 0x5f, 0xf8, 0x56, - 0xb5, 0x42, 0xea, 0x30, 0x5c, 0xa3, 0x4e, 0xdb, 0xc4, 0x8e, 0xf2, 0xe7, 0xec, 0xde, 0x4c, 0xd8, - 0x4e, 0x65, 0xb8, 0x13, 0x16, 0x42, 0x66, 0x32, 0x17, 0xf2, 0x1e, 0x00, 0xb7, 0x51, 0x76, 0x19, - 0xaf, 0xf2, 0x69, 0xb4, 0xfb, 0xb9, 0x69, 0x99, 0x62, 0xe3, 0x49, 0xcc, 0xc8, 0x43, 0x98, 0x58, - 0xb4, 0x0d, 0xf3, 0x81, 0xc9, 0x5d, 0x2f, 0xb1, 0x82, 0xd2, 0xce, 0x0e, 0x4f, 0xcc, 0x94, 0x6c, - 0x4b, 0xe5, 0xd2, 0xaa, 0x49, 0x30, 0x56, 0xff, 0x6e, 0x3f, 0x14, 0x59, 0xb7, 0x9f, 0x8c, 0xdf, - 0x83, 0x8c, 0xdf, 0x32, 0x4c, 0xdc, 0xb7, 0x9d, 0x87, 0xa6, 0xb5, 0x16, 0x78, 0xc5, 0x8b, 0xbd, - 0x29, 0x7a, 0xf2, 0x6c, 0x70, 0x5c, 0x23, 0x70, 0xa0, 0xd7, 0x12, 0xe4, 0x3b, 0x8c, 0xe0, 0xd7, - 0x01, 0xf8, 0x5b, 0x77, 0xa4, 0x19, 0x0c, 0x83, 0x63, 0xf0, 0x97, 0xf0, 0xe8, 0x68, 0x2f, 0x07, - 0xc7, 0x08, 0x89, 0xd9, 0x26, 0x9c, 0xfb, 0x42, 0x0c, 0xa1, 0xdf, 0x3d, 0x6e, 0xc2, 0xd1, 0x17, - 0x42, 0x36, 0x02, 0xb8, 0x57, 0x44, 0x0d, 0x40, 0xba, 0x5f, 0x82, 0x98, 0x20, 0x22, 0x93, 0x83, - 0x08, 0x47, 0x97, 0x72, 0xbd, 0xa4, 0x49, 0x3c, 0xc8, 0xab, 0xb1, 0x0b, 0x70, 0x12, 0xe1, 0x96, - 0x79, 0xff, 0x1d, 0x3a, 0x50, 0x8d, 0xec, 0xe4, 0x40, 0xa5, 0xfe, 0xad, 0x02, 0x0c, 0x33, 0x6e, - 0xf5, 0x6e, 0xbb, 0xad, 0x3b, 0x9b, 0x27, 0x8a, 0x7c, 0x10, 0x45, 0x6e, 0xc0, 0x29, 0xd9, 0x61, - 0x9e, 0x99, 0xae, 0x7e, 0x68, 0xa3, 0xe0, 0xf8, 0x27, 0x4e, 0xc0, 0x6d, 0x4b, 0x9c, 0xf7, 0x3d, - 0x01, 0xc6, 0xb3, 0x05, 0x57, 0x4b, 0xf2, 0x52, 0x7f, 0x26, 0x07, 0x13, 0x71, 0x68, 0xa0, 0xfb, - 0xb9, 0x54, 0xdd, 0x7f, 0x01, 0x86, 0xc4, 0x15, 0xba, 0x6e, 0x08, 0x8f, 0xbe, 0xb1, 0xed, 0xad, - 0x49, 0xc0, 0xf7, 0xcb, 0x0d, 0x87, 0xea, 0x86, 0x16, 0x12, 0x90, 0x57, 0x60, 0x04, 0x7f, 0xdc, - 0x77, 0x4c, 0xcf, 0xa3, 0xbc, 0x33, 0x8a, 0xfc, 0x56, 0x80, 0x17, 0xd8, 0xe0, 0x08, 0x2d, 0x42, - 0xa6, 0xfe, 0x5e, 0x1e, 0x86, 0xea, 0xdd, 0x55, 0x77, 0xd3, 0xf5, 0x68, 0xfb, 0x98, 0xeb, 0x90, - 0xbf, 0x49, 0x2f, 0xa6, 0x6e, 0xd2, 0x9f, 0xf3, 0x87, 0x96, 0x74, 0x7a, 0x1d, 0x6c, 0x0c, 0x7c, - 0xaf, 0xc4, 0x50, 0x8b, 0x4a, 0x7b, 0xd7, 0x22, 0xf5, 0xef, 0xe4, 0x61, 0x82, 0x5f, 0xde, 0x56, - 0x4c, 0xb7, 0x79, 0x08, 0x0f, 0x4a, 0x8e, 0x5e, 0xa6, 0x07, 0x73, 0x78, 0xd8, 0xc5, 0x33, 0x1d, - 0xf5, 0xcb, 0x79, 0x18, 0x2e, 0x77, 0xbd, 0xf5, 0xb2, 0x87, 0xf3, 0xdb, 0x13, 0xb9, 0x47, 0xfe, - 0x07, 0x39, 0x18, 0x67, 0x0d, 0x59, 0xb1, 0x1f, 0x52, 0xeb, 0x10, 0x0e, 0xbf, 0xe5, 0x43, 0xec, - 0xfc, 0x3e, 0x0f, 0xb1, 0x7d, 0x59, 0x16, 0xf6, 0x26, 0x4b, 0xbc, 0xb2, 0xd1, 0xec, 0x16, 0x3d, - 0xde, 0x9f, 0x71, 0x88, 0x57, 0x36, 0xbe, 0x40, 0x0e, 0xe1, 0x8a, 0xf0, 0xfb, 0x4b, 0x20, 0x87, - 0x70, 0xbe, 0xf9, 0xfd, 0x21, 0x90, 0xdf, 0xcd, 0xc1, 0xd0, 0xb4, 0xed, 0x1d, 0xf3, 0x81, 0x2f, - 0xbe, 0xe2, 0x78, 0xab, 0xb9, 0xff, 0x15, 0xc7, 0x5b, 0x37, 0xd5, 0x9f, 0xcf, 0xc3, 0x19, 0x11, - 0x0f, 0x5f, 0x9c, 0x81, 0x9d, 0x4c, 0xc7, 0x62, 0xb0, 0x25, 0x45, 0x73, 0x32, 0x0f, 0x09, 0xd1, - 0xfc, 0x62, 0x01, 0xce, 0x60, 0xf8, 0x5e, 0xb6, 0xa3, 0xfa, 0x3e, 0xb0, 0x45, 0x48, 0x33, 0x7a, - 0x11, 0xbf, 0x98, 0x72, 0x11, 0xff, 0x2f, 0xb7, 0x26, 0x5f, 0x5d, 0x33, 0xbd, 0xf5, 0xee, 0xea, - 0x54, 0xd3, 0x6e, 0x5f, 0x5f, 0x73, 0xf4, 0x47, 0x26, 0xbf, 0x82, 0xd6, 0x5b, 0xd7, 0xc3, 0x34, - 0x35, 0x1d, 0x53, 0x24, 0x9d, 0xa9, 0xe3, 0x4e, 0x89, 0x71, 0xf5, 0xaf, 0xf0, 0x5d, 0x80, 0xdb, - 0xb6, 0x69, 0x09, 0xbf, 0x56, 0x6e, 0xe8, 0xd6, 0xb7, 0xb7, 0x26, 0xcf, 0xbe, 0x6f, 0x9b, 0x56, - 0x23, 0xee, 0xdc, 0xba, 0xd7, 0xfa, 0x42, 0xd6, 0x9a, 0x54, 0x8d, 0xfa, 0xdf, 0xe4, 0xe0, 0x42, - 0x54, 0x8b, 0xbf, 0x1f, 0x6c, 0xc7, 0xbf, 0x90, 0x87, 0xb3, 0xb7, 0x50, 0x38, 0x81, 0x33, 0xd1, - 0xc9, 0xbc, 0x25, 0x06, 0x67, 0x8a, 0x6c, 0x4e, 0x2c, 0xca, 0x6c, 0xd9, 0x9c, 0x4c, 0xea, 0x42, - 0x36, 0xff, 0x75, 0x0e, 0x4e, 0x2f, 0x57, 0x2b, 0x33, 0xdf, 0x27, 0x23, 0x2a, 0xf9, 0x3d, 0xc7, - 0xdc, 0xe0, 0x4c, 0x7c, 0xcf, 0x31, 0x37, 0x3d, 0xbf, 0x9e, 0x87, 0xd3, 0xf5, 0xf2, 0xe2, 0xc2, - 0xf7, 0xcb, 0x0c, 0x3e, 0x23, 0x7b, 0xbe, 0xfa, 0x87, 0x60, 0xc2, 0x16, 0x90, 0x3f, 0xf3, 0xde, - 0x8d, 0x6c, 0x8f, 0xd8, 0xa4, 0x50, 0x8e, 0xf9, 0xd4, 0x7d, 0x28, 0x42, 0x61, 0x9a, 0x1f, 0xa1, - 0x3e, 0xe6, 0x9a, 0xff, 0x9f, 0x97, 0x60, 0xf8, 0x4e, 0x77, 0x95, 0x0a, 0x07, 0xa9, 0x27, 0xfa, - 0xe4, 0xf7, 0x06, 0x0c, 0x0b, 0x31, 0xe0, 0x0d, 0x87, 0x14, 0xc0, 0x51, 0x04, 0xe4, 0xe1, 0x31, - 0xb2, 0x64, 0x22, 0x72, 0x09, 0x8a, 0xf7, 0xa8, 0xb3, 0x2a, 0xbf, 0x6d, 0x7e, 0x44, 0x9d, 0x55, - 0x0d, 0xa1, 0x64, 0x21, 0x7c, 0xb6, 0x51, 0xae, 0x55, 0x31, 0x79, 0x90, 0xb8, 0x34, 0xc4, 0x6c, - 0x48, 0x81, 0xef, 0xa5, 0xde, 0x31, 0x79, 0xda, 0x21, 0x39, 0xae, 0x42, 0xbc, 0x24, 0x59, 0x82, - 0x53, 0xb2, 0xf3, 0x1d, 0xcf, 0x9c, 0x33, 0x98, 0xc2, 0x2e, 0x2d, 0x67, 0x4e, 0xb2, 0x28, 0x79, - 0x07, 0x46, 0x7c, 0x20, 0xba, 0x11, 0x0e, 0x85, 0xe9, 0x1a, 0x02, 0x56, 0xb1, 0xe8, 0xfa, 0x91, - 0x02, 0x32, 0x03, 0xbc, 0xc4, 0x80, 0x14, 0x06, 0x31, 0xb7, 0xcc, 0x48, 0x01, 0xf2, 0x0a, 0x32, - 0xc0, 0xa7, 0x46, 0xe8, 0x30, 0x35, 0x8c, 0x0f, 0x7f, 0xf1, 0x02, 0xc8, 0x11, 0x70, 0xfe, 0xbc, - 0x3b, 0x42, 0x46, 0x96, 0x01, 0x42, 0xc7, 0x16, 0x11, 0x44, 0x63, 0xcf, 0x2e, 0x37, 0x12, 0x0b, - 0xf9, 0x26, 0x6f, 0x74, 0x3f, 0x37, 0x79, 0xea, 0xcf, 0x16, 0x60, 0xb8, 0xdc, 0xe9, 0x04, 0x43, - 0xe1, 0x45, 0x28, 0x95, 0x3b, 0x9d, 0xbb, 0x5a, 0x55, 0x0e, 0xa7, 0xaf, 0x77, 0x3a, 0x8d, 0xae, - 0x63, 0xca, 0x7e, 0xc9, 0x9c, 0x88, 0xcc, 0xc0, 0x68, 0xb9, 0xd3, 0xa9, 0x75, 0x57, 0x5b, 0x66, - 0x53, 0xca, 0x06, 0xc6, 0xf3, 0x25, 0x76, 0x3a, 0x8d, 0x0e, 0x62, 0xe2, 0x29, 0xe1, 0xa2, 0x65, - 0xc8, 0x97, 0x30, 0xf4, 0x94, 0x48, 0x46, 0xc5, 0xd3, 0xdd, 0xa8, 0x41, 0x20, 0xfd, 0xb0, 0x6d, - 0x53, 0x01, 0x11, 0x4f, 0x38, 0x70, 0xc9, 0x4f, 0x13, 0xc1, 0x2a, 0x4a, 0x24, 0x9d, 0x0a, 0x59, - 0x92, 0x4f, 0xc1, 0x40, 0xb9, 0xd3, 0x91, 0x6e, 0xab, 0xd0, 0xb1, 0x8d, 0x95, 0x8a, 0xe7, 0xfb, - 0x13, 0x64, 0xe2, 0xb3, 0xc4, 0xfd, 0xb6, 0xed, 0x78, 0x38, 0xa4, 0x46, 0xc3, 0xcf, 0xf2, 0x2f, - 0xc4, 0x6d, 0x39, 0xda, 0x8b, 0x16, 0x2d, 0x73, 0xf1, 0x2d, 0x18, 0x8b, 0xb6, 0x78, 0x4f, 0x59, - 0x0f, 0xbe, 0x97, 0x43, 0xa9, 0x1c, 0x73, 0xe7, 0xfc, 0x97, 0xa1, 0x50, 0xee, 0x74, 0xc4, 0xa4, - 0x76, 0x3a, 0xa5, 0x53, 0xe3, 0x6f, 0xf9, 0xcb, 0x9d, 0x8e, 0xff, 0xe9, 0xc7, 0xfc, 0x95, 0xcf, - 0xbe, 0x3e, 0xfd, 0x77, 0xf9, 0xa7, 0x1f, 0xef, 0x17, 0x38, 0xea, 0xaf, 0x17, 0x60, 0xbc, 0xdc, - 0xe9, 0x9c, 0x64, 0x4b, 0x38, 0xac, 0x88, 0x01, 0x2f, 0x01, 0x48, 0x73, 0xec, 0x40, 0xf0, 0x06, - 0x71, 0x58, 0x9a, 0x5f, 0x95, 0x9c, 0x26, 0x11, 0xf9, 0xea, 0x37, 0xb8, 0x27, 0xf5, 0xfb, 0x72, - 0x01, 0x27, 0xbe, 0xe3, 0x1e, 0xfd, 0xec, 0xa3, 0xd2, 0x6d, 0xa2, 0x0f, 0x4a, 0x7b, 0xea, 0x83, - 0xbf, 0x1f, 0x19, 0x3c, 0x18, 0x7d, 0xff, 0xa4, 0x17, 0xfa, 0x0f, 0x64, 0x5b, 0x8f, 0xc9, 0xc2, - 0x14, 0x21, 0x99, 0xfc, 0x0c, 0x64, 0x22, 0x40, 0x58, 0x93, 0xa1, 0x1a, 0xa6, 0xa1, 0xc5, 0x68, - 0xfd, 0x3e, 0x1c, 0xd8, 0x53, 0x1f, 0x6e, 0xe5, 0x31, 0x08, 0x40, 0x10, 0x60, 0xec, 0xe0, 0x5b, - 0x94, 0xeb, 0x00, 0xdc, 0x7d, 0x21, 0xf0, 0xcf, 0x1f, 0xe5, 0xb1, 0x84, 0x78, 0x62, 0x32, 0x11, - 0x4b, 0x28, 0x24, 0x09, 0xdc, 0x9d, 0x0a, 0xa9, 0xee, 0x4e, 0xd7, 0x60, 0x50, 0xd3, 0x37, 0xde, - 0xed, 0x52, 0x67, 0x53, 0xd8, 0x44, 0x3c, 0x7e, 0xa7, 0xbe, 0xd1, 0xf8, 0x21, 0x06, 0xd4, 0x02, - 0x34, 0x51, 0x83, 0x28, 0x12, 0x92, 0x5b, 0x09, 0x3f, 0x68, 0x0f, 0x62, 0x47, 0xec, 0x47, 0xd1, - 0xc9, 0x1b, 0x50, 0x28, 0xdf, 0xaf, 0x0b, 0xc9, 0x06, 0x5d, 0x5b, 0xbe, 0x5f, 0x17, 0xf2, 0xca, - 0x2c, 0x7b, 0xbf, 0xae, 0x7e, 0x39, 0x0f, 0x24, 0x49, 0x49, 0x5e, 0x85, 0x21, 0x84, 0xae, 0x31, - 0x9d, 0x91, 0x33, 0xda, 0x6e, 0xb8, 0x0d, 0x07, 0xa1, 0x11, 0x0b, 0xd1, 0x27, 0x25, 0xaf, 0x63, - 0xce, 0x70, 0x91, 0x53, 0x31, 0x92, 0xd1, 0x76, 0xc3, 0xf5, 0xb3, 0x6c, 0xc7, 0x52, 0x86, 0x0b, - 0x62, 0x34, 0x2e, 0xef, 0xd7, 0xe7, 0x6d, 0xd7, 0x13, 0xa2, 0xe6, 0xc6, 0xe5, 0x86, 0x8b, 0xa9, - 0x94, 0x23, 0xc6, 0x25, 0x27, 0xc3, 0x74, 0x70, 0xf7, 0xeb, 0xfc, 0xbd, 0x95, 0xa1, 0xd9, 0x2d, - 0xdf, 0x2a, 0xe5, 0xe9, 0xe0, 0x36, 0xdc, 0x06, 0x7f, 0xab, 0x65, 0x60, 0xb2, 0xf2, 0x48, 0x3a, - 0xb8, 0x48, 0x29, 0xf5, 0xa7, 0x06, 0x61, 0xa2, 0xa2, 0x7b, 0xfa, 0xaa, 0xee, 0x52, 0x69, 0x4b, - 0x3e, 0xee, 0xc3, 0xfc, 0xcf, 0x91, 0xe4, 0x60, 0xac, 0xa6, 0x7c, 0x4d, 0xbc, 0x00, 0x79, 0x33, - 0xe4, 0x1b, 0x24, 0xeb, 0x95, 0xb3, 0xff, 0xad, 0x36, 0x3a, 0x02, 0xac, 0x25, 0x08, 0xc9, 0x0b, - 0x30, 0xec, 0xc3, 0xd8, 0x2e, 0xa2, 0x10, 0xea, 0x8c, 0xb1, 0xca, 0x36, 0x11, 0x9a, 0x8c, 0x26, - 0xaf, 0xc3, 0x88, 0xff, 0x53, 0xb2, 0xcf, 0x79, 0x2a, 0xc3, 0xd5, 0xc4, 0x16, 0x4c, 0x26, 0x95, - 0x8b, 0xe2, 0xfc, 0xd6, 0x1f, 0x29, 0x1a, 0xcb, 0x16, 0x18, 0x21, 0x25, 0x3f, 0x04, 0x63, 0xfe, - 0x6f, 0xb1, 0xeb, 0xe0, 0xde, 0x87, 0x2f, 0x04, 0xb9, 0xd0, 0x63, 0x62, 0x9d, 0x8a, 0x92, 0xf3, - 0xfd, 0xc7, 0x53, 0x7e, 0x02, 0x3c, 0x63, 0x35, 0xb9, 0xfd, 0x88, 0x55, 0x40, 0xaa, 0x70, 0xca, - 0x87, 0x84, 0x1a, 0x3a, 0x10, 0x6e, 0x3b, 0x8d, 0xd5, 0x46, 0xaa, 0x92, 0x26, 0x4b, 0x91, 0x16, - 0x5c, 0x8a, 0x00, 0x0d, 0x77, 0xdd, 0x7c, 0xe0, 0x89, 0x3d, 0xa3, 0x08, 0xa6, 0x2d, 0x32, 0x9e, - 0x06, 0x5c, 0x39, 0x8d, 0x9f, 0xba, 0x38, 0x9a, 0xe6, 0xac, 0x27, 0x37, 0x52, 0x87, 0x33, 0x3e, - 0xfe, 0xd6, 0x4c, 0xad, 0xe6, 0xd8, 0xef, 0xd3, 0xa6, 0x57, 0xad, 0x88, 0x3d, 0x37, 0x06, 0x59, - 0x34, 0x56, 0x1b, 0x6b, 0xcd, 0x0e, 0x53, 0x0a, 0x86, 0x8b, 0x32, 0x4f, 0x2d, 0x4c, 0xee, 0xc1, - 0x59, 0x09, 0x2e, 0xe5, 0x55, 0x87, 0xf0, 0x50, 0x40, 0x70, 0x4d, 0x4f, 0xad, 0x9e, 0x5e, 0x9c, - 0xbc, 0x05, 0xa3, 0x3e, 0x82, 0x5f, 0x45, 0x0e, 0xe3, 0x55, 0x24, 0x0e, 0x49, 0x63, 0xb5, 0x11, - 0x7f, 0x16, 0x1c, 0x25, 0x96, 0x35, 0x6a, 0x65, 0xb3, 0x43, 0x85, 0x5b, 0xb0, 0xaf, 0x51, 0xde, - 0x66, 0x27, 0x55, 0x19, 0x19, 0x29, 0x79, 0x27, 0xd4, 0xa8, 0x65, 0xc7, 0x5c, 0x33, 0xf9, 0x76, - 0xdc, 0x7f, 0x09, 0xbc, 0xda, 0xb0, 0x11, 0x98, 0xa6, 0x1f, 0x9c, 0xfc, 0x62, 0x19, 0x4e, 0xa7, - 0xe8, 0xd8, 0x9e, 0x76, 0x8c, 0x5f, 0xc9, 0x87, 0x8d, 0x38, 0xe6, 0xdb, 0xc6, 0x69, 0x18, 0xf4, - 0xbf, 0x44, 0x18, 0x0f, 0x4a, 0xd6, 0xd0, 0x8c, 0xf3, 0xf0, 0xf1, 0x11, 0x71, 0x1c, 0xf3, 0xad, - 0xe4, 0x61, 0x88, 0xe3, 0x3b, 0xb9, 0x50, 0x1c, 0xc7, 0x7c, 0x7b, 0xf9, 0x93, 0xc5, 0x70, 0x4e, - 0x3a, 0xd9, 0x63, 0x1e, 0x96, 0x99, 0x1c, 0x3a, 0xd3, 0x96, 0xf6, 0xf0, 0x22, 0x57, 0x56, 0xcd, - 0x81, 0xfd, 0xa9, 0x26, 0x79, 0x0b, 0x86, 0x6b, 0xb6, 0xeb, 0xad, 0x39, 0xd4, 0xad, 0x05, 0xc9, - 0x20, 0xf0, 0x35, 0x77, 0x47, 0x80, 0x1b, 0x9d, 0xc8, 0xec, 0x2f, 0x93, 0xab, 0xff, 0xb8, 0x90, - 0xd0, 0x06, 0x6e, 0xb8, 0x1e, 0x4b, 0x6d, 0x38, 0x84, 0xa1, 0x4e, 0x6e, 0x84, 0xab, 0x20, 0xb7, - 0xf0, 0xfb, 0xa5, 0x48, 0x97, 0xab, 0xc2, 0xc0, 0x8f, 0x92, 0x90, 0x2f, 0xc0, 0xf9, 0x08, 0xa0, - 0xa6, 0x3b, 0x7a, 0x9b, 0x7a, 0x61, 0xe2, 0x4d, 0x8c, 0x5d, 0xe6, 0x97, 0x6e, 0x74, 0x02, 0xb4, - 0x9c, 0xcc, 0x33, 0x83, 0x83, 0xa4, 0x5a, 0x03, 0x7b, 0xf0, 0xd3, 0xfe, 0xb9, 0x42, 0x68, 0xe8, - 0x44, 0x63, 0x10, 0x6b, 0xd4, 0xed, 0xb6, 0xbc, 0x27, 0xb7, 0x83, 0xf7, 0x97, 0xe1, 0x65, 0x1e, - 0xc6, 0xcb, 0x0f, 0x1e, 0xd0, 0xa6, 0xe7, 0x87, 0x56, 0x77, 0x45, 0xd4, 0x49, 0xbe, 0xf1, 0x10, - 0x28, 0x11, 0x2a, 0x5b, 0xee, 0xd7, 0x78, 0x31, 0xf5, 0x9f, 0x14, 0x41, 0x09, 0x0c, 0xff, 0xe0, - 0xbd, 0xe2, 0x11, 0x2e, 0xb2, 0x1f, 0x89, 0x5e, 0x31, 0xe1, 0x54, 0x28, 0x0c, 0xf1, 0x50, 0x4c, - 0xa4, 0x82, 0x9f, 0x8c, 0x33, 0x0b, 0x09, 0xf9, 0x5e, 0xe2, 0xa2, 0xd8, 0x4b, 0x90, 0xf0, 0x3d, - 0x68, 0xc3, 0xe5, 0x2c, 0xb4, 0x24, 0x57, 0xf2, 0xd5, 0x1c, 0x9c, 0xf1, 0x3b, 0x65, 0x79, 0x95, - 0x19, 0xd5, 0x33, 0x76, 0xd7, 0x0a, 0x5e, 0x51, 0xbd, 0x91, 0x5d, 0x1d, 0xef, 0xa4, 0xa9, 0xb4, - 0xc2, 0xbc, 0x25, 0x41, 0x7c, 0x95, 0x40, 0x21, 0x6c, 0xa4, 0x69, 0x34, 0x91, 0x48, 0x4b, 0xad, - 0xf7, 0xe2, 0x2d, 0xb8, 0x90, 0xc9, 0x72, 0x27, 0x23, 0xb6, 0x5f, 0x36, 0x62, 0xff, 0xbb, 0x5c, - 0x38, 0x11, 0xc5, 0x84, 0x44, 0xa6, 0x00, 0x42, 0x90, 0xd8, 0xd6, 0xe2, 0x23, 0xad, 0x50, 0x68, - 0x9a, 0x44, 0x41, 0x96, 0xa1, 0x24, 0xc4, 0xc2, 0x93, 0x5c, 0x7f, 0x72, 0x87, 0x5e, 0x98, 0x92, - 0xe5, 0x80, 0x5b, 0x56, 0xf1, 0xcd, 0x82, 0xcd, 0xc5, 0xd7, 0x61, 0x78, 0xbf, 0xdf, 0xf5, 0xd5, - 0x02, 0x10, 0x79, 0x0f, 0x7a, 0x84, 0x06, 0xfa, 0x31, 0x9e, 0xc2, 0xae, 0xc2, 0x20, 0xfb, 0x04, - 0x4c, 0xfb, 0x22, 0x85, 0x79, 0xee, 0x0a, 0x98, 0x16, 0x60, 0xc3, 0x18, 0x6b, 0x03, 0xe9, 0x31, - 0xd6, 0xd4, 0x9f, 0x29, 0xc0, 0x39, 0xb9, 0x43, 0x2a, 0x14, 0x33, 0x47, 0x9c, 0x74, 0xca, 0x87, - 0xd8, 0x29, 0x2a, 0x94, 0xf8, 0xd6, 0x43, 0xa4, 0xf0, 0xe0, 0xc7, 0x42, 0x08, 0xd1, 0x04, 0x46, - 0xfd, 0x9f, 0xf3, 0x30, 0x1a, 0x98, 0x77, 0xba, 0xe3, 0x3e, 0xc1, 0xdd, 0xf1, 0x69, 0x18, 0xc5, - 0x28, 0x59, 0x6d, 0x6a, 0xf1, 0x48, 0x52, 0xfd, 0x52, 0xce, 0x1d, 0x1f, 0x21, 0xd2, 0xab, 0x45, - 0x08, 0x99, 0xf6, 0x73, 0xcb, 0x4f, 0x8a, 0x5d, 0xc6, 0xcd, 0x3e, 0x0e, 0x57, 0xff, 0x6a, 0x01, - 0x46, 0x7c, 0x29, 0x4f, 0x9b, 0xc7, 0xf5, 0x9e, 0xe7, 0x68, 0x85, 0x7c, 0x1d, 0xa0, 0x66, 0x3b, - 0x9e, 0xde, 0x5a, 0x0a, 0x35, 0x1f, 0x0f, 0x48, 0x3b, 0x08, 0xe5, 0x65, 0x24, 0x12, 0x5c, 0xbf, - 0x42, 0xb3, 0x9a, 0x4f, 0x4c, 0x7c, 0xfd, 0x0a, 0xa0, 0x9a, 0x44, 0xa1, 0xfe, 0x76, 0x1e, 0xc6, - 0xfd, 0x4e, 0x9a, 0x7d, 0x4c, 0x9b, 0xdd, 0x27, 0x79, 0x6e, 0x8a, 0x4a, 0xbb, 0x7f, 0x47, 0x69, - 0xab, 0xff, 0xa7, 0x34, 0x91, 0xcc, 0xb4, 0xec, 0x93, 0x89, 0xe4, 0x4f, 0x43, 0xc7, 0xd5, 0x1f, - 0x2d, 0xc0, 0x19, 0x5f, 0xea, 0x73, 0x5d, 0x0b, 0x8f, 0x16, 0x66, 0xf4, 0x56, 0xeb, 0x49, 0xde, - 0x8d, 0x0f, 0xfb, 0x82, 0x58, 0x16, 0x61, 0x27, 0x45, 0xaa, 0xcb, 0x07, 0x02, 0xdc, 0xb0, 0x4d, - 0x43, 0x93, 0x89, 0xc8, 0x3b, 0x30, 0xe2, 0xff, 0x2c, 0x3b, 0x6b, 0xfe, 0x16, 0x1c, 0x2f, 0x0a, - 0x82, 0x42, 0xba, 0x13, 0x89, 0xae, 0x11, 0x29, 0xa0, 0x7e, 0x79, 0x00, 0x2e, 0xde, 0x37, 0x2d, - 0xc3, 0xde, 0x70, 0xfd, 0x4c, 0xa9, 0xc7, 0xfe, 0xa0, 0xec, 0xa8, 0x33, 0xa4, 0xbe, 0x0b, 0x67, - 0xe3, 0x22, 0x75, 0x82, 0xf8, 0xf5, 0xa2, 0x77, 0x36, 0x38, 0x41, 0xc3, 0xcf, 0x99, 0x2a, 0x6e, - 0xdb, 0xb4, 0xf4, 0x92, 0xf1, 0xa4, 0xab, 0x03, 0xbb, 0x49, 0xba, 0xfa, 0x3c, 0x94, 0x2a, 0x76, - 0x5b, 0x37, 0xfd, 0x38, 0x4b, 0x38, 0x8a, 0x83, 0x7a, 0x11, 0xa3, 0x09, 0x0a, 0xc6, 0x5f, 0x54, - 0x8c, 0x5d, 0x36, 0x14, 0xf2, 0xf7, 0x0b, 0x30, 0x2b, 0x4d, 0x93, 0x89, 0x88, 0x0d, 0xa3, 0xa2, - 0x3a, 0x71, 0x37, 0x06, 0xb8, 0x79, 0x7a, 0xc5, 0x97, 0x51, 0xb6, 0x5a, 0x4d, 0x45, 0xca, 0xf1, - 0x6d, 0x14, 0xcf, 0x05, 0x2b, 0x3e, 0x86, 0xdf, 0x92, 0x69, 0x51, 0xfe, 0x92, 0x10, 0x70, 0x92, - 0x19, 0x4e, 0x0a, 0x01, 0x67, 0x19, 0x99, 0x88, 0xcc, 0xc2, 0x29, 0x8c, 0x32, 0x1e, 0x6c, 0xa5, - 0x98, 0x4a, 0x8c, 0xa0, 0x51, 0x89, 0x57, 0x2e, 0x3c, 0x30, 0x39, 0xfb, 0xb8, 0x46, 0x53, 0xa0, - 0xb5, 0x64, 0x09, 0x72, 0x01, 0x0a, 0x4b, 0x0b, 0x65, 0xbc, 0xab, 0x19, 0xe4, 0x19, 0xbe, 0xac, - 0x96, 0xae, 0x31, 0xd8, 0xc5, 0xcf, 0x02, 0x49, 0x7e, 0xce, 0x9e, 0xee, 0x63, 0xfe, 0x4b, 0x69, - 0xcb, 0x77, 0xdc, 0x3d, 0x6a, 0x0e, 0x63, 0x22, 0x8c, 0x24, 0xd7, 0xeb, 0xff, 0x30, 0x93, 0xeb, - 0x95, 0x0e, 0x35, 0xb9, 0x9e, 0xfa, 0x2b, 0x39, 0x38, 0x95, 0x88, 0xc4, 0x4f, 0x5e, 0x06, 0xe0, - 0x10, 0x29, 0xe2, 0x29, 0x86, 0x10, 0x0a, 0xa3, 0xf3, 0x8b, 0xe5, 0x31, 0x24, 0x23, 0xd7, 0x61, - 0x90, 0xff, 0x12, 0x51, 0xca, 0x92, 0x45, 0xba, 0x5d, 0xd3, 0xd0, 0x02, 0xa2, 0xb0, 0x16, 0xbc, - 0x91, 0x2c, 0xa4, 0x16, 0xf1, 0x36, 0x3b, 0x41, 0x2d, 0x8c, 0x4c, 0xfd, 0xa9, 0x3c, 0x8c, 0x04, - 0x0d, 0x2e, 0x1b, 0x47, 0xa5, 0x73, 0x25, 0x91, 0xd4, 0xa0, 0xb0, 0x53, 0x52, 0x83, 0xd8, 0x7c, - 0x2b, 0xb2, 0x18, 0x1c, 0xde, 0xab, 0xac, 0xaf, 0xe5, 0x61, 0x3c, 0xa8, 0xf5, 0x08, 0x2f, 0xbf, - 0x3e, 0x42, 0x22, 0xf9, 0x6a, 0x0e, 0x94, 0x69, 0xb3, 0xd5, 0x32, 0xad, 0xb5, 0xaa, 0xf5, 0xc0, - 0x76, 0xda, 0x38, 0x21, 0x1e, 0xdd, 0x11, 0xae, 0xfa, 0x67, 0x73, 0x70, 0x4a, 0x34, 0x68, 0x46, - 0x77, 0x8c, 0xa3, 0x3b, 0x1f, 0x8b, 0xb7, 0xe4, 0xe8, 0xf4, 0x45, 0xfd, 0x56, 0x1e, 0x60, 0xc1, - 0x6e, 0x3e, 0x3c, 0xe6, 0x8f, 0xba, 0xde, 0x84, 0x12, 0x77, 0x8b, 0x17, 0x1a, 0x7b, 0x4a, 0x3c, - 0x5e, 0x62, 0x9f, 0xc6, 0x11, 0xd3, 0x13, 0x62, 0x3e, 0x2e, 0x71, 0xcf, 0x7a, 0x25, 0xa7, 0x89, - 0x22, 0xac, 0x52, 0x46, 0x27, 0x16, 0x8c, 0xa0, 0x52, 0x06, 0x8b, 0x56, 0xba, 0xbd, 0x35, 0x59, - 0x6c, 0xd9, 0xcd, 0x87, 0x1a, 0xd2, 0xab, 0xff, 0x2a, 0xc7, 0x65, 0x77, 0xcc, 0x9f, 0xa6, 0xfa, - 0x9f, 0x5f, 0xdc, 0xe3, 0xe7, 0xff, 0xb9, 0x1c, 0x9c, 0xd1, 0x68, 0xd3, 0x7e, 0x44, 0x9d, 0xcd, - 0x19, 0xdb, 0xa0, 0xb7, 0xa8, 0x45, 0x9d, 0xa3, 0x1a, 0x51, 0xbf, 0x83, 0x59, 0x60, 0xc2, 0xc6, - 0xdc, 0x75, 0xa9, 0x71, 0x7c, 0x32, 0xf4, 0xa8, 0xbf, 0x36, 0x00, 0x4a, 0xaa, 0xd5, 0x7b, 0x6c, - 0xcd, 0xb9, 0xcc, 0xad, 0x4c, 0xf1, 0xb0, 0xb6, 0x32, 0xfd, 0x7b, 0xdb, 0xca, 0x94, 0xf6, 0xba, - 0x95, 0x19, 0xd8, 0xcd, 0x56, 0xa6, 0x1d, 0xdf, 0xca, 0x0c, 0xe2, 0x56, 0xe6, 0xe5, 0x9e, 0x5b, - 0x99, 0x59, 0xcb, 0xd8, 0xe7, 0x46, 0xe6, 0xd8, 0x66, 0x8f, 0xde, 0xcf, 0x0e, 0xec, 0x2a, 0x9b, - 0x14, 0x9b, 0xb6, 0x63, 0x50, 0x43, 0x6c, 0xbc, 0xf0, 0xd4, 0xdf, 0x11, 0x30, 0x2d, 0xc0, 0x26, - 0x52, 0x71, 0x8f, 0xee, 0x26, 0x15, 0xf7, 0x21, 0xec, 0xbf, 0xbe, 0x92, 0x87, 0x53, 0x33, 0xd4, - 0xf1, 0x78, 0x2c, 0xda, 0xc3, 0x70, 0x89, 0x2b, 0xc3, 0xb8, 0xc4, 0x10, 0x2d, 0xf2, 0x7c, 0xe8, - 0xe6, 0xd7, 0xa4, 0x8e, 0x17, 0xf7, 0x12, 0x8c, 0xd3, 0xb3, 0xea, 0xfd, 0x74, 0x78, 0x62, 0xec, - 0x06, 0xd5, 0xfb, 0x70, 0x2e, 0x48, 0x53, 0xfc, 0xd2, 0x02, 0x7a, 0x29, 0xc3, 0x5d, 0x71, 0xef, - 0x19, 0xee, 0xd4, 0x5f, 0xce, 0xc1, 0x15, 0x8d, 0x5a, 0x74, 0x43, 0x5f, 0x6d, 0x51, 0xa9, 0x59, - 0x62, 0x65, 0x60, 0xb3, 0x86, 0xe9, 0xb6, 0x75, 0xaf, 0xb9, 0x7e, 0x20, 0x19, 0xcd, 0xc1, 0x88, - 0x3c, 0x7f, 0xed, 0x61, 0x6e, 0x8b, 0x94, 0x53, 0x7f, 0xad, 0x08, 0x03, 0xd3, 0xb6, 0x77, 0xdb, - 0x3e, 0x60, 0xca, 0xc5, 0x70, 0xca, 0xcf, 0xef, 0xe1, 0xac, 0xe7, 0x53, 0x58, 0xb9, 0x94, 0x85, - 0x02, 0x5d, 0x48, 0x57, 0xed, 0x44, 0xb6, 0x0e, 0x9f, 0x6c, 0x8f, 0xc9, 0x16, 0x5f, 0x85, 0x21, - 0x0c, 0x21, 0x23, 0x9d, 0xc6, 0xa2, 0x83, 0xb6, 0xc7, 0x80, 0xf1, 0x3a, 0x42, 0x52, 0xf2, 0x85, - 0x48, 0xf0, 0xdc, 0xd2, 0xc1, 0x93, 0x33, 0xca, 0x71, 0x74, 0x5f, 0xe6, 0x17, 0x79, 0xd8, 0x26, - 0x29, 0x91, 0x0d, 0x9e, 0xa2, 0xc4, 0x9a, 0x14, 0x10, 0x1e, 0x62, 0xe2, 0xc4, 0x19, 0x18, 0x9d, - 0xb6, 0x3d, 0xc9, 0x19, 0x78, 0x28, 0x7c, 0x4b, 0xca, 0x24, 0x9f, 0xee, 0x09, 0x1c, 0x2d, 0xa3, - 0xfe, 0x49, 0x11, 0x46, 0xfc, 0x9f, 0x47, 0xa4, 0x3b, 0x2f, 0x42, 0x69, 0xde, 0x96, 0x72, 0x79, - 0xa0, 0x03, 0xf1, 0xba, 0xed, 0xc6, 0x3c, 0xa3, 0x05, 0x11, 0x93, 0xfa, 0x92, 0x6d, 0xc8, 0xee, - 0xef, 0x28, 0x75, 0xcb, 0x36, 0x12, 0x6f, 0x90, 0x03, 0x42, 0x72, 0x05, 0x8a, 0xf8, 0x72, 0x40, - 0x3a, 0xc8, 0x8f, 0xbd, 0x16, 0x40, 0xbc, 0xa4, 0x95, 0xa5, 0xbd, 0x6a, 0xe5, 0xc0, 0x7e, 0xb5, - 0x72, 0xf0, 0x70, 0xb5, 0xf2, 0x3d, 0x18, 0xc1, 0x9a, 0xfc, 0x54, 0x80, 0x3b, 0x2f, 0xac, 0x17, - 0xc4, 0xda, 0x37, 0xca, 0xdb, 0x2d, 0x12, 0x02, 0xe2, 0x92, 0x17, 0x61, 0x15, 0xd3, 0x5d, 0x38, - 0xc0, 0x76, 0xfa, 0x1f, 0xe7, 0x60, 0xe0, 0xae, 0xf5, 0xd0, 0xb2, 0x37, 0x0e, 0xa6, 0x71, 0x2f, - 0xc3, 0xb0, 0x60, 0x23, 0xad, 0x2e, 0xf8, 0xac, 0xbc, 0xcb, 0xc1, 0x0d, 0xe4, 0xa4, 0xc9, 0x54, - 0xe4, 0xad, 0xa0, 0x10, 0x3e, 0x0e, 0x2a, 0x84, 0xd9, 0x70, 0xfc, 0x42, 0xcd, 0x68, 0x02, 0x0f, - 0x99, 0x9c, 0x5c, 0x82, 0x62, 0x85, 0x35, 0x55, 0x0a, 0xe4, 0xcb, 0x9a, 0xa2, 0x21, 0x54, 0xfd, - 0x4a, 0x11, 0xc6, 0x62, 0x07, 0x5f, 0xcf, 0xc3, 0x90, 0x38, 0x78, 0x32, 0xfd, 0x8c, 0x22, 0xf8, - 0x78, 0x28, 0x00, 0x6a, 0x83, 0xfc, 0xcf, 0xaa, 0x41, 0x3e, 0x03, 0x03, 0xb6, 0x8b, 0x8b, 0x22, - 0x7e, 0xcb, 0x58, 0x38, 0x84, 0x96, 0xeb, 0xac, 0xed, 0x7c, 0x70, 0x08, 0x12, 0x59, 0x23, 0x6d, - 0x17, 0x3f, 0xed, 0x26, 0x0c, 0xe9, 0xae, 0x4b, 0xbd, 0x86, 0xa7, 0xaf, 0xc9, 0x49, 0x46, 0x02, - 0xa0, 0x3c, 0x3a, 0x10, 0xb8, 0xa2, 0xaf, 0x91, 0xcf, 0xc2, 0x68, 0xd3, 0xa1, 0xb8, 0x6c, 0xea, - 0x2d, 0xd6, 0x4a, 0xc9, 0xac, 0x8d, 0x20, 0xe4, 0xfb, 0x93, 0x10, 0x51, 0x35, 0xc8, 0x3d, 0x18, - 0x15, 0x9f, 0xc3, 0x3d, 0xf7, 0x71, 0xa0, 0x8d, 0x85, 0xcb, 0x18, 0x17, 0x09, 0xf7, 0xdd, 0x17, - 0x0f, 0x38, 0x64, 0x72, 0x99, 0xaf, 0x21, 0x91, 0x92, 0x65, 0x20, 0x1b, 0x74, 0xb5, 0xa1, 0x77, - 0xbd, 0x75, 0x56, 0x17, 0x8f, 0x91, 0x2f, 0x72, 0x6b, 0xe2, 0xab, 0x87, 0x24, 0x56, 0x7e, 0x0c, - 0xb2, 0x41, 0x57, 0xcb, 0x11, 0x24, 0xb9, 0x0f, 0x67, 0x93, 0x45, 0xd8, 0x27, 0xf3, 0xcb, 0x81, - 0xe7, 0xb6, 0xb7, 0x26, 0x27, 0x53, 0x09, 0x24, 0xb6, 0xa7, 0x13, 0x6c, 0xab, 0xc6, 0xed, 0xe2, - 0xe0, 0xc0, 0xc4, 0xa0, 0x36, 0xc6, 0xca, 0xfa, 0x26, 0xa4, 0x69, 0xa8, 0xbf, 0x9f, 0x63, 0xa6, - 0x22, 0xfb, 0x20, 0x4c, 0x2e, 0xce, 0x74, 0xbd, 0xbd, 0x47, 0x5d, 0x6f, 0x87, 0x69, 0x40, 0x4b, - 0x6e, 0x8f, 0xd9, 0x55, 0x13, 0x58, 0x32, 0x05, 0x25, 0x43, 0x3e, 0x35, 0x3b, 0x17, 0xed, 0x04, - 0xbf, 0x1e, 0x4d, 0x50, 0x91, 0xab, 0x50, 0x64, 0x4b, 0x56, 0x7c, 0xcb, 0x2c, 0x5b, 0x17, 0x1a, - 0x52, 0xa8, 0x3f, 0x9c, 0x87, 0x11, 0xe9, 0x6b, 0x6e, 0x1c, 0xe8, 0x73, 0xde, 0xd8, 0x5d, 0x33, - 0x7d, 0xa7, 0x17, 0xdc, 0x4b, 0xf9, 0x4d, 0xbe, 0x19, 0x88, 0x62, 0x57, 0x17, 0x52, 0x42, 0x30, - 0xaf, 0x8a, 0x0f, 0x2d, 0xed, 0x7e, 0xfb, 0xc8, 0xe8, 0x6f, 0x17, 0x07, 0xf3, 0x13, 0x85, 0xdb, - 0xc5, 0xc1, 0xe2, 0x44, 0x3f, 0x06, 0xf3, 0xc2, 0xf8, 0xd9, 0x7c, 0x6f, 0x6e, 0x3d, 0x30, 0xd7, - 0x8e, 0xf9, 0xdb, 0x91, 0xc3, 0x0d, 0x74, 0x16, 0x93, 0xcd, 0x31, 0x7f, 0x48, 0xf2, 0xa1, 0xca, - 0xe6, 0x24, 0x6d, 0xa8, 0x90, 0xcd, 0x3f, 0xc9, 0x81, 0x92, 0x2a, 0x9b, 0xf2, 0x11, 0xf9, 0x41, - 0x1c, 0x5e, 0xf2, 0xd0, 0x3f, 0xca, 0xc3, 0xa9, 0xaa, 0xe5, 0xd1, 0x35, 0xbe, 0x63, 0x3c, 0xe6, - 0x53, 0xc5, 0x1d, 0x18, 0x96, 0x3e, 0x46, 0xf4, 0xf9, 0x53, 0xc1, 0x7e, 0x3c, 0x44, 0x65, 0x70, - 0x92, 0x4b, 0x1f, 0xde, 0x4b, 0x9c, 0xb8, 0x90, 0x8f, 0xf9, 0x9c, 0x73, 0x3c, 0x84, 0x7c, 0xcc, - 0x27, 0xaf, 0x8f, 0xa8, 0x90, 0xff, 0xb3, 0x3c, 0x9c, 0x4e, 0xa9, 0x9c, 0x5c, 0x81, 0x81, 0x7a, - 0x77, 0x15, 0x63, 0x77, 0xe5, 0x42, 0x8f, 0x61, 0xb7, 0xbb, 0x8a, 0x61, 0xbb, 0x34, 0x1f, 0x49, - 0x56, 0xf0, 0x71, 0xfd, 0x72, 0xb5, 0x32, 0x23, 0xa4, 0xaa, 0x4a, 0x61, 0x02, 0x18, 0x38, 0xed, - 0xcb, 0x82, 0x07, 0xf8, 0xb6, 0x69, 0x34, 0x63, 0x0f, 0xf0, 0x59, 0x19, 0xf2, 0x03, 0x30, 0x54, - 0xfe, 0xa0, 0xeb, 0x50, 0xe4, 0xcb, 0x25, 0xfe, 0xb1, 0x80, 0xaf, 0x8f, 0x48, 0xe3, 0xcc, 0x63, - 0x09, 0x30, 0x8a, 0x38, 0xef, 0x90, 0x21, 0x59, 0x86, 0xd2, 0x2d, 0xd3, 0x9b, 0xef, 0xae, 0x8a, - 0x5e, 0x08, 0xe2, 0x7b, 0x71, 0x68, 0x1a, 0x5f, 0xdc, 0x95, 0xf3, 0x38, 0xc5, 0xf2, 0x1e, 0x88, - 0x17, 0x50, 0x7f, 0x2a, 0x07, 0x17, 0xb3, 0x3f, 0x97, 0x7c, 0x0a, 0x06, 0xd8, 0x56, 0xbf, 0xac, - 0x2d, 0x09, 0x59, 0xf2, 0xcc, 0xbd, 0x76, 0x8b, 0x36, 0x74, 0x47, 0xde, 0x3d, 0xf8, 0x64, 0xe4, - 0x6d, 0x18, 0xae, 0xba, 0x6e, 0x97, 0x3a, 0xf5, 0x97, 0xef, 0x6a, 0x55, 0xb1, 0xc9, 0xc4, 0x4d, - 0x8c, 0x89, 0xe0, 0x86, 0xfb, 0x72, 0x2c, 0xdc, 0x97, 0x4c, 0xaf, 0xfe, 0x78, 0x0e, 0x2e, 0xf5, - 0x12, 0x13, 0x79, 0x19, 0x06, 0x57, 0xa8, 0xa5, 0x5b, 0x5e, 0xb5, 0x22, 0x9a, 0x84, 0x7b, 0x36, - 0x0f, 0x61, 0xd1, 0xad, 0x47, 0x40, 0xc8, 0x0a, 0xf1, 0x83, 0xca, 0xc0, 0x33, 0x82, 0x1f, 0xaa, - 0x22, 0x2c, 0x56, 0xc8, 0x27, 0x54, 0xbf, 0x00, 0x17, 0x32, 0xa5, 0x4a, 0x3e, 0x03, 0x23, 0xcb, - 0xce, 0x9a, 0x6e, 0x99, 0x1f, 0xf0, 0x41, 0x91, 0x0b, 0xf7, 0xc5, 0xb6, 0x04, 0x97, 0xf7, 0x6a, - 0x32, 0xbd, 0xfa, 0x07, 0x79, 0x18, 0xa9, 0xb5, 0xba, 0x6b, 0xa6, 0xb4, 0xcc, 0xed, 0x7b, 0x77, - 0xe0, 0xdb, 0xea, 0xf9, 0xbd, 0xd9, 0xea, 0x6c, 0x72, 0x70, 0xf6, 0x39, 0x39, 0xf8, 0xe5, 0xc8, - 0x5b, 0x50, 0xea, 0xe0, 0x77, 0xc4, 0xcf, 0x8d, 0xf9, 0xd7, 0x65, 0x9d, 0x1b, 0xf3, 0x32, 0x6c, - 0x36, 0x68, 0x1e, 0x60, 0x36, 0x08, 0xcb, 0x4a, 0x02, 0x0d, 0x97, 0xb4, 0x13, 0x81, 0x1e, 0x8a, - 0x40, 0xc3, 0xe5, 0xeb, 0x44, 0xa0, 0x07, 0x10, 0xe8, 0xaf, 0xe5, 0x61, 0x2c, 0x5a, 0x25, 0xf9, - 0x14, 0x0c, 0xf3, 0x6a, 0xf8, 0x29, 0x56, 0x4e, 0x72, 0x81, 0x0e, 0xc1, 0x1a, 0xf0, 0x1f, 0xe2, - 0x38, 0x6e, 0x7c, 0x5d, 0x77, 0x1b, 0xe1, 0x79, 0x12, 0xbf, 0x6d, 0x1e, 0xe4, 0x7e, 0x5b, 0x31, - 0x94, 0x36, 0xb6, 0xae, 0xbb, 0x33, 0xe1, 0x6f, 0x32, 0x0b, 0xc4, 0xa1, 0x5d, 0x97, 0x46, 0x19, - 0x14, 0x91, 0x81, 0xc8, 0xc9, 0x1e, 0xc7, 0x6a, 0xa7, 0x38, 0x4c, 0x66, 0xf3, 0xc5, 0xa0, 0xd9, - 0xa8, 0x0c, 0xfd, 0xbb, 0x48, 0x18, 0x2f, 0xd1, 0xa7, 0x1f, 0xca, 0x72, 0x82, 0x8a, 0xee, 0xe9, - 0xfc, 0x08, 0xc1, 0xef, 0x00, 0xf5, 0x47, 0x3a, 0xd0, 0xbf, 0x6c, 0xd1, 0xe5, 0x07, 0xe4, 0x25, - 0x18, 0x62, 0x0a, 0xb3, 0x60, 0xb3, 0xbe, 0xcc, 0x09, 0x6f, 0x0f, 0x49, 0x93, 0x10, 0x31, 0xdf, - 0xa7, 0x85, 0x54, 0xe4, 0x26, 0x40, 0xf8, 0x20, 0x4e, 0x68, 0x1f, 0x91, 0xcb, 0x70, 0xcc, 0x7c, - 0x9f, 0x26, 0xd1, 0xf9, 0xa5, 0xc4, 0x73, 0xa2, 0x42, 0xb2, 0x14, 0xc7, 0xf8, 0xa5, 0xc4, 0xf8, - 0x58, 0x00, 0xc2, 0x7e, 0xd5, 0x74, 0xd7, 0xdd, 0xb0, 0x1d, 0x63, 0x66, 0x5d, 0xb7, 0xd6, 0x68, - 0x7c, 0xaf, 0x97, 0xa4, 0x98, 0xef, 0xd3, 0x52, 0xca, 0x91, 0x37, 0x60, 0x44, 0x76, 0x7f, 0x8d, - 0xbb, 0xa8, 0xc8, 0xb8, 0xf9, 0x3e, 0x2d, 0x42, 0x4b, 0x5e, 0x83, 0x61, 0xf1, 0xfb, 0xb6, 0x2d, - 0xee, 0xbf, 0xa5, 0xc8, 0x49, 0x12, 0x6a, 0xbe, 0x4f, 0x93, 0x29, 0xa5, 0x4a, 0x6b, 0x8e, 0x69, - 0x79, 0xe2, 0x45, 0x75, 0xbc, 0x52, 0xc4, 0x49, 0x95, 0xe2, 0x6f, 0xf2, 0x36, 0x8c, 0x06, 0x21, - 0xa9, 0xde, 0xa7, 0x4d, 0x4f, 0x1c, 0xd5, 0x9f, 0x8d, 0x15, 0xe6, 0xc8, 0xf9, 0x3e, 0x2d, 0x4a, - 0x4d, 0xae, 0x42, 0x49, 0xa3, 0xae, 0xf9, 0x81, 0x7f, 0xb9, 0x3d, 0x26, 0x8d, 0x73, 0xf3, 0x03, - 0x26, 0x25, 0x81, 0x67, 0xbd, 0x13, 0xde, 0xa6, 0x8b, 0x83, 0x75, 0x12, 0xab, 0x65, 0xd6, 0x32, - 0x58, 0xef, 0x48, 0xae, 0x14, 0x9f, 0x0d, 0x03, 0x75, 0x89, 0x3c, 0xb5, 0xc3, 0xf1, 0x88, 0x08, - 0x32, 0x76, 0xbe, 0x4f, 0x8b, 0xd1, 0x4b, 0x52, 0xad, 0x98, 0xee, 0x43, 0x11, 0x60, 0x35, 0x2e, - 0x55, 0x86, 0x92, 0xa4, 0xca, 0x7e, 0x4a, 0x55, 0x2f, 0x51, 0x6f, 0xc3, 0x76, 0x1e, 0x8a, 0x70, - 0xaa, 0xf1, 0xaa, 0x05, 0x56, 0xaa, 0x5a, 0x40, 0xe4, 0xaa, 0xd9, 0x80, 0x1b, 0x4b, 0xaf, 0x5a, - 0xf7, 0x74, 0xb9, 0x6a, 0x7e, 0x6e, 0xe8, 0x77, 0xd2, 0x02, 0xd5, 0x1f, 0x51, 0x65, 0x3c, 0xb5, - 0x43, 0x11, 0x27, 0x75, 0x28, 0xfe, 0x66, 0x95, 0x4a, 0x29, 0xe1, 0x95, 0x89, 0x68, 0xa5, 0x12, - 0x8a, 0x55, 0x2a, 0x27, 0x8f, 0xbf, 0x29, 0x67, 0x4a, 0x57, 0x4e, 0x45, 0x3b, 0x28, 0xc4, 0xb0, - 0x0e, 0x92, 0x32, 0xaa, 0x4f, 0x62, 0x16, 0x66, 0x85, 0x20, 0xf9, 0x70, 0xd0, 0xc2, 0x99, 0xda, - 0x7c, 0x9f, 0x86, 0xf9, 0x99, 0x55, 0x9e, 0xdf, 0x5b, 0x39, 0x8d, 0x14, 0x23, 0x3e, 0x05, 0x83, - 0xcd, 0xf7, 0x69, 0x3c, 0xf7, 0xf7, 0x4b, 0x52, 0x0e, 0x44, 0xe5, 0x4c, 0x74, 0x8a, 0x08, 0x10, - 0x6c, 0x8a, 0x08, 0x33, 0x25, 0xce, 0x25, 0x33, 0xfd, 0x29, 0x67, 0xa3, 0x4b, 0x4d, 0x1c, 0x3f, - 0xdf, 0xa7, 0x25, 0xb3, 0x03, 0xbe, 0x16, 0x49, 0x7e, 0xa7, 0x9c, 0x8b, 0x85, 0x2b, 0x0b, 0x51, - 0x4c, 0x5c, 0x72, 0x9a, 0xbc, 0x65, 0x38, 0xcd, 0x73, 0xe7, 0x8a, 0x80, 0x63, 0x62, 0xb2, 0x3a, - 0x1f, 0xdd, 0x66, 0xa5, 0x90, 0xcc, 0xf7, 0x69, 0x69, 0x25, 0xc9, 0x4c, 0x22, 0x05, 0x9d, 0xa2, - 0x44, 0x3d, 0x79, 0x62, 0xe8, 0xf9, 0x3e, 0x2d, 0x91, 0xb4, 0xee, 0xa6, 0x9c, 0xfb, 0x4d, 0xb9, - 0x10, 0xed, 0xc4, 0x10, 0xc3, 0x3a, 0x51, 0xca, 0x11, 0x77, 0x53, 0xce, 0x07, 0xa6, 0x5c, 0x4c, - 0x96, 0x0a, 0x67, 0x4e, 0x29, 0x6f, 0x98, 0x96, 0x9e, 0xe2, 0x48, 0x79, 0x4a, 0x24, 0x3a, 0x16, - 0xe5, 0xd3, 0x68, 0xe6, 0xfb, 0xb4, 0xf4, 0xf4, 0x48, 0x5a, 0x7a, 0x6e, 0x20, 0xe5, 0x52, 0x2f, - 0x9e, 0x41, 0xeb, 0xd2, 0xf3, 0x0a, 0xe9, 0x3d, 0x32, 0xb5, 0x28, 0x4f, 0x47, 0x37, 0x64, 0x99, - 0x84, 0xf3, 0x7d, 0x5a, 0x8f, 0x7c, 0x2f, 0x77, 0x33, 0xd2, 0xa6, 0x28, 0x97, 0xa3, 0x79, 0xce, - 0x53, 0x89, 0xe6, 0xfb, 0xb4, 0x8c, 0xa4, 0x2b, 0x77, 0x33, 0xb2, 0x6a, 0x28, 0x93, 0x3d, 0xd9, - 0x06, 0xf2, 0xc8, 0xc8, 0xc9, 0xb1, 0x9c, 0x9a, 0x90, 0x42, 0x79, 0x26, 0xaa, 0xba, 0x29, 0x24, - 0x4c, 0x75, 0xd3, 0x52, 0x59, 0x2c, 0xa7, 0x66, 0x50, 0x50, 0x9e, 0xed, 0xc1, 0x30, 0x68, 0x63, - 0x6a, 0xee, 0x85, 0xe5, 0xd4, 0x14, 0x06, 0x8a, 0x1a, 0x65, 0x98, 0x42, 0xc2, 0x18, 0xa6, 0x25, - 0x3f, 0x58, 0x4e, 0x8d, 0x74, 0xaf, 0x3c, 0xd7, 0x83, 0x61, 0xd8, 0xc2, 0xb4, 0x18, 0xf9, 0xaf, - 0x45, 0x42, 0xcd, 0x2b, 0x1f, 0x8b, 0xce, 0x1b, 0x12, 0x8a, 0xcd, 0x1b, 0x72, 0x50, 0xfa, 0x99, - 0x44, 0x1c, 0x5c, 0xe5, 0xe3, 0xd1, 0x61, 0x1e, 0x43, 0xb3, 0x61, 0x1e, 0x8f, 0x9c, 0x3b, 0x93, - 0x88, 0x07, 0xaa, 0x5c, 0xc9, 0x62, 0x82, 0xe8, 0x28, 0x13, 0x1e, 0x41, 0xb4, 0x9a, 0x12, 0x90, - 0x52, 0xf9, 0x44, 0xd4, 0x0b, 0x3d, 0x41, 0x30, 0xdf, 0xa7, 0xa5, 0x84, 0xb1, 0xd4, 0xd2, 0xa3, - 0x2f, 0x29, 0x57, 0xa3, 0xc3, 0x36, 0x8d, 0x86, 0x0d, 0xdb, 0xd4, 0xc8, 0x4d, 0x0b, 0x69, 0x4f, - 0x65, 0x94, 0x6b, 0x51, 0xc3, 0x2c, 0x49, 0xc1, 0x0c, 0xb3, 0x94, 0x27, 0x36, 0x5a, 0x7a, 0x44, - 0x20, 0xe5, 0xf9, 0x9e, 0x2d, 0x44, 0x9a, 0x94, 0x16, 0xf2, 0x00, 0x39, 0xa1, 0xed, 0x74, 0xb7, - 0xd3, 0xb2, 0x75, 0x43, 0xf9, 0x64, 0xaa, 0xed, 0xc4, 0x91, 0x92, 0xed, 0xc4, 0x01, 0x6c, 0x95, - 0x97, 0x5f, 0x64, 0x28, 0x2f, 0x44, 0x57, 0x79, 0x19, 0xc7, 0x56, 0xf9, 0xc8, 0xeb, 0x8d, 0x99, - 0xc4, 0xeb, 0x05, 0xe5, 0xc5, 0xa8, 0x02, 0xc4, 0xd0, 0x4c, 0x01, 0xe2, 0xef, 0x1d, 0xbe, 0x94, - 0xed, 0xef, 0xaf, 0x4c, 0x21, 0xb7, 0x67, 0x7c, 0x6e, 0x59, 0x74, 0xf3, 0x7d, 0x5a, 0xf6, 0x9b, - 0x81, 0x6a, 0x8a, 0xfb, 0xbe, 0x72, 0x3d, 0xaa, 0x60, 0x09, 0x02, 0xa6, 0x60, 0x49, 0xa7, 0xff, - 0x6a, 0x8a, 0xff, 0xbd, 0xf2, 0xa9, 0x4c, 0x56, 0xc1, 0x37, 0xa7, 0x78, 0xed, 0xdf, 0x94, 0x1d, - 0xe8, 0x95, 0x97, 0xa2, 0x8b, 0x5d, 0x88, 0x61, 0x8b, 0x9d, 0xe4, 0x68, 0x7f, 0x53, 0x76, 0x1d, - 0x57, 0x6e, 0x24, 0x4b, 0x85, 0x4b, 0xa4, 0xe4, 0x62, 0xae, 0xa5, 0x7b, 0x5c, 0x2b, 0x2f, 0x47, - 0xb5, 0x2e, 0x8d, 0x86, 0x69, 0x5d, 0xaa, 0xb7, 0xf6, 0x5c, 0xd2, 0x71, 0x5a, 0xb9, 0x19, 0xdf, - 0x64, 0x47, 0xf1, 0xcc, 0xf2, 0x49, 0x38, 0x5b, 0x7f, 0x36, 0x1e, 0x1a, 0x50, 0x79, 0x25, 0x76, - 0x49, 0x1d, 0xc1, 0x32, 0xfb, 0x36, 0x16, 0x4a, 0xf0, 0xb3, 0xf1, 0x68, 0x7a, 0xca, 0xab, 0xe9, - 0x1c, 0x02, 0x5d, 0x89, 0x47, 0xdf, 0xfb, 0x6c, 0x3c, 0x00, 0x9d, 0xf2, 0x5a, 0x3a, 0x87, 0x40, - 0xba, 0xf1, 0x80, 0x75, 0x2f, 0x49, 0x21, 0xf1, 0x95, 0x4f, 0x47, 0x4d, 0xc7, 0x00, 0xc1, 0x4c, - 0xc7, 0x30, 0x70, 0xfe, 0x4b, 0x52, 0x28, 0x79, 0xe5, 0xf5, 0x44, 0x91, 0xa0, 0xb1, 0x52, 0xc0, - 0xf9, 0x97, 0xa4, 0x10, 0xec, 0xca, 0x1b, 0x89, 0x22, 0x41, 0xeb, 0xa4, 0x40, 0xed, 0x46, 0xaf, - 0xd7, 0xb6, 0xca, 0x9b, 0xd1, 0xa3, 0xeb, 0x6c, 0xca, 0xf9, 0x3e, 0xad, 0xd7, 0xab, 0xdd, 0x2f, - 0x65, 0xbb, 0xa1, 0x2b, 0x6f, 0x45, 0x87, 0x70, 0x16, 0x1d, 0x1b, 0xc2, 0x99, 0xae, 0xec, 0x6f, - 0xc7, 0x22, 0x6f, 0x28, 0x6f, 0x47, 0xa7, 0xb8, 0x08, 0x92, 0x4d, 0x71, 0xf1, 0x38, 0x1d, 0x91, - 0x90, 0x12, 0xca, 0x67, 0xa2, 0x53, 0x9c, 0x8c, 0x63, 0x53, 0x5c, 0x24, 0xfc, 0xc4, 0x4c, 0x22, - 0xd2, 0x81, 0xf2, 0x4e, 0x74, 0x8a, 0x8b, 0xa1, 0xd9, 0x14, 0x17, 0x8f, 0x8d, 0xf0, 0x76, 0xec, - 0xc1, 0xbf, 0xf2, 0xd9, 0xf4, 0xf6, 0x23, 0x52, 0x6e, 0x3f, 0x0f, 0x0f, 0xa0, 0xa5, 0xbf, 0x5c, - 0x57, 0xca, 0xd1, 0xf1, 0x9b, 0x46, 0xc3, 0xc6, 0x6f, 0xea, 0xab, 0xf7, 0xf8, 0xc6, 0x41, 0x68, - 0xd5, 0x74, 0x8f, 0x8d, 0x43, 0x68, 0x8a, 0xa4, 0x80, 0x23, 0x7b, 0x64, 0xbe, 0x11, 0x9a, 0xc9, - 0xd8, 0x23, 0xfb, 0xdb, 0xa0, 0x18, 0x3d, 0x9b, 0x5d, 0x13, 0x5e, 0xd1, 0x4a, 0x25, 0x3a, 0xbb, - 0x26, 0x08, 0xd8, 0xec, 0x9a, 0xf4, 0xa5, 0x9e, 0x83, 0x09, 0xa1, 0x45, 0xdc, 0xd9, 0xdb, 0xb4, - 0xd6, 0x94, 0xd9, 0xd8, 0xeb, 0xd0, 0x18, 0x9e, 0xcd, 0x4e, 0x71, 0x18, 0xae, 0xd7, 0x1c, 0x36, - 0xd3, 0x32, 0x3b, 0xab, 0xb6, 0xee, 0x18, 0x75, 0x6a, 0x19, 0xca, 0x5c, 0x6c, 0xbd, 0x4e, 0xa1, - 0xc1, 0xf5, 0x3a, 0x05, 0x8e, 0x01, 0xed, 0x62, 0x70, 0x8d, 0x36, 0xa9, 0xf9, 0x88, 0x2a, 0xb7, - 0x90, 0xed, 0x64, 0x16, 0x5b, 0x41, 0x36, 0xdf, 0xa7, 0x65, 0x71, 0x60, 0xb6, 0xfa, 0xe2, 0x66, - 0xfd, 0xdd, 0x85, 0x20, 0x58, 0x42, 0xcd, 0xa1, 0x1d, 0xdd, 0xa1, 0xca, 0x7c, 0xd4, 0x56, 0x4f, - 0x25, 0x62, 0xb6, 0x7a, 0x2a, 0x22, 0xc9, 0xd6, 0x1f, 0x0b, 0xd5, 0x5e, 0x6c, 0xc3, 0x11, 0x91, - 0x5e, 0x9a, 0xcd, 0x4e, 0x51, 0x04, 0x13, 0xd0, 0x82, 0x6d, 0xad, 0xe1, 0x49, 0xc5, 0xed, 0xe8, - 0xec, 0x94, 0x4d, 0xc9, 0x66, 0xa7, 0x6c, 0x2c, 0x53, 0xf5, 0x28, 0x96, 0x8f, 0xc1, 0x3b, 0x51, - 0x55, 0x4f, 0x21, 0x61, 0xaa, 0x9e, 0x02, 0x4e, 0x32, 0xd4, 0xa8, 0x4b, 0x3d, 0x65, 0xa1, 0x17, - 0x43, 0x24, 0x49, 0x32, 0x44, 0x70, 0x92, 0xe1, 0x1c, 0xf5, 0x9a, 0xeb, 0xca, 0x62, 0x2f, 0x86, - 0x48, 0x92, 0x64, 0x88, 0x60, 0xb6, 0xd9, 0x8c, 0x82, 0xa7, 0xbb, 0xad, 0x87, 0x7e, 0x9f, 0x2d, - 0x45, 0x37, 0x9b, 0x99, 0x84, 0x6c, 0xb3, 0x99, 0x89, 0x24, 0x3f, 0xbe, 0x6b, 0xaf, 0x7d, 0x65, - 0x19, 0x2b, 0x9c, 0x0a, 0xed, 0x82, 0xdd, 0x94, 0x9a, 0xef, 0xd3, 0x76, 0xfb, 0x2a, 0xe0, 0x93, - 0x81, 0x8b, 0xab, 0x52, 0xc3, 0xaa, 0xc6, 0x83, 0xb3, 0x0a, 0x0e, 0x9e, 0xef, 0xd3, 0x02, 0x27, - 0xd8, 0xd7, 0x60, 0x18, 0x3f, 0xaa, 0x6a, 0x99, 0x5e, 0x65, 0x5a, 0x79, 0x37, 0xba, 0x65, 0x92, - 0x50, 0x6c, 0xcb, 0x24, 0xfd, 0x64, 0x93, 0x38, 0xfe, 0xe4, 0x53, 0x4c, 0x65, 0x5a, 0xd1, 0xa2, - 0x93, 0x78, 0x04, 0xc9, 0x26, 0xf1, 0x08, 0x20, 0xa8, 0xb7, 0xe2, 0xd8, 0x9d, 0xca, 0xb4, 0x52, - 0x4f, 0xa9, 0x97, 0xa3, 0x82, 0x7a, 0xf9, 0xcf, 0xa0, 0xde, 0xfa, 0x7a, 0xd7, 0xab, 0xb0, 0x6f, - 0x5c, 0x49, 0xa9, 0xd7, 0x47, 0x06, 0xf5, 0xfa, 0x00, 0x36, 0x15, 0x22, 0xa0, 0xe6, 0xd8, 0x6c, - 0xd2, 0xbe, 0x63, 0xb6, 0x5a, 0xca, 0xdd, 0xe8, 0x54, 0x18, 0xc7, 0xb3, 0xa9, 0x30, 0x0e, 0x63, - 0xa6, 0x27, 0x6f, 0x15, 0x5d, 0xed, 0xae, 0x29, 0xf7, 0xa2, 0xa6, 0x67, 0x88, 0x61, 0xa6, 0x67, - 0xf8, 0x0b, 0x77, 0x17, 0xec, 0x97, 0x46, 0x1f, 0x38, 0xd4, 0x5d, 0x57, 0xee, 0xc7, 0x76, 0x17, - 0x12, 0x0e, 0x77, 0x17, 0xd2, 0x6f, 0xb2, 0x06, 0x4f, 0x45, 0x16, 0x1a, 0xff, 0xd2, 0xa6, 0x4e, - 0x75, 0xa7, 0xb9, 0xae, 0x7c, 0x0e, 0x59, 0x3d, 0x97, 0xba, 0x54, 0x45, 0x49, 0xe7, 0xfb, 0xb4, - 0x5e, 0x9c, 0x70, 0x5b, 0xfe, 0xee, 0x02, 0x8f, 0x5b, 0xab, 0xd5, 0x66, 0xfc, 0x4d, 0xe8, 0x7b, - 0xb1, 0x6d, 0x79, 0x92, 0x04, 0xb7, 0xe5, 0x49, 0x30, 0xe9, 0xc0, 0xe5, 0xd8, 0x56, 0x6d, 0x51, - 0x6f, 0xb1, 0x7d, 0x09, 0x35, 0x6a, 0x7a, 0xf3, 0x21, 0xf5, 0x94, 0xcf, 0x23, 0xef, 0x2b, 0x19, - 0x1b, 0xbe, 0x18, 0xf5, 0x7c, 0x9f, 0xb6, 0x03, 0x3f, 0xa2, 0x42, 0xb1, 0x3e, 0xb7, 0x52, 0x53, - 0xbe, 0x10, 0x3d, 0xdf, 0x64, 0xb0, 0xf9, 0x3e, 0x0d, 0x71, 0xcc, 0x4a, 0xbb, 0xdb, 0x59, 0x73, - 0x74, 0x83, 0x72, 0x43, 0x0b, 0x6d, 0x37, 0x61, 0x80, 0xfe, 0x40, 0xd4, 0x4a, 0xcb, 0xa2, 0x63, - 0x56, 0x5a, 0x16, 0x8e, 0x29, 0x6a, 0x24, 0x45, 0x8b, 0xf2, 0xc5, 0xa8, 0xa2, 0x46, 0x90, 0x4c, - 0x51, 0xa3, 0x09, 0x5d, 0x3e, 0x07, 0xe7, 0x82, 0xfd, 0xbc, 0x58, 0x7f, 0x79, 0xa7, 0x29, 0x5f, - 0x42, 0x3e, 0x97, 0x13, 0x97, 0x01, 0x11, 0xaa, 0xf9, 0x3e, 0x2d, 0xa3, 0x3c, 0x5b, 0x71, 0x13, - 0x29, 0xcc, 0x84, 0x79, 0xf1, 0x83, 0xd1, 0x15, 0x37, 0x83, 0x8c, 0xad, 0xb8, 0x19, 0xa8, 0x54, - 0xe6, 0x42, 0xa8, 0xfa, 0x0e, 0xcc, 0x03, 0x99, 0x66, 0x71, 0x48, 0x65, 0x2e, 0x2c, 0xb5, 0xd5, - 0x1d, 0x98, 0x07, 0xd6, 0x5a, 0x16, 0x07, 0x72, 0x15, 0x4a, 0xf5, 0xfa, 0xa2, 0xd6, 0xb5, 0x94, - 0x66, 0xcc, 0xb7, 0x17, 0xa1, 0xf3, 0x7d, 0x9a, 0xc0, 0x33, 0x33, 0x68, 0xb6, 0xa5, 0xbb, 0x9e, - 0xd9, 0x74, 0x71, 0xc4, 0xf8, 0x23, 0xc4, 0x88, 0x9a, 0x41, 0x69, 0x34, 0xcc, 0x0c, 0x4a, 0x83, - 0x33, 0x7b, 0x71, 0x46, 0x77, 0x5d, 0xdd, 0x32, 0x1c, 0x7d, 0x1a, 0x97, 0x09, 0x1a, 0x7b, 0x3b, - 0x16, 0xc1, 0x32, 0x7b, 0x31, 0x0a, 0xc1, 0xc3, 0x77, 0x1f, 0xe2, 0x9b, 0x39, 0x0f, 0x62, 0x87, - 0xef, 0x31, 0x3c, 0x1e, 0xbe, 0xc7, 0x60, 0x68, 0x77, 0xfa, 0x30, 0x8d, 0xae, 0x99, 0x4c, 0x44, - 0xca, 0x5a, 0xcc, 0xee, 0x8c, 0x13, 0xa0, 0xdd, 0x19, 0x07, 0x46, 0x9a, 0xe4, 0x2f, 0xb7, 0xeb, - 0x19, 0x4d, 0x0a, 0x57, 0xd9, 0x44, 0x19, 0xb6, 0x7e, 0x87, 0x83, 0xa3, 0xb2, 0x69, 0xe9, 0x6d, - 0xbb, 0x32, 0xed, 0x4b, 0xdd, 0x8c, 0xae, 0xdf, 0x99, 0x84, 0x6c, 0xfd, 0xce, 0x44, 0xb2, 0xd9, - 0xd5, 0xdf, 0x68, 0xad, 0xeb, 0x0e, 0x35, 0x2a, 0xa6, 0x83, 0x27, 0x8b, 0x9b, 0x7c, 0x6b, 0xf8, - 0x7e, 0x74, 0x76, 0xed, 0x41, 0xca, 0x66, 0xd7, 0x1e, 0x68, 0x66, 0xe4, 0xa5, 0xa3, 0x35, 0xaa, - 0x1b, 0xca, 0xc3, 0xa8, 0x91, 0x97, 0x4d, 0xc9, 0x8c, 0xbc, 0x6c, 0x6c, 0xf6, 0xe7, 0xdc, 0x77, - 0x4c, 0x8f, 0x2a, 0xad, 0xdd, 0x7c, 0x0e, 0x92, 0x66, 0x7f, 0x0e, 0xa2, 0xd9, 0x86, 0x30, 0xde, - 0x21, 0xed, 0xe8, 0x86, 0x30, 0xd9, 0x0d, 0xf1, 0x12, 0xcc, 0x62, 0x11, 0x4f, 0x08, 0x15, 0x2b, - 0x6a, 0xb1, 0x08, 0x30, 0xb3, 0x58, 0xc2, 0x47, 0x86, 0x91, 0x87, 0x63, 0x8a, 0x1d, 0x5d, 0x43, - 0x65, 0x1c, 0x5b, 0x43, 0x23, 0x8f, 0xcc, 0x5e, 0x8b, 0xbc, 0x8a, 0x50, 0x3a, 0x51, 0xab, 0x43, - 0x42, 0x31, 0xab, 0x43, 0x7e, 0x3f, 0x31, 0x03, 0xe3, 0x78, 0x0b, 0xae, 0x75, 0x83, 0x7b, 0x9c, - 0x1f, 0x8a, 0x7e, 0x66, 0x0c, 0xcd, 0x3e, 0x33, 0x06, 0x8a, 0x30, 0x11, 0xd3, 0x96, 0x93, 0xc1, - 0x24, 0x3c, 0x1f, 0x8c, 0x81, 0xc8, 0x02, 0x90, 0x7a, 0x79, 0x71, 0xa1, 0x6a, 0xd4, 0xe4, 0x2b, - 0x32, 0x37, 0x7a, 0x02, 0x9b, 0xa4, 0x98, 0xef, 0xd3, 0x52, 0xca, 0x91, 0xf7, 0xe1, 0x92, 0x80, - 0x8a, 0xf7, 0xe1, 0x35, 0xc7, 0x7e, 0x64, 0x1a, 0xc1, 0x82, 0xe0, 0x45, 0xbd, 0xee, 0x7a, 0xd1, - 0xce, 0xf7, 0x69, 0x3d, 0x79, 0x65, 0xd7, 0x25, 0xd6, 0x87, 0xee, 0x6e, 0xea, 0x0a, 0x16, 0x89, - 0x9e, 0xbc, 0xb2, 0xeb, 0x12, 0x72, 0x7f, 0xb4, 0x9b, 0xba, 0x82, 0x4e, 0xe8, 0xc9, 0x8b, 0xb8, - 0x30, 0xd9, 0x0b, 0x5f, 0x6e, 0xb5, 0x94, 0x0d, 0xac, 0xee, 0x13, 0xbb, 0xa9, 0xae, 0x8c, 0x06, - 0xe7, 0x4e, 0x1c, 0xd9, 0x2c, 0xbd, 0xdc, 0xa1, 0x56, 0x3d, 0xb2, 0x00, 0x3d, 0x8e, 0xce, 0xd2, - 0x09, 0x02, 0x36, 0x4b, 0x27, 0x80, 0x6c, 0x40, 0xc9, 0x8f, 0x6b, 0x94, 0xcd, 0xe8, 0x80, 0x92, - 0x71, 0x6c, 0x40, 0x45, 0x1e, 0xe2, 0x2c, 0xc3, 0xe9, 0xe5, 0x87, 0x9e, 0xee, 0x5b, 0x90, 0xae, - 0xe8, 0xca, 0x0f, 0x62, 0x97, 0x4c, 0x49, 0x12, 0xbc, 0x64, 0x4a, 0x82, 0xd9, 0x18, 0x61, 0xe0, - 0xfa, 0xa6, 0xd5, 0x9c, 0xd3, 0xcd, 0x56, 0xd7, 0xa1, 0xca, 0xbf, 0x16, 0x1d, 0x23, 0x31, 0x34, - 0x1b, 0x23, 0x31, 0x10, 0x5b, 0xa0, 0x19, 0xa8, 0xec, 0xba, 0xe6, 0x9a, 0x25, 0xf6, 0x95, 0xdd, - 0x96, 0xa7, 0xfc, 0xeb, 0xd1, 0x05, 0x3a, 0x8d, 0x86, 0x2d, 0xd0, 0x69, 0x70, 0x3c, 0x75, 0x62, - 0xbd, 0xc0, 0x16, 0x0f, 0xf9, 0xae, 0xf2, 0xdf, 0x88, 0x9d, 0x3a, 0xa5, 0xd0, 0xe0, 0xa9, 0x53, - 0x0a, 0x9c, 0xad, 0x8f, 0xdc, 0x26, 0x5b, 0x30, 0x83, 0xbb, 0xea, 0x7f, 0x33, 0xba, 0x3e, 0xc6, - 0xf1, 0x6c, 0x7d, 0x8c, 0xc3, 0xa2, 0x7c, 0x44, 0x17, 0xfc, 0x5b, 0x59, 0x7c, 0x02, 0xf9, 0x27, - 0xca, 0x90, 0x5b, 0x32, 0x1f, 0x31, 0x52, 0x7e, 0x38, 0x97, 0xc5, 0x28, 0x18, 0x1e, 0x89, 0x42, - 0x51, 0x46, 0x1a, 0x7d, 0x64, 0xd2, 0x0d, 0xe5, 0xcb, 0x99, 0x8c, 0x38, 0x41, 0x94, 0x11, 0x87, - 0x91, 0xf7, 0xe0, 0x5c, 0x08, 0x5b, 0xa4, 0xed, 0xd5, 0x60, 0x66, 0xfa, 0x91, 0x5c, 0xd4, 0x0c, - 0x4e, 0x27, 0x63, 0x66, 0x70, 0x3a, 0x26, 0x8d, 0xb5, 0x10, 0xdd, 0xbf, 0xbd, 0x03, 0xeb, 0x40, - 0x82, 0x19, 0x0c, 0xd2, 0x58, 0x0b, 0x69, 0xfe, 0xe8, 0x0e, 0xac, 0x03, 0x99, 0x66, 0x30, 0x20, - 0x3f, 0x91, 0x83, 0x2b, 0xe9, 0xa8, 0x72, 0xab, 0x35, 0x67, 0x3b, 0x21, 0x4e, 0xf9, 0x33, 0xb9, - 0xe8, 0x41, 0xc3, 0xee, 0x8a, 0xcd, 0xf7, 0x69, 0xbb, 0xac, 0x80, 0x7c, 0x06, 0x46, 0xcb, 0x5d, - 0xc3, 0xf4, 0xf0, 0xe2, 0x8d, 0x19, 0xce, 0x3f, 0x96, 0x8b, 0x6d, 0x71, 0x64, 0x2c, 0x6e, 0x71, - 0x64, 0x00, 0xb9, 0x0d, 0xa7, 0xea, 0xb4, 0xd9, 0x75, 0x4c, 0x6f, 0x53, 0xa3, 0x1d, 0xdb, 0xf1, - 0x18, 0x8f, 0x3f, 0x9b, 0x8b, 0x4e, 0x62, 0x09, 0x0a, 0x36, 0x89, 0x25, 0x80, 0xe4, 0x5e, 0xe2, - 0x56, 0x5e, 0x74, 0xe6, 0x8f, 0xe7, 0x7a, 0x5e, 0xcb, 0x07, 0x7d, 0x99, 0x5e, 0x9c, 0xd4, 0x62, - 0xb7, 0xe8, 0x82, 0xeb, 0x4f, 0xe4, 0x7a, 0x5c, 0xa3, 0x4b, 0x33, 0x5c, 0x12, 0xcc, 0x38, 0xa6, - 0x24, 0xbd, 0x57, 0xfe, 0x5c, 0xae, 0xc7, 0xb5, 0x77, 0xc8, 0x31, 0x2d, 0x5f, 0xfe, 0x2b, 0xdc, - 0x53, 0x44, 0x30, 0xfa, 0xc9, 0x5c, 0xd2, 0x55, 0x24, 0x28, 0x2f, 0x11, 0xb2, 0x62, 0x77, 0xdd, - 0x40, 0xe9, 0xbf, 0x92, 0x4b, 0xfa, 0xe6, 0x85, 0xc5, 0xc2, 0x5f, 0x84, 0xc2, 0xc5, 0xd9, 0xc7, - 0x1e, 0x75, 0x2c, 0xbd, 0x85, 0xdd, 0x59, 0xf7, 0x6c, 0x47, 0x5f, 0xa3, 0xb3, 0x96, 0xbe, 0xda, - 0xa2, 0xca, 0x4f, 0xe5, 0xa2, 0x16, 0x6c, 0x36, 0x29, 0xb3, 0x60, 0xb3, 0xb1, 0x64, 0x1d, 0x9e, - 0x4a, 0xc3, 0x56, 0x4c, 0x17, 0xeb, 0xf9, 0x6a, 0x2e, 0x6a, 0xc2, 0xf6, 0xa0, 0x65, 0x26, 0x6c, - 0x0f, 0x34, 0xb9, 0x01, 0x43, 0xd3, 0xb6, 0x3f, 0xfd, 0xfe, 0xf9, 0x98, 0x33, 0x64, 0x80, 0x99, - 0xef, 0xd3, 0x42, 0x32, 0x51, 0x46, 0x0c, 0xea, 0xaf, 0x25, 0xcb, 0x84, 0x97, 0x4f, 0xc1, 0x0f, - 0x51, 0x46, 0x88, 0xfb, 0xdf, 0x49, 0x96, 0x09, 0xef, 0xb8, 0x82, 0x1f, 0x6c, 0x26, 0xe1, 0x35, - 0x2e, 0xce, 0x95, 0x99, 0xdd, 0x36, 0xb3, 0xae, 0xb7, 0x5a, 0xd4, 0x5a, 0xa3, 0xca, 0xd7, 0x63, - 0x33, 0x49, 0x3a, 0x19, 0x9b, 0x49, 0xd2, 0x31, 0xe4, 0x07, 0xe0, 0xfc, 0x3d, 0xbd, 0x65, 0x1a, - 0x21, 0xce, 0x4f, 0x81, 0xae, 0xfc, 0x74, 0x2e, 0xba, 0x9b, 0xce, 0xa0, 0x63, 0xbb, 0xe9, 0x0c, - 0x14, 0x59, 0x04, 0x82, 0xcb, 0x68, 0x30, 0x5b, 0xb0, 0xf5, 0x59, 0xf9, 0x77, 0x73, 0x51, 0x3b, - 0x35, 0x49, 0xc2, 0xec, 0xd4, 0x24, 0x94, 0x34, 0xb2, 0x13, 0x99, 0x28, 0x3f, 0x93, 0x8b, 0x9e, - 0xd6, 0x64, 0x11, 0xce, 0xf7, 0x69, 0xd9, 0xd9, 0x50, 0x6e, 0xc1, 0x44, 0xbd, 0x56, 0x9d, 0x9b, - 0x9b, 0xad, 0xdf, 0xab, 0x56, 0xf0, 0x15, 0x85, 0xa1, 0xfc, 0x6c, 0x6c, 0xc5, 0x8a, 0x13, 0xb0, - 0x15, 0x2b, 0x0e, 0x23, 0x6f, 0xc2, 0x08, 0x6b, 0x3f, 0x1b, 0x30, 0xf8, 0xc9, 0x3f, 0x97, 0x8b, - 0x9a, 0x53, 0x32, 0x92, 0x99, 0x53, 0xf2, 0x6f, 0x52, 0x87, 0x33, 0x4c, 0x8a, 0x35, 0x87, 0x3e, - 0xa0, 0x0e, 0xb5, 0x9a, 0xfe, 0x98, 0xfe, 0xf9, 0x5c, 0xd4, 0xca, 0x48, 0x23, 0x62, 0x56, 0x46, - 0x1a, 0x9c, 0x3c, 0x84, 0x4b, 0xf1, 0x93, 0x20, 0xf9, 0x91, 0xac, 0xf2, 0x17, 0x72, 0x31, 0x63, - 0xb8, 0x07, 0x31, 0x1a, 0xc3, 0x3d, 0xf0, 0xc4, 0x82, 0xa7, 0xc5, 0xb1, 0x8a, 0x70, 0xb8, 0x8c, - 0xd7, 0xf6, 0x17, 0x79, 0x6d, 0x1f, 0x0f, 0x1d, 0x02, 0x7b, 0x50, 0xcf, 0xf7, 0x69, 0xbd, 0xd9, - 0x31, 0x3d, 0x4b, 0xa6, 0xeb, 0x50, 0xfe, 0x52, 0x2e, 0xdd, 0x23, 0x25, 0xe2, 0xa6, 0x9c, 0x96, - 0xe7, 0xe3, 0xbd, 0xac, 0x64, 0x13, 0xca, 0x5f, 0x8e, 0x8d, 0xb7, 0x74, 0x32, 0x36, 0xde, 0x32, - 0xb2, 0x55, 0xdc, 0x86, 0x53, 0x5c, 0xa9, 0x6b, 0x3a, 0x0e, 0x43, 0x6b, 0x8d, 0x1a, 0xca, 0xbf, - 0x17, 0x5b, 0xed, 0x12, 0x14, 0xe8, 0xda, 0x13, 0x07, 0xb2, 0xa9, 0xbb, 0xde, 0xd1, 0x2d, 0x0b, - 0x8f, 0x59, 0x95, 0x7f, 0x3f, 0x36, 0x75, 0x87, 0x28, 0x74, 0xdc, 0x0d, 0x7e, 0x31, 0x4d, 0xe8, - 0x95, 0xa8, 0x49, 0xf9, 0x2b, 0x31, 0x4d, 0xe8, 0x45, 0xcc, 0x34, 0xa1, 0x67, 0xd6, 0xa7, 0x7b, - 0x19, 0x0f, 0xd6, 0x95, 0x6f, 0xc4, 0x56, 0xe4, 0x54, 0x2a, 0xb6, 0x22, 0xa7, 0xbf, 0x77, 0xbf, - 0x97, 0xf1, 0xd8, 0x5b, 0xf9, 0x85, 0xde, 0x7c, 0xc3, 0x95, 0x3e, 0xfd, 0xad, 0xf8, 0xbd, 0x8c, - 0x87, 0xd2, 0xca, 0x5f, 0xed, 0xcd, 0x37, 0x74, 0xec, 0x4b, 0x7f, 0x67, 0xdd, 0xc8, 0x7e, 0x64, - 0xac, 0xfc, 0xb5, 0xf8, 0xd4, 0x95, 0x41, 0x88, 0x53, 0x57, 0xd6, 0x4b, 0xe5, 0x55, 0xb8, 0xc0, - 0x35, 0xe4, 0x96, 0xa3, 0x77, 0xd6, 0xeb, 0xd4, 0xf3, 0x4c, 0x6b, 0xcd, 0xdf, 0x89, 0xfd, 0xf5, - 0x5c, 0xec, 0x78, 0x2c, 0x8b, 0x12, 0x8f, 0xc7, 0xb2, 0x90, 0x4c, 0x79, 0x13, 0xcf, 0x89, 0x95, - 0xbf, 0x11, 0x53, 0xde, 0x04, 0x05, 0x53, 0xde, 0xe4, 0x2b, 0xe4, 0xdb, 0x29, 0xaf, 0x66, 0x95, - 0xff, 0x20, 0x9b, 0x57, 0xd0, 0xbe, 0x94, 0xc7, 0xb6, 0xb7, 0x53, 0x1e, 0x87, 0x2a, 0xff, 0x61, - 0x36, 0xaf, 0xd0, 0x07, 0x29, 0xf9, 0xa6, 0xf4, 0x3d, 0x38, 0xc7, 0x67, 0xf3, 0x39, 0x6a, 0xd0, - 0xc8, 0x87, 0xfe, 0x62, 0x6c, 0xec, 0xa7, 0x93, 0xe1, 0x91, 0x7b, 0x2a, 0x26, 0x8d, 0xb5, 0x68, - 0xeb, 0xdf, 0xdc, 0x81, 0x75, 0xb8, 0x21, 0x48, 0xc7, 0xb0, 0xf5, 0x46, 0x7e, 0xfc, 0xa6, 0xfc, - 0x52, 0x6c, 0xbd, 0x91, 0x91, 0xe8, 0xce, 0x21, 0xbf, 0x94, 0x7b, 0x33, 0xfa, 0xd0, 0x4b, 0xf9, - 0x5b, 0xa9, 0x85, 0x83, 0x0e, 0x88, 0xbe, 0x0a, 0x7b, 0x33, 0xfa, 0xa8, 0x49, 0xf9, 0xe5, 0xd4, - 0xc2, 0xc1, 0x07, 0x44, 0x5f, 0x40, 0xb1, 0x2d, 0x52, 0xd7, 0xb3, 0x39, 0xab, 0xc8, 0xf4, 0xf0, - 0xb7, 0xe3, 0x5b, 0xa4, 0x54, 0x32, 0xdc, 0x22, 0xa5, 0x62, 0xd2, 0x58, 0x8b, 0xcf, 0xfb, 0x95, - 0x1d, 0x58, 0x4b, 0x1b, 0xbb, 0x54, 0x4c, 0x1a, 0x6b, 0xf1, 0xf1, 0xdf, 0xdc, 0x81, 0xb5, 0xb4, - 0xb1, 0x4b, 0xc5, 0x30, 0x73, 0x2c, 0xc4, 0xdc, 0xa3, 0x8e, 0x1b, 0xaa, 0xdf, 0x7f, 0x14, 0x33, - 0xc7, 0x32, 0xe8, 0x98, 0x39, 0x96, 0x81, 0x4a, 0xe5, 0x2e, 0x84, 0xf2, 0xab, 0x3b, 0x71, 0x0f, - 0xef, 0x65, 0x32, 0x50, 0xa9, 0xdc, 0x85, 0x5c, 0xfe, 0xce, 0x4e, 0xdc, 0xc3, 0x8b, 0x99, 0x0c, - 0x14, 0x33, 0x8a, 0xea, 0x9e, 0xee, 0x99, 0xcd, 0x79, 0xdb, 0xf5, 0xa4, 0x45, 0xfe, 0x3f, 0x8e, - 0x19, 0x45, 0x69, 0x44, 0xcc, 0x28, 0x4a, 0x83, 0x27, 0x99, 0x0a, 0x69, 0xfc, 0x5a, 0x4f, 0xa6, - 0xa1, 0xa5, 0x95, 0x06, 0x4f, 0x32, 0x15, 0x42, 0xf8, 0x4f, 0x7a, 0x32, 0x0d, 0x3d, 0xe5, 0xd3, - 0xe0, 0xcc, 0x32, 0x9d, 0x71, 0xec, 0x0d, 0xeb, 0x36, 0xdd, 0xa0, 0x2d, 0xf1, 0xe9, 0xbf, 0x1e, - 0xb3, 0x4c, 0xe3, 0x04, 0x78, 0x8b, 0x12, 0x83, 0x45, 0x19, 0x89, 0xcf, 0xfd, 0x8d, 0x4c, 0x46, - 0xe1, 0x31, 0x51, 0x1c, 0x16, 0x65, 0x24, 0x3e, 0xf1, 0x37, 0x33, 0x19, 0x85, 0xc7, 0x44, 0x71, - 0x18, 0x29, 0xc3, 0x18, 0xbe, 0x95, 0xd0, 0x5d, 0xdf, 0xf3, 0xf3, 0x77, 0x72, 0xd1, 0x5b, 0xaf, - 0x28, 0x7a, 0xbe, 0x4f, 0x8b, 0x15, 0x90, 0x59, 0x88, 0x4f, 0xfa, 0x76, 0x06, 0x8b, 0xd0, 0xdf, - 0x31, 0x0a, 0x91, 0x59, 0x88, 0x8f, 0xf9, 0x4f, 0x33, 0x58, 0x84, 0x0e, 0x8f, 0x51, 0x08, 0xf9, - 0x34, 0x0c, 0xd7, 0xe7, 0x56, 0x6a, 0x7e, 0x32, 0xc1, 0xbf, 0x9b, 0x8b, 0xbd, 0x2a, 0x0a, 0x71, - 0xf8, 0xaa, 0x28, 0xfc, 0x39, 0x3d, 0x00, 0xfd, 0x78, 0x94, 0x7a, 0xbb, 0x34, 0xf8, 0xad, 0xdc, - 0xc4, 0x6f, 0xe5, 0x6e, 0x97, 0x06, 0x7f, 0x2b, 0x37, 0xf1, 0xdb, 0xec, 0xff, 0xdf, 0xce, 0x4d, - 0xfc, 0x4e, 0x4e, 0xbb, 0x10, 0x0e, 0x8b, 0xf2, 0x1a, 0xb5, 0xbc, 0x5a, 0x4b, 0x17, 0x83, 0x3a, - 0x15, 0xc5, 0x7f, 0xa6, 0xa2, 0x44, 0xe2, 0xae, 0x6f, 0xe4, 0x60, 0xa4, 0xee, 0x39, 0x54, 0x6f, - 0x8b, 0x38, 0x78, 0x17, 0x61, 0x90, 0x3b, 0x3f, 0xfb, 0xcf, 0xc0, 0xb5, 0xe0, 0x37, 0xb9, 0x02, - 0x63, 0x0b, 0xba, 0xeb, 0x61, 0x13, 0xab, 0x96, 0x41, 0x1f, 0xe3, 0xc3, 0xbf, 0x82, 0x16, 0x83, - 0x92, 0x05, 0x4e, 0xc7, 0xcb, 0x61, 0xe8, 0xd3, 0xc2, 0x8e, 0xe1, 0xdf, 0x06, 0xbf, 0xb3, 0x35, - 0xd9, 0x87, 0xd1, 0xde, 0x62, 0x65, 0xd5, 0xdf, 0xcf, 0x41, 0xc2, 0x2d, 0x7b, 0xff, 0xf1, 0x1e, - 0x96, 0x61, 0x3c, 0x16, 0x6e, 0x57, 0xbc, 0x5e, 0xdc, 0x65, 0x34, 0xde, 0x78, 0x69, 0xf2, 0x89, - 0xe0, 0xd5, 0xdc, 0x5d, 0x6d, 0x41, 0x84, 0xf6, 0xc3, 0xa4, 0x14, 0x5d, 0xa7, 0xa5, 0x49, 0x28, - 0x11, 0xba, 0xe9, 0x7b, 0x13, 0x61, 0x2c, 0x51, 0x72, 0x45, 0x04, 0x9f, 0xc8, 0x85, 0x01, 0x01, - 0x63, 0x29, 0xf0, 0x79, 0xb0, 0x89, 0xcf, 0xc0, 0x48, 0xb5, 0xdd, 0xa1, 0x8e, 0x6b, 0x5b, 0xba, - 0x67, 0x3b, 0xe2, 0xa9, 0x3d, 0x3e, 0x8a, 0x37, 0x25, 0xb8, 0xfc, 0x28, 0x5e, 0xa6, 0x27, 0xd7, - 0xfc, 0xbc, 0x7a, 0x05, 0x8c, 0xe2, 0x8a, 0x4f, 0x5a, 0xe3, 0x69, 0xd5, 0x39, 0x05, 0x23, 0xbd, - 0xeb, 0xea, 0xf8, 0xbe, 0x32, 0x20, 0xed, 0x32, 0x80, 0x4c, 0x8a, 0x14, 0xe4, 0x05, 0x28, 0xe1, - 0x7d, 0x94, 0x8b, 0xf9, 0x32, 0x45, 0x98, 0xc2, 0x16, 0x42, 0xe4, 0x80, 0x08, 0x9c, 0x86, 0xdc, - 0x81, 0x89, 0xf0, 0xb2, 0xfd, 0x96, 0x63, 0x77, 0x3b, 0x7e, 0x86, 0x1c, 0x4c, 0x47, 0xff, 0x30, - 0xc0, 0x35, 0xd6, 0x10, 0x29, 0xb1, 0x48, 0x14, 0x24, 0xf3, 0x30, 0x1e, 0xc2, 0x98, 0x88, 0xfc, - 0xcc, 0x5c, 0x98, 0x15, 0x55, 0xe2, 0xc5, 0xc4, 0x19, 0xc9, 0x8a, 0x1a, 0x2b, 0x46, 0xaa, 0x30, - 0xe0, 0xc7, 0x28, 0x1c, 0xdc, 0x51, 0x49, 0x4f, 0x8b, 0x18, 0x85, 0x03, 0x72, 0x74, 0x42, 0xbf, - 0x3c, 0x99, 0x83, 0x31, 0xcd, 0xee, 0x7a, 0x74, 0xc5, 0x16, 0xbb, 0x54, 0x11, 0x0b, 0x13, 0xdb, - 0xe4, 0x30, 0x4c, 0xc3, 0xb3, 0xfd, 0x6c, 0xfe, 0x72, 0x56, 0xf9, 0x68, 0x29, 0xb2, 0x04, 0xa7, - 0x12, 0x6e, 0x09, 0x72, 0x8e, 0x7d, 0xe9, 0xf3, 0x92, 0xcc, 0x92, 0x45, 0xc9, 0x8f, 0xe5, 0xa0, - 0xb4, 0xe2, 0xe8, 0xa6, 0xe7, 0x8a, 0xa7, 0x99, 0x67, 0xa7, 0x36, 0x1c, 0xbd, 0xc3, 0xf4, 0x63, - 0x0a, 0xc3, 0xf4, 0xde, 0xd3, 0x5b, 0x5d, 0xea, 0x4e, 0xdf, 0x67, 0x5f, 0xf7, 0xdf, 0x6f, 0x4d, - 0xbe, 0xc9, 0x83, 0x5a, 0x4c, 0x35, 0xed, 0xf6, 0xf5, 0x35, 0x47, 0x7f, 0x64, 0x7a, 0x68, 0x62, - 0xea, 0xad, 0xeb, 0x1e, 0x6d, 0xe1, 0x19, 0xeb, 0x75, 0xbd, 0x63, 0x5e, 0xc7, 0x70, 0xf0, 0xd7, - 0x03, 0x4e, 0xbc, 0x06, 0xa6, 0x02, 0x1e, 0xfe, 0x25, 0xab, 0x00, 0xc7, 0x91, 0x25, 0x00, 0xf1, - 0xa9, 0xe5, 0x4e, 0x47, 0xbc, 0xf3, 0x94, 0x4e, 0x26, 0x7d, 0x0c, 0x57, 0xec, 0x40, 0x60, 0x7a, - 0x47, 0x0a, 0x81, 0xac, 0x49, 0x1c, 0x98, 0x16, 0xac, 0x88, 0x16, 0xf9, 0x62, 0x1a, 0x0d, 0x25, - 0xee, 0x37, 0x36, 0x45, 0x48, 0xf1, 0x62, 0x64, 0x15, 0xc6, 0x05, 0xdf, 0x20, 0x61, 0xca, 0x58, - 0x74, 0x56, 0x88, 0xa1, 0xb9, 0xd2, 0x06, 0x6d, 0x34, 0x04, 0x58, 0xae, 0x23, 0x56, 0x82, 0x4c, - 0x87, 0x09, 0x9e, 0x97, 0xf4, 0x36, 0x75, 0x95, 0x71, 0xd4, 0xd8, 0x4b, 0xdb, 0x5b, 0x93, 0x8a, - 0x5f, 0x1e, 0xc3, 0x75, 0xca, 0xa2, 0x8b, 0x16, 0x91, 0x79, 0x70, 0xad, 0x9f, 0x48, 0xe1, 0x11, - 0xd7, 0xf9, 0x68, 0x11, 0x32, 0x03, 0xa3, 0xc1, 0x33, 0x93, 0xbb, 0x77, 0xab, 0x15, 0x7c, 0x48, - 0x2a, 0x22, 0xb6, 0xc6, 0x52, 0x9a, 0xc8, 0x4c, 0x22, 0x65, 0xa4, 0xc0, 0x1f, 0xfc, 0x65, 0x69, - 0x2c, 0xf0, 0x47, 0x27, 0x25, 0xf0, 0x47, 0x8d, 0xbc, 0x0d, 0xc3, 0xe5, 0xfb, 0x75, 0x11, 0xd0, - 0xc4, 0x55, 0x4e, 0x87, 0xf9, 0xb1, 0xf4, 0x0d, 0xb7, 0xe1, 0x07, 0x3f, 0x91, 0x9b, 0x2e, 0xd3, - 0x93, 0x59, 0x18, 0x8b, 0x78, 0xaa, 0xb9, 0xca, 0x19, 0xe4, 0x80, 0x2d, 0xd7, 0x11, 0xd3, 0x70, - 0x04, 0x4a, 0x1e, 0x5e, 0xd1, 0x42, 0x4c, 0x6b, 0x2a, 0xa6, 0x8b, 0xb9, 0x86, 0x34, 0x8a, 0xb1, - 0x53, 0xf0, 0x59, 0xea, 0x20, 0xd7, 0x1a, 0x43, 0xa0, 0x1a, 0x0e, 0xc7, 0xc9, 0x3d, 0x1a, 0x2b, - 0x46, 0xde, 0x07, 0x82, 0xd9, 0x89, 0xa8, 0xe1, 0x5f, 0x5c, 0x56, 0x2b, 0xae, 0x72, 0x0e, 0xc3, - 0x95, 0x93, 0x78, 0x38, 0x85, 0x6a, 0x65, 0xfa, 0x8a, 0x98, 0x3e, 0x2e, 0xeb, 0xbc, 0x54, 0xc3, - 0x0f, 0xa5, 0xd0, 0x30, 0x23, 0xa9, 0x9b, 0x53, 0xb8, 0x92, 0x0d, 0x38, 0x5f, 0x73, 0xe8, 0x23, - 0xd3, 0xee, 0xba, 0xfe, 0xf2, 0xe1, 0xcf, 0x5b, 0xe7, 0x77, 0x9c, 0xb7, 0x9e, 0x15, 0x15, 0x9f, - 0xed, 0x38, 0xf4, 0x51, 0xc3, 0x0f, 0x52, 0x1d, 0x89, 0xb1, 0x9a, 0xc5, 0x1d, 0x13, 0x50, 0x7f, - 0xd0, 0x75, 0xa8, 0x80, 0x9b, 0xd4, 0x55, 0x94, 0x70, 0xaa, 0xe5, 0x71, 0x75, 0xcc, 0x00, 0x17, - 0x49, 0x40, 0x1d, 0x2d, 0x46, 0x34, 0x20, 0xb7, 0x66, 0xfc, 0x4b, 0xec, 0x72, 0x93, 0xa7, 0xe9, - 0x55, 0x2e, 0x20, 0x33, 0x95, 0x89, 0x65, 0xad, 0x19, 0x04, 0xac, 0x6f, 0xe8, 0x02, 0x2f, 0x8b, - 0x25, 0x59, 0x9a, 0x2c, 0xc0, 0x44, 0xcd, 0xc1, 0x23, 0xb5, 0x3b, 0x74, 0xb3, 0x66, 0xb7, 0xcc, - 0xe6, 0x26, 0xbe, 0x8e, 0x15, 0x53, 0x65, 0x87, 0xe3, 0x1a, 0x0f, 0xe9, 0x66, 0xa3, 0x83, 0x58, - 0x79, 0x59, 0x89, 0x97, 0x94, 0x03, 0x48, 0x3f, 0xb5, 0xbb, 0x00, 0xd2, 0x14, 0x26, 0xc4, 0x15, - 0xf8, 0x63, 0x8f, 0x5a, 0x6c, 0xa9, 0x77, 0xc5, 0x4b, 0x58, 0x25, 0x76, 0x65, 0x1e, 0xe0, 0xf9, - 0xd4, 0x21, 0x46, 0x19, 0x0d, 0xc0, 0x72, 0xc3, 0xe2, 0x45, 0x92, 0x51, 0x96, 0x9f, 0xde, 0x47, - 0x94, 0xe5, 0xff, 0xbd, 0x20, 0xcf, 0xbf, 0xe4, 0x12, 0x14, 0xa5, 0x24, 0x48, 0x18, 0x42, 0x16, - 0x03, 0xc6, 0x17, 0x45, 0x64, 0xec, 0x21, 0x61, 0xbb, 0x04, 0xa1, 0x7d, 0x30, 0xeb, 0x65, 0x18, - 0x56, 0x54, 0x0b, 0x09, 0x30, 0xe3, 0x60, 0x77, 0xb5, 0x65, 0x36, 0x31, 0x8d, 0x40, 0x41, 0x0a, - 0xb7, 0x81, 0x50, 0x9e, 0x45, 0x40, 0x22, 0x21, 0x37, 0x60, 0xd8, 0x3f, 0xca, 0x0d, 0x43, 0x28, - 0x63, 0x74, 0x79, 0x31, 0x5b, 0x8b, 0xe0, 0xf5, 0x12, 0x11, 0x79, 0x03, 0x20, 0x9c, 0x0e, 0x84, - 0xa5, 0x85, 0x4b, 0x85, 0x3c, 0x7b, 0xc8, 0x4b, 0x45, 0x48, 0xcd, 0x26, 0x4e, 0x59, 0x1d, 0xfd, - 0x1c, 0xab, 0x38, 0x71, 0x46, 0x74, 0x58, 0x56, 0x90, 0x68, 0x11, 0xb2, 0x0c, 0xa7, 0x12, 0x1a, - 0x28, 0x02, 0x2e, 0x63, 0x9e, 0xfd, 0x14, 0xf5, 0x95, 0x17, 0xe6, 0x44, 0x59, 0xf2, 0x1c, 0x14, - 0xee, 0x6a, 0x55, 0x11, 0xf4, 0x95, 0xc7, 0x0b, 0x8e, 0x04, 0x70, 0x62, 0x58, 0xf2, 0x3a, 0x00, - 0x4f, 0xaa, 0x52, 0xb3, 0x1d, 0x0f, 0x2d, 0x8a, 0xd1, 0xe9, 0x0b, 0x6c, 0x2c, 0xf3, 0xa4, 0x2b, - 0x0d, 0xb6, 0x8c, 0xc9, 0x1f, 0x1d, 0x12, 0xab, 0x3f, 0x92, 0x4f, 0x2c, 0x6b, 0x4c, 0xf0, 0xa2, - 0x15, 0x52, 0xe7, 0xa3, 0xe0, 0xfd, 0xa6, 0x73, 0xc1, 0x4b, 0x44, 0xe4, 0x2a, 0x0c, 0xd6, 0xd8, - 0xa4, 0xd2, 0xb4, 0x5b, 0x42, 0x15, 0x30, 0xf2, 0x57, 0x47, 0xc0, 0xb4, 0x00, 0x4b, 0x6e, 0x48, - 0x59, 0x85, 0xa5, 0x10, 0xec, 0x7e, 0x56, 0xe1, 0x78, 0x2c, 0x72, 0xcc, 0x2f, 0x7c, 0x23, 0x96, - 0xa5, 0x4c, 0x94, 0x49, 0x59, 0x52, 0xc3, 0xac, 0x64, 0x81, 0x41, 0xdb, 0xbf, 0x93, 0x41, 0xab, - 0xfe, 0xbd, 0x5c, 0x72, 0x88, 0x92, 0x9b, 0xc9, 0x68, 0xc8, 0xb8, 0x7e, 0x05, 0x40, 0xb9, 0xd6, - 0x20, 0x2e, 0x72, 0x24, 0xae, 0x71, 0x7e, 0xdf, 0x71, 0x8d, 0x0b, 0x7b, 0x8c, 0x6b, 0xac, 0xfe, - 0x3f, 0xc5, 0x9e, 0xde, 0xde, 0x47, 0x12, 0xff, 0xee, 0x75, 0xb6, 0x29, 0x63, 0xb5, 0x97, 0xdd, - 0xc4, 0xd6, 0x82, 0x3b, 0xb3, 0x36, 0x74, 0x3e, 0x2a, 0x5d, 0x2d, 0x4a, 0x49, 0xde, 0x81, 0x11, - 0xff, 0x03, 0x30, 0x5e, 0xb6, 0x14, 0xe7, 0x39, 0x58, 0x10, 0x63, 0x91, 0xa5, 0x23, 0x05, 0xc8, - 0x2b, 0x30, 0x84, 0xe6, 0x50, 0x47, 0x6f, 0xfa, 0xc1, 0xd4, 0x79, 0xf4, 0x75, 0x1f, 0x28, 0xc7, - 0x78, 0x0b, 0x28, 0xc9, 0x17, 0xa1, 0x24, 0x32, 0x8a, 0xf0, 0x84, 0xfb, 0xd7, 0x77, 0xe1, 0x1e, - 0x3f, 0x25, 0x67, 0x13, 0xe1, 0x1b, 0x1c, 0x04, 0x44, 0x36, 0x38, 0x3c, 0x91, 0xc8, 0x0a, 0x9c, - 0xae, 0x39, 0xd4, 0xc0, 0x87, 0x18, 0xb3, 0x8f, 0x3b, 0x8e, 0xc8, 0xf5, 0xc2, 0x27, 0x08, 0x5c, - 0xdf, 0x3a, 0x3e, 0x9a, 0xad, 0xbc, 0x02, 0x2f, 0x47, 0x74, 0x4e, 0x29, 0xce, 0x8c, 0x1e, 0xde, - 0x92, 0x3b, 0x74, 0x73, 0xc3, 0x76, 0x0c, 0x9e, 0x0e, 0x45, 0x4c, 0xfd, 0x42, 0xd0, 0x0f, 0x05, - 0x4a, 0x36, 0x7a, 0xa2, 0x85, 0x2e, 0xbe, 0x0e, 0xc3, 0xfb, 0xcd, 0xc8, 0xf1, 0xab, 0xf9, 0x8c, - 0x77, 0x53, 0x4f, 0x6e, 0x52, 0xc4, 0x20, 0x53, 0x77, 0x7f, 0x46, 0xa6, 0xee, 0x3f, 0xc9, 0x67, - 0x3c, 0x0a, 0x7b, 0xa2, 0x33, 0xea, 0x06, 0xc2, 0x88, 0x66, 0xd4, 0x0d, 0x93, 0x19, 0x9b, 0x86, - 0x26, 0x13, 0xc5, 0x72, 0x6f, 0x97, 0x76, 0xcc, 0xbd, 0xfd, 0x8b, 0x85, 0x5e, 0x8f, 0xe6, 0x4e, - 0x64, 0xbf, 0x17, 0xd9, 0xdf, 0x80, 0xe1, 0x40, 0xb2, 0xd5, 0x0a, 0xda, 0x4b, 0xa3, 0x41, 0xfe, - 0x1f, 0x0e, 0xc6, 0x32, 0x12, 0x11, 0xb9, 0xc6, 0xdb, 0x5a, 0x37, 0x3f, 0xe0, 0x99, 0x28, 0x46, - 0x45, 0x8e, 0x01, 0xdd, 0xd3, 0x1b, 0xae, 0xf9, 0x01, 0xd5, 0x02, 0x34, 0x06, 0x19, 0x4d, 0x7b, - 0x3f, 0x78, 0xd2, 0x47, 0xbb, 0xef, 0xa3, 0x14, 0x21, 0xf2, 0x37, 0x93, 0x27, 0x42, 0xdc, 0x83, - 0x10, 0xff, 0x38, 0x9f, 0xfa, 0xc2, 0xf4, 0x44, 0x88, 0x7b, 0x99, 0x2d, 0x5e, 0x80, 0x21, 0xcd, - 0xde, 0x70, 0x67, 0x70, 0x4f, 0xc4, 0xe7, 0x0a, 0x9c, 0xa8, 0x1d, 0x7b, 0xc3, 0x6d, 0xe0, 0x6e, - 0x47, 0x0b, 0x09, 0xd4, 0xef, 0xe5, 0x7b, 0xbc, 0xc1, 0x3d, 0x11, 0xfc, 0x87, 0xb9, 0x44, 0xfe, - 0x46, 0x3e, 0xf2, 0xc6, 0xf7, 0xc9, 0x15, 0xf6, 0x75, 0x80, 0x7a, 0x73, 0x9d, 0xb6, 0x75, 0x29, - 0x9b, 0x17, 0x1e, 0x59, 0xb8, 0x08, 0x15, 0x59, 0xa0, 0x43, 0x12, 0xf5, 0x5b, 0xf9, 0xd8, 0x23, - 0xe7, 0x13, 0xd9, 0xed, 0x5a, 0x76, 0x81, 0xd6, 0x89, 0x77, 0xdb, 0x27, 0x92, 0xdb, 0xad, 0xe4, - 0x7e, 0x3c, 0x1f, 0x7b, 0xe2, 0xfe, 0xc4, 0xca, 0x8e, 0x0d, 0xc0, 0xe4, 0xd3, 0xfb, 0x27, 0x56, - 0x93, 0x5e, 0x80, 0x21, 0x21, 0x87, 0x60, 0xa9, 0xe0, 0xf3, 0x3e, 0x07, 0xe2, 0x01, 0x6d, 0x40, - 0xa0, 0xfe, 0x99, 0x3c, 0x44, 0x43, 0x0f, 0x3c, 0xa1, 0x3a, 0xf4, 0x1b, 0xf9, 0x68, 0xd0, 0x85, - 0x27, 0x57, 0x7f, 0xa6, 0x00, 0xea, 0xdd, 0xd5, 0xa6, 0x88, 0xd9, 0xdb, 0x2f, 0x9d, 0xf0, 0x07, - 0x50, 0x4d, 0xa2, 0x50, 0xff, 0xdf, 0x7c, 0x6a, 0x24, 0x88, 0x27, 0x57, 0x80, 0x2f, 0xe3, 0xa9, - 0x78, 0xd3, 0x0a, 0x27, 0x72, 0x3c, 0x84, 0x64, 0xe3, 0x2f, 0x91, 0x02, 0xd2, 0x27, 0x24, 0x9f, - 0x4e, 0x31, 0xd7, 0x30, 0x41, 0x45, 0x68, 0xae, 0xc9, 0x87, 0xf9, 0x92, 0xe1, 0xf6, 0x7b, 0xf9, - 0x9d, 0x02, 0x67, 0x3c, 0xc9, 0xab, 0xea, 0x40, 0x4d, 0xdf, 0xc4, 0x00, 0x8f, 0xac, 0x27, 0x46, - 0x78, 0x82, 0xc2, 0x0e, 0x07, 0xc9, 0xd7, 0x76, 0x82, 0x4a, 0xfd, 0xe7, 0xfd, 0xe9, 0x51, 0x1b, - 0x9e, 0x5c, 0x11, 0x5e, 0x82, 0x62, 0x4d, 0xf7, 0xd6, 0x85, 0x26, 0xe3, 0x6d, 0x60, 0x47, 0xf7, - 0xd6, 0x35, 0x84, 0x92, 0x6b, 0x30, 0xa8, 0xe9, 0x1b, 0xfc, 0xcc, 0xb3, 0x14, 0x26, 0x8f, 0x74, - 0xf4, 0x8d, 0x06, 0x3f, 0xf7, 0x0c, 0xd0, 0x44, 0x0d, 0x92, 0x97, 0xf2, 0x93, 0x6f, 0xcc, 0x9c, - 0xc7, 0x93, 0x97, 0x06, 0x29, 0x4b, 0x2f, 0x41, 0x71, 0xda, 0x36, 0x36, 0xf1, 0xe6, 0x6b, 0x84, - 0x57, 0xb6, 0x6a, 0x1b, 0x9b, 0x1a, 0x42, 0xc9, 0x4f, 0xe4, 0x60, 0x60, 0x9e, 0xea, 0x06, 0x1b, - 0x21, 0x43, 0xbd, 0x1c, 0x56, 0x3e, 0x77, 0x38, 0x0e, 0x2b, 0xa7, 0xd6, 0x79, 0x65, 0xb2, 0xa2, - 0x88, 0xfa, 0xc9, 0x2d, 0x18, 0x9c, 0xd1, 0x3d, 0xba, 0x66, 0x3b, 0x9b, 0xe8, 0x82, 0x33, 0x16, - 0x7a, 0xfe, 0x47, 0xf4, 0xc7, 0x27, 0xe2, 0x37, 0x63, 0x4d, 0xf1, 0x4b, 0x0b, 0x0a, 0x33, 0xb1, - 0xf0, 0x9b, 0x39, 0x91, 0xa8, 0x1b, 0xc5, 0xc2, 0xaf, 0xf0, 0x34, 0x81, 0x09, 0x8f, 0x95, 0x47, - 0xd2, 0x8f, 0x95, 0xd1, 0x7a, 0x44, 0x37, 0x3d, 0x4c, 0x19, 0x3a, 0x8a, 0x8b, 0x3e, 0xb7, 0x1e, - 0x11, 0x8a, 0x19, 0x43, 0x35, 0x89, 0x44, 0xfd, 0x6e, 0x3f, 0xa4, 0xbe, 0xf1, 0x3e, 0x51, 0xf2, - 0x13, 0x25, 0x0f, 0x95, 0xbc, 0x92, 0x50, 0xf2, 0x8b, 0xc9, 0xa8, 0x01, 0x1f, 0x51, 0x0d, 0xff, - 0xb9, 0x62, 0x22, 0xe6, 0xc8, 0x93, 0xbd, 0xbb, 0x0c, 0xa5, 0xd7, 0xbf, 0xa3, 0xf4, 0x82, 0x01, - 0x51, 0xda, 0x71, 0x40, 0x0c, 0xec, 0x76, 0x40, 0x0c, 0x66, 0x0e, 0x88, 0x50, 0x41, 0x86, 0x32, - 0x15, 0xa4, 0x2a, 0x06, 0x0d, 0xf4, 0x4e, 0x7d, 0x72, 0x69, 0x7b, 0x6b, 0x72, 0x8c, 0x8d, 0xa6, - 0xd4, 0x9c, 0x27, 0xc8, 0x42, 0xfd, 0xfd, 0x62, 0x8f, 0x40, 0x41, 0x47, 0xa2, 0x23, 0x2f, 0x43, - 0xa1, 0xdc, 0xe9, 0x08, 0xfd, 0x38, 0x2d, 0xc5, 0x28, 0xca, 0x28, 0xc5, 0xa8, 0xc9, 0x1b, 0x50, - 0x28, 0xdf, 0xaf, 0xc7, 0xd3, 0x9d, 0x94, 0xef, 0xd7, 0xc5, 0x97, 0x64, 0x96, 0xbd, 0x5f, 0x27, - 0x6f, 0x85, 0x71, 0x47, 0xd7, 0xbb, 0xd6, 0x43, 0xb1, 0x51, 0x14, 0x9e, 0xba, 0xbe, 0x27, 0x4f, - 0x93, 0xa1, 0xd8, 0x76, 0x31, 0x46, 0x1b, 0xd3, 0xa6, 0xd2, 0xee, 0xb5, 0x69, 0x60, 0x47, 0x6d, - 0x1a, 0xdc, 0xad, 0x36, 0x0d, 0xed, 0x42, 0x9b, 0x60, 0x47, 0x6d, 0x1a, 0x3e, 0xb8, 0x36, 0x75, - 0xe0, 0x62, 0x32, 0xb8, 0x5b, 0xa0, 0x11, 0x1a, 0x90, 0x24, 0x56, 0x38, 0x96, 0xe0, 0xd5, 0x7f, - 0x97, 0x63, 0x1b, 0x1b, 0x88, 0x6e, 0xb8, 0x0c, 0x2f, 0xbb, 0xb6, 0x25, 0x4b, 0xab, 0xbf, 0x9a, - 0xcf, 0x8e, 0x49, 0x77, 0x3c, 0xa7, 0xb8, 0x1f, 0x4c, 0x95, 0x52, 0x31, 0x1a, 0x23, 0x20, 0x5b, - 0xca, 0x31, 0xb6, 0x69, 0x32, 0xfb, 0x66, 0x3e, 0x2b, 0x50, 0xde, 0x81, 0x24, 0xf6, 0xf1, 0xa4, - 0x33, 0x1c, 0xba, 0xf8, 0xbb, 0x51, 0x2f, 0xb8, 0x39, 0x18, 0x91, 0x85, 0x28, 0xa4, 0xb4, 0x1b, - 0x01, 0x47, 0xca, 0x91, 0xb7, 0x82, 0xac, 0x34, 0x92, 0x7f, 0x0c, 0x7a, 0xba, 0xf9, 0x63, 0x36, - 0xe6, 0x1e, 0x23, 0x93, 0x93, 0x17, 0xa0, 0x34, 0x87, 0x61, 0xde, 0xe5, 0xc1, 0xce, 0x03, 0xbf, - 0xcb, 0x5e, 0x2b, 0x9c, 0x46, 0xfd, 0x7b, 0x39, 0x38, 0x7d, 0xa7, 0xbb, 0x4a, 0x85, 0xa3, 0x5d, - 0xd0, 0x86, 0xf7, 0x01, 0x18, 0x58, 0x38, 0xcc, 0xe4, 0xd0, 0x61, 0xe6, 0x93, 0x72, 0x40, 0xbd, - 0x58, 0x81, 0xa9, 0x90, 0x9a, 0x3b, 0xcb, 0x3c, 0xed, 0xfb, 0x9c, 0x3e, 0xec, 0xae, 0xd2, 0x46, - 0xc2, 0x6b, 0x46, 0xe2, 0x7e, 0xf1, 0x6d, 0xee, 0xcd, 0xbf, 0x5f, 0x07, 0x95, 0x5f, 0xc9, 0x67, - 0xc6, 0x30, 0x3c, 0xb6, 0xa9, 0x41, 0xbf, 0x90, 0xda, 0x2b, 0xf1, 0x14, 0xa1, 0x29, 0x24, 0x31, - 0x8e, 0x69, 0x5c, 0xd2, 0x05, 0x76, 0xcc, 0x13, 0xd6, 0x7e, 0xa8, 0x02, 0xfb, 0x87, 0xb9, 0xcc, - 0x58, 0x93, 0xc7, 0x55, 0x60, 0xea, 0xff, 0x52, 0xf0, 0x43, 0x5c, 0x1e, 0xe8, 0x13, 0x5e, 0x80, - 0x21, 0xf1, 0xd2, 0x3f, 0xea, 0x27, 0x2c, 0x8e, 0x0d, 0xf1, 0x18, 0x3a, 0x20, 0x60, 0x26, 0x85, - 0xe4, 0xc4, 0x2c, 0xf9, 0x09, 0x4b, 0x0e, 0xcc, 0x9a, 0x44, 0xc2, 0x8c, 0x86, 0xd9, 0xc7, 0xa6, - 0x87, 0x16, 0x08, 0xeb, 0xcb, 0x02, 0x37, 0x1a, 0xe8, 0x63, 0xd3, 0xe3, 0xf6, 0x47, 0x80, 0x66, - 0x06, 0x41, 0x3d, 0x4c, 0xc7, 0x2f, 0x0c, 0x02, 0x6e, 0xaa, 0x68, 0x02, 0xc3, 0x5a, 0x2b, 0x9c, - 0x6f, 0x85, 0x4b, 0x8b, 0x68, 0xad, 0x70, 0xd7, 0xc5, 0xd6, 0x06, 0x04, 0x8c, 0xa3, 0x46, 0xd7, - 0x42, 0x27, 0x3e, 0xe4, 0xe8, 0x20, 0x44, 0x13, 0x18, 0x72, 0x03, 0xc6, 0xea, 0x9e, 0x6e, 0x19, - 0xba, 0x63, 0x2c, 0x77, 0xbd, 0x4e, 0xd7, 0x93, 0x0d, 0x60, 0xd7, 0x33, 0xec, 0xae, 0xa7, 0xc5, - 0x28, 0xc8, 0xa7, 0x60, 0xd4, 0x87, 0xcc, 0x3a, 0x8e, 0xed, 0xc8, 0x56, 0x8e, 0xeb, 0x19, 0xd4, - 0x71, 0xb4, 0x28, 0x01, 0xf9, 0x34, 0x8c, 0x56, 0xad, 0x47, 0x76, 0x93, 0xbf, 0x76, 0xd7, 0x16, - 0x84, 0xcd, 0x83, 0x2f, 0xc6, 0xcc, 0x00, 0xd1, 0xe8, 0x3a, 0x2d, 0x2d, 0x4a, 0xa8, 0x6e, 0xe7, - 0x93, 0x91, 0x40, 0x9f, 0xdc, 0x0d, 0xd2, 0xb5, 0xa8, 0xe3, 0x1e, 0x7a, 0xab, 0xa2, 0xf1, 0x29, - 0xfb, 0x0d, 0x73, 0x1b, 0xf4, 0x06, 0x0c, 0xde, 0xa1, 0x9b, 0xdc, 0xc7, 0xb4, 0x14, 0xba, 0x25, - 0x3f, 0x14, 0x30, 0xf9, 0x74, 0xd7, 0xa7, 0x53, 0xbf, 0x9d, 0x4f, 0xc6, 0x38, 0x7d, 0x72, 0x85, - 0xfd, 0x29, 0x18, 0x40, 0x51, 0x56, 0xfd, 0xeb, 0x05, 0x14, 0x20, 0x8a, 0x3b, 0xea, 0xed, 0xec, - 0x93, 0xa9, 0xbf, 0x50, 0x8a, 0x07, 0xbe, 0x7d, 0x72, 0xa5, 0xf7, 0x26, 0x0c, 0xcf, 0xd8, 0x96, - 0x6b, 0xba, 0x1e, 0xb5, 0x9a, 0xbe, 0xc2, 0xa2, 0xe3, 0x7f, 0x33, 0x04, 0xcb, 0x36, 0xa0, 0x44, - 0xbd, 0x1f, 0xe5, 0x25, 0xaf, 0xc2, 0x10, 0x8a, 0x1c, 0x6d, 0x4e, 0x3e, 0xe1, 0xe1, 0xcd, 0xc4, - 0x2a, 0x03, 0xc6, 0x2d, 0xce, 0x90, 0x94, 0xdc, 0x85, 0xc1, 0x99, 0x75, 0xb3, 0x65, 0x38, 0xd4, - 0x42, 0xdf, 0x64, 0x29, 0xbe, 0x48, 0xb4, 0x2f, 0xa7, 0xf0, 0x5f, 0xa4, 0xe5, 0xcd, 0x69, 0x8a, - 0x62, 0x91, 0xc7, 0x62, 0x02, 0x76, 0xf1, 0x67, 0xf2, 0x00, 0x61, 0x01, 0xf2, 0x0c, 0xe4, 0x83, - 0xc4, 0xd4, 0xe8, 0x12, 0x13, 0xd1, 0xa0, 0x3c, 0x2e, 0x15, 0x62, 0x6c, 0xe7, 0x77, 0x1c, 0xdb, - 0x77, 0xa1, 0xc4, 0x4f, 0xd7, 0xd0, 0x6b, 0x5d, 0x8a, 0xc5, 0x99, 0xd9, 0xe0, 0x29, 0xa4, 0xe7, - 0xb6, 0x34, 0x5a, 0x9e, 0x11, 0x0f, 0x70, 0xce, 0xec, 0x62, 0x13, 0xfa, 0xf1, 0x2f, 0x72, 0x05, - 0x8a, 0x2b, 0x7e, 0xde, 0xd9, 0x51, 0x3e, 0x4b, 0xc7, 0xe4, 0x87, 0x78, 0xd6, 0x4d, 0x33, 0xb6, - 0xe5, 0xb1, 0xaa, 0xb1, 0xd5, 0x23, 0x42, 0x2e, 0x02, 0x16, 0x91, 0x8b, 0x80, 0xa9, 0xff, 0x55, - 0x3e, 0x25, 0x24, 0xf3, 0x93, 0x3b, 0x4c, 0x5e, 0x07, 0xc0, 0x97, 0xe7, 0x4c, 0x9e, 0xfe, 0x73, - 0x10, 0x1c, 0x25, 0xc8, 0x08, 0xd5, 0x36, 0xb2, 0xed, 0x08, 0x89, 0xd5, 0x7f, 0x90, 0x4b, 0xc4, - 0xf1, 0x3d, 0x90, 0x1c, 0x65, 0xab, 0x2c, 0xbf, 0x4f, 0x33, 0xd6, 0xef, 0x8b, 0xc2, 0xde, 0xfa, - 0x22, 0xfa, 0x2d, 0x87, 0x60, 0x99, 0x1e, 0xe5, 0xb7, 0x7c, 0x37, 0x9f, 0x16, 0xd5, 0xf8, 0x78, - 0xaa, 0xf8, 0xcd, 0xc0, 0x28, 0x2d, 0xc6, 0xe2, 0xc8, 0x23, 0x34, 0x9e, 0x1b, 0x5b, 0x98, 0xa9, - 0x5f, 0x82, 0xf1, 0x58, 0xac, 0x5f, 0x91, 0xa6, 0xf8, 0x4a, 0xef, 0xa0, 0xc1, 0xd9, 0x31, 0x0b, - 0x22, 0x64, 0xea, 0xff, 0x97, 0xeb, 0x1d, 0xe9, 0xf9, 0xc8, 0x55, 0x27, 0x45, 0x00, 0x85, 0x3f, - 0x1d, 0x01, 0x1c, 0xc2, 0x36, 0xf8, 0x78, 0x0b, 0xe0, 0x23, 0x32, 0x79, 0x7c, 0xd8, 0x02, 0xf8, - 0x85, 0xdc, 0x8e, 0x81, 0xba, 0x8f, 0x5a, 0x06, 0xea, 0xff, 0x98, 0x4b, 0x0d, 0xa8, 0x7d, 0xa0, - 0x76, 0xbd, 0x05, 0x25, 0xee, 0xc2, 0x23, 0x5a, 0x25, 0xa5, 0x20, 0x63, 0xd0, 0xac, 0xa4, 0xfd, - 0x1c, 0x4b, 0x16, 0x60, 0x80, 0xb7, 0xc1, 0x10, 0xbd, 0xf1, 0xb1, 0x1e, 0x51, 0xbd, 0x8d, 0xac, - 0xc9, 0x51, 0xa0, 0xd5, 0xbf, 0x9f, 0x4b, 0xc4, 0xf7, 0x3e, 0xc2, 0x6f, 0x0b, 0xa7, 0xea, 0xc2, - 0xee, 0xa7, 0x6a, 0xf5, 0x9f, 0xe5, 0xd3, 0xc3, 0x8b, 0x1f, 0xe1, 0x87, 0x1c, 0xc6, 0x71, 0xda, - 0xfe, 0xd6, 0xad, 0x15, 0x18, 0x8b, 0xca, 0x42, 0x2c, 0x5b, 0x97, 0xd3, 0x83, 0xac, 0x67, 0xb4, - 0x22, 0xc6, 0x43, 0xfd, 0x4e, 0x2e, 0x19, 0x19, 0xfd, 0xc8, 0xe7, 0xa7, 0xfd, 0x69, 0x4b, 0xf4, - 0x53, 0x3e, 0x22, 0x6b, 0xcd, 0x61, 0x7c, 0xca, 0x47, 0x64, 0xd5, 0xd8, 0xdf, 0xa7, 0xfc, 0x52, - 0x3e, 0x2b, 0xb0, 0xfc, 0x91, 0x7f, 0xd0, 0xe7, 0x65, 0x21, 0xf3, 0x96, 0x89, 0x4f, 0x7b, 0x26, - 0x2b, 0x92, 0x7b, 0x06, 0xcf, 0x04, 0x9f, 0xfd, 0x8d, 0xf1, 0x54, 0x61, 0x7d, 0x44, 0x14, 0xf9, - 0x78, 0x08, 0xeb, 0x23, 0x32, 0x54, 0x3e, 0x7a, 0xc2, 0xfa, 0xad, 0xfc, 0x6e, 0xb3, 0x19, 0x9c, - 0x08, 0x2f, 0x21, 0xbc, 0xaf, 0xe5, 0x93, 0x59, 0x36, 0x8e, 0x5c, 0x4c, 0x73, 0x50, 0x12, 0xf9, - 0x3e, 0x32, 0x85, 0xc3, 0xf1, 0x59, 0x16, 0x8d, 0xf8, 0x8e, 0x9b, 0x20, 0x2e, 0x72, 0x76, 0x27, - 0x12, 0x4e, 0xab, 0x7e, 0x2f, 0x17, 0x4b, 0x49, 0x71, 0x24, 0x47, 0x08, 0xfb, 0x5a, 0x92, 0xc8, - 0xdb, 0xfe, 0x61, 0x66, 0x31, 0x16, 0x12, 0x3c, 0xf8, 0x9e, 0x0a, 0xf5, 0x74, 0xb3, 0x15, 0x2f, - 0x2f, 0xe2, 0x0f, 0x7c, 0x3b, 0x0f, 0xa7, 0x12, 0xa4, 0xe4, 0x4a, 0x24, 0xe2, 0x0f, 0x1e, 0x4b, - 0xc6, 0x1c, 0xd5, 0x79, 0xec, 0x9f, 0x3d, 0x9c, 0xa4, 0x5e, 0x81, 0x62, 0x45, 0xdf, 0xe4, 0xdf, - 0xd6, 0xcf, 0x59, 0x1a, 0xfa, 0xa6, 0x7c, 0xe2, 0x86, 0x78, 0xb2, 0x0a, 0x67, 0xf9, 0x7d, 0x88, - 0x69, 0x5b, 0x2b, 0x66, 0x9b, 0x56, 0xad, 0x45, 0xb3, 0xd5, 0x32, 0x5d, 0x71, 0xa9, 0xf7, 0xc2, - 0xf6, 0xd6, 0xe4, 0x55, 0xcf, 0xf6, 0xf4, 0x56, 0x83, 0xfa, 0x64, 0x0d, 0xcf, 0x6c, 0xd3, 0x86, - 0x69, 0x35, 0xda, 0x48, 0x29, 0xb1, 0x4c, 0x67, 0x45, 0xaa, 0x3c, 0xfa, 0x7b, 0xbd, 0xa9, 0x5b, - 0x16, 0x35, 0xaa, 0xd6, 0xf4, 0xa6, 0x47, 0xf9, 0x65, 0x60, 0x81, 0x1f, 0x09, 0xf2, 0x77, 0xe8, - 0x1c, 0xcd, 0x18, 0xaf, 0x32, 0x02, 0x2d, 0xa5, 0x90, 0xfa, 0xdb, 0xc5, 0x94, 0x6c, 0x24, 0xc7, - 0x48, 0x7d, 0xfc, 0x9e, 0x2e, 0xee, 0xd0, 0xd3, 0xd7, 0x61, 0x40, 0x84, 0xd7, 0x15, 0x17, 0x0c, - 0xe8, 0x38, 0xff, 0x88, 0x83, 0xe4, 0x1b, 0x1a, 0x41, 0x45, 0x5a, 0x70, 0x71, 0x85, 0x75, 0x53, - 0x7a, 0x67, 0x96, 0xf6, 0xd1, 0x99, 0x3d, 0xf8, 0x91, 0xf7, 0xe0, 0x3c, 0x62, 0x53, 0xba, 0x75, - 0x00, 0xab, 0xc2, 0x50, 0x5a, 0xbc, 0xaa, 0xf4, 0xce, 0xcd, 0x2a, 0x4f, 0x3e, 0x0f, 0x23, 0xc1, - 0x00, 0x31, 0xa9, 0x2b, 0x6e, 0x2e, 0x7a, 0x8c, 0x33, 0x1e, 0xa7, 0x8e, 0x81, 0xd1, 0x5d, 0x2d, - 0x1a, 0xeb, 0x2c, 0xc2, 0x4b, 0xfd, 0x1f, 0x72, 0xbd, 0xb2, 0xa2, 0x1c, 0xf9, 0xac, 0xfc, 0x36, - 0x0c, 0x18, 0xfc, 0xa3, 0x84, 0x4e, 0xf5, 0xce, 0x9b, 0xc2, 0x49, 0x35, 0xbf, 0x8c, 0xfa, 0x4f, - 0x73, 0x3d, 0x93, 0xb1, 0x1c, 0xf7, 0xcf, 0xfb, 0x5a, 0x21, 0xe3, 0xf3, 0xc4, 0x24, 0x7a, 0x0d, - 0x26, 0xcc, 0x30, 0x5a, 0x7c, 0x23, 0x0c, 0x75, 0xa5, 0x8d, 0x4b, 0x70, 0x1c, 0x5d, 0x37, 0x21, - 0x70, 0xd8, 0x72, 0x7c, 0x6f, 0x34, 0xb7, 0xd1, 0x75, 0x4c, 0x3e, 0x2e, 0xb5, 0x33, 0x6e, 0xcc, - 0x55, 0xcd, 0xbd, 0xeb, 0x98, 0xac, 0x02, 0xdd, 0x5b, 0xa7, 0x96, 0xde, 0xd8, 0xb0, 0x9d, 0x87, - 0x18, 0x0c, 0x95, 0x0f, 0x4e, 0x6d, 0x9c, 0xc3, 0xef, 0xfb, 0x60, 0xf2, 0x1c, 0x8c, 0xae, 0xb5, - 0xba, 0x34, 0x08, 0x3f, 0xc9, 0xef, 0xfa, 0xb4, 0x11, 0x06, 0x0c, 0x6e, 0x48, 0x9e, 0x06, 0x40, - 0x22, 0x0f, 0x53, 0xe5, 0xe0, 0xc5, 0x9e, 0x36, 0xc4, 0x20, 0x2b, 0xa2, 0xbb, 0x2e, 0x72, 0xad, - 0xe6, 0x42, 0x6a, 0xb4, 0x6c, 0x6b, 0xad, 0xe1, 0x51, 0xa7, 0x8d, 0x0d, 0x45, 0x67, 0x06, 0xed, - 0x1c, 0x52, 0xe0, 0xd5, 0x89, 0xbb, 0x60, 0x5b, 0x6b, 0x2b, 0xd4, 0x69, 0xb3, 0xa6, 0xbe, 0x00, - 0x44, 0x34, 0xd5, 0xc1, 0x43, 0x0f, 0xfe, 0x71, 0xe8, 0xcd, 0xa0, 0x89, 0x8f, 0xe0, 0xa7, 0x21, - 0xf8, 0x61, 0x93, 0x30, 0xcc, 0x63, 0xf0, 0x71, 0xa1, 0xa1, 0x0b, 0x83, 0x06, 0x1c, 0x84, 0xf2, - 0x3a, 0x07, 0xc2, 0xbb, 0x82, 0x7b, 0x90, 0x6b, 0xe2, 0x97, 0xfa, 0x95, 0x42, 0x5a, 0xfe, 0x98, - 0x03, 0x29, 0x5a, 0x38, 0xad, 0xe6, 0xf7, 0x34, 0xad, 0x8e, 0x5b, 0xdd, 0x76, 0x43, 0xef, 0x74, - 0x1a, 0x0f, 0xcc, 0x16, 0x3e, 0xe1, 0xc2, 0x85, 0x4f, 0x1b, 0xb5, 0xba, 0xed, 0x72, 0xa7, 0x33, - 0xc7, 0x81, 0xe4, 0x79, 0x38, 0xc5, 0xe8, 0xb0, 0x93, 0x02, 0xca, 0x22, 0x52, 0x32, 0x06, 0x18, - 0xc4, 0xd6, 0xa7, 0xbd, 0x00, 0x83, 0x82, 0x27, 0x5f, 0xab, 0xfa, 0xb5, 0x01, 0xce, 0xcc, 0x65, - 0x3d, 0x17, 0xb0, 0xe1, 0x93, 0x6b, 0xbf, 0x36, 0xe4, 0x97, 0xc7, 0x50, 0xcd, 0x56, 0xb7, 0xcd, - 0xa3, 0x6f, 0x0d, 0x20, 0x32, 0xf8, 0x4d, 0xae, 0xc0, 0x18, 0xe3, 0x12, 0x08, 0x8c, 0x47, 0xb7, - 0xed, 0xd7, 0x62, 0x50, 0x72, 0x03, 0xce, 0x44, 0x20, 0xdc, 0x06, 0xe5, 0x4f, 0x12, 0xfa, 0xb5, - 0x54, 0x9c, 0xfa, 0xad, 0x42, 0x34, 0xab, 0xcd, 0x11, 0x74, 0xc4, 0x79, 0x18, 0xb0, 0x9d, 0xb5, - 0x46, 0xd7, 0x69, 0x89, 0xb1, 0x57, 0xb2, 0x9d, 0xb5, 0xbb, 0x4e, 0x8b, 0x9c, 0x85, 0x12, 0xeb, - 0x1d, 0xd3, 0x10, 0x43, 0xac, 0x5f, 0xef, 0x74, 0xaa, 0x06, 0x29, 0xf3, 0x0e, 0xc1, 0xc8, 0xa8, - 0x8d, 0x26, 0x6e, 0xed, 0xb9, 0x53, 0x42, 0x3f, 0x5f, 0xf1, 0x12, 0x48, 0xec, 0x27, 0x8c, 0x97, - 0xca, 0x0f, 0x02, 0x62, 0x2c, 0x0c, 0xdc, 0x96, 0x18, 0xbc, 0x4f, 0xe2, 0x2c, 0x04, 0x32, 0x64, - 0xc1, 0x37, 0x31, 0x06, 0xa9, 0x00, 0x09, 0xa9, 0xda, 0xb6, 0x61, 0x3e, 0x30, 0x29, 0x7f, 0x41, - 0xd2, 0xcf, 0x2f, 0x7e, 0x93, 0x58, 0x6d, 0xc2, 0x67, 0xb2, 0x28, 0x20, 0xe4, 0x4d, 0xae, 0x84, - 0x9c, 0x0e, 0xd7, 0x3e, 0xde, 0xb7, 0xdc, 0x4e, 0x8b, 0xa1, 0x50, 0x33, 0xb1, 0x3c, 0x2e, 0x84, - 0xea, 0x5f, 0x2f, 0x26, 0x53, 0x1b, 0x1d, 0x89, 0x5d, 0x33, 0x0f, 0x20, 0x32, 0x97, 0x85, 0x97, - 0x6b, 0x81, 0x77, 0x7b, 0x88, 0xc9, 0xe0, 0x21, 0x95, 0x25, 0xd7, 0x60, 0x90, 0x7f, 0x51, 0xb5, - 0x22, 0xec, 0x1d, 0x74, 0x11, 0x73, 0x3b, 0xe6, 0x83, 0x07, 0xe8, 0x4f, 0x16, 0xa0, 0xc9, 0x15, - 0x18, 0xa8, 0x2c, 0xd5, 0xeb, 0xe5, 0x25, 0xff, 0xa6, 0x18, 0xdf, 0xb2, 0x18, 0x96, 0xdb, 0x70, - 0x75, 0xcb, 0xd5, 0x7c, 0x24, 0x79, 0x0e, 0x4a, 0xd5, 0x1a, 0x92, 0xf1, 0x17, 0x9a, 0xc3, 0xdb, - 0x5b, 0x93, 0x03, 0x66, 0x87, 0x53, 0x09, 0x14, 0xd6, 0x7b, 0xaf, 0x5a, 0x91, 0xdc, 0x25, 0x78, - 0xbd, 0x8f, 0x4c, 0x03, 0xaf, 0x9d, 0xb5, 0x00, 0x4d, 0x5e, 0x81, 0x91, 0x3a, 0x75, 0x4c, 0xbd, - 0xb5, 0xd4, 0xc5, 0xad, 0xa2, 0x14, 0xf1, 0xd1, 0x45, 0x78, 0xc3, 0x42, 0x84, 0x16, 0x21, 0x23, - 0x97, 0xa0, 0x38, 0x6f, 0x5a, 0xfe, 0x73, 0x09, 0xf4, 0xa7, 0x5f, 0x37, 0x2d, 0x4f, 0x43, 0x28, - 0x79, 0x0e, 0x0a, 0xb7, 0x57, 0xaa, 0xc2, 0x13, 0x0c, 0x79, 0xbd, 0xef, 0x45, 0xa2, 0x47, 0xde, - 0x5e, 0xa9, 0x92, 0x57, 0x60, 0x88, 0x2d, 0x62, 0xd4, 0x6a, 0x52, 0x57, 0x19, 0xc6, 0x8f, 0xe1, - 0x21, 0x0b, 0x7d, 0xa0, 0xec, 0xd3, 0x11, 0x50, 0xaa, 0xff, 0x47, 0x3e, 0x3d, 0xf7, 0xd4, 0x11, - 0x0c, 0xf5, 0x7d, 0xde, 0x22, 0xc7, 0x14, 0xac, 0x78, 0x00, 0x05, 0x7b, 0x00, 0xe3, 0x65, 0xa3, - 0x6d, 0x5a, 0x65, 0xfc, 0xe9, 0x2e, 0xce, 0x95, 0x71, 0xea, 0x90, 0x9e, 0x02, 0xc6, 0xd0, 0xe2, - 0x7b, 0x78, 0x5c, 0x62, 0x86, 0x6a, 0xe8, 0x1c, 0xd7, 0x68, 0x3f, 0xd0, 0x1b, 0x4d, 0x9e, 0xb6, - 0x49, 0x8b, 0x33, 0x55, 0x7f, 0x3a, 0xbf, 0x43, 0xba, 0xac, 0x27, 0x51, 0xfa, 0xea, 0xd7, 0xf3, - 0xbd, 0x33, 0x96, 0x3d, 0x91, 0x42, 0xf9, 0xe3, 0x7c, 0x4a, 0xfe, 0xb0, 0x03, 0x49, 0xe2, 0x1a, - 0x0c, 0x72, 0x36, 0x81, 0x1b, 0x2f, 0xce, 0x66, 0x5c, 0x59, 0x71, 0x16, 0xf5, 0xd1, 0x64, 0x09, - 0xce, 0x94, 0x1f, 0x3c, 0xa0, 0x4d, 0x2f, 0x8c, 0x50, 0xbd, 0x14, 0x06, 0x7c, 0xe5, 0x11, 0x79, - 0x05, 0x3e, 0x8c, 0x70, 0x8d, 0x81, 0x4d, 0x52, 0xcb, 0x91, 0x15, 0x38, 0x17, 0x87, 0xd7, 0xf9, - 0x16, 0xa0, 0x28, 0x05, 0xe9, 0x4d, 0x70, 0xe4, 0xff, 0x69, 0x19, 0x65, 0xd3, 0x5a, 0x89, 0x53, - 0x75, 0x7f, 0xaf, 0x56, 0xe2, 0xbc, 0x9d, 0x5a, 0x4e, 0xfd, 0x76, 0x41, 0x4e, 0xb3, 0xf6, 0xe4, - 0x3a, 0x5c, 0xdd, 0x8c, 0xb8, 0x59, 0xef, 0x76, 0xc8, 0xbc, 0x22, 0xa2, 0x95, 0x18, 0x5d, 0xc7, - 0xf7, 0x48, 0x0c, 0xa2, 0x25, 0x20, 0x50, 0x5e, 0x87, 0x02, 0x4a, 0x52, 0x85, 0x62, 0xd9, 0x59, - 0xe3, 0xe6, 0xed, 0x4e, 0x0f, 0xb8, 0x74, 0x67, 0xcd, 0x4d, 0x7f, 0xc0, 0xc5, 0x58, 0xa8, 0x7f, - 0x3e, 0xdf, 0x23, 0x33, 0xda, 0x13, 0x39, 0x89, 0xfc, 0xc5, 0x7c, 0x56, 0x8e, 0xb3, 0xe3, 0xea, - 0x3a, 0xf6, 0x21, 0x0b, 0xe7, 0x78, 0xfb, 0xd5, 0x1d, 0xa2, 0x70, 0xfe, 0x30, 0x9f, 0x95, 0xb0, - 0xed, 0x44, 0x38, 0xfb, 0x9b, 0x20, 0x53, 0x45, 0xfa, 0x04, 0xdb, 0xdc, 0xb2, 0x2a, 0xf4, 0xef, - 0xd3, 0x7d, 0x2a, 0x4d, 0xa4, 0x27, 0x43, 0xf8, 0x40, 0x5a, 0xfa, 0x0f, 0xf3, 0x99, 0x89, 0x09, - 0x4f, 0x64, 0x7a, 0x98, 0x32, 0x3d, 0x19, 0xfa, 0x07, 0x1a, 0xfa, 0xa9, 0x32, 0x3d, 0x19, 0xfb, - 0x07, 0xd2, 0xd3, 0x3f, 0xc8, 0xa7, 0xa7, 0xde, 0x3c, 0x02, 0x25, 0x3d, 0x0c, 0x0f, 0x47, 0xbf, - 0x1b, 0x8a, 0x07, 0xea, 0x86, 0xfe, 0x03, 0x58, 0x51, 0x49, 0x81, 0x1e, 0xd9, 0xa8, 0xff, 0x7e, - 0x15, 0xe8, 0x21, 0x0c, 0xf9, 0x27, 0x59, 0xa0, 0x3f, 0x59, 0x48, 0xa6, 0x9b, 0x7d, 0x52, 0xd7, - 0x24, 0x67, 0x9f, 0x6b, 0x92, 0x5f, 0x8e, 0xbc, 0x03, 0xe3, 0xa1, 0x2c, 0xe5, 0x28, 0x63, 0x78, - 0x7d, 0xd4, 0x64, 0xa8, 0xc6, 0xfb, 0x0c, 0x27, 0xc2, 0xe1, 0xc4, 0xa9, 0xd5, 0xef, 0x15, 0x92, - 0x39, 0x7b, 0x4f, 0x7a, 0x63, 0x9f, 0xbd, 0x71, 0x17, 0xce, 0xcd, 0x74, 0x1d, 0x87, 0x5a, 0x5e, - 0x7a, 0xa7, 0xe0, 0xe1, 0x7d, 0x93, 0x53, 0x34, 0x92, 0x9d, 0x93, 0x51, 0x98, 0xb1, 0x15, 0xaf, - 0x1b, 0xe2, 0x6c, 0x07, 0x42, 0xb6, 0x5d, 0x4e, 0x91, 0xc6, 0x36, 0xbd, 0xb0, 0xfa, 0x7b, 0xf9, - 0x64, 0x96, 0xe5, 0x93, 0xae, 0xdf, 0x5f, 0xd7, 0xab, 0x5f, 0x29, 0xc4, 0x33, 0x4d, 0x9f, 0x2c, - 0x10, 0xfb, 0xef, 0x0e, 0x5f, 0x92, 0x38, 0x6e, 0xa4, 0xaf, 0xf0, 0xe1, 0x59, 0x5f, 0xe1, 0xe3, - 0xd5, 0x5f, 0x29, 0xc6, 0xb3, 0x76, 0x9f, 0x74, 0xc7, 0xd1, 0x75, 0x07, 0x59, 0x86, 0x33, 0x62, - 0x6e, 0xf3, 0x41, 0x98, 0x6e, 0x42, 0xcc, 0x5f, 0x3c, 0x6b, 0x9d, 0x98, 0x16, 0xbb, 0x2e, 0x75, - 0x1a, 0x9e, 0xee, 0x3e, 0x6c, 0x60, 0x7e, 0x0a, 0x2d, 0xb5, 0x20, 0x63, 0x28, 0x66, 0xb5, 0x28, - 0xc3, 0xc1, 0x90, 0xa1, 0x3f, 0x21, 0x26, 0x18, 0xa6, 0x15, 0x54, 0x7f, 0x23, 0x07, 0x13, 0xf1, - 0xcf, 0x21, 0x53, 0x30, 0xc8, 0x7e, 0x07, 0xcf, 0xee, 0xa5, 0x74, 0xda, 0x9c, 0x23, 0xbf, 0x92, - 0xf7, 0x69, 0xc8, 0xab, 0x30, 0x84, 0xde, 0x0f, 0x58, 0x20, 0x1f, 0x46, 0x3b, 0x08, 0x0b, 0x60, - 0x8e, 0x57, 0x5e, 0x2c, 0x24, 0x25, 0x6f, 0xc2, 0x70, 0x35, 0x74, 0xf3, 0x12, 0x77, 0x5e, 0xe8, - 0x5d, 0x2a, 0x95, 0x0c, 0x09, 0x34, 0x99, 0x5a, 0xfd, 0x4e, 0x3e, 0x9e, 0x5d, 0xfe, 0x44, 0xd5, - 0xf7, 0xa7, 0xea, 0xcf, 0x2f, 0x72, 0x55, 0xbf, 0x63, 0x5a, 0x06, 0xb9, 0x00, 0x67, 0xef, 0xd6, - 0x67, 0xb5, 0xc6, 0x9d, 0xea, 0x52, 0xa5, 0x71, 0x77, 0xa9, 0x5e, 0x9b, 0x9d, 0xa9, 0xce, 0x55, - 0x67, 0x2b, 0x13, 0x7d, 0xe4, 0x34, 0x8c, 0x87, 0xa8, 0xf9, 0xbb, 0x8b, 0xe5, 0xa5, 0x89, 0x1c, - 0x39, 0x05, 0xa3, 0x21, 0x70, 0x7a, 0x79, 0x65, 0x22, 0xff, 0xfc, 0x27, 0x60, 0x18, 0xdd, 0xdb, - 0xf8, 0x75, 0x3c, 0x19, 0x81, 0xc1, 0xe5, 0xe9, 0xfa, 0xac, 0x76, 0x0f, 0x99, 0x00, 0x94, 0x2a, - 0xb3, 0x4b, 0x8c, 0x61, 0xee, 0xf9, 0xff, 0x3b, 0x07, 0x50, 0x9f, 0x5b, 0xa9, 0x09, 0xc2, 0x61, - 0x18, 0xa8, 0x2e, 0xdd, 0x2b, 0x2f, 0x54, 0x19, 0xdd, 0x20, 0x14, 0x97, 0x6b, 0xb3, 0xac, 0x86, - 0x21, 0xe8, 0x9f, 0x59, 0x58, 0xae, 0xcf, 0x4e, 0xe4, 0x19, 0x50, 0x9b, 0x2d, 0x57, 0x26, 0x0a, - 0x0c, 0x78, 0x5f, 0xab, 0xae, 0xcc, 0x4e, 0x14, 0xd9, 0x9f, 0x0b, 0xf5, 0x95, 0xf2, 0xca, 0x44, - 0x3f, 0xfb, 0x73, 0x0e, 0xff, 0x2c, 0x31, 0x66, 0xf5, 0xd9, 0x15, 0xfc, 0x31, 0xc0, 0x9a, 0x30, - 0xe7, 0xff, 0x1a, 0x64, 0x28, 0xc6, 0xba, 0x52, 0xd5, 0x26, 0x86, 0xd8, 0x0f, 0xc6, 0x92, 0xfd, - 0x00, 0xd6, 0x38, 0x6d, 0x76, 0x71, 0xf9, 0xde, 0xec, 0xc4, 0x30, 0xe3, 0xb5, 0x78, 0x87, 0x81, - 0x47, 0xd8, 0x9f, 0xda, 0x22, 0xfb, 0x73, 0x94, 0x71, 0xd2, 0x66, 0xcb, 0x0b, 0xb5, 0xf2, 0xca, - 0xfc, 0xc4, 0x18, 0x6b, 0x0f, 0xf2, 0x1c, 0xe7, 0x25, 0x97, 0xca, 0x8b, 0xb3, 0x13, 0x13, 0x82, - 0xa6, 0xb2, 0x50, 0x5d, 0xba, 0x33, 0x71, 0x0a, 0x1b, 0xf2, 0xde, 0x22, 0xfe, 0x20, 0xac, 0x00, - 0xfe, 0x75, 0xfa, 0xf9, 0x1f, 0x80, 0xd2, 0x72, 0x1d, 0x47, 0xc1, 0x79, 0x38, 0xbd, 0x5c, 0x6f, - 0xac, 0xbc, 0x57, 0x9b, 0x8d, 0xc9, 0xfb, 0x14, 0x8c, 0xfa, 0x88, 0x85, 0xea, 0xd2, 0xdd, 0xcf, - 0x71, 0x69, 0xfb, 0xa0, 0xc5, 0xf2, 0xcc, 0x72, 0x7d, 0x22, 0xcf, 0x7a, 0xc5, 0x07, 0xdd, 0xaf, - 0x2e, 0x55, 0x96, 0xef, 0xd7, 0x27, 0x0a, 0xcf, 0x3f, 0x82, 0x11, 0x9e, 0xa7, 0x73, 0xd9, 0x31, - 0xd7, 0x4c, 0x8b, 0x3c, 0x0d, 0x17, 0x2a, 0xb3, 0xf7, 0xaa, 0x33, 0xb3, 0x8d, 0x65, 0xad, 0x7a, - 0xab, 0xba, 0x14, 0xab, 0xe9, 0x2c, 0x9c, 0x8a, 0xa2, 0xcb, 0xb5, 0xea, 0x44, 0x8e, 0x9c, 0x03, - 0x12, 0x05, 0xdf, 0x2e, 0x2f, 0xce, 0x4d, 0xe4, 0x89, 0x02, 0x67, 0xa2, 0xf0, 0xea, 0xd2, 0xca, - 0xdd, 0xa5, 0xd9, 0x89, 0xc2, 0xf3, 0x7f, 0x2d, 0x07, 0x67, 0x53, 0x63, 0x39, 0x13, 0x15, 0x2e, - 0xcf, 0x2e, 0x94, 0xeb, 0x2b, 0xd5, 0x99, 0xfa, 0x6c, 0x59, 0x9b, 0x99, 0x6f, 0xcc, 0x94, 0x57, - 0x66, 0x6f, 0x2d, 0x6b, 0xef, 0x35, 0x6e, 0xcd, 0x2e, 0xcd, 0x6a, 0xe5, 0x85, 0x89, 0x3e, 0xf2, - 0x1c, 0x4c, 0x66, 0xd0, 0xd4, 0x67, 0x67, 0xee, 0x6a, 0xd5, 0x95, 0xf7, 0x26, 0x72, 0xe4, 0x59, - 0x78, 0x3a, 0x93, 0x88, 0xfd, 0x9e, 0xc8, 0x93, 0xcb, 0x70, 0x31, 0x8b, 0xe4, 0xdd, 0x85, 0x89, - 0xc2, 0xf3, 0x3f, 0x9f, 0x03, 0x92, 0x0c, 0xc6, 0x4b, 0x9e, 0x81, 0x4b, 0x4c, 0x2f, 0x1a, 0xd9, - 0x0d, 0x7c, 0x16, 0x9e, 0x4e, 0xa5, 0x90, 0x9a, 0x37, 0x09, 0x4f, 0x65, 0x90, 0x88, 0xc6, 0x5d, - 0x02, 0x25, 0x9d, 0x00, 0x9b, 0xf6, 0xeb, 0x39, 0x38, 0x9b, 0xea, 0x01, 0x43, 0xae, 0xc2, 0xc7, - 0xca, 0x95, 0x45, 0xd6, 0x37, 0x33, 0x2b, 0xd5, 0xe5, 0xa5, 0x7a, 0x63, 0x71, 0xae, 0xdc, 0x60, - 0xda, 0x77, 0xb7, 0x1e, 0xeb, 0xcd, 0x2b, 0xa0, 0xf6, 0xa0, 0x9c, 0x99, 0x2f, 0x2f, 0xdd, 0x62, - 0xc3, 0x8f, 0x7c, 0x0c, 0x9e, 0xc9, 0xa4, 0x9b, 0x5d, 0x2a, 0x4f, 0x2f, 0xcc, 0x56, 0x26, 0xf2, - 0xe4, 0xe3, 0xf0, 0x6c, 0x26, 0x55, 0xa5, 0x5a, 0xe7, 0x64, 0x85, 0xe9, 0xca, 0x77, 0xfe, 0xa7, - 0xcb, 0x7d, 0xdf, 0xf9, 0xa3, 0xcb, 0xb9, 0x3f, 0xfc, 0xa3, 0xcb, 0xb9, 0x7f, 0xf6, 0x47, 0x97, - 0x73, 0x9f, 0xbf, 0xb1, 0x97, 0x20, 0xcb, 0x7c, 0xda, 0x5a, 0x2d, 0xe1, 0x6d, 0xf4, 0xcb, 0xff, - 0x7f, 0x00, 0x00, 0x00, 0xff, 0xff, 0xcd, 0xcc, 0xfb, 0x5a, 0x5a, 0x82, 0x01, 0x00, + // 17266 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xec, 0xbd, 0x6d, 0x74, 0x25, 0xc9, + 0x75, 0x18, 0x86, 0xf7, 0x81, 0x07, 0xe0, 0xe2, 0x63, 0x30, 0x35, 0x5f, 0x3d, 0xb3, 0xb3, 0xfb, + 0x76, 0x7b, 0xc9, 0xe1, 0xcc, 0x72, 0x17, 0xc3, 0x9d, 0x9d, 0xdd, 0xe5, 0x7e, 0x71, 0xf9, 0x80, + 0x07, 0x0c, 0xde, 0x0c, 0xbe, 0xb6, 0x1f, 0x66, 0x86, 0x4b, 0x8a, 0x7c, 0x6a, 0xbc, 0xae, 0x01, + 0x7a, 0xf1, 0x5e, 0xf7, 0x53, 0x77, 0xbf, 0xc1, 0x60, 0x9d, 0x0f, 0xd1, 0x91, 0x65, 0xc9, 0xa2, + 0x68, 0x86, 0x8a, 0x44, 0x59, 0x76, 0x12, 0xca, 0x1f, 0x89, 0x2c, 0xcb, 0x62, 0xe4, 0x28, 0x92, + 0x28, 0x89, 0xb1, 0x64, 0x3a, 0x09, 0x2d, 0x9d, 0xe8, 0x48, 0x4e, 0xe2, 0xe3, 0x93, 0x38, 0xa0, + 0xa3, 0xc4, 0x7f, 0x70, 0x92, 0x1c, 0x9d, 0x44, 0x27, 0x66, 0x1c, 0x27, 0x27, 0xa7, 0x6e, 0x55, + 0x77, 0x57, 0x7f, 0x3d, 0x7c, 0xae, 0xb0, 0xe0, 0xe0, 0xcf, 0x0c, 0xde, 0xbd, 0xb7, 0x6e, 0x55, + 0xdf, 0xba, 0x55, 0x75, 0xab, 0xea, 0xd6, 0xbd, 0x70, 0xcd, 0xa3, 0x2d, 0xda, 0xb1, 0x1d, 0xef, + 0x7a, 0x8b, 0xae, 0xea, 0xcd, 0xcd, 0xeb, 0xde, 0x66, 0x87, 0xba, 0xd7, 0xe9, 0x43, 0x6a, 0x79, + 0xfe, 0x7f, 0x13, 0x1d, 0xc7, 0xf6, 0x6c, 0x52, 0xe2, 0xbf, 0x2e, 0x9d, 0x5d, 0xb5, 0x57, 0x6d, + 0x04, 0x5d, 0x67, 0x7f, 0x71, 0xec, 0xa5, 0xcb, 0xab, 0xb6, 0xbd, 0xda, 0xa2, 0xd7, 0xf1, 0xd7, + 0x4a, 0xf7, 0xc1, 0x75, 0xd7, 0x73, 0xba, 0x4d, 0x4f, 0x60, 0xcb, 0x71, 0xac, 0x67, 0xb6, 0xa9, + 0xeb, 0xe9, 0xed, 0x8e, 0x20, 0x78, 0x2a, 0x4e, 0xb0, 0xe1, 0xe8, 0x9d, 0x0e, 0x75, 0x44, 0xe5, + 0x97, 0x3e, 0x16, 0xb4, 0x53, 0x6f, 0x36, 0xa9, 0xeb, 0xb6, 0x4c, 0xd7, 0xbb, 0xfe, 0xf0, 0x45, + 0xe9, 0x97, 0x20, 0x7c, 0x26, 0xfd, 0x83, 0xf0, 0x5f, 0x41, 0xf2, 0x42, 0x3a, 0x89, 0x5f, 0x63, + 0xac, 0x6a, 0xf5, 0xab, 0x79, 0x18, 0x9c, 0xa7, 0x9e, 0x6e, 0xe8, 0x9e, 0x4e, 0x2e, 0x43, 0x7f, + 0xcd, 0x32, 0xe8, 0x23, 0x25, 0xf7, 0x74, 0xee, 0x6a, 0x61, 0xb2, 0xb4, 0xbd, 0x55, 0xce, 0x53, + 0x53, 0xe3, 0x40, 0xf2, 0x24, 0x14, 0x97, 0x37, 0x3b, 0x54, 0xc9, 0x3f, 0x9d, 0xbb, 0x3a, 0x34, + 0x39, 0xb4, 0xbd, 0x55, 0xee, 0x47, 0xa1, 0x69, 0x08, 0x26, 0xcf, 0x40, 0xbe, 0x56, 0x55, 0x0a, + 0x88, 0x3c, 0xbd, 0xbd, 0x55, 0x1e, 0xed, 0x9a, 0xc6, 0xf3, 0x76, 0xdb, 0xf4, 0x68, 0xbb, 0xe3, + 0x6d, 0x6a, 0xf9, 0x5a, 0x95, 0x5c, 0x81, 0xe2, 0x94, 0x6d, 0x50, 0xa5, 0x88, 0x44, 0x64, 0x7b, + 0xab, 0x3c, 0xd6, 0xb4, 0x0d, 0x2a, 0x51, 0x21, 0x9e, 0x7c, 0x1a, 0x8a, 0xcb, 0x66, 0x9b, 0x2a, + 0xfd, 0x4f, 0xe7, 0xae, 0x0e, 0xdf, 0xb8, 0x34, 0xc1, 0xc5, 0x37, 0xe1, 0x8b, 0x6f, 0x62, 0xd9, + 0x97, 0xef, 0xe4, 0xf8, 0x77, 0xb6, 0xca, 0x7d, 0xdb, 0x5b, 0xe5, 0x22, 0x13, 0xf9, 0x57, 0xbe, + 0x5b, 0xce, 0x69, 0x58, 0x92, 0xbc, 0x09, 0xc3, 0x53, 0xad, 0xae, 0xeb, 0x51, 0x67, 0x41, 0x6f, + 0x53, 0xa5, 0x84, 0x15, 0x5e, 0xda, 0xde, 0x2a, 0x9f, 0x6f, 0x72, 0x70, 0xc3, 0xd2, 0xdb, 0x72, + 0xc5, 0x32, 0xb9, 0xfa, 0x1b, 0x39, 0x38, 0x55, 0xa7, 0xae, 0x6b, 0xda, 0x56, 0x20, 0x9b, 0x8f, + 0xc2, 0x90, 0x00, 0xd5, 0xaa, 0x28, 0x9f, 0xa1, 0xc9, 0x81, 0xed, 0xad, 0x72, 0xc1, 0x35, 0x0d, + 0x2d, 0xc4, 0x90, 0x4f, 0xc0, 0xc0, 0x7d, 0xd3, 0x5b, 0x9b, 0x9f, 0xa9, 0x08, 0x39, 0x9d, 0xdf, + 0xde, 0x2a, 0x93, 0x0d, 0xd3, 0x5b, 0x6b, 0xb4, 0x1f, 0xe8, 0x52, 0x85, 0x3e, 0x19, 0x99, 0x83, + 0xf1, 0x25, 0xc7, 0x7c, 0xa8, 0x7b, 0xf4, 0x0e, 0xdd, 0x5c, 0xb2, 0x5b, 0x66, 0x73, 0x53, 0x48, + 0xf1, 0xe9, 0xed, 0xad, 0xf2, 0xe5, 0x0e, 0xc7, 0x35, 0xd6, 0xe9, 0x66, 0xa3, 0x83, 0x58, 0x89, + 0x49, 0xa2, 0xa4, 0xfa, 0x9b, 0x25, 0x18, 0xb9, 0xeb, 0x52, 0x27, 0x68, 0xf7, 0x15, 0x28, 0xb2, + 0xdf, 0xa2, 0xc9, 0x28, 0xf3, 0xae, 0x4b, 0x1d, 0x59, 0xe6, 0x0c, 0x4f, 0xae, 0x41, 0xff, 0x9c, + 0xbd, 0x6a, 0x5a, 0xa2, 0xd9, 0x67, 0xb6, 0xb7, 0xca, 0xa7, 0x5a, 0x0c, 0x20, 0x51, 0x72, 0x0a, + 0xf2, 0x29, 0x18, 0xa9, 0xb5, 0x99, 0x0e, 0xd9, 0x96, 0xee, 0xd9, 0x8e, 0x68, 0x2d, 0x4a, 0xd7, + 0x94, 0xe0, 0x52, 0xc1, 0x08, 0x3d, 0x79, 0x1d, 0xa0, 0x72, 0xbf, 0xae, 0xd9, 0x2d, 0x5a, 0xd1, + 0x16, 0x84, 0x32, 0x60, 0x69, 0x7d, 0xc3, 0x6d, 0x38, 0x76, 0x8b, 0x36, 0x74, 0x47, 0xae, 0x56, + 0xa2, 0x26, 0xd3, 0x30, 0x56, 0xc1, 0x51, 0xa1, 0xd1, 0x1f, 0xea, 0x52, 0xd7, 0x73, 0x95, 0xfe, + 0xa7, 0x0b, 0x57, 0x87, 0x26, 0x9f, 0xdc, 0xde, 0x2a, 0x5f, 0xe4, 0xe3, 0xa5, 0xe1, 0x08, 0x94, + 0xc4, 0x22, 0x56, 0x88, 0x4c, 0xc2, 0x68, 0xe5, 0xfd, 0xae, 0x43, 0x6b, 0x06, 0xb5, 0x3c, 0xd3, + 0xdb, 0x14, 0x1a, 0x72, 0x79, 0x7b, 0xab, 0xac, 0xe8, 0x0c, 0xd1, 0x30, 0x05, 0x46, 0x62, 0x12, + 0x2d, 0x42, 0x16, 0xe1, 0xf4, 0xad, 0xa9, 0xa5, 0x3a, 0x75, 0x1e, 0x9a, 0x4d, 0x5a, 0x69, 0x36, + 0xed, 0xae, 0xe5, 0x29, 0x03, 0xc8, 0xe7, 0x99, 0xed, 0xad, 0xf2, 0x93, 0xab, 0xcd, 0x4e, 0xc3, + 0xe5, 0xd8, 0x86, 0xce, 0xd1, 0x12, 0xb3, 0x64, 0x59, 0xf2, 0x59, 0x18, 0x5d, 0x76, 0x98, 0x16, + 0x1a, 0x55, 0xca, 0xe0, 0xca, 0x20, 0xea, 0xff, 0xf9, 0x09, 0x31, 0x53, 0x71, 0xa8, 0xdf, 0xb3, + 0xbc, 0xb1, 0x1e, 0x2f, 0xd0, 0x30, 0x10, 0x27, 0x37, 0x36, 0xc2, 0x8a, 0x50, 0x50, 0xd8, 0xc7, + 0x9b, 0x0e, 0x35, 0x12, 0xda, 0x36, 0x84, 0x6d, 0xbe, 0xb6, 0xbd, 0x55, 0xfe, 0xa8, 0x23, 0x68, + 0x1a, 0x3d, 0xd5, 0x2e, 0x93, 0x15, 0x99, 0x86, 0x41, 0xa6, 0x4d, 0x77, 0x4c, 0xcb, 0x50, 0xe0, + 0xe9, 0xdc, 0xd5, 0xb1, 0x1b, 0xe3, 0x7e, 0xeb, 0x7d, 0xf8, 0xe4, 0x85, 0xed, 0xad, 0xf2, 0x19, + 0xa6, 0x83, 0x8d, 0x75, 0xd3, 0x92, 0xa7, 0x88, 0xa0, 0x28, 0x1b, 0x45, 0x93, 0xb6, 0x87, 0x43, + 0x77, 0x38, 0x1c, 0x45, 0x2b, 0xb6, 0x17, 0x1f, 0xb6, 0x3e, 0x19, 0x99, 0x82, 0xd1, 0x49, 0xdb, + 0xab, 0x59, 0xae, 0xa7, 0x5b, 0x4d, 0x5a, 0xab, 0x2a, 0x23, 0x58, 0x0e, 0xd5, 0x82, 0x95, 0x33, + 0x05, 0xa6, 0x11, 0x99, 0x94, 0xa2, 0x65, 0xd4, 0x7f, 0x59, 0x84, 0x31, 0xd6, 0x27, 0xd2, 0xf0, + 0xa9, 0xb0, 0x99, 0x80, 0x41, 0x58, 0x2d, 0x6e, 0x47, 0x6f, 0x52, 0x31, 0x92, 0xf0, 0x2b, 0x2c, + 0x1f, 0x28, 0xf1, 0x8c, 0xd3, 0x93, 0x6b, 0x30, 0xc8, 0x41, 0xb5, 0xaa, 0x18, 0x5c, 0xa3, 0xdb, + 0x5b, 0xe5, 0x21, 0x17, 0x61, 0x0d, 0xd3, 0xd0, 0x02, 0x34, 0xd3, 0x6e, 0xfe, 0xf7, 0xac, 0xed, + 0x7a, 0x8c, 0xb9, 0x18, 0x5b, 0xf8, 0x19, 0xa2, 0xc0, 0x9a, 0x40, 0xc9, 0xda, 0x1d, 0x2d, 0x44, + 0x5e, 0x03, 0xe0, 0x90, 0x8a, 0x61, 0x38, 0x62, 0x80, 0x5d, 0xdc, 0xde, 0x2a, 0x9f, 0x13, 0x2c, + 0x74, 0xc3, 0x90, 0x47, 0xa7, 0x44, 0x4c, 0xda, 0x30, 0xc2, 0x7f, 0xcd, 0xe9, 0x2b, 0xb4, 0xc5, + 0x47, 0xd7, 0xf0, 0x8d, 0xab, 0x7e, 0x27, 0x46, 0xa5, 0x33, 0x21, 0x93, 0x4e, 0x5b, 0x9e, 0xb3, + 0x39, 0x59, 0x16, 0x13, 0xf2, 0x05, 0x51, 0x55, 0x0b, 0x71, 0xf2, 0x54, 0x20, 0x97, 0x61, 0xf3, + 0xf4, 0x8c, 0xed, 0x6c, 0xe8, 0x8e, 0x41, 0x8d, 0xc9, 0x4d, 0x79, 0x9e, 0x7e, 0xe0, 0x83, 0x1b, + 0x2b, 0xb2, 0xea, 0xc9, 0xe4, 0xac, 0xd3, 0x39, 0xb7, 0x7a, 0x77, 0x05, 0x55, 0x6e, 0x20, 0x21, + 0x2d, 0xb7, 0xbb, 0x12, 0x57, 0xb3, 0x68, 0x19, 0x36, 0x15, 0x70, 0xc0, 0x3d, 0xea, 0xb0, 0x49, + 0x1c, 0x47, 0x9d, 0x98, 0x0a, 0x04, 0x93, 0x87, 0x1c, 0x93, 0xe4, 0x21, 0x8a, 0x5c, 0x7a, 0x1b, + 0x4e, 0x27, 0x44, 0x41, 0xc6, 0xa1, 0xb0, 0x4e, 0x37, 0xb9, 0xba, 0x68, 0xec, 0x4f, 0x72, 0x16, + 0xfa, 0x1f, 0xea, 0xad, 0xae, 0x58, 0x42, 0x35, 0xfe, 0xe3, 0xf5, 0xfc, 0x27, 0x73, 0x6c, 0xc5, + 0x21, 0x53, 0xb6, 0x65, 0xd1, 0xa6, 0x27, 0x2f, 0x3a, 0xaf, 0xc0, 0xd0, 0x9c, 0xdd, 0xd4, 0x5b, + 0xd8, 0x8f, 0x5c, 0xef, 0x94, 0xed, 0xad, 0xf2, 0x59, 0xd6, 0x81, 0x13, 0x2d, 0x86, 0x91, 0xda, + 0x14, 0x92, 0x32, 0x05, 0xd0, 0x68, 0xdb, 0xf6, 0x28, 0x16, 0xcc, 0x87, 0x0a, 0x80, 0x05, 0x1d, + 0x44, 0xc9, 0x0a, 0x10, 0x12, 0x93, 0xeb, 0x30, 0xb8, 0xc4, 0xd6, 0xd9, 0xa6, 0xdd, 0x12, 0xca, + 0x87, 0x4b, 0x01, 0xae, 0xbd, 0xf2, 0x58, 0xf5, 0x89, 0xd4, 0x59, 0x18, 0x9b, 0x6a, 0x99, 0xd4, + 0xf2, 0xe4, 0x56, 0xb3, 0x91, 0x5c, 0x59, 0xa5, 0x96, 0x27, 0xb7, 0x1a, 0xc7, 0xbc, 0xce, 0xa0, + 0x72, 0xab, 0x03, 0x52, 0xf5, 0x0f, 0x0a, 0x70, 0xf1, 0x4e, 0x77, 0x85, 0x3a, 0x16, 0xf5, 0xa8, + 0x2b, 0x16, 0xe4, 0x80, 0xeb, 0x02, 0x9c, 0x4e, 0x20, 0x05, 0x77, 0x5c, 0x28, 0xd7, 0x03, 0x64, + 0x43, 0xac, 0xf1, 0xf2, 0x6c, 0x9b, 0x28, 0x4a, 0x66, 0xe1, 0x54, 0x08, 0x64, 0x8d, 0x70, 0x95, + 0x3c, 0x2e, 0x25, 0x4f, 0x6d, 0x6f, 0x95, 0x2f, 0x49, 0xdc, 0x58, 0xb3, 0x65, 0x0d, 0x8e, 0x17, + 0x23, 0x77, 0x60, 0x3c, 0x04, 0xdd, 0x72, 0xec, 0x6e, 0xc7, 0x55, 0x0a, 0xc8, 0xaa, 0xbc, 0xbd, + 0x55, 0x7e, 0x42, 0x62, 0xb5, 0x8a, 0x48, 0x79, 0x01, 0x8f, 0x17, 0x24, 0x3f, 0x92, 0x93, 0xb9, + 0x89, 0x51, 0x58, 0xc4, 0x51, 0xf8, 0xaa, 0x3f, 0x0a, 0x33, 0x85, 0x34, 0x11, 0x2f, 0x29, 0x06, + 0x65, 0xac, 0x19, 0x89, 0x41, 0x99, 0xa8, 0xf1, 0xd2, 0x14, 0x9c, 0x4b, 0xe5, 0xb5, 0x27, 0xad, + 0xfe, 0x17, 0x05, 0x99, 0xcb, 0x92, 0x6d, 0x04, 0x9d, 0xb9, 0x28, 0x77, 0xe6, 0x92, 0x6d, 0xe0, + 0x54, 0x9f, 0x0b, 0xd7, 0x4e, 0xa9, 0xb1, 0x1d, 0xdb, 0x88, 0xcf, 0xfa, 0xc9, 0xb2, 0xe4, 0x0b, + 0x70, 0x3e, 0x01, 0xe4, 0xd3, 0x35, 0xd7, 0xfe, 0x2b, 0xdb, 0x5b, 0x65, 0x35, 0x85, 0x6b, 0x7c, + 0xf6, 0xce, 0xe0, 0x42, 0x74, 0xb8, 0x20, 0x49, 0xdd, 0xb6, 0x3c, 0xdd, 0xb4, 0x84, 0x71, 0xc9, + 0x47, 0xc9, 0xc7, 0xb6, 0xb7, 0xca, 0xcf, 0xca, 0x3a, 0xe8, 0xd3, 0xc4, 0x1b, 0x9f, 0xc5, 0x87, + 0x18, 0xa0, 0xa4, 0xa0, 0x6a, 0x6d, 0x7d, 0xd5, 0xb7, 0x98, 0xaf, 0x6e, 0x6f, 0x95, 0x3f, 0x92, + 0x5a, 0x87, 0xc9, 0xa8, 0xe4, 0x15, 0x3a, 0x8b, 0x13, 0xd1, 0x80, 0x84, 0xb8, 0x05, 0xdb, 0xa0, + 0xf8, 0x0d, 0xfd, 0xc8, 0x5f, 0xdd, 0xde, 0x2a, 0x3f, 0x25, 0xf1, 0xb7, 0x6c, 0x83, 0xc6, 0x9b, + 0x9f, 0x52, 0x5a, 0xfd, 0x8d, 0x02, 0x3c, 0x55, 0xaf, 0xcc, 0xcf, 0xd5, 0x0c, 0xdf, 0xa4, 0x59, + 0x72, 0xec, 0x87, 0xa6, 0x21, 0x8d, 0xde, 0x15, 0xb8, 0x10, 0x43, 0x4d, 0xa3, 0x15, 0x15, 0x18, + 0xd3, 0xf8, 0x6d, 0xbe, 0xb9, 0xd4, 0x11, 0x34, 0x0d, 0x6e, 0x6a, 0x45, 0x17, 0xed, 0x2c, 0x46, + 0xac, 0x8f, 0x62, 0xa8, 0xfa, 0x9a, 0xed, 0x78, 0xcd, 0xae, 0x27, 0x94, 0x00, 0xfb, 0x28, 0x51, + 0x87, 0x2b, 0x88, 0x7a, 0x54, 0xe1, 0xf3, 0x21, 0x3f, 0x9e, 0x83, 0xf1, 0x8a, 0xe7, 0x39, 0xe6, + 0x4a, 0xd7, 0xa3, 0xf3, 0x7a, 0xa7, 0x63, 0x5a, 0xab, 0x38, 0xd6, 0x87, 0x6f, 0xbc, 0x19, 0xac, + 0x91, 0x3d, 0x25, 0x31, 0x11, 0x2f, 0x2e, 0x0d, 0x51, 0xdd, 0x47, 0x35, 0xda, 0x1c, 0x27, 0x0f, + 0xd1, 0x78, 0x39, 0x36, 0x44, 0x53, 0x79, 0xed, 0x69, 0x88, 0x7e, 0xb5, 0x00, 0x97, 0x17, 0xd7, + 0x3d, 0x5d, 0xa3, 0xae, 0xdd, 0x75, 0x9a, 0xd4, 0xbd, 0xdb, 0x31, 0x74, 0x8f, 0x86, 0x23, 0xb5, + 0x0c, 0xfd, 0x15, 0xc3, 0xa0, 0x06, 0xb2, 0xeb, 0xe7, 0xdb, 0x3e, 0x9d, 0x01, 0x34, 0x0e, 0x27, + 0x1f, 0x85, 0x01, 0x51, 0x06, 0xb9, 0xf7, 0x4f, 0x0e, 0x6f, 0x6f, 0x95, 0x07, 0xba, 0x1c, 0xa4, + 0xf9, 0x38, 0x46, 0x56, 0xa5, 0x2d, 0xca, 0xc8, 0x0a, 0x21, 0x99, 0xc1, 0x41, 0x9a, 0x8f, 0x23, + 0xef, 0xc0, 0x18, 0xb2, 0x0d, 0xda, 0x23, 0xe6, 0xbe, 0xb3, 0xbe, 0x74, 0xe5, 0xc6, 0xf2, 0xa5, + 0x09, 0x5b, 0xd3, 0x70, 0xfc, 0x02, 0x5a, 0x8c, 0x01, 0xb9, 0x0f, 0xe3, 0xa2, 0x11, 0x21, 0xd3, + 0xfe, 0x1e, 0x4c, 0xcf, 0x6d, 0x6f, 0x95, 0x4f, 0x8b, 0xf6, 0x4b, 0x6c, 0x13, 0x4c, 0x18, 0x63, + 0xd1, 0xec, 0x90, 0x71, 0x69, 0x27, 0xc6, 0xe2, 0x8b, 0x65, 0xc6, 0x71, 0x26, 0xea, 0xbb, 0x30, + 0x22, 0x17, 0x24, 0xe7, 0x71, 0x6b, 0xcd, 0xc7, 0x09, 0x6e, 0xca, 0x4d, 0x03, 0xf7, 0xd3, 0x2f, + 0xc2, 0x70, 0x95, 0xba, 0x4d, 0xc7, 0xec, 0x30, 0xab, 0x41, 0x28, 0xf9, 0xa9, 0xed, 0xad, 0xf2, + 0xb0, 0x11, 0x82, 0x35, 0x99, 0x46, 0xfd, 0xbf, 0x72, 0x70, 0x9e, 0xf1, 0xae, 0xb8, 0xae, 0xb9, + 0x6a, 0xb5, 0xe5, 0x65, 0xfb, 0x79, 0x28, 0xd5, 0xb1, 0x3e, 0x51, 0xd3, 0xd9, 0xed, 0xad, 0xf2, + 0x38, 0x6f, 0x81, 0xa4, 0x87, 0x82, 0x26, 0xd8, 0x57, 0xe6, 0x77, 0xd8, 0x57, 0x32, 0x93, 0xd6, + 0xd3, 0x1d, 0xcf, 0xb4, 0x56, 0xeb, 0x9e, 0xee, 0x75, 0xdd, 0x88, 0x49, 0x2b, 0x30, 0x0d, 0x17, + 0x51, 0x11, 0x93, 0x36, 0x52, 0x88, 0xbc, 0x0d, 0x23, 0xd3, 0x96, 0x11, 0x32, 0xe1, 0x13, 0xe2, + 0x13, 0xcc, 0xd2, 0xa4, 0x08, 0x4f, 0xb2, 0x88, 0x14, 0x50, 0xff, 0x6e, 0x0e, 0x14, 0xbe, 0x09, + 0x9c, 0x33, 0x5d, 0x6f, 0x9e, 0xb6, 0x57, 0xa4, 0xd9, 0x69, 0xc6, 0xdf, 0x55, 0x32, 0x9c, 0xb4, + 0x16, 0xa1, 0x29, 0x20, 0x76, 0x95, 0x2d, 0xd3, 0x4d, 0x6c, 0x3f, 0x62, 0xa5, 0x48, 0x0d, 0x06, + 0x38, 0x67, 0x6e, 0x4b, 0x0c, 0xdf, 0x50, 0x7c, 0x45, 0x88, 0x57, 0xcd, 0x95, 0xa1, 0xcd, 0x89, + 0xe5, 0x0d, 0x8d, 0x28, 0xaf, 0x7e, 0xbd, 0x00, 0xe3, 0xf1, 0x42, 0xe4, 0x3e, 0x0c, 0xde, 0xb6, + 0x4d, 0x8b, 0x1a, 0x8b, 0x16, 0xb6, 0xb0, 0xf7, 0xe1, 0x88, 0x6f, 0x8b, 0x9f, 0x79, 0x0f, 0xcb, + 0x34, 0x64, 0x0b, 0x16, 0xcf, 0x4a, 0x02, 0x66, 0xe4, 0xb3, 0x30, 0xc4, 0x6c, 0xc0, 0x87, 0xc8, + 0x39, 0xbf, 0x23, 0xe7, 0xa7, 0x05, 0xe7, 0xb3, 0x0e, 0x2f, 0x94, 0x64, 0x1d, 0xb2, 0x63, 0x7a, + 0xa5, 0x51, 0xdd, 0xb5, 0x2d, 0xd1, 0xf3, 0xa8, 0x57, 0x0e, 0x42, 0x64, 0xbd, 0xe2, 0x34, 0xcc, + 0x74, 0xe5, 0x1f, 0x8b, 0xdd, 0x20, 0xed, 0x5d, 0xb8, 0xac, 0xe2, 0x3d, 0x20, 0x11, 0x13, 0x0b, + 0x4e, 0x09, 0x81, 0xae, 0x99, 0x1d, 0xb4, 0xfa, 0x71, 0x5d, 0x1b, 0xbb, 0x71, 0x65, 0xc2, 0x3f, + 0x14, 0x9b, 0x90, 0x8e, 0xd4, 0x1e, 0xbe, 0x38, 0x31, 0x1f, 0x90, 0xe3, 0xce, 0x14, 0x75, 0x32, + 0xc6, 0x42, 0xee, 0xed, 0x76, 0x84, 0x5c, 0xfd, 0xd1, 0x3c, 0xbc, 0x10, 0x76, 0x91, 0x46, 0x1f, + 0x9a, 0x74, 0x23, 0xe4, 0x28, 0xf6, 0xc8, 0x6c, 0x88, 0xb9, 0x53, 0x6b, 0xba, 0xb5, 0x4a, 0x0d, + 0x72, 0x0d, 0xfa, 0x35, 0xbb, 0x45, 0x5d, 0x25, 0x87, 0xe6, 0x21, 0x4e, 0x5f, 0x0e, 0x03, 0xc8, + 0x87, 0x2c, 0x48, 0x41, 0x6c, 0x28, 0x2d, 0x3b, 0xba, 0xe9, 0xf9, 0x9a, 0x54, 0x49, 0x6a, 0xd2, + 0x2e, 0x6a, 0x9c, 0xe0, 0x3c, 0xf8, 0x1a, 0x83, 0x82, 0xf7, 0x10, 0x20, 0x0b, 0x9e, 0x93, 0x5c, + 0x7a, 0x0d, 0x86, 0x25, 0xe2, 0x3d, 0x2d, 0x22, 0xdf, 0x2c, 0xca, 0x63, 0xcb, 0x6f, 0x96, 0x18, + 0x5b, 0xd7, 0xd9, 0x98, 0x70, 0x5d, 0x66, 0xc5, 0xf0, 0x41, 0x25, 0x34, 0x1f, 0x41, 0x51, 0xcd, + 0x47, 0x10, 0x79, 0x09, 0x06, 0x39, 0x8b, 0x60, 0xbf, 0x8c, 0x7b, 0x6d, 0x07, 0x61, 0x51, 0x53, + 0x20, 0x20, 0x24, 0xbf, 0x98, 0x83, 0x27, 0x7b, 0x4a, 0x02, 0x95, 0x6f, 0xf8, 0xc6, 0xcb, 0xfb, + 0x12, 0xe3, 0xe4, 0x0b, 0xdb, 0x5b, 0xe5, 0x6b, 0x92, 0x66, 0x38, 0x12, 0x4d, 0xa3, 0xc9, 0x89, + 0xa4, 0x76, 0xf5, 0x6e, 0x0a, 0x33, 0x56, 0x79, 0xa5, 0x33, 0x78, 0x54, 0x65, 0x35, 0x37, 0xfd, + 0x46, 0x16, 0x43, 0x63, 0x55, 0x7c, 0xef, 0x03, 0x9f, 0x24, 0xa5, 0x9a, 0x0c, 0x2e, 0xa4, 0x09, + 0x17, 0x38, 0xa6, 0xaa, 0x6f, 0x2e, 0x3e, 0x98, 0xb7, 0x2d, 0x6f, 0xcd, 0xaf, 0xa0, 0x5f, 0x3e, + 0xeb, 0xc1, 0x0a, 0x0c, 0x7d, 0xb3, 0x61, 0x3f, 0x68, 0xb4, 0x19, 0x55, 0x4a, 0x1d, 0x59, 0x9c, + 0xd8, 0xc4, 0x2e, 0xc6, 0xb8, 0x3f, 0xe5, 0x95, 0xc2, 0x93, 0x38, 0x7f, 0x5e, 0x48, 0x4e, 0x70, + 0xb1, 0x42, 0x6a, 0x0d, 0x46, 0xe6, 0xec, 0xe6, 0x7a, 0xa0, 0x2e, 0xaf, 0x41, 0x69, 0x59, 0x77, + 0x56, 0xa9, 0x87, 0xb2, 0x18, 0xbe, 0x71, 0x7a, 0x82, 0x9f, 0x6e, 0x33, 0x22, 0x8e, 0x98, 0x1c, + 0x13, 0xb3, 0x4f, 0xc9, 0xc3, 0xdf, 0x9a, 0x28, 0xa0, 0x7e, 0xb7, 0x1f, 0x46, 0xc4, 0x49, 0x2c, + 0xae, 0x1e, 0xe4, 0xf5, 0xf0, 0x6c, 0x5b, 0x4c, 0x97, 0xc1, 0x69, 0x54, 0x70, 0x8a, 0x36, 0xc2, + 0x98, 0xfd, 0xe1, 0x56, 0x39, 0xb7, 0xbd, 0x55, 0xee, 0xd3, 0x06, 0xa5, 0x4d, 0x6c, 0xb8, 0xbe, + 0x49, 0x0b, 0xba, 0x7c, 0xb6, 0x1a, 0x2b, 0xcb, 0xd7, 0xbb, 0xb7, 0x61, 0x40, 0xb4, 0x41, 0x68, + 0xdc, 0x85, 0xf0, 0xec, 0x24, 0x72, 0xa2, 0x1c, 0x2b, 0xed, 0x97, 0x22, 0x6f, 0x42, 0x89, 0x9f, + 0x25, 0x08, 0x01, 0x9c, 0x4f, 0x3f, 0x7b, 0x89, 0x15, 0x17, 0x65, 0xc8, 0x2c, 0x40, 0x78, 0x8e, + 0x10, 0x1c, 0xa0, 0x0b, 0x0e, 0xc9, 0x13, 0x86, 0x18, 0x17, 0xa9, 0x2c, 0x79, 0x05, 0x46, 0x96, + 0xa9, 0xd3, 0x36, 0x2d, 0xbd, 0x55, 0x37, 0xdf, 0xf7, 0xcf, 0xd0, 0x71, 0xa1, 0x77, 0xcd, 0xf7, + 0xe5, 0x91, 0x1b, 0xa1, 0x23, 0x9f, 0x4f, 0xdb, 0xa7, 0x0f, 0x60, 0x43, 0x9e, 0xd9, 0x71, 0x03, + 0x1b, 0x6b, 0x4f, 0xca, 0xb6, 0xfd, 0x1d, 0x18, 0x8d, 0x6c, 0xd1, 0xc4, 0x21, 0xe9, 0x93, 0x49, + 0xd6, 0xd2, 0x7e, 0x33, 0xc6, 0x36, 0xca, 0x81, 0x69, 0x72, 0xcd, 0x32, 0x3d, 0x53, 0x6f, 0x4d, + 0xd9, 0xed, 0xb6, 0x6e, 0x19, 0xca, 0x50, 0xa8, 0xc9, 0x26, 0xc7, 0x34, 0x9a, 0x1c, 0x25, 0x6b, + 0x72, 0xb4, 0x10, 0xb9, 0x03, 0xe3, 0xa2, 0x0f, 0x35, 0xda, 0xb4, 0x1d, 0x66, 0x7b, 0xe0, 0x19, + 0xa8, 0x38, 0x06, 0x70, 0x39, 0xae, 0xe1, 0xf8, 0x48, 0xd9, 0xb8, 0x8f, 0x17, 0xbc, 0x5d, 0x1c, + 0x1c, 0x1e, 0x1f, 0x89, 0x1f, 0x5b, 0xab, 0x7f, 0xbb, 0x00, 0xc3, 0x82, 0x94, 0x2d, 0xdd, 0x27, + 0x0a, 0x7e, 0x10, 0x05, 0x4f, 0x55, 0xd4, 0xd2, 0x61, 0x29, 0xaa, 0xfa, 0xa5, 0x7c, 0x30, 0x1b, + 0x2d, 0x39, 0xa6, 0x75, 0xb0, 0xd9, 0xe8, 0x0a, 0xc0, 0xd4, 0x5a, 0xd7, 0x5a, 0xe7, 0xd7, 0x73, + 0xf9, 0xf0, 0x7a, 0xae, 0x69, 0x6a, 0x12, 0x86, 0x3c, 0x09, 0xc5, 0x2a, 0xe3, 0xcf, 0x7a, 0x66, + 0x64, 0x72, 0xe8, 0x3b, 0x9c, 0x53, 0xee, 0x05, 0x0d, 0xc1, 0x6c, 0x33, 0x37, 0xb9, 0xe9, 0x51, + 0x6e, 0x3e, 0x17, 0xf8, 0x66, 0x6e, 0x85, 0x01, 0x34, 0x0e, 0x27, 0x37, 0xe1, 0x74, 0x95, 0xb6, + 0xf4, 0xcd, 0x79, 0xb3, 0xd5, 0x32, 0x5d, 0xda, 0xb4, 0x2d, 0xc3, 0x45, 0x21, 0x8b, 0xea, 0xda, + 0xae, 0x96, 0x24, 0x20, 0x2a, 0x94, 0x16, 0x1f, 0x3c, 0x70, 0xa9, 0x87, 0xe2, 0x2b, 0x4c, 0x02, + 0x9b, 0x9c, 0x6d, 0x84, 0x68, 0x02, 0xa3, 0x7e, 0x23, 0xc7, 0x76, 0x4b, 0xee, 0xba, 0x67, 0x77, + 0x02, 0x2d, 0x3f, 0x90, 0x48, 0xae, 0x85, 0x76, 0x45, 0x1e, 0xbf, 0xf6, 0x94, 0xf8, 0xda, 0x01, + 0x61, 0x5b, 0x84, 0x16, 0x45, 0xea, 0x57, 0x15, 0x76, 0xf8, 0x2a, 0xf5, 0x4f, 0xf2, 0x70, 0x41, + 0xb4, 0x78, 0xaa, 0x65, 0x76, 0x56, 0x6c, 0xdd, 0x31, 0x34, 0xda, 0xa4, 0xe6, 0x43, 0x7a, 0x3c, + 0x07, 0x5e, 0x74, 0xe8, 0x14, 0x0f, 0x30, 0x74, 0x6e, 0xe0, 0xc6, 0x93, 0x49, 0x06, 0x0f, 0x98, + 0xb9, 0x51, 0x31, 0xbe, 0xbd, 0x55, 0x1e, 0x31, 0x38, 0x18, 0xaf, 0x18, 0x34, 0x99, 0x88, 0x29, + 0xc9, 0x1c, 0xb5, 0x56, 0xbd, 0x35, 0x54, 0x92, 0x7e, 0xae, 0x24, 0x2d, 0x84, 0x68, 0x02, 0xa3, + 0xfe, 0x6f, 0x79, 0x38, 0x1b, 0x17, 0x79, 0x9d, 0x5a, 0xc6, 0x89, 0xbc, 0x3f, 0x18, 0x79, 0xff, + 0x69, 0x01, 0x9e, 0x10, 0x65, 0xea, 0x6b, 0xba, 0x43, 0x8d, 0xaa, 0xe9, 0xd0, 0xa6, 0x67, 0x3b, + 0x9b, 0xc7, 0xd8, 0x80, 0x3a, 0x3c, 0xb1, 0xdf, 0x84, 0x92, 0x38, 0x6e, 0xe0, 0xeb, 0xcc, 0x58, + 0xd0, 0x12, 0x84, 0x26, 0x56, 0x28, 0x7e, 0x54, 0x11, 0xeb, 0xac, 0xd2, 0x6e, 0x3a, 0xeb, 0x93, + 0x30, 0x1a, 0x88, 0x1e, 0x37, 0xbe, 0x03, 0xa1, 0xb5, 0x65, 0xf8, 0x08, 0xdc, 0xfb, 0x6a, 0x51, + 0x42, 0xac, 0xcd, 0x07, 0xd4, 0xaa, 0x68, 0x0d, 0x8d, 0x8a, 0xda, 0x82, 0x72, 0xa6, 0xa1, 0xc9, + 0x44, 0xea, 0x56, 0x11, 0x2e, 0xa5, 0x77, 0xbb, 0x46, 0x75, 0xe3, 0xa4, 0xd7, 0xbf, 0x2f, 0x7b, + 0x9d, 0x3c, 0x03, 0xc5, 0x25, 0xdd, 0x5b, 0x13, 0xd7, 0xfd, 0x78, 0x07, 0xfd, 0xc0, 0x6c, 0xd1, + 0x46, 0x47, 0xf7, 0xd6, 0x34, 0x44, 0x49, 0x73, 0x06, 0x20, 0xc7, 0x94, 0x39, 0x43, 0x5a, 0xec, + 0x87, 0x9f, 0xce, 0x5d, 0x2d, 0xa6, 0x2e, 0xf6, 0xdf, 0x2d, 0x66, 0xcd, 0x2b, 0xf7, 0x1d, 0xd3, + 0xa3, 0x27, 0x1a, 0x76, 0xa2, 0x61, 0x07, 0xd4, 0xb0, 0x7f, 0x9c, 0x87, 0xd1, 0x60, 0xd3, 0xf4, + 0x1e, 0x6d, 0x1e, 0xcd, 0x5a, 0x15, 0x6e, 0x65, 0x0a, 0x07, 0xde, 0xca, 0x1c, 0x44, 0xa1, 0xd4, + 0xe0, 0x88, 0x95, 0x9b, 0x06, 0x28, 0x31, 0x7e, 0xc4, 0x1a, 0x1c, 0xac, 0x3e, 0x03, 0x03, 0xf3, + 0xfa, 0x23, 0xb3, 0xdd, 0x6d, 0x0b, 0x2b, 0x1d, 0xdd, 0xd7, 0xda, 0xfa, 0x23, 0xcd, 0x87, 0xab, + 0xff, 0x6d, 0x0e, 0xc6, 0x84, 0x50, 0x05, 0xf3, 0x03, 0x49, 0x35, 0x94, 0x4e, 0xfe, 0xc0, 0xd2, + 0x29, 0xec, 0x5f, 0x3a, 0xea, 0x5f, 0x2b, 0x80, 0x32, 0x63, 0xb6, 0xe8, 0xb2, 0xa3, 0x5b, 0xee, + 0x03, 0xea, 0x88, 0xed, 0xf4, 0x34, 0x63, 0x75, 0xa0, 0x0f, 0x94, 0xa6, 0x94, 0xfc, 0xbe, 0xa6, + 0x94, 0x8f, 0xc3, 0x90, 0x68, 0x4c, 0xe0, 0x3a, 0x89, 0xa3, 0xc6, 0xf1, 0x81, 0x5a, 0x88, 0x67, + 0xc4, 0x95, 0x4e, 0xc7, 0xb1, 0x1f, 0x52, 0x87, 0xdf, 0x8a, 0x09, 0x62, 0xdd, 0x07, 0x6a, 0x21, + 0x5e, 0xe2, 0x4c, 0x7d, 0x7b, 0x51, 0xe6, 0x4c, 0x1d, 0x2d, 0xc4, 0x93, 0xab, 0x30, 0x38, 0x67, + 0x37, 0x75, 0x14, 0x34, 0x9f, 0x56, 0x46, 0xb6, 0xb7, 0xca, 0x83, 0x2d, 0x01, 0xd3, 0x02, 0x2c, + 0xa3, 0xac, 0xda, 0x1b, 0x56, 0xcb, 0xd6, 0xb9, 0xb3, 0xcd, 0x20, 0xa7, 0x34, 0x04, 0x4c, 0x0b, + 0xb0, 0x8c, 0x92, 0xc9, 0x1c, 0x9d, 0x98, 0x06, 0x43, 0x9e, 0x0f, 0x04, 0x4c, 0x0b, 0xb0, 0xea, + 0x37, 0x8a, 0x4c, 0x7b, 0x5d, 0xf3, 0xfd, 0xc7, 0x7e, 0x5d, 0x08, 0x07, 0x4c, 0xff, 0x3e, 0x06, + 0xcc, 0x63, 0x73, 0x60, 0xa7, 0xfe, 0xcb, 0x01, 0x00, 0x21, 0xfd, 0xe9, 0x93, 0xcd, 0xe1, 0xc1, + 0xb4, 0xa6, 0x0a, 0xa7, 0xa7, 0xad, 0x35, 0xdd, 0x6a, 0x52, 0x23, 0x3c, 0xb6, 0x2c, 0xe1, 0xd0, + 0x46, 0xa7, 0x4b, 0x2a, 0x90, 0xe1, 0xb9, 0xa5, 0x96, 0x2c, 0x40, 0x5e, 0x84, 0xe1, 0x9a, 0xe5, + 0x51, 0x47, 0x6f, 0x7a, 0xe6, 0x43, 0x2a, 0xa6, 0x06, 0xbc, 0x89, 0x36, 0x43, 0xb0, 0x26, 0xd3, + 0x90, 0x9b, 0x30, 0xb2, 0xa4, 0x3b, 0x9e, 0xd9, 0x34, 0x3b, 0xba, 0xe5, 0xb9, 0xca, 0x20, 0xce, + 0x68, 0x68, 0x61, 0x74, 0x24, 0xb8, 0x16, 0xa1, 0x22, 0x9f, 0x87, 0x21, 0xdc, 0x9a, 0xa2, 0x7f, + 0xf8, 0xd0, 0x8e, 0x17, 0x95, 0xcf, 0x86, 0xee, 0x88, 0xfc, 0xf4, 0x15, 0x6f, 0x9c, 0xe3, 0x77, + 0x95, 0x01, 0x47, 0xf2, 0x19, 0x18, 0x98, 0xb6, 0x0c, 0x64, 0x0e, 0x3b, 0x32, 0x57, 0x05, 0xf3, + 0xf3, 0x21, 0x73, 0xbb, 0x13, 0xe3, 0xed, 0xb3, 0x4b, 0x1f, 0x65, 0xc3, 0x1f, 0xdc, 0x28, 0x1b, + 0xf9, 0x00, 0x8e, 0xc5, 0x47, 0x0f, 0xeb, 0x58, 0x7c, 0x6c, 0x9f, 0xc7, 0xe2, 0xea, 0xfb, 0x30, + 0x3c, 0xb9, 0x34, 0x13, 0x8c, 0xde, 0x8b, 0x50, 0x58, 0x12, 0x9e, 0x11, 0x45, 0x6e, 0xcf, 0x74, + 0x4c, 0x43, 0x63, 0x30, 0x72, 0x0d, 0x06, 0xa7, 0xd0, 0xdd, 0x4e, 0xdc, 0x22, 0x16, 0xf9, 0xfa, + 0xd7, 0x44, 0x18, 0x7a, 0xdd, 0xfa, 0x68, 0xf2, 0x51, 0x18, 0x58, 0x72, 0xec, 0x55, 0x47, 0x6f, + 0x8b, 0x35, 0x18, 0x5d, 0x53, 0x3a, 0x1c, 0xa4, 0xf9, 0x38, 0xf5, 0xa7, 0x72, 0xbe, 0xd9, 0xce, + 0x4a, 0xd4, 0xbb, 0x78, 0x34, 0x8f, 0x75, 0x0f, 0xf2, 0x12, 0x2e, 0x07, 0x69, 0x3e, 0x8e, 0x5c, + 0x83, 0xfe, 0x69, 0xc7, 0xb1, 0x1d, 0xd9, 0xa7, 0x9e, 0x32, 0x80, 0x7c, 0xdd, 0x8b, 0x14, 0xe4, + 0x55, 0x18, 0xe6, 0x73, 0x0e, 0x3f, 0xd1, 0x2c, 0xf4, 0xba, 0x29, 0x95, 0x29, 0xd5, 0x6f, 0x17, + 0x24, 0x9b, 0x8d, 0x4b, 0xfc, 0x31, 0xbc, 0x15, 0x78, 0x09, 0x0a, 0x93, 0x4b, 0x33, 0x62, 0x02, + 0x3c, 0xe3, 0x17, 0x95, 0x54, 0x25, 0x56, 0x8e, 0x51, 0x93, 0xcb, 0x50, 0x5c, 0x62, 0xea, 0x53, + 0x42, 0xf5, 0x18, 0xdc, 0xde, 0x2a, 0x17, 0x3b, 0x4c, 0x7f, 0x10, 0x8a, 0x58, 0xb6, 0x99, 0xe1, + 0x3b, 0x26, 0x8e, 0x0d, 0xf7, 0x31, 0x97, 0xa1, 0x58, 0x71, 0x56, 0x1f, 0x8a, 0x59, 0x0b, 0xb1, + 0xba, 0xb3, 0xfa, 0x50, 0x43, 0x28, 0xb9, 0x0e, 0xa0, 0x51, 0xaf, 0xeb, 0x58, 0xf8, 0xdc, 0x65, + 0x08, 0xcf, 0xdf, 0x70, 0x36, 0x74, 0x10, 0xda, 0x68, 0xda, 0x06, 0xd5, 0x24, 0x12, 0xf5, 0x6f, + 0x85, 0x17, 0x3b, 0x55, 0xd3, 0x5d, 0x3f, 0xe9, 0xc2, 0x3d, 0x74, 0xa1, 0x2e, 0x8e, 0x38, 0x93, + 0x9d, 0x54, 0x86, 0xfe, 0x99, 0x96, 0xbe, 0xea, 0x62, 0x1f, 0x0a, 0xdf, 0xb5, 0x07, 0x0c, 0xa0, + 0x71, 0x78, 0xac, 0x9f, 0x06, 0x77, 0xee, 0xa7, 0xaf, 0xf5, 0x07, 0xa3, 0x6d, 0x81, 0x7a, 0x1b, + 0xb6, 0x73, 0xd2, 0x55, 0xbb, 0xed, 0xaa, 0x2b, 0x30, 0x50, 0x77, 0x9a, 0xd2, 0xd1, 0x05, 0xee, + 0x07, 0x5c, 0xa7, 0xc9, 0x8f, 0x2d, 0x7c, 0x24, 0xa3, 0xab, 0xba, 0x1e, 0xd2, 0x0d, 0x84, 0x74, + 0x86, 0xeb, 0x09, 0x3a, 0x81, 0x14, 0x74, 0x4b, 0xb6, 0xe3, 0x89, 0x8e, 0x0b, 0xe8, 0x3a, 0xb6, + 0xe3, 0x69, 0x3e, 0x92, 0x7c, 0x1c, 0x60, 0x79, 0x6a, 0xc9, 0x77, 0xee, 0x1f, 0x0a, 0x7d, 0x0f, + 0x85, 0x57, 0xbf, 0x26, 0xa1, 0xc9, 0x32, 0x0c, 0x2d, 0x76, 0xa8, 0xc3, 0xb7, 0x42, 0xfc, 0x01, + 0xcb, 0xc7, 0x62, 0xa2, 0x15, 0xfd, 0x3e, 0x21, 0xfe, 0x0f, 0xc8, 0xf9, 0xfa, 0x62, 0xfb, 0x3f, + 0xb5, 0x90, 0x11, 0x79, 0x15, 0x4a, 0x15, 0x6e, 0xe7, 0x0d, 0x23, 0xcb, 0x40, 0x64, 0xb8, 0x05, + 0xe5, 0x28, 0xbe, 0x67, 0xd7, 0xf1, 0x6f, 0x4d, 0x90, 0xab, 0xd7, 0x60, 0x3c, 0x5e, 0x0d, 0x19, + 0x86, 0x81, 0xa9, 0xc5, 0x85, 0x85, 0xe9, 0xa9, 0xe5, 0xf1, 0x3e, 0x32, 0x08, 0xc5, 0xfa, 0xf4, + 0x42, 0x75, 0x3c, 0xa7, 0xfe, 0x92, 0x34, 0x83, 0x30, 0xd5, 0x3a, 0xb9, 0x1a, 0x3e, 0xd0, 0x7d, + 0xcb, 0x38, 0xde, 0x87, 0xe2, 0x89, 0x41, 0xdb, 0xf4, 0x3c, 0x6a, 0x88, 0x55, 0x02, 0xef, 0x0b, + 0xbd, 0x47, 0x5a, 0x02, 0x4f, 0x9e, 0x87, 0x51, 0x84, 0x89, 0x2b, 0x42, 0xbe, 0x3f, 0x16, 0x05, + 0x9c, 0x47, 0x5a, 0x14, 0xa9, 0xfe, 0x7e, 0x78, 0x3b, 0x3c, 0x47, 0xf5, 0xe3, 0x7a, 0xa3, 0xf8, + 0x21, 0xe9, 0x2f, 0xf5, 0x5f, 0x17, 0xf9, 0x93, 0x13, 0xfe, 0x3e, 0xf1, 0x28, 0x44, 0x19, 0x1e, + 0xe9, 0x16, 0xf6, 0x70, 0xa4, 0xfb, 0x3c, 0x94, 0xe6, 0xa9, 0xb7, 0x66, 0xfb, 0x8e, 0x5f, 0xe8, + 0xa1, 0xd7, 0x46, 0x88, 0xec, 0xa1, 0xc7, 0x69, 0xc8, 0x3a, 0x10, 0xff, 0xf1, 0x61, 0xe0, 0xf8, + 0xed, 0x1f, 0x21, 0x5f, 0x48, 0xec, 0x53, 0xea, 0xf8, 0x44, 0x19, 0x7d, 0xfa, 0xcf, 0x06, 0x8e, + 0xe5, 0x92, 0x27, 0xd6, 0xbf, 0xda, 0x2a, 0x97, 0x38, 0x8d, 0x96, 0xc2, 0x96, 0xbc, 0x03, 0x43, + 0xf3, 0x33, 0x15, 0xf1, 0x10, 0x91, 0x7b, 0x45, 0x5c, 0x0c, 0xa4, 0xe8, 0x23, 0x02, 0x91, 0xe0, + 0xfb, 0x9e, 0xf6, 0x03, 0x3d, 0xf9, 0x0e, 0x31, 0xe4, 0xc2, 0xb4, 0x85, 0xbf, 0x14, 0x12, 0xa7, + 0x0b, 0x81, 0xb6, 0x44, 0xdf, 0x0f, 0xc5, 0x65, 0xc5, 0xb1, 0x31, 0x6d, 0x19, 0x3c, 0xc0, 0xe8, + 0x5e, 0x84, 0xd3, 0x95, 0x4e, 0xa7, 0x65, 0x52, 0x03, 0xf5, 0x45, 0xeb, 0xb6, 0xa8, 0x2b, 0x5c, + 0x7e, 0xf0, 0xf1, 0x89, 0xce, 0x91, 0x0d, 0x7c, 0xfe, 0xda, 0x70, 0xba, 0x51, 0xff, 0xcc, 0x64, + 0x59, 0xf5, 0x67, 0xf2, 0x70, 0x7e, 0xca, 0xa1, 0xba, 0x47, 0xe7, 0x67, 0x2a, 0x95, 0x2e, 0xfa, + 0xc8, 0xb5, 0x5a, 0xd4, 0x5a, 0x3d, 0x9a, 0x61, 0xfd, 0x06, 0x8c, 0x05, 0x0d, 0xa8, 0x37, 0xed, + 0x0e, 0x95, 0x1f, 0x72, 0x35, 0x7d, 0x4c, 0xc3, 0x65, 0x28, 0x2d, 0x46, 0x4a, 0xee, 0xc0, 0x99, + 0x00, 0x52, 0x69, 0xb5, 0xec, 0x0d, 0x8d, 0x76, 0x5d, 0xee, 0x88, 0x3b, 0xc8, 0x1d, 0x71, 0x43, + 0x0e, 0x3a, 0xc3, 0x37, 0x1c, 0x46, 0xa0, 0xa5, 0x95, 0x52, 0xbf, 0x5e, 0x80, 0x0b, 0xf7, 0xf4, + 0x96, 0x69, 0x84, 0xa2, 0xd1, 0xa8, 0xdb, 0xb1, 0x2d, 0x97, 0x1e, 0xa3, 0x51, 0x1a, 0x19, 0x0a, + 0xc5, 0x43, 0x19, 0x0a, 0xc9, 0x2e, 0xea, 0x3f, 0x70, 0x17, 0x95, 0xf6, 0xd5, 0x45, 0xff, 0x6b, + 0x0e, 0xc6, 0xfd, 0x87, 0x06, 0xf2, 0xa3, 0x71, 0xc9, 0x0b, 0x1e, 0x8f, 0x10, 0x63, 0x7e, 0xd7, + 0x88, 0x27, 0x75, 0x18, 0x98, 0x7e, 0xd4, 0x31, 0x1d, 0xea, 0xee, 0xc2, 0x69, 0xfc, 0x49, 0x71, + 0x5c, 0x72, 0x9a, 0xf2, 0x22, 0x89, 0x93, 0x12, 0x0e, 0xc6, 0xe7, 0x83, 0xfc, 0xa9, 0xc5, 0xa4, + 0xff, 0x12, 0x9e, 0x3f, 0x1f, 0x14, 0x4f, 0x32, 0x22, 0xef, 0x41, 0x43, 0x52, 0xf2, 0x2c, 0x14, + 0x96, 0x97, 0xe7, 0xc4, 0x4c, 0x8a, 0x11, 0x08, 0x3c, 0x4f, 0x7e, 0x1f, 0xc9, 0xb0, 0xea, 0x3f, + 0xcb, 0x03, 0x30, 0x55, 0xe0, 0xc3, 0xf5, 0x48, 0x94, 0x70, 0x12, 0x06, 0x7d, 0x81, 0x0b, 0x35, + 0x0c, 0x5e, 0x09, 0xc4, 0x3b, 0x22, 0x5e, 0x77, 0xf0, 0x22, 0xa4, 0xec, 0x3b, 0x92, 0xf3, 0x7b, + 0x00, 0xdc, 0xd9, 0xa0, 0x23, 0xb9, 0xef, 0x3e, 0xfe, 0x71, 0x18, 0x12, 0x33, 0x9e, 0x1d, 0x39, + 0xff, 0x6f, 0xfa, 0x40, 0x2d, 0xc4, 0xc7, 0xa6, 0xd6, 0xd2, 0x01, 0x16, 0x62, 0x5f, 0xbc, 0xbc, + 0x57, 0x4e, 0xc4, 0x7b, 0xc8, 0xe2, 0xfd, 0xb2, 0x10, 0x2f, 0x7f, 0x31, 0x74, 0x6c, 0xc5, 0x7b, + 0x68, 0x67, 0xdf, 0xea, 0x3f, 0xce, 0x01, 0x61, 0xcd, 0x5a, 0xd2, 0x5d, 0x77, 0xc3, 0x76, 0x0c, + 0xee, 0x9c, 0x7e, 0x24, 0x82, 0x39, 0xbc, 0xfb, 0xca, 0x6f, 0x0f, 0xc2, 0x99, 0x88, 0xe3, 0xef, + 0x31, 0x9f, 0xac, 0xae, 0x45, 0x47, 0x53, 0xaf, 0x57, 0x2f, 0x1f, 0x91, 0x2f, 0x44, 0xfb, 0x23, + 0x0f, 0xde, 0xa4, 0x9b, 0xd0, 0x17, 0x60, 0x44, 0xfc, 0x60, 0x2b, 0xb4, 0x7f, 0xd3, 0x85, 0xa3, + 0xd4, 0x65, 0x00, 0x2d, 0x82, 0x26, 0x2f, 0xc3, 0x10, 0x1b, 0x30, 0xab, 0x18, 0xac, 0x64, 0x20, + 0x7c, 0x51, 0x62, 0xf8, 0x40, 0x79, 0x3d, 0x09, 0x28, 0xa5, 0x77, 0x4b, 0x83, 0xbb, 0x78, 0xb7, + 0xf4, 0x05, 0x18, 0xae, 0x58, 0x96, 0xed, 0xe1, 0x26, 0xdd, 0x15, 0x57, 0x13, 0x99, 0x56, 0xf9, + 0xb3, 0xf8, 0x18, 0x3f, 0xa4, 0x4f, 0x35, 0xcb, 0x65, 0x86, 0xe4, 0x86, 0xff, 0x2a, 0x86, 0x3a, + 0xc2, 0xab, 0x1c, 0xaf, 0x67, 0x1c, 0x01, 0x4b, 0x3e, 0x8a, 0xc1, 0xce, 0x1b, 0x5d, 0x72, 0xec, + 0x8e, 0xed, 0x52, 0x83, 0x0b, 0x6a, 0x38, 0x0c, 0x6d, 0xd0, 0x11, 0x08, 0x7c, 0x37, 0x17, 0x09, + 0x1c, 0x12, 0x29, 0x42, 0x1e, 0xc0, 0x59, 0xff, 0xa2, 0x38, 0x78, 0xa1, 0x58, 0xab, 0xba, 0xca, + 0x08, 0xbe, 0x4a, 0x22, 0x71, 0x65, 0xa8, 0x55, 0x27, 0x9f, 0xf2, 0xaf, 0x45, 0xfc, 0x27, 0x8e, + 0x0d, 0xd3, 0x90, 0xbb, 0x3a, 0x95, 0x1f, 0xf9, 0x41, 0x18, 0x9e, 0xd7, 0x1f, 0x55, 0xbb, 0xe2, + 0xec, 0x65, 0x74, 0xf7, 0xb7, 0x2f, 0x6d, 0xfd, 0x51, 0xc3, 0x10, 0xe5, 0x62, 0x36, 0x85, 0xcc, + 0x92, 0x34, 0xe0, 0xfc, 0x92, 0x63, 0xb7, 0x6d, 0x8f, 0x1a, 0xb1, 0xc7, 0x7e, 0xa7, 0xc2, 0xd7, + 0xc1, 0x1d, 0x41, 0xd1, 0xe8, 0xf1, 0xea, 0x2f, 0x83, 0x0d, 0x69, 0xc3, 0xa9, 0x8a, 0xeb, 0x76, + 0xdb, 0x34, 0xbc, 0xa1, 0x1a, 0xdf, 0xf1, 0x33, 0x3e, 0x26, 0xbc, 0x96, 0x9f, 0xd0, 0xb1, 0x28, + 0xbf, 0xa0, 0x6a, 0x78, 0xa6, 0x5c, 0x23, 0x7e, 0x4b, 0x9c, 0xf7, 0xed, 0xe2, 0xe0, 0xd8, 0xf8, + 0x29, 0xed, 0x42, 0xb2, 0x31, 0xcb, 0xa6, 0xd7, 0xa2, 0xea, 0xb7, 0x72, 0x00, 0xa1, 0x80, 0xc9, + 0x0b, 0xd1, 0x88, 0x48, 0xb9, 0xf0, 0xa2, 0x43, 0x44, 0x4b, 0x88, 0x84, 0x40, 0x22, 0x97, 0xa1, + 0x88, 0x11, 0x35, 0xf2, 0xe1, 0xc1, 0xea, 0xba, 0x69, 0x19, 0x1a, 0x42, 0x19, 0x56, 0x7a, 0xfa, + 0x8e, 0x58, 0xbc, 0xd4, 0xe7, 0x56, 0x61, 0x15, 0x4e, 0xd5, 0xbb, 0x2b, 0x7e, 0xdd, 0xd2, 0x3b, + 0x3e, 0x0c, 0xec, 0xe1, 0x76, 0x57, 0x82, 0xc7, 0xaf, 0x91, 0xb0, 0x29, 0xd1, 0x22, 0xea, 0x37, + 0x72, 0xb1, 0x59, 0xf0, 0x08, 0x17, 0xbd, 0x8f, 0x24, 0xfd, 0x34, 0x92, 0xd3, 0x92, 0xfa, 0x47, + 0x05, 0x18, 0x5e, 0xb2, 0x1d, 0x4f, 0x84, 0x28, 0x39, 0xde, 0xab, 0x90, 0xb4, 0x57, 0x2a, 0xee, + 0x61, 0xaf, 0x74, 0x19, 0x8a, 0x92, 0x8b, 0x32, 0xbf, 0x17, 0x31, 0x0c, 0x47, 0x43, 0xe8, 0x07, + 0xfc, 0xe4, 0x22, 0x79, 0x09, 0x3a, 0x70, 0x60, 0x57, 0x83, 0x1f, 0xce, 0x03, 0x7c, 0xe6, 0xc5, + 0x17, 0x1f, 0xe3, 0x2e, 0x55, 0xff, 0x6a, 0x0e, 0x4e, 0x89, 0xab, 0x45, 0x29, 0x1a, 0xda, 0x80, + 0x7f, 0x29, 0x2c, 0xcf, 0x24, 0x1c, 0xa4, 0xf9, 0x38, 0xb6, 0x68, 0x4d, 0x3f, 0x32, 0x3d, 0xbc, + 0x5d, 0x91, 0xc2, 0xa1, 0x51, 0x01, 0x93, 0x17, 0x2d, 0x9f, 0x8e, 0xbc, 0xe0, 0x5f, 0x9a, 0x16, + 0xc2, 0x95, 0x9a, 0x15, 0x98, 0x4e, 0xbd, 0x38, 0x55, 0x7f, 0xad, 0x08, 0xc5, 0xe9, 0x47, 0xb4, + 0x79, 0xcc, 0xbb, 0x46, 0x3a, 0x8a, 0x2d, 0x1e, 0xf0, 0x28, 0x76, 0x3f, 0x5e, 0x20, 0x6f, 0x87, + 0xfd, 0x59, 0x8a, 0x56, 0x1f, 0xeb, 0xf9, 0x78, 0xf5, 0x7e, 0x4f, 0x1f, 0x3f, 0x27, 0xa2, 0xff, + 0xa2, 0x00, 0x85, 0xfa, 0xd4, 0xd2, 0x89, 0xde, 0x1c, 0xa9, 0xde, 0xf4, 0xbe, 0x65, 0x57, 0x83, + 0x8b, 0xb3, 0xc1, 0xd0, 0xaf, 0x35, 0x76, 0x47, 0xf6, 0xa7, 0x05, 0x18, 0xab, 0xcf, 0x2c, 0x2f, + 0x49, 0x67, 0xd7, 0x77, 0xb8, 0xef, 0x21, 0x7a, 0xc1, 0xf1, 0x2e, 0xbd, 0x9c, 0xb0, 0xc0, 0xee, + 0xd6, 0x2c, 0xef, 0x95, 0x9b, 0xf7, 0xf4, 0x56, 0x97, 0xe2, 0x61, 0x11, 0xf7, 0x54, 0x76, 0xcd, + 0xf7, 0xe9, 0xd7, 0x31, 0x34, 0x82, 0xcf, 0x80, 0xbc, 0x01, 0x85, 0xbb, 0xc2, 0x87, 0x24, 0x8b, + 0xcf, 0x4b, 0x37, 0x38, 0x1f, 0x36, 0x09, 0x16, 0xba, 0xa6, 0x81, 0x1c, 0x58, 0x29, 0x56, 0xf8, + 0x96, 0x30, 0x19, 0x76, 0x55, 0x78, 0xd5, 0x2f, 0x7c, 0xab, 0x56, 0x25, 0x75, 0x18, 0x5e, 0xa2, + 0x4e, 0xdb, 0xc4, 0x8e, 0xf2, 0xe7, 0xec, 0xde, 0x4c, 0xd8, 0xde, 0x6a, 0xb8, 0x13, 0x16, 0x42, + 0x66, 0x32, 0x17, 0xf2, 0x2e, 0x00, 0xb7, 0xaa, 0x76, 0x19, 0x61, 0xf3, 0x49, 0xdc, 0xa9, 0x70, + 0x63, 0x38, 0xc5, 0x2a, 0x95, 0x98, 0x91, 0x75, 0x18, 0x9f, 0xb7, 0x0d, 0xf3, 0x81, 0xc9, 0x9d, + 0x45, 0xb1, 0x82, 0xd2, 0xce, 0x2e, 0x5a, 0xcc, 0xf8, 0x6d, 0x4b, 0xe5, 0xd2, 0xaa, 0x49, 0x30, + 0x56, 0xff, 0x7e, 0x3f, 0x14, 0x59, 0xb7, 0x9f, 0x8c, 0xdf, 0x83, 0x8c, 0xdf, 0x0a, 0x8c, 0xdf, + 0xb7, 0x9d, 0x75, 0xd3, 0x5a, 0x0d, 0xfc, 0xf8, 0xc5, 0x6e, 0x1a, 0x7d, 0x8f, 0x36, 0x38, 0xae, + 0x11, 0xb8, 0xfc, 0x6b, 0x09, 0xf2, 0x1d, 0x46, 0xf0, 0x6b, 0x00, 0xfc, 0x75, 0x3e, 0xd2, 0x0c, + 0x86, 0xe1, 0x3c, 0xf8, 0xdb, 0x7d, 0x7c, 0x1a, 0x20, 0x87, 0xf3, 0x08, 0x89, 0xc9, 0x35, 0xdf, + 0x7b, 0x63, 0x08, 0x5f, 0x0a, 0xe0, 0xb1, 0x01, 0x7a, 0x6f, 0xc8, 0x46, 0x00, 0xf7, 0xe3, 0x58, + 0x02, 0x90, 0x6e, 0xc4, 0x20, 0x26, 0x88, 0xc8, 0xe4, 0x20, 0x02, 0xe8, 0xa5, 0x5c, 0x88, 0x69, + 0x12, 0x0f, 0xf2, 0x4a, 0xec, 0xca, 0x9e, 0x44, 0xb8, 0x65, 0xde, 0xd8, 0x87, 0x2e, 0x5f, 0x23, + 0x3b, 0xb9, 0x7c, 0xa9, 0x7f, 0xa7, 0x00, 0xc3, 0x8c, 0x5b, 0xbd, 0xdb, 0x6e, 0xeb, 0xce, 0xe6, + 0x89, 0x22, 0x1f, 0x44, 0x91, 0x1b, 0x70, 0x5a, 0x76, 0xf1, 0x67, 0xa6, 0xab, 0x1f, 0x8c, 0x29, + 0x38, 0xb0, 0x8a, 0x13, 0x70, 0xdb, 0x12, 0xe7, 0x7d, 0x4f, 0x80, 0xf1, 0x34, 0xc4, 0xd5, 0x92, + 0xbc, 0xd4, 0x9f, 0xce, 0xc1, 0x78, 0x1c, 0x1a, 0xe8, 0x7e, 0x2e, 0x55, 0xf7, 0x9f, 0x87, 0x21, + 0x71, 0xe9, 0xaf, 0x1b, 0xc2, 0x07, 0x71, 0x6c, 0x7b, 0xab, 0x0c, 0xf8, 0xe2, 0xba, 0xe1, 0x50, + 0xdd, 0xd0, 0x42, 0x02, 0xf2, 0x32, 0x8c, 0xe0, 0x8f, 0xfb, 0x8e, 0xe9, 0x79, 0x94, 0x77, 0x46, + 0x91, 0xdf, 0x63, 0xf0, 0x02, 0x1b, 0x1c, 0xa1, 0x45, 0xc8, 0xd4, 0xdf, 0xcb, 0xc3, 0x50, 0xbd, + 0xbb, 0xe2, 0x6e, 0xba, 0x1e, 0x6d, 0x1f, 0x73, 0x1d, 0xf2, 0x8f, 0x15, 0x8a, 0xa9, 0xc7, 0x0a, + 0xcf, 0xfa, 0x43, 0x4b, 0x3a, 0x6f, 0x0f, 0x36, 0x06, 0xbe, 0x1f, 0x65, 0xa8, 0x45, 0xa5, 0xbd, + 0x6b, 0x91, 0xfa, 0xf7, 0xf2, 0x30, 0xce, 0xaf, 0x9b, 0xab, 0xa6, 0xdb, 0x3c, 0x84, 0x27, 0x30, + 0x47, 0x2f, 0xd3, 0x83, 0xb9, 0x68, 0xec, 0xe2, 0x61, 0x91, 0xfa, 0xc5, 0x3c, 0x0c, 0x57, 0xba, + 0xde, 0x5a, 0xc5, 0xc3, 0xf9, 0xed, 0xb1, 0xdc, 0x23, 0xff, 0xa3, 0x1c, 0x9c, 0x62, 0x0d, 0x59, + 0xb6, 0xd7, 0xa9, 0x75, 0x08, 0xc7, 0xf5, 0xf2, 0xb1, 0x7b, 0x7e, 0x9f, 0xc7, 0xee, 0xbe, 0x2c, + 0x0b, 0x7b, 0x93, 0x25, 0x5e, 0x32, 0x69, 0x76, 0x8b, 0x1e, 0xef, 0xcf, 0x38, 0xc4, 0x4b, 0x26, + 0x5f, 0x20, 0x87, 0x70, 0xa9, 0xf9, 0xfd, 0x25, 0x90, 0x43, 0x38, 0x91, 0xfd, 0xfe, 0x10, 0xc8, + 0xb7, 0x73, 0x30, 0x34, 0x69, 0x7b, 0xc7, 0x7c, 0xe0, 0x8b, 0xaf, 0x38, 0xde, 0x6a, 0xee, 0x7f, + 0xc5, 0xf1, 0xd6, 0x4d, 0xf5, 0x67, 0xf3, 0x70, 0x56, 0x44, 0xf0, 0x17, 0x67, 0x60, 0x27, 0xd3, + 0xb1, 0x18, 0x6c, 0x49, 0xd1, 0x9c, 0xcc, 0x43, 0x42, 0x34, 0xbf, 0x50, 0x80, 0xb3, 0x18, 0x70, + 0x98, 0xed, 0xa8, 0xbe, 0x0f, 0x6c, 0x11, 0xd2, 0x8c, 0xba, 0x0e, 0xcc, 0xa7, 0xb8, 0x0e, 0xfc, + 0xab, 0xad, 0xf2, 0x2b, 0xab, 0xa6, 0xb7, 0xd6, 0x5d, 0x99, 0x68, 0xda, 0xed, 0xeb, 0xab, 0x8e, + 0xfe, 0xd0, 0xe4, 0x97, 0xe6, 0x7a, 0xeb, 0x7a, 0x98, 0x58, 0xa7, 0x63, 0x8a, 0x34, 0x39, 0x75, + 0xdc, 0x29, 0x31, 0xae, 0xbe, 0xd3, 0x81, 0x0b, 0x70, 0xdb, 0x36, 0x2d, 0xe1, 0x89, 0xcb, 0x0d, + 0xdd, 0xfa, 0xf6, 0x56, 0xf9, 0xdc, 0x7b, 0xb6, 0x69, 0x35, 0xe2, 0xee, 0xb8, 0x7b, 0xad, 0x2f, + 0x64, 0xad, 0x49, 0xd5, 0xa8, 0xff, 0x4d, 0x0e, 0x2e, 0x46, 0xb5, 0xf8, 0xfb, 0xc1, 0x76, 0xfc, + 0x2b, 0x79, 0x38, 0x77, 0x0b, 0x85, 0x13, 0xb8, 0x3f, 0x9d, 0xcc, 0x5b, 0x62, 0x70, 0xa6, 0xc8, + 0xe6, 0xc4, 0xa2, 0xcc, 0x96, 0xcd, 0xc9, 0xa4, 0x2e, 0x64, 0xf3, 0x5f, 0xe7, 0xe0, 0xcc, 0x62, + 0xad, 0x3a, 0xf5, 0x7d, 0x32, 0xa2, 0x92, 0xdf, 0x73, 0xcc, 0x0d, 0xce, 0xc4, 0xf7, 0x1c, 0x73, + 0xd3, 0xf3, 0xab, 0x79, 0x38, 0x53, 0xaf, 0xcc, 0xcf, 0x7d, 0xbf, 0xcc, 0xe0, 0x53, 0xb2, 0xaf, + 0xae, 0x7f, 0x08, 0x26, 0x6c, 0x01, 0xf9, 0x33, 0xef, 0xdd, 0xc8, 0xf6, 0xe1, 0x4d, 0x0a, 0xe5, + 0x98, 0x4f, 0xdd, 0x87, 0x22, 0x14, 0xa6, 0xf9, 0x11, 0xea, 0x63, 0xae, 0xf9, 0xff, 0xb0, 0x04, + 0xc3, 0x77, 0xba, 0x2b, 0x54, 0xb8, 0x74, 0x3d, 0xd6, 0x27, 0xbf, 0x37, 0x60, 0x58, 0x88, 0x01, + 0x6f, 0x38, 0xa4, 0x90, 0x93, 0x22, 0x84, 0x10, 0x8f, 0xea, 0x25, 0x13, 0x91, 0xcb, 0x50, 0xbc, + 0x47, 0x9d, 0x15, 0xf9, 0x35, 0xf6, 0x43, 0xea, 0xac, 0x68, 0x08, 0x25, 0x73, 0xe1, 0x43, 0x93, + 0xca, 0x52, 0x0d, 0xd3, 0x1d, 0x89, 0x4b, 0x43, 0xcc, 0xdf, 0x14, 0x78, 0x8b, 0xea, 0x1d, 0x93, + 0x27, 0x4a, 0x92, 0x23, 0x41, 0xc4, 0x4b, 0x92, 0x05, 0x38, 0x2d, 0xbb, 0x0b, 0xf2, 0x5c, 0x3f, + 0x83, 0x29, 0xec, 0xd2, 0xb2, 0xfc, 0x24, 0x8b, 0x92, 0xb7, 0x61, 0xc4, 0x07, 0xa2, 0xe3, 0xe3, + 0x50, 0x98, 0x60, 0x22, 0x60, 0x15, 0xcb, 0x07, 0x10, 0x29, 0x20, 0x33, 0xc0, 0x4b, 0x0c, 0x48, + 0x61, 0x10, 0x73, 0x24, 0x8d, 0x14, 0x20, 0x2f, 0x23, 0x03, 0x7c, 0x1c, 0x85, 0x0e, 0x53, 0xc3, + 0xf8, 0x54, 0x19, 0x2f, 0x80, 0x1c, 0x01, 0xe7, 0x0f, 0xd2, 0x23, 0x64, 0x64, 0x11, 0x20, 0x74, + 0x6c, 0x11, 0x61, 0x3f, 0xf6, 0xec, 0x72, 0x23, 0xb1, 0x90, 0x6f, 0xf2, 0x46, 0xf7, 0x73, 0x93, + 0xa7, 0xfe, 0x4c, 0x01, 0x86, 0x2b, 0x9d, 0x4e, 0x30, 0x14, 0x5e, 0x80, 0x52, 0xa5, 0xd3, 0xb9, + 0xab, 0xd5, 0xe4, 0x04, 0x00, 0x7a, 0xa7, 0xd3, 0xe8, 0x3a, 0xa6, 0xec, 0x49, 0xcd, 0x89, 0xc8, + 0x14, 0x8c, 0x56, 0x3a, 0x9d, 0xa5, 0xee, 0x4a, 0xcb, 0x6c, 0x4a, 0xf9, 0xcb, 0x78, 0x86, 0xc7, + 0x4e, 0xa7, 0xd1, 0x41, 0x4c, 0x3c, 0x89, 0x5d, 0xb4, 0x0c, 0xf9, 0x02, 0x06, 0xcb, 0x12, 0xe9, + 0xb3, 0x78, 0x82, 0x1e, 0x35, 0x08, 0xfd, 0x1f, 0xb6, 0x6d, 0x22, 0x20, 0xe2, 0x29, 0x12, 0x2e, + 0xfb, 0x89, 0x2d, 0x58, 0x45, 0x89, 0x34, 0x59, 0x21, 0x4b, 0xf2, 0x09, 0x18, 0xa8, 0x74, 0x3a, + 0xd2, 0x6d, 0x15, 0x3a, 0xb6, 0xb1, 0x52, 0xf1, 0x0c, 0x85, 0x82, 0x4c, 0x7c, 0x96, 0xb8, 0xdf, + 0xb6, 0x1d, 0x0f, 0x87, 0xd4, 0x68, 0xf8, 0x59, 0xfe, 0x85, 0xb8, 0x2d, 0xc7, 0xa7, 0xd1, 0xa2, + 0x65, 0x2e, 0xbd, 0x09, 0x63, 0xd1, 0x16, 0xef, 0x29, 0x4f, 0xc3, 0xf7, 0x72, 0x28, 0x95, 0x63, + 0xfe, 0x9c, 0xe0, 0x25, 0x28, 0x54, 0x3a, 0x1d, 0x31, 0xa9, 0x9d, 0x49, 0xe9, 0xd4, 0x78, 0xf4, + 0x81, 0x4a, 0xa7, 0xe3, 0x7f, 0xfa, 0x31, 0x7f, 0x97, 0xb4, 0xaf, 0x4f, 0xff, 0x36, 0xff, 0xf4, + 0xe3, 0xfd, 0x66, 0x48, 0xfd, 0xb5, 0x02, 0x9c, 0xaa, 0x74, 0x3a, 0x27, 0xf9, 0x1d, 0x0e, 0x2b, + 0xc6, 0xc1, 0x8b, 0x00, 0xd2, 0x1c, 0x3b, 0x10, 0xbc, 0x9a, 0x1c, 0x96, 0xe6, 0x57, 0x25, 0xa7, + 0x49, 0x44, 0xbe, 0xfa, 0x0d, 0xee, 0x49, 0xfd, 0xbe, 0x58, 0xc0, 0x89, 0xef, 0xb8, 0xc7, 0x6b, + 0xfb, 0xb0, 0x74, 0x9b, 0xe8, 0x83, 0xd2, 0x9e, 0xfa, 0xe0, 0x77, 0x23, 0x83, 0x07, 0xf3, 0x05, + 0x9c, 0xf4, 0x42, 0xff, 0x81, 0x6c, 0xeb, 0x31, 0x59, 0x98, 0x22, 0x88, 0x94, 0x9f, 0x33, 0x4d, + 0x84, 0x34, 0x6b, 0x32, 0x54, 0xc3, 0x34, 0xb4, 0x18, 0xad, 0xdf, 0x87, 0x03, 0x7b, 0xea, 0xc3, + 0xad, 0x3c, 0x86, 0x2d, 0x08, 0x42, 0xa2, 0x1d, 0x7c, 0x8b, 0x72, 0x1d, 0x80, 0xbb, 0x2f, 0x04, + 0xfe, 0xf9, 0xa3, 0x3c, 0xfa, 0x11, 0x4f, 0xa5, 0x26, 0xa2, 0x1f, 0x85, 0x24, 0x81, 0xbb, 0x53, + 0x21, 0xd5, 0xdd, 0xe9, 0x1a, 0x0c, 0x6a, 0xfa, 0xc6, 0x3b, 0x5d, 0xea, 0x6c, 0x0a, 0x9b, 0x88, + 0x47, 0x1c, 0xd5, 0x37, 0x1a, 0x3f, 0xc4, 0x80, 0x5a, 0x80, 0x26, 0x6a, 0x10, 0xf7, 0x42, 0x72, + 0x2b, 0xe1, 0x07, 0xed, 0x41, 0xb4, 0x8b, 0xfd, 0x28, 0x3a, 0x79, 0x1d, 0x0a, 0x95, 0xfb, 0x75, + 0x21, 0xd9, 0xa0, 0x6b, 0x2b, 0xf7, 0xeb, 0x42, 0x5e, 0x99, 0x65, 0xef, 0xd7, 0xd5, 0x2f, 0xe6, + 0x81, 0x24, 0x29, 0xc9, 0x2b, 0x30, 0x84, 0xd0, 0x55, 0xa6, 0x33, 0x72, 0x0e, 0xde, 0x0d, 0xb7, + 0xe1, 0x20, 0x34, 0x62, 0x21, 0xfa, 0xa4, 0xe4, 0x35, 0xcc, 0x72, 0x2e, 0xb2, 0x40, 0x46, 0x72, + 0xf0, 0x6e, 0xb8, 0x7e, 0x5e, 0xf0, 0x58, 0x92, 0x73, 0x41, 0x8c, 0xc6, 0xe5, 0xfd, 0xfa, 0xac, + 0xed, 0x7a, 0x42, 0xd4, 0xdc, 0xb8, 0xdc, 0x70, 0x31, 0xf9, 0x73, 0xc4, 0xb8, 0xe4, 0x64, 0x98, + 0xc0, 0xee, 0x7e, 0x9d, 0xbf, 0x10, 0x33, 0x34, 0xbb, 0xe5, 0x5b, 0xa5, 0x3c, 0x81, 0xdd, 0x86, + 0xdb, 0xe0, 0xaf, 0xcb, 0x0c, 0x4c, 0xaf, 0x1e, 0x49, 0x60, 0x17, 0x29, 0xa5, 0xfe, 0xe4, 0x20, + 0x8c, 0x57, 0x75, 0x4f, 0x5f, 0xd1, 0x5d, 0x2a, 0x6d, 0xc9, 0x4f, 0xf9, 0x30, 0xff, 0x73, 0x24, + 0x39, 0x18, 0x2b, 0x29, 0x5f, 0x13, 0x2f, 0x40, 0xde, 0x08, 0xf9, 0x06, 0xe9, 0x85, 0xe5, 0x7c, + 0x85, 0x2b, 0x8d, 0x8e, 0x00, 0x6b, 0x09, 0x42, 0xf2, 0x3c, 0x0c, 0xfb, 0x30, 0xb6, 0x8b, 0x28, + 0x84, 0x3a, 0x63, 0xac, 0xb0, 0x4d, 0x84, 0x26, 0xa3, 0xc9, 0x6b, 0x30, 0xe2, 0xff, 0x94, 0xec, + 0x73, 0x9e, 0x7c, 0x71, 0x25, 0xb1, 0x05, 0x93, 0x49, 0xe5, 0xa2, 0x38, 0xbf, 0xf5, 0x47, 0x8a, + 0xc6, 0xf2, 0x1b, 0x46, 0x48, 0xc9, 0x0f, 0xc1, 0x98, 0xff, 0x5b, 0xec, 0x3a, 0xb8, 0xf7, 0xe1, + 0xf3, 0x41, 0xf6, 0xf6, 0x98, 0x58, 0x27, 0xa2, 0xe4, 0x7c, 0xff, 0xf1, 0x84, 0x9f, 0xb2, 0xcf, + 0x58, 0x49, 0x6e, 0x3f, 0x62, 0x15, 0x90, 0x1a, 0x9c, 0xf6, 0x21, 0xa1, 0x86, 0x0e, 0x84, 0xdb, + 0x4e, 0x63, 0xa5, 0x91, 0xaa, 0xa4, 0xc9, 0x52, 0xa4, 0x05, 0x97, 0x23, 0x40, 0xc3, 0x5d, 0x33, + 0x1f, 0x78, 0x62, 0xcf, 0x28, 0xc2, 0x7f, 0x8b, 0x1c, 0xad, 0x01, 0x57, 0x4e, 0xe3, 0x27, 0x5b, + 0x8e, 0x26, 0x66, 0xeb, 0xc9, 0x8d, 0xd4, 0xe1, 0xac, 0x8f, 0xbf, 0x35, 0xb5, 0xb4, 0xe4, 0xd8, + 0xef, 0xd1, 0xa6, 0x57, 0xab, 0x8a, 0x3d, 0x37, 0x86, 0x85, 0x34, 0x56, 0x1a, 0xab, 0xcd, 0x0e, + 0x53, 0x0a, 0x86, 0x8b, 0x32, 0x4f, 0x2d, 0x4c, 0xee, 0xc1, 0x39, 0x09, 0x2e, 0x65, 0x82, 0x87, + 0xf0, 0x50, 0x40, 0x70, 0x4d, 0x4f, 0x06, 0x9f, 0x5e, 0x9c, 0xbc, 0x09, 0xa3, 0x3e, 0x82, 0x5f, + 0x45, 0x0e, 0xe3, 0x55, 0x24, 0x0e, 0x49, 0x63, 0xa5, 0x11, 0x7f, 0xc8, 0x1c, 0x25, 0x96, 0x35, + 0x6a, 0x79, 0xb3, 0x43, 0x85, 0x5b, 0xb0, 0xaf, 0x51, 0xde, 0x66, 0x27, 0x55, 0x19, 0x19, 0x29, + 0x79, 0x3b, 0xd4, 0xa8, 0x45, 0xc7, 0x5c, 0x35, 0xf9, 0x76, 0xdc, 0x7f, 0xbb, 0xbc, 0xd2, 0xb0, + 0x11, 0x98, 0xa6, 0x1f, 0x9c, 0xfc, 0x52, 0x05, 0xce, 0xa4, 0xe8, 0xd8, 0x9e, 0x76, 0x8c, 0x5f, + 0xca, 0x87, 0x8d, 0x38, 0xe6, 0xdb, 0xc6, 0x49, 0x18, 0xf4, 0xbf, 0x44, 0x18, 0x0f, 0x4a, 0xd6, + 0xd0, 0x8c, 0xf3, 0xf0, 0xf1, 0x11, 0x71, 0x1c, 0xf3, 0xad, 0xe4, 0x61, 0x88, 0xe3, 0x3b, 0xb9, + 0x50, 0x1c, 0xc7, 0x7c, 0x7b, 0xf9, 0x13, 0xc5, 0x70, 0x4e, 0x3a, 0xd9, 0x63, 0x1e, 0x96, 0x99, + 0x1c, 0x3a, 0xd3, 0x96, 0xf6, 0xf0, 0x86, 0x58, 0x56, 0xcd, 0x81, 0xfd, 0xa9, 0x26, 0x79, 0x13, + 0x86, 0x97, 0x6c, 0xd7, 0x5b, 0x75, 0xa8, 0xbb, 0x14, 0xa4, 0xaf, 0xc0, 0xf7, 0xe7, 0x1d, 0x01, + 0x6e, 0x74, 0x22, 0xb3, 0xbf, 0x4c, 0xae, 0xfe, 0x93, 0x42, 0x42, 0x1b, 0xb8, 0xe1, 0x7a, 0x2c, + 0xb5, 0xe1, 0x10, 0x86, 0x3a, 0xb9, 0x11, 0xae, 0x82, 0xdc, 0xc2, 0xef, 0x97, 0x62, 0x73, 0xae, + 0x08, 0x03, 0x3f, 0x4a, 0x42, 0x3e, 0x07, 0x17, 0x22, 0x80, 0x25, 0xdd, 0xd1, 0xdb, 0xd4, 0x0b, + 0x53, 0x85, 0x62, 0xb4, 0x35, 0xbf, 0x74, 0xa3, 0x13, 0xa0, 0xe5, 0xf4, 0xa3, 0x19, 0x1c, 0x24, + 0xd5, 0x1a, 0xd8, 0x83, 0x9f, 0xf6, 0xd7, 0x0a, 0xa1, 0xa1, 0x13, 0x8d, 0x9a, 0xac, 0x51, 0xb7, + 0xdb, 0xf2, 0x1e, 0xdf, 0x0e, 0xde, 0x5f, 0x4e, 0x9a, 0x59, 0x38, 0x55, 0x79, 0xf0, 0x80, 0x36, + 0x3d, 0x3f, 0x18, 0xbc, 0x2b, 0xe2, 0x64, 0xf2, 0x8d, 0x87, 0x40, 0x89, 0xe0, 0xde, 0x72, 0xbf, + 0xc6, 0x8b, 0xa9, 0xff, 0xb4, 0x08, 0x4a, 0x60, 0xf8, 0x07, 0xef, 0x15, 0x8f, 0x70, 0x91, 0xfd, + 0x50, 0xf4, 0x8a, 0x09, 0xa7, 0x43, 0x61, 0x88, 0x87, 0x62, 0x22, 0x79, 0x7d, 0x39, 0xce, 0x2c, + 0x24, 0xe4, 0x7b, 0x89, 0x4b, 0x62, 0x2f, 0x41, 0xc2, 0xf7, 0xa0, 0x0d, 0x97, 0xb3, 0xd0, 0x92, + 0x5c, 0xc9, 0x97, 0x73, 0x70, 0xd6, 0xef, 0x94, 0xc5, 0x15, 0x66, 0x54, 0x4f, 0xd9, 0x5d, 0x2b, + 0x78, 0x45, 0xf5, 0x7a, 0x76, 0x75, 0xbc, 0x93, 0x26, 0xd2, 0x0a, 0xf3, 0x96, 0x04, 0x11, 0x61, + 0x02, 0x85, 0xb0, 0x91, 0xa6, 0xd1, 0x44, 0x22, 0x2d, 0xb5, 0xde, 0x4b, 0xb7, 0xe0, 0x62, 0x26, + 0xcb, 0x9d, 0x8c, 0xd8, 0x7e, 0xd9, 0x88, 0xfd, 0xef, 0x72, 0xe1, 0x44, 0x14, 0x13, 0x12, 0x99, + 0x00, 0x08, 0x41, 0x62, 0x5b, 0x8b, 0x8f, 0xb4, 0x42, 0xa1, 0x69, 0x12, 0x05, 0x59, 0x84, 0x92, + 0x10, 0x0b, 0x4f, 0xcb, 0xfd, 0xf1, 0x1d, 0x7a, 0x61, 0x42, 0x96, 0x03, 0x6e, 0x59, 0xc5, 0x37, + 0x0b, 0x36, 0x97, 0x5e, 0x83, 0xe1, 0xfd, 0x7e, 0xd7, 0x97, 0x0b, 0x40, 0xe4, 0x3d, 0xe8, 0x11, + 0x1a, 0xe8, 0xc7, 0x78, 0x0a, 0xbb, 0x0a, 0x83, 0xec, 0x13, 0x30, 0x51, 0x8d, 0x14, 0x98, 0xba, + 0x2b, 0x60, 0x5a, 0x80, 0x0d, 0xa3, 0xc2, 0x0d, 0xa4, 0x47, 0x85, 0x53, 0x7f, 0xba, 0x00, 0xe7, + 0xe5, 0x0e, 0xa9, 0x52, 0xcc, 0x75, 0x71, 0xd2, 0x29, 0x1f, 0x60, 0xa7, 0xa8, 0x50, 0xe2, 0x5b, + 0x0f, 0x91, 0x74, 0x84, 0x1f, 0x0b, 0x21, 0x44, 0x13, 0x18, 0xf5, 0x7f, 0xce, 0xc3, 0x68, 0x60, + 0xde, 0xe9, 0x8e, 0xfb, 0x18, 0x77, 0xc7, 0x27, 0x61, 0x14, 0xe3, 0x7a, 0xb5, 0xa9, 0xc5, 0x63, + 0x5f, 0xf5, 0x4b, 0x59, 0x82, 0x7c, 0x84, 0x48, 0x08, 0x17, 0x21, 0x64, 0xda, 0xcf, 0x2d, 0x3f, + 0x29, 0xda, 0x1a, 0x37, 0xfb, 0x38, 0x5c, 0xfd, 0xeb, 0x05, 0x18, 0xf1, 0xa5, 0x3c, 0x69, 0x1e, + 0xd7, 0x7b, 0x9e, 0xa3, 0x15, 0xf2, 0x75, 0x80, 0x25, 0xdb, 0xf1, 0xf4, 0xd6, 0x42, 0xa8, 0xf9, + 0x78, 0x40, 0xda, 0x41, 0x28, 0x2f, 0x23, 0x91, 0xe0, 0xfa, 0x15, 0x9a, 0xd5, 0x7c, 0x62, 0xe2, + 0xeb, 0x57, 0x00, 0xd5, 0x24, 0x0a, 0xf5, 0xb7, 0xf2, 0x70, 0xca, 0xef, 0xa4, 0xe9, 0x47, 0xb4, + 0xd9, 0x7d, 0x9c, 0xe7, 0xa6, 0xa8, 0xb4, 0xfb, 0x77, 0x94, 0xb6, 0xfa, 0x7f, 0x4a, 0x13, 0xc9, + 0x54, 0xcb, 0x3e, 0x99, 0x48, 0xfe, 0x2c, 0x74, 0x5c, 0xfd, 0x91, 0x02, 0x9c, 0xf5, 0xa5, 0x3e, + 0xd3, 0xb5, 0xf0, 0x68, 0x61, 0x4a, 0x6f, 0xb5, 0x1e, 0xe7, 0xdd, 0xf8, 0xb0, 0x2f, 0x88, 0x45, + 0x11, 0x28, 0x53, 0x24, 0xe7, 0x7c, 0x20, 0xc0, 0x0d, 0xdb, 0x34, 0x34, 0x99, 0x88, 0xbc, 0x0d, + 0x23, 0xfe, 0xcf, 0x8a, 0xb3, 0xea, 0x6f, 0xc1, 0xf1, 0xa2, 0x20, 0x28, 0xa4, 0x3b, 0x91, 0xe8, + 0x1a, 0x91, 0x02, 0xea, 0x17, 0x07, 0xe0, 0xd2, 0x7d, 0xd3, 0x32, 0xec, 0x0d, 0xd7, 0xcf, 0xed, + 0x7a, 0xec, 0x0f, 0xca, 0x8e, 0x3a, 0xa7, 0xeb, 0x3b, 0x70, 0x2e, 0x2e, 0x52, 0x27, 0x88, 0xb8, + 0x2f, 0x7a, 0x67, 0x83, 0x13, 0x34, 0xfc, 0x2c, 0xaf, 0xe2, 0xb6, 0x4d, 0x4b, 0x2f, 0x19, 0x4f, + 0x13, 0x3b, 0xb0, 0x9b, 0x34, 0xb1, 0xcf, 0x41, 0xa9, 0x6a, 0xb7, 0x75, 0xd3, 0x8f, 0xb3, 0x84, + 0xa3, 0x38, 0xa8, 0x17, 0x31, 0x9a, 0xa0, 0x60, 0xfc, 0x45, 0xc5, 0xd8, 0x65, 0x43, 0x21, 0x7f, + 0xbf, 0x00, 0xb3, 0xd2, 0x34, 0x99, 0x88, 0xd8, 0x30, 0x2a, 0xaa, 0x13, 0x77, 0x63, 0x80, 0x9b, + 0xa7, 0x97, 0x7d, 0x19, 0x65, 0xab, 0xd5, 0x44, 0xa4, 0x1c, 0xdf, 0x46, 0xf1, 0xec, 0xb5, 0xe2, + 0x63, 0xf8, 0x2d, 0x99, 0x16, 0xe5, 0x2f, 0x09, 0x01, 0x27, 0x99, 0xe1, 0xa4, 0x10, 0x70, 0x96, + 0x91, 0x89, 0xc8, 0x34, 0x9c, 0xc6, 0xb8, 0xe8, 0xc1, 0x56, 0x8a, 0xa9, 0xc4, 0x08, 0x1a, 0x95, + 0x78, 0xe5, 0xc2, 0x43, 0xa9, 0xb3, 0x8f, 0x6b, 0x34, 0x05, 0x5a, 0x4b, 0x96, 0x20, 0x17, 0xa1, + 0xb0, 0x30, 0x57, 0xc1, 0xbb, 0x9a, 0x41, 0x9e, 0x93, 0xcc, 0x6a, 0xe9, 0x1a, 0x83, 0x5d, 0xfa, + 0x34, 0x90, 0xe4, 0xe7, 0xec, 0xe9, 0x3e, 0xe6, 0xbf, 0x94, 0xb6, 0x7c, 0xc7, 0xdd, 0xa3, 0xe6, + 0x30, 0x26, 0xc2, 0x48, 0x3a, 0xc0, 0xfe, 0x0f, 0x32, 0x1d, 0x60, 0xe9, 0x50, 0xd3, 0x01, 0xaa, + 0xbf, 0x9c, 0x83, 0xd3, 0x89, 0xdc, 0x01, 0xe4, 0x25, 0x00, 0x0e, 0x91, 0x62, 0xb4, 0x62, 0x08, + 0xa1, 0x30, 0x9f, 0x80, 0x58, 0x1e, 0x43, 0x32, 0x72, 0x1d, 0x06, 0xf9, 0x2f, 0x11, 0xa5, 0x2c, + 0x59, 0xa4, 0xdb, 0x35, 0x0d, 0x2d, 0x20, 0x0a, 0x6b, 0xc1, 0x1b, 0xc9, 0x42, 0x6a, 0x11, 0x6f, + 0xb3, 0x13, 0xd4, 0xc2, 0xc8, 0xd4, 0x9f, 0xcc, 0xc3, 0x48, 0xd0, 0xe0, 0x8a, 0x71, 0x54, 0x3a, + 0x57, 0x12, 0x69, 0x18, 0x0a, 0x3b, 0xa5, 0x61, 0x88, 0xcd, 0xb7, 0x22, 0xef, 0xc2, 0xe1, 0xbd, + 0xca, 0xfa, 0x4a, 0x1e, 0x4e, 0x05, 0xb5, 0x1e, 0xe1, 0xe5, 0xd7, 0x87, 0x48, 0x24, 0x5f, 0xce, + 0x81, 0x32, 0x69, 0xb6, 0x5a, 0xa6, 0xb5, 0x5a, 0xb3, 0x1e, 0xd8, 0x4e, 0x1b, 0x27, 0xc4, 0xa3, + 0x3b, 0xc2, 0x55, 0xff, 0x62, 0x0e, 0x4e, 0x8b, 0x06, 0x4d, 0xe9, 0x8e, 0x71, 0x74, 0xe7, 0x63, + 0xf1, 0x96, 0x1c, 0x9d, 0xbe, 0xa8, 0xdf, 0xcc, 0x03, 0xcc, 0xd9, 0xcd, 0xf5, 0x63, 0xfe, 0xa8, + 0xeb, 0x0d, 0x28, 0x71, 0xb7, 0x78, 0xa1, 0xb1, 0xa7, 0xc5, 0xe3, 0x25, 0xf6, 0x69, 0x1c, 0x31, + 0x39, 0x2e, 0xe6, 0xe3, 0x12, 0xf7, 0xac, 0x57, 0x72, 0x9a, 0x28, 0xc2, 0x2a, 0x65, 0x74, 0x62, + 0xc1, 0x08, 0x2a, 0x65, 0xb0, 0x68, 0xa5, 0xdb, 0x5b, 0xe5, 0x62, 0xcb, 0x6e, 0xae, 0x6b, 0x48, + 0xaf, 0xfe, 0xeb, 0x1c, 0x97, 0xdd, 0x31, 0x7f, 0x9a, 0xea, 0x7f, 0x7e, 0x71, 0x8f, 0x9f, 0xff, + 0x97, 0x72, 0x70, 0x56, 0xa3, 0x4d, 0xfb, 0x21, 0x75, 0x36, 0xa7, 0x6c, 0x83, 0xde, 0xa2, 0x16, + 0x75, 0x8e, 0x6a, 0x44, 0xfd, 0x36, 0xe6, 0xad, 0x09, 0x1b, 0x73, 0xd7, 0xa5, 0xc6, 0xf1, 0xc9, + 0x29, 0xa4, 0xfe, 0xea, 0x00, 0x28, 0xa9, 0x56, 0xef, 0xb1, 0x35, 0xe7, 0x32, 0xb7, 0x32, 0xc5, + 0xc3, 0xda, 0xca, 0xf4, 0xef, 0x6d, 0x2b, 0x53, 0xda, 0xeb, 0x56, 0x66, 0x60, 0x37, 0x5b, 0x99, + 0x76, 0x7c, 0x2b, 0x33, 0x88, 0x5b, 0x99, 0x97, 0x7a, 0x6e, 0x65, 0xa6, 0x2d, 0x63, 0x9f, 0x1b, + 0x99, 0x63, 0x9b, 0xef, 0x7a, 0x3f, 0x3b, 0xb0, 0xab, 0x6c, 0x52, 0x6c, 0xda, 0x8e, 0x41, 0x0d, + 0xb1, 0xf1, 0xc2, 0x53, 0x7f, 0x47, 0xc0, 0xb4, 0x00, 0x9b, 0x48, 0x1e, 0x3e, 0xba, 0x9b, 0xe4, + 0xe1, 0x87, 0xb0, 0xff, 0xfa, 0x52, 0x1e, 0x4e, 0x4f, 0x51, 0xc7, 0xe3, 0xb1, 0x68, 0x0f, 0xc3, + 0x25, 0xae, 0x02, 0xa7, 0x24, 0x86, 0x68, 0x91, 0xe7, 0x43, 0x37, 0xbf, 0x26, 0x75, 0xbc, 0xb8, + 0x97, 0x60, 0x9c, 0x9e, 0x55, 0xef, 0x27, 0xf0, 0x13, 0x63, 0x37, 0xa8, 0xde, 0x87, 0x73, 0x41, + 0x9a, 0xe2, 0x97, 0x16, 0xd0, 0x4b, 0x39, 0xf9, 0x8a, 0x7b, 0xcf, 0xc9, 0xa7, 0xfe, 0x52, 0x0e, + 0xae, 0x68, 0xd4, 0xa2, 0x1b, 0xfa, 0x4a, 0x8b, 0x4a, 0xcd, 0x12, 0x2b, 0x03, 0x9b, 0x35, 0x4c, + 0xb7, 0xad, 0x7b, 0xcd, 0xb5, 0x03, 0xc9, 0x68, 0x06, 0x46, 0xe4, 0xf9, 0x6b, 0x0f, 0x73, 0x5b, + 0xa4, 0x9c, 0xfa, 0xab, 0x45, 0x18, 0x98, 0xb4, 0xbd, 0xdb, 0xf6, 0x01, 0x93, 0x44, 0x86, 0x53, + 0x7e, 0x7e, 0x0f, 0x67, 0x3d, 0x9f, 0xc0, 0xca, 0xa5, 0xbc, 0x19, 0xe8, 0x42, 0xba, 0x62, 0x27, + 0xf2, 0x8b, 0xf8, 0x64, 0x7b, 0x4c, 0x0f, 0xf9, 0x0a, 0x0c, 0x61, 0x08, 0x19, 0xe9, 0x34, 0x16, + 0x1d, 0xb4, 0x3d, 0x06, 0x8c, 0xd7, 0x11, 0x92, 0x92, 0xcf, 0x45, 0x82, 0xe7, 0x96, 0x0e, 0x9e, + 0x4e, 0x52, 0x8e, 0xa3, 0xfb, 0x12, 0xbf, 0xc8, 0xc3, 0x36, 0x49, 0xa9, 0x77, 0xf0, 0x14, 0x25, + 0xd6, 0xa4, 0x80, 0xf0, 0x10, 0x53, 0x3d, 0x4e, 0xc1, 0xe8, 0xa4, 0xed, 0x49, 0xce, 0xc0, 0x43, + 0xe1, 0x5b, 0x52, 0x26, 0xf9, 0x74, 0x4f, 0xe0, 0x68, 0x19, 0xf5, 0x4f, 0x8b, 0x30, 0xe2, 0xff, + 0x3c, 0x22, 0xdd, 0x79, 0x01, 0x4a, 0xb3, 0xb6, 0x94, 0x7d, 0x04, 0x1d, 0x88, 0xd7, 0x6c, 0x37, + 0xe6, 0x19, 0x2d, 0x88, 0x98, 0xd4, 0x17, 0x6c, 0x43, 0x76, 0x7f, 0x47, 0xa9, 0x5b, 0xb6, 0x91, + 0x78, 0x83, 0x1c, 0x10, 0x92, 0x2b, 0x50, 0xc4, 0x97, 0x03, 0xd2, 0x41, 0x7e, 0xec, 0xb5, 0x00, + 0xe2, 0x25, 0xad, 0x2c, 0xed, 0x55, 0x2b, 0x07, 0xf6, 0xab, 0x95, 0x83, 0x87, 0xab, 0x95, 0xef, + 0xc2, 0x08, 0xd6, 0xe4, 0x27, 0x2f, 0xdc, 0x79, 0x61, 0xbd, 0x28, 0xd6, 0xbe, 0x51, 0xde, 0x6e, + 0x91, 0xc2, 0x10, 0x97, 0xbc, 0x08, 0xab, 0x98, 0xee, 0xc2, 0x01, 0xb6, 0xd3, 0xff, 0x24, 0x07, + 0x03, 0x77, 0xad, 0x75, 0xcb, 0xde, 0x38, 0x98, 0xc6, 0xbd, 0x04, 0xc3, 0x82, 0x8d, 0xb4, 0xba, + 0xe0, 0xb3, 0xf2, 0x2e, 0x07, 0x37, 0x90, 0x93, 0x26, 0x53, 0x91, 0x37, 0x83, 0x42, 0xf8, 0x38, + 0xa8, 0x10, 0xe6, 0xef, 0xf1, 0x0b, 0x35, 0xa3, 0x09, 0x3c, 0x64, 0x72, 0x72, 0x19, 0x8a, 0x55, + 0xd6, 0x54, 0x29, 0x90, 0x2f, 0x6b, 0x8a, 0x86, 0x50, 0xf5, 0x4b, 0x45, 0x18, 0x8b, 0x1d, 0x7c, + 0x3d, 0x07, 0x43, 0xe2, 0xe0, 0xc9, 0xf4, 0x33, 0x8a, 0xe0, 0xe3, 0xa1, 0x00, 0xa8, 0x0d, 0xf2, + 0x3f, 0x6b, 0x06, 0xf9, 0x14, 0x0c, 0xd8, 0x2e, 0x2e, 0x8a, 0xf8, 0x2d, 0x63, 0xe1, 0x10, 0x5a, + 0xac, 0xb3, 0xb6, 0xf3, 0xc1, 0x21, 0x48, 0x64, 0x8d, 0xb4, 0x5d, 0xfc, 0xb4, 0x9b, 0x30, 0xa4, + 0xbb, 0x2e, 0xf5, 0x1a, 0x9e, 0xbe, 0x2a, 0x27, 0x19, 0x09, 0x80, 0xf2, 0xe8, 0x40, 0xe0, 0xb2, + 0xbe, 0x4a, 0x3e, 0x0d, 0xa3, 0x4d, 0x87, 0xe2, 0xb2, 0xa9, 0xb7, 0x58, 0x2b, 0x25, 0xb3, 0x36, + 0x82, 0x90, 0xef, 0x4f, 0x42, 0x44, 0xcd, 0x20, 0xf7, 0x60, 0x54, 0x7c, 0x0e, 0xf7, 0xdc, 0xc7, + 0x81, 0x36, 0x16, 0x2e, 0x63, 0x5c, 0x24, 0xdc, 0x77, 0x5f, 0x3c, 0xe0, 0x90, 0xc9, 0x65, 0xbe, + 0x86, 0x44, 0x4a, 0x16, 0x81, 0x6c, 0xd0, 0x95, 0x86, 0xde, 0xf5, 0xd6, 0x58, 0x5d, 0x3c, 0x46, + 0xbe, 0xc8, 0x06, 0x8a, 0xaf, 0x1e, 0x92, 0x58, 0xf9, 0x31, 0xc8, 0x06, 0x5d, 0xa9, 0x44, 0x90, + 0xe4, 0x3e, 0x9c, 0x4b, 0x16, 0x61, 0x9f, 0xcc, 0x2f, 0x07, 0x9e, 0xdd, 0xde, 0x2a, 0x97, 0x53, + 0x09, 0x24, 0xb6, 0x67, 0x12, 0x6c, 0x6b, 0xc6, 0xed, 0xe2, 0xe0, 0xc0, 0xf8, 0xa0, 0x36, 0xc6, + 0xca, 0xfa, 0x26, 0xa4, 0x69, 0xa8, 0xbf, 0x9f, 0x63, 0xa6, 0x22, 0xfb, 0x20, 0x4c, 0x87, 0xce, + 0x74, 0xbd, 0xbd, 0x47, 0x5d, 0x6f, 0x87, 0x89, 0x4b, 0x4b, 0x6e, 0x8f, 0xd9, 0x55, 0x13, 0x58, + 0x32, 0x01, 0x25, 0x43, 0x3e, 0x35, 0x3b, 0x1f, 0xed, 0x04, 0xbf, 0x1e, 0x4d, 0x50, 0x91, 0xab, + 0x50, 0x64, 0x4b, 0x56, 0x7c, 0xcb, 0x2c, 0x5b, 0x17, 0x1a, 0x52, 0xa8, 0x3f, 0x9c, 0x87, 0x11, + 0xe9, 0x6b, 0x6e, 0x1c, 0xe8, 0x73, 0x5e, 0xdf, 0x5d, 0x33, 0x7d, 0xa7, 0x17, 0xdc, 0x4b, 0xf9, + 0x4d, 0xbe, 0x19, 0x88, 0x62, 0x57, 0x17, 0x52, 0x42, 0x30, 0xaf, 0x88, 0x0f, 0x2d, 0xed, 0x7e, + 0xfb, 0xc8, 0xe8, 0x6f, 0x17, 0x07, 0xf3, 0xe3, 0x85, 0xdb, 0xc5, 0xc1, 0xe2, 0x78, 0x3f, 0x06, + 0xf3, 0xc2, 0xf8, 0xd9, 0x7c, 0x6f, 0x6e, 0x3d, 0x30, 0x57, 0x8f, 0xf9, 0xdb, 0x91, 0xc3, 0x0d, + 0x74, 0x16, 0x93, 0xcd, 0x31, 0x7f, 0x48, 0xf2, 0x81, 0xca, 0xe6, 0x24, 0xd1, 0xa9, 0x90, 0xcd, + 0x3f, 0xcd, 0x81, 0x92, 0x2a, 0x9b, 0xca, 0x11, 0xf9, 0x41, 0x1c, 0x5e, 0xba, 0xd3, 0x3f, 0xce, + 0xc3, 0xe9, 0x9a, 0xe5, 0xd1, 0x55, 0xbe, 0x63, 0x3c, 0xe6, 0x53, 0xc5, 0x1d, 0x18, 0x96, 0x3e, + 0x46, 0xf4, 0xf9, 0x13, 0xc1, 0x7e, 0x3c, 0x44, 0x65, 0x70, 0x92, 0x4b, 0x1f, 0xde, 0x4b, 0x9c, + 0xb8, 0x90, 0x8f, 0xf9, 0x9c, 0x73, 0x3c, 0x84, 0x7c, 0xcc, 0x27, 0xaf, 0x0f, 0xa9, 0x90, 0xff, + 0x41, 0x1e, 0xce, 0xa4, 0x54, 0x4e, 0xae, 0xc0, 0x40, 0xbd, 0xbb, 0x82, 0xb1, 0xbb, 0x72, 0xa1, + 0xc7, 0xb0, 0xdb, 0x5d, 0xc1, 0xb0, 0x5d, 0x9a, 0x8f, 0x24, 0xcb, 0xf8, 0xb8, 0x7e, 0xb1, 0x56, + 0x9d, 0x12, 0x52, 0x55, 0xa5, 0x30, 0x01, 0x0c, 0x9c, 0xf6, 0x65, 0xc1, 0x03, 0x7c, 0xdb, 0x34, + 0x9a, 0xb1, 0x07, 0xf8, 0xac, 0x0c, 0xf9, 0x01, 0x18, 0xaa, 0xbc, 0xdf, 0x75, 0x28, 0xf2, 0xe5, + 0x12, 0xff, 0x48, 0xc0, 0xd7, 0x47, 0xa4, 0x71, 0xe6, 0xb1, 0x04, 0x18, 0x45, 0x9c, 0x77, 0xc8, + 0x90, 0x2c, 0x42, 0xe9, 0x96, 0xe9, 0xcd, 0x76, 0x57, 0x44, 0x2f, 0x04, 0xf1, 0xbd, 0x38, 0x34, + 0x8d, 0x2f, 0xee, 0xca, 0x79, 0x9c, 0x62, 0x79, 0x0f, 0xc4, 0x0b, 0xa8, 0x3f, 0x99, 0x83, 0x4b, + 0xd9, 0x9f, 0x4b, 0x3e, 0x01, 0x03, 0x6c, 0xab, 0x5f, 0xd1, 0x16, 0x84, 0x2c, 0x79, 0xae, 0x61, + 0xbb, 0x45, 0x1b, 0xba, 0x23, 0xef, 0x1e, 0x7c, 0x32, 0xf2, 0x16, 0x0c, 0xd7, 0x5c, 0xb7, 0x4b, + 0x9d, 0xfa, 0x4b, 0x77, 0xb5, 0x9a, 0xd8, 0x64, 0xe2, 0x26, 0xc6, 0x44, 0x70, 0xc3, 0x7d, 0x29, + 0x16, 0xee, 0x4b, 0xa6, 0x57, 0x7f, 0x2c, 0x07, 0x97, 0x7b, 0x89, 0x89, 0xbc, 0x04, 0x83, 0xcb, + 0xd4, 0xd2, 0x2d, 0xaf, 0x56, 0x15, 0x4d, 0xc2, 0x3d, 0x9b, 0x87, 0xb0, 0xe8, 0xd6, 0x23, 0x20, + 0x64, 0x85, 0xf8, 0x41, 0x65, 0xe0, 0x19, 0xc1, 0x0f, 0x55, 0x11, 0x16, 0x2b, 0xe4, 0x13, 0xaa, + 0x9f, 0x83, 0x8b, 0x99, 0x52, 0x25, 0x9f, 0x82, 0x91, 0x45, 0x67, 0x55, 0xb7, 0xcc, 0xf7, 0xf9, + 0xa0, 0xc8, 0x85, 0xfb, 0x62, 0x5b, 0x82, 0xcb, 0x7b, 0x35, 0x99, 0x5e, 0xfd, 0x83, 0x3c, 0x8c, + 0x2c, 0xb5, 0xba, 0xab, 0xa6, 0xb4, 0xcc, 0xed, 0x7b, 0x77, 0xe0, 0xdb, 0xea, 0xf9, 0xbd, 0xd9, + 0xea, 0x6c, 0x72, 0x70, 0xf6, 0x39, 0x39, 0xf8, 0xe5, 0xc8, 0x9b, 0x50, 0xea, 0xe0, 0x77, 0xc4, + 0xcf, 0x8d, 0xf9, 0xd7, 0x65, 0x9d, 0x1b, 0xf3, 0x32, 0x6c, 0x36, 0x68, 0x1e, 0x60, 0x36, 0x08, + 0xcb, 0x4a, 0x02, 0x0d, 0x97, 0xb4, 0x13, 0x81, 0x1e, 0x8a, 0x40, 0xc3, 0xe5, 0xeb, 0x44, 0xa0, + 0x07, 0x10, 0xe8, 0xaf, 0xe6, 0x61, 0x2c, 0x5a, 0x25, 0xf9, 0x04, 0x0c, 0xf3, 0x6a, 0xf8, 0x29, + 0x56, 0x4e, 0x72, 0x81, 0x0e, 0xc1, 0x1a, 0xf0, 0x1f, 0xe2, 0x38, 0xee, 0xd4, 0x9a, 0xee, 0x36, + 0xc2, 0xf3, 0x24, 0x7e, 0xdb, 0x3c, 0xc8, 0xfd, 0xb6, 0x62, 0x28, 0x6d, 0x6c, 0x4d, 0x77, 0xa7, + 0xc2, 0xdf, 0x64, 0x1a, 0x88, 0x43, 0xbb, 0x2e, 0x8d, 0x32, 0x28, 0x22, 0x03, 0x91, 0x45, 0x3e, + 0x8e, 0xd5, 0x4e, 0x73, 0x98, 0xcc, 0xe6, 0xf3, 0x41, 0xb3, 0x51, 0x19, 0xfa, 0x77, 0x91, 0xe2, + 0x5e, 0xa2, 0x4f, 0x3f, 0x94, 0xe5, 0x04, 0x55, 0xdd, 0xd3, 0xf9, 0x11, 0x82, 0xdf, 0x01, 0xea, + 0x4f, 0xb9, 0xd0, 0xbf, 0x68, 0xd1, 0xc5, 0x07, 0xe4, 0x45, 0x18, 0x62, 0x0a, 0x33, 0x67, 0xb3, + 0xbe, 0xcc, 0x09, 0x6f, 0x0f, 0x49, 0x93, 0x10, 0x31, 0xdb, 0xa7, 0x85, 0x54, 0xe4, 0x26, 0x40, + 0xf8, 0x20, 0x4e, 0x68, 0x1f, 0x91, 0xcb, 0x70, 0xcc, 0x6c, 0x9f, 0x26, 0xd1, 0xf9, 0xa5, 0xc4, + 0x73, 0xa2, 0x42, 0xb2, 0x14, 0xc7, 0xf8, 0xa5, 0xc4, 0xf8, 0x98, 0x03, 0xc2, 0x7e, 0x2d, 0xe9, + 0xae, 0xbb, 0x61, 0x3b, 0xc6, 0xd4, 0x9a, 0x6e, 0xad, 0xd2, 0xf8, 0x5e, 0x2f, 0x49, 0x31, 0xdb, + 0xa7, 0xa5, 0x94, 0x23, 0xaf, 0xc3, 0x88, 0xec, 0xfe, 0x1a, 0x77, 0x51, 0x91, 0x71, 0xb3, 0x7d, + 0x5a, 0x84, 0x96, 0xbc, 0x0a, 0xc3, 0xe2, 0xf7, 0x6d, 0x5b, 0xdc, 0x7f, 0x4b, 0x91, 0x93, 0x24, + 0xd4, 0x6c, 0x9f, 0x26, 0x53, 0x4a, 0x95, 0x2e, 0x39, 0xa6, 0xe5, 0x89, 0x17, 0xd5, 0xf1, 0x4a, + 0x11, 0x27, 0x55, 0x8a, 0xbf, 0xc9, 0x5b, 0x30, 0x1a, 0x84, 0xa4, 0x7a, 0x8f, 0x36, 0x3d, 0x71, + 0x54, 0x7f, 0x2e, 0x56, 0x98, 0x23, 0x67, 0xfb, 0xb4, 0x28, 0x35, 0xb9, 0x0a, 0x25, 0x8d, 0xba, + 0xe6, 0xfb, 0xfe, 0xe5, 0xf6, 0x98, 0x34, 0xce, 0xcd, 0xf7, 0x99, 0x94, 0x04, 0x9e, 0xf5, 0x4e, + 0x78, 0x9b, 0x2e, 0x0e, 0xd6, 0x49, 0xac, 0x96, 0x69, 0xcb, 0x60, 0xbd, 0x23, 0xb9, 0x52, 0x7c, + 0x3a, 0x0c, 0xd4, 0x25, 0xf2, 0xd4, 0x0e, 0xc7, 0x23, 0x22, 0xc8, 0xd8, 0xd9, 0x3e, 0x2d, 0x46, + 0x2f, 0x49, 0xb5, 0x6a, 0xba, 0xeb, 0x22, 0xc0, 0x6a, 0x5c, 0xaa, 0x0c, 0x25, 0x49, 0x95, 0xfd, + 0x94, 0xaa, 0x5e, 0xa0, 0xde, 0x86, 0xed, 0xac, 0x8b, 0x70, 0xaa, 0xf1, 0xaa, 0x05, 0x56, 0xaa, + 0x5a, 0x40, 0xe4, 0xaa, 0xd9, 0x80, 0x1b, 0x4b, 0xaf, 0x5a, 0xf7, 0x74, 0xb9, 0x6a, 0x7e, 0x6e, + 0xe8, 0x77, 0xd2, 0x1c, 0xd5, 0x1f, 0x52, 0xe5, 0x54, 0x6a, 0x87, 0x22, 0x4e, 0xea, 0x50, 0xfc, + 0xcd, 0x2a, 0x95, 0x92, 0xd8, 0x2b, 0xe3, 0xd1, 0x4a, 0x25, 0x14, 0xab, 0x54, 0x4e, 0x77, 0x7f, + 0x53, 0xce, 0x94, 0xae, 0x9c, 0x8e, 0x76, 0x50, 0x88, 0x61, 0x1d, 0x24, 0x65, 0x54, 0x2f, 0x63, + 0x16, 0x66, 0x85, 0x20, 0xf9, 0x70, 0xd0, 0xc2, 0xa9, 0xa5, 0xd9, 0x3e, 0x0d, 0xf3, 0x33, 0xab, + 0x3c, 0xbf, 0xb7, 0x72, 0x06, 0x29, 0x46, 0x7c, 0x0a, 0x06, 0x9b, 0xed, 0xd3, 0x78, 0xee, 0xef, + 0x17, 0xa5, 0x1c, 0x88, 0xca, 0xd9, 0xe8, 0x14, 0x11, 0x20, 0xd8, 0x14, 0x11, 0x66, 0x4a, 0x9c, + 0x49, 0x66, 0xfa, 0x53, 0xce, 0x45, 0x97, 0x9a, 0x38, 0x7e, 0xb6, 0x4f, 0x4b, 0x66, 0x07, 0x7c, + 0x35, 0x92, 0xfc, 0x4e, 0x39, 0x1f, 0x0b, 0x57, 0x16, 0xa2, 0x98, 0xb8, 0xe4, 0x34, 0x79, 0x8b, + 0x70, 0x86, 0xe7, 0xce, 0x15, 0x01, 0xc7, 0xc4, 0x64, 0x75, 0x21, 0xba, 0xcd, 0x4a, 0x21, 0x99, + 0xed, 0xd3, 0xd2, 0x4a, 0x92, 0xa9, 0x44, 0x0a, 0x3a, 0x45, 0x89, 0x7a, 0xf2, 0xc4, 0xd0, 0xb3, + 0x7d, 0x5a, 0x22, 0x69, 0xdd, 0x4d, 0x39, 0xf7, 0x9b, 0x72, 0x31, 0xda, 0x89, 0x21, 0x86, 0x75, + 0xa2, 0x94, 0x23, 0xee, 0xa6, 0x9c, 0x0f, 0x4c, 0xb9, 0x94, 0x2c, 0x15, 0xce, 0x9c, 0x52, 0xde, + 0x30, 0x2d, 0x3d, 0xc5, 0x91, 0xf2, 0x84, 0x48, 0x74, 0x2c, 0xca, 0xa7, 0xd1, 0xcc, 0xf6, 0x69, + 0xe9, 0xe9, 0x91, 0xb4, 0xf4, 0xdc, 0x40, 0xca, 0xe5, 0x5e, 0x3c, 0x83, 0xd6, 0xa5, 0xe7, 0x15, + 0xd2, 0x7b, 0x64, 0x6a, 0x51, 0x9e, 0x8c, 0x6e, 0xc8, 0x32, 0x09, 0x67, 0xfb, 0xb4, 0x1e, 0xf9, + 0x5e, 0xee, 0x66, 0xa4, 0x4d, 0x51, 0x9e, 0x8a, 0xe6, 0x39, 0x4f, 0x25, 0x9a, 0xed, 0xd3, 0x32, + 0x92, 0xae, 0xdc, 0xcd, 0xc8, 0xaa, 0xa1, 0x94, 0x7b, 0xb2, 0x0d, 0xe4, 0x91, 0x91, 0x93, 0x63, + 0x31, 0x35, 0x21, 0x85, 0xf2, 0x74, 0x54, 0x75, 0x53, 0x48, 0x98, 0xea, 0xa6, 0xa5, 0xb2, 0x58, + 0x4c, 0xcd, 0xa0, 0xa0, 0x3c, 0xd3, 0x83, 0x61, 0xd0, 0xc6, 0xd4, 0xdc, 0x0b, 0x8b, 0xa9, 0x29, + 0x0c, 0x14, 0x35, 0xca, 0x30, 0x85, 0x84, 0x31, 0x4c, 0x4b, 0x7e, 0xb0, 0x98, 0x1a, 0xe9, 0x5e, + 0x79, 0xb6, 0x07, 0xc3, 0xb0, 0x85, 0x69, 0x31, 0xf2, 0x5f, 0x8d, 0x84, 0x9a, 0x57, 0x3e, 0x12, + 0x9d, 0x37, 0x24, 0x14, 0x9b, 0x37, 0xe4, 0xa0, 0xf4, 0x53, 0x89, 0x38, 0xb8, 0xca, 0x47, 0xa3, + 0xc3, 0x3c, 0x86, 0x66, 0xc3, 0x3c, 0x1e, 0x39, 0x77, 0x2a, 0x11, 0x0f, 0x54, 0xb9, 0x92, 0xc5, + 0x04, 0xd1, 0x51, 0x26, 0x3c, 0x82, 0x68, 0x2d, 0x25, 0x20, 0xa5, 0xf2, 0xb1, 0xa8, 0x17, 0x7a, + 0x82, 0x60, 0xb6, 0x4f, 0x4b, 0x09, 0x63, 0xa9, 0xa5, 0x47, 0x5f, 0x52, 0xae, 0x46, 0x87, 0x6d, + 0x1a, 0x0d, 0x1b, 0xb6, 0xa9, 0x91, 0x9b, 0xe6, 0xd2, 0x9e, 0xca, 0x28, 0xd7, 0xa2, 0x86, 0x59, + 0x92, 0x82, 0x19, 0x66, 0x29, 0x4f, 0x6c, 0xb4, 0xf4, 0x88, 0x40, 0xca, 0x73, 0x3d, 0x5b, 0x88, + 0x34, 0x29, 0x2d, 0xe4, 0x01, 0x72, 0x42, 0xdb, 0xe9, 0x6e, 0xa7, 0x65, 0xeb, 0x86, 0xf2, 0xf1, + 0x54, 0xdb, 0x89, 0x23, 0x25, 0xdb, 0x89, 0x03, 0xd8, 0x2a, 0x2f, 0xbf, 0xc8, 0x50, 0x9e, 0x8f, + 0xae, 0xf2, 0x32, 0x8e, 0xad, 0xf2, 0x91, 0xd7, 0x1b, 0x53, 0x89, 0xd7, 0x0b, 0xca, 0x0b, 0x51, + 0x05, 0x88, 0xa1, 0x99, 0x02, 0xc4, 0xdf, 0x3b, 0x7c, 0x21, 0xdb, 0xdf, 0x5f, 0x99, 0x40, 0x6e, + 0x4f, 0xfb, 0xdc, 0xb2, 0xe8, 0x66, 0xfb, 0xb4, 0xec, 0x37, 0x03, 0xb5, 0x14, 0xf7, 0x7d, 0xe5, + 0x7a, 0x54, 0xc1, 0x12, 0x04, 0x4c, 0xc1, 0x92, 0x4e, 0xff, 0xb5, 0x14, 0xff, 0x7b, 0xe5, 0x13, + 0x99, 0xac, 0x82, 0x6f, 0x4e, 0xf1, 0xda, 0xbf, 0x29, 0x3b, 0xd0, 0x2b, 0x2f, 0x46, 0x17, 0xbb, + 0x10, 0xc3, 0x16, 0x3b, 0xc9, 0xd1, 0xfe, 0xa6, 0xec, 0x3a, 0xae, 0xdc, 0x48, 0x96, 0x0a, 0x97, + 0x48, 0xc9, 0xc5, 0x5c, 0x4b, 0xf7, 0xb8, 0x56, 0x5e, 0x8a, 0x6a, 0x5d, 0x1a, 0x0d, 0xd3, 0xba, + 0x54, 0x6f, 0xed, 0x99, 0xa4, 0xe3, 0xb4, 0x72, 0x33, 0xbe, 0xc9, 0x8e, 0xe2, 0x99, 0xe5, 0x93, + 0x70, 0xb6, 0xfe, 0x74, 0x3c, 0x34, 0xa0, 0xf2, 0x72, 0xec, 0x92, 0x3a, 0x82, 0x65, 0xf6, 0x6d, + 0x2c, 0x94, 0xe0, 0xa7, 0xe3, 0xd1, 0xf4, 0x94, 0x57, 0xd2, 0x39, 0x04, 0xba, 0x12, 0x8f, 0xbe, + 0xf7, 0xe9, 0x78, 0x00, 0x3a, 0xe5, 0xd5, 0x74, 0x0e, 0x81, 0x74, 0xe3, 0x01, 0xeb, 0x5e, 0x94, + 0x42, 0xe2, 0x2b, 0x9f, 0x8c, 0x9a, 0x8e, 0x01, 0x82, 0x99, 0x8e, 0x61, 0xe0, 0xfc, 0x17, 0xa5, + 0x50, 0xf2, 0xca, 0x6b, 0x89, 0x22, 0x41, 0x63, 0xa5, 0x80, 0xf3, 0x2f, 0x4a, 0x21, 0xd8, 0x95, + 0xd7, 0x13, 0x45, 0x82, 0xd6, 0x49, 0x81, 0xda, 0x8d, 0x5e, 0xaf, 0x6d, 0x95, 0x37, 0xa2, 0x47, + 0xd7, 0xd9, 0x94, 0xb3, 0x7d, 0x5a, 0xaf, 0x57, 0xbb, 0x5f, 0xc8, 0x76, 0x43, 0x57, 0xde, 0x8c, + 0x0e, 0xe1, 0x2c, 0x3a, 0x36, 0x84, 0x33, 0x5d, 0xd9, 0xdf, 0x8a, 0x45, 0xde, 0x50, 0xde, 0x8a, + 0x4e, 0x71, 0x11, 0x24, 0x9b, 0xe2, 0xe2, 0x71, 0x3a, 0x22, 0x21, 0x25, 0x94, 0x4f, 0x45, 0xa7, + 0x38, 0x19, 0xc7, 0xa6, 0xb8, 0x48, 0xf8, 0x89, 0xa9, 0x44, 0xa4, 0x03, 0xe5, 0xed, 0xe8, 0x14, + 0x17, 0x43, 0xb3, 0x29, 0x2e, 0x1e, 0x1b, 0xe1, 0xad, 0xd8, 0x83, 0x7f, 0xe5, 0xd3, 0xe9, 0xed, + 0x47, 0xa4, 0xdc, 0x7e, 0x1e, 0x1e, 0x40, 0x4b, 0x7f, 0xb9, 0xae, 0x54, 0xa2, 0xe3, 0x37, 0x8d, + 0x86, 0x8d, 0xdf, 0xd4, 0x57, 0xef, 0xf1, 0x8d, 0x83, 0xd0, 0xaa, 0xc9, 0x1e, 0x1b, 0x87, 0xd0, + 0x14, 0x49, 0x01, 0x47, 0xf6, 0xc8, 0x7c, 0x23, 0x34, 0x95, 0xb1, 0x47, 0xf6, 0xb7, 0x41, 0x31, + 0x7a, 0x36, 0xbb, 0x26, 0xbc, 0xa2, 0x95, 0x6a, 0x74, 0x76, 0x4d, 0x10, 0xb0, 0xd9, 0x35, 0xe9, + 0x4b, 0x3d, 0x03, 0xe3, 0x42, 0x8b, 0xb8, 0xb3, 0xb7, 0x69, 0xad, 0x2a, 0xd3, 0xb1, 0xd7, 0xa1, + 0x31, 0x3c, 0x9b, 0x9d, 0xe2, 0x30, 0x5c, 0xaf, 0x39, 0x6c, 0xaa, 0x65, 0x76, 0x56, 0x6c, 0xdd, + 0x31, 0xea, 0xd4, 0x32, 0x94, 0x99, 0xd8, 0x7a, 0x9d, 0x42, 0x83, 0xeb, 0x75, 0x0a, 0x1c, 0x03, + 0xda, 0xc5, 0xe0, 0x1a, 0x6d, 0x52, 0xf3, 0x21, 0x55, 0x6e, 0x21, 0xdb, 0x72, 0x16, 0x5b, 0x41, + 0x36, 0xdb, 0xa7, 0x65, 0x71, 0x60, 0xb6, 0xfa, 0xfc, 0x66, 0xfd, 0x9d, 0xb9, 0x20, 0x58, 0xc2, + 0x92, 0x43, 0x3b, 0xba, 0x43, 0x95, 0xd9, 0xa8, 0xad, 0x9e, 0x4a, 0xc4, 0x6c, 0xf5, 0x54, 0x44, + 0x92, 0xad, 0x3f, 0x16, 0x6a, 0xbd, 0xd8, 0x86, 0x23, 0x22, 0xbd, 0x34, 0x9b, 0x9d, 0xa2, 0x08, + 0x26, 0xa0, 0x39, 0xdb, 0x5a, 0xc5, 0x93, 0x8a, 0xdb, 0xd1, 0xd9, 0x29, 0x9b, 0x92, 0xcd, 0x4e, + 0xd9, 0x58, 0xa6, 0xea, 0x51, 0x2c, 0x1f, 0x83, 0x77, 0xa2, 0xaa, 0x9e, 0x42, 0xc2, 0x54, 0x3d, + 0x05, 0x9c, 0x64, 0xa8, 0x51, 0x97, 0x7a, 0xca, 0x5c, 0x2f, 0x86, 0x48, 0x92, 0x64, 0x88, 0xe0, + 0x24, 0xc3, 0x19, 0xea, 0x35, 0xd7, 0x94, 0xf9, 0x5e, 0x0c, 0x91, 0x24, 0xc9, 0x10, 0xc1, 0x6c, + 0xb3, 0x19, 0x05, 0x4f, 0x76, 0x5b, 0xeb, 0x7e, 0x9f, 0x2d, 0x44, 0x37, 0x9b, 0x99, 0x84, 0x6c, + 0xb3, 0x99, 0x89, 0x24, 0x3f, 0xb6, 0x6b, 0xaf, 0x7d, 0x65, 0x11, 0x2b, 0x9c, 0x08, 0xed, 0x82, + 0xdd, 0x94, 0x9a, 0xed, 0xd3, 0x76, 0xfb, 0x2a, 0xe0, 0xe3, 0x81, 0x8b, 0xab, 0xb2, 0x84, 0x55, + 0x9d, 0x0a, 0xce, 0x2a, 0x38, 0x78, 0xb6, 0x4f, 0x0b, 0x9c, 0x60, 0x5f, 0x85, 0x61, 0xfc, 0xa8, + 0x9a, 0x65, 0x7a, 0xd5, 0x49, 0xe5, 0x9d, 0xe8, 0x96, 0x49, 0x42, 0xb1, 0x2d, 0x93, 0xf4, 0x93, + 0x4d, 0xe2, 0xf8, 0x93, 0x4f, 0x31, 0xd5, 0x49, 0x45, 0x8b, 0x4e, 0xe2, 0x11, 0x24, 0x9b, 0xc4, + 0x23, 0x80, 0xa0, 0xde, 0xaa, 0x63, 0x77, 0xaa, 0x93, 0x4a, 0x3d, 0xa5, 0x5e, 0x8e, 0x0a, 0xea, + 0xe5, 0x3f, 0x83, 0x7a, 0xeb, 0x6b, 0x5d, 0xaf, 0xca, 0xbe, 0x71, 0x39, 0xa5, 0x5e, 0x1f, 0x19, + 0xd4, 0xeb, 0x03, 0xd8, 0x54, 0x88, 0x80, 0x25, 0xc7, 0x66, 0x93, 0xf6, 0x1d, 0xb3, 0xd5, 0x52, + 0xee, 0x46, 0xa7, 0xc2, 0x38, 0x9e, 0x4d, 0x85, 0x71, 0x18, 0x33, 0x3d, 0x79, 0xab, 0xe8, 0x4a, + 0x77, 0x55, 0xb9, 0x17, 0x35, 0x3d, 0x43, 0x0c, 0x33, 0x3d, 0xc3, 0x5f, 0xb8, 0xbb, 0x60, 0xbf, + 0x34, 0xfa, 0xc0, 0xa1, 0xee, 0x9a, 0x72, 0x3f, 0xb6, 0xbb, 0x90, 0x70, 0xb8, 0xbb, 0x90, 0x7e, + 0x93, 0x55, 0x78, 0x22, 0xb2, 0xd0, 0xf8, 0x97, 0x36, 0x75, 0xaa, 0x3b, 0xcd, 0x35, 0xe5, 0x33, + 0xc8, 0xea, 0xd9, 0xd4, 0xa5, 0x2a, 0x4a, 0x3a, 0xdb, 0xa7, 0xf5, 0xe2, 0x84, 0xdb, 0xf2, 0x77, + 0xe6, 0x78, 0xdc, 0x5a, 0x6d, 0x69, 0xca, 0xdf, 0x84, 0xbe, 0x1b, 0xdb, 0x96, 0x27, 0x49, 0x70, + 0x5b, 0x9e, 0x04, 0x93, 0x0e, 0x3c, 0x15, 0xdb, 0xaa, 0xcd, 0xeb, 0x2d, 0xb6, 0x2f, 0xa1, 0xc6, + 0x92, 0xde, 0x5c, 0xa7, 0x9e, 0xf2, 0x59, 0xe4, 0x7d, 0x25, 0x63, 0xc3, 0x17, 0xa3, 0x9e, 0xed, + 0xd3, 0x76, 0xe0, 0x47, 0x54, 0x28, 0xd6, 0x67, 0x96, 0x97, 0x94, 0xcf, 0x45, 0xcf, 0x37, 0x19, + 0x6c, 0xb6, 0x4f, 0x43, 0x1c, 0xb3, 0xd2, 0xee, 0x76, 0x56, 0x1d, 0xdd, 0xa0, 0xdc, 0xd0, 0x42, + 0xdb, 0x4d, 0x18, 0xa0, 0x3f, 0x10, 0xb5, 0xd2, 0xb2, 0xe8, 0x98, 0x95, 0x96, 0x85, 0x63, 0x8a, + 0x1a, 0x49, 0xd1, 0xa2, 0x7c, 0x3e, 0xaa, 0xa8, 0x11, 0x24, 0x53, 0xd4, 0x68, 0x42, 0x97, 0xcf, + 0xc0, 0xf9, 0x60, 0x3f, 0x2f, 0xd6, 0x5f, 0xde, 0x69, 0xca, 0x17, 0x90, 0xcf, 0x53, 0x89, 0xcb, + 0x80, 0x08, 0xd5, 0x6c, 0x9f, 0x96, 0x51, 0x9e, 0xad, 0xb8, 0x89, 0x14, 0x66, 0xc2, 0xbc, 0xf8, + 0xc1, 0xe8, 0x8a, 0x9b, 0x41, 0xc6, 0x56, 0xdc, 0x0c, 0x54, 0x2a, 0x73, 0x21, 0x54, 0x7d, 0x07, + 0xe6, 0x81, 0x4c, 0xb3, 0x38, 0xa4, 0x32, 0x17, 0x96, 0xda, 0xca, 0x0e, 0xcc, 0x03, 0x6b, 0x2d, + 0x8b, 0x03, 0xb9, 0x0a, 0xa5, 0x7a, 0x7d, 0x5e, 0xeb, 0x5a, 0x4a, 0x33, 0xe6, 0xdb, 0x8b, 0xd0, + 0xd9, 0x3e, 0x4d, 0xe0, 0x99, 0x19, 0x34, 0xdd, 0xd2, 0x5d, 0xcf, 0x6c, 0xba, 0x38, 0x62, 0xfc, + 0x11, 0x62, 0x44, 0xcd, 0xa0, 0x34, 0x1a, 0x66, 0x06, 0xa5, 0xc1, 0x99, 0xbd, 0x38, 0xa5, 0xbb, + 0xae, 0x6e, 0x19, 0x8e, 0x3e, 0x89, 0xcb, 0x04, 0x8d, 0xbd, 0x1d, 0x8b, 0x60, 0x99, 0xbd, 0x18, + 0x85, 0xe0, 0xe1, 0xbb, 0x0f, 0xf1, 0xcd, 0x9c, 0x07, 0xb1, 0xc3, 0xf7, 0x18, 0x1e, 0x0f, 0xdf, + 0x63, 0x30, 0xb4, 0x3b, 0x7d, 0x98, 0x46, 0x57, 0x4d, 0x26, 0x22, 0x65, 0x35, 0x66, 0x77, 0xc6, + 0x09, 0xd0, 0xee, 0x8c, 0x03, 0x23, 0x4d, 0xf2, 0x97, 0xdb, 0xb5, 0x8c, 0x26, 0x85, 0xab, 0x6c, + 0xa2, 0x0c, 0x5b, 0xbf, 0xc3, 0xc1, 0x51, 0xdd, 0xb4, 0xf4, 0xb6, 0x5d, 0x9d, 0xf4, 0xa5, 0x6e, + 0x46, 0xd7, 0xef, 0x4c, 0x42, 0xb6, 0x7e, 0x67, 0x22, 0xd9, 0xec, 0xea, 0x6f, 0xb4, 0xd6, 0x74, + 0x87, 0x1a, 0x55, 0xd3, 0xc1, 0x93, 0xc5, 0x4d, 0xbe, 0x35, 0x7c, 0x2f, 0x3a, 0xbb, 0xf6, 0x20, + 0x65, 0xb3, 0x6b, 0x0f, 0x34, 0x33, 0xf2, 0xd2, 0xd1, 0x1a, 0xd5, 0x0d, 0x65, 0x3d, 0x6a, 0xe4, + 0x65, 0x53, 0x32, 0x23, 0x2f, 0x1b, 0x9b, 0xfd, 0x39, 0xf7, 0x1d, 0xd3, 0xa3, 0x4a, 0x6b, 0x37, + 0x9f, 0x83, 0xa4, 0xd9, 0x9f, 0x83, 0x68, 0xb6, 0x21, 0x8c, 0x77, 0x48, 0x3b, 0xba, 0x21, 0x4c, + 0x76, 0x43, 0xbc, 0x04, 0xb3, 0x58, 0xc4, 0x13, 0x42, 0xc5, 0x8a, 0x5a, 0x2c, 0x02, 0xcc, 0x2c, + 0x96, 0xf0, 0x91, 0x61, 0xe4, 0xe1, 0x98, 0x62, 0x47, 0xd7, 0x50, 0x19, 0xc7, 0xd6, 0xd0, 0xc8, + 0x23, 0xb3, 0x57, 0x23, 0xaf, 0x22, 0x94, 0x4e, 0xd4, 0xea, 0x90, 0x50, 0xcc, 0xea, 0x90, 0xdf, + 0x4f, 0x4c, 0xc1, 0x29, 0xbc, 0x05, 0xd7, 0xba, 0xc1, 0x3d, 0xce, 0x0f, 0x45, 0x3f, 0x33, 0x86, + 0x66, 0x9f, 0x19, 0x03, 0x45, 0x98, 0x88, 0x69, 0xcb, 0xc9, 0x60, 0x12, 0x9e, 0x0f, 0xc6, 0x40, + 0x64, 0x0e, 0x48, 0xbd, 0x32, 0x3f, 0x57, 0x33, 0x96, 0xe4, 0x2b, 0x32, 0x37, 0x7a, 0x02, 0x9b, + 0xa4, 0x98, 0xed, 0xd3, 0x52, 0xca, 0x91, 0xf7, 0xe0, 0xb2, 0x80, 0x8a, 0xf7, 0xe1, 0x4b, 0x8e, + 0xfd, 0xd0, 0x34, 0x82, 0x05, 0xc1, 0x8b, 0x7a, 0xdd, 0xf5, 0xa2, 0x9d, 0xed, 0xd3, 0x7a, 0xf2, + 0xca, 0xae, 0x4b, 0xac, 0x0f, 0xdd, 0xdd, 0xd4, 0x15, 0x2c, 0x12, 0x3d, 0x79, 0x65, 0xd7, 0x25, + 0xe4, 0xfe, 0x70, 0x37, 0x75, 0x05, 0x9d, 0xd0, 0x93, 0x17, 0x71, 0xa1, 0xdc, 0x0b, 0x5f, 0x69, + 0xb5, 0x94, 0x0d, 0xac, 0xee, 0x63, 0xbb, 0xa9, 0xae, 0x82, 0x06, 0xe7, 0x4e, 0x1c, 0xd9, 0x2c, + 0xbd, 0xd8, 0xa1, 0x56, 0x3d, 0xb2, 0x00, 0x3d, 0x8a, 0xce, 0xd2, 0x09, 0x02, 0x36, 0x4b, 0x27, + 0x80, 0x6c, 0x40, 0xc9, 0x8f, 0x6b, 0x94, 0xcd, 0xe8, 0x80, 0x92, 0x71, 0x6c, 0x40, 0x45, 0x1e, + 0xe2, 0x2c, 0xc2, 0x99, 0xc5, 0x75, 0x4f, 0xf7, 0x2d, 0x48, 0x57, 0x74, 0xe5, 0xfb, 0xb1, 0x4b, + 0xa6, 0x24, 0x09, 0x5e, 0x32, 0x25, 0xc1, 0x6c, 0x8c, 0x30, 0x70, 0x7d, 0xd3, 0x6a, 0xce, 0xe8, + 0x66, 0xab, 0xeb, 0x50, 0xe5, 0xcf, 0x45, 0xc7, 0x48, 0x0c, 0xcd, 0xc6, 0x48, 0x0c, 0xc4, 0x16, + 0x68, 0x06, 0xaa, 0xb8, 0xae, 0xb9, 0x6a, 0x89, 0x7d, 0x65, 0xb7, 0xe5, 0x29, 0xff, 0x46, 0x74, + 0x81, 0x4e, 0xa3, 0x61, 0x0b, 0x74, 0x1a, 0x1c, 0x4f, 0x9d, 0x58, 0x2f, 0xb0, 0xc5, 0x43, 0xbe, + 0xab, 0xfc, 0x37, 0x63, 0xa7, 0x4e, 0x29, 0x34, 0x78, 0xea, 0x94, 0x02, 0x67, 0xeb, 0x23, 0xb7, + 0xc9, 0xe6, 0xcc, 0xe0, 0xae, 0xfa, 0xdf, 0x8a, 0xae, 0x8f, 0x71, 0x3c, 0x5b, 0x1f, 0xe3, 0xb0, + 0x28, 0x1f, 0xd1, 0x05, 0xff, 0x76, 0x16, 0x9f, 0x40, 0xfe, 0x89, 0x32, 0xe4, 0x96, 0xcc, 0x47, + 0x8c, 0x94, 0x1f, 0xce, 0x65, 0x31, 0x0a, 0x86, 0x47, 0xa2, 0x50, 0x94, 0x91, 0x46, 0x1f, 0x9a, + 0x74, 0x43, 0xf9, 0x62, 0x26, 0x23, 0x4e, 0x10, 0x65, 0xc4, 0x61, 0xe4, 0x5d, 0x38, 0x1f, 0xc2, + 0xe6, 0x69, 0x7b, 0x25, 0x98, 0x99, 0xfe, 0x7c, 0x2e, 0x6a, 0x06, 0xa7, 0x93, 0x31, 0x33, 0x38, + 0x1d, 0x93, 0xc6, 0x5a, 0x88, 0xee, 0xdf, 0xd9, 0x81, 0x75, 0x20, 0xc1, 0x0c, 0x06, 0x69, 0xac, + 0x85, 0x34, 0x7f, 0x64, 0x07, 0xd6, 0x81, 0x4c, 0x33, 0x18, 0x90, 0x1f, 0xcf, 0xc1, 0x95, 0x74, + 0x54, 0xa5, 0xd5, 0x9a, 0xb1, 0x9d, 0x10, 0xa7, 0xfc, 0x85, 0x5c, 0xf4, 0xa0, 0x61, 0x77, 0xc5, + 0x66, 0xfb, 0xb4, 0x5d, 0x56, 0x40, 0x3e, 0x05, 0xa3, 0x95, 0xae, 0x61, 0x7a, 0x78, 0xf1, 0xc6, + 0x0c, 0xe7, 0x1f, 0xcd, 0xc5, 0xb6, 0x38, 0x32, 0x16, 0xb7, 0x38, 0x32, 0x80, 0xdc, 0x86, 0xd3, + 0x75, 0xda, 0xec, 0x3a, 0xa6, 0xb7, 0xa9, 0xd1, 0x8e, 0xed, 0x78, 0x8c, 0xc7, 0x5f, 0xcc, 0x45, + 0x27, 0xb1, 0x04, 0x05, 0x9b, 0xc4, 0x12, 0x40, 0x72, 0x2f, 0x71, 0x2b, 0x2f, 0x3a, 0xf3, 0xc7, + 0x72, 0x3d, 0xaf, 0xe5, 0x83, 0xbe, 0x4c, 0x2f, 0x4e, 0x96, 0x62, 0xb7, 0xe8, 0x82, 0xeb, 0x8f, + 0xe7, 0x7a, 0x5c, 0xa3, 0x4b, 0x33, 0x5c, 0x12, 0xcc, 0x38, 0xa6, 0x24, 0xbd, 0x57, 0xfe, 0x52, + 0xae, 0xc7, 0xb5, 0x77, 0xc8, 0x31, 0x2d, 0x5f, 0xfe, 0xcb, 0xdc, 0x53, 0x44, 0x30, 0xfa, 0x89, + 0x5c, 0xd2, 0x55, 0x24, 0x28, 0x2f, 0x11, 0xb2, 0x62, 0x77, 0xdd, 0x40, 0xe9, 0xbf, 0x94, 0x4b, + 0xfa, 0xe6, 0x85, 0xc5, 0xc2, 0x5f, 0x84, 0xc2, 0xa5, 0xe9, 0x47, 0x1e, 0x75, 0x2c, 0xbd, 0x85, + 0xdd, 0x59, 0xf7, 0x6c, 0x47, 0x5f, 0xa5, 0xd3, 0x96, 0xbe, 0xd2, 0xa2, 0xca, 0x4f, 0xe6, 0xa2, + 0x16, 0x6c, 0x36, 0x29, 0xb3, 0x60, 0xb3, 0xb1, 0x64, 0x0d, 0x9e, 0x48, 0xc3, 0x56, 0x4d, 0x17, + 0xeb, 0xf9, 0x72, 0x2e, 0x6a, 0xc2, 0xf6, 0xa0, 0x65, 0x26, 0x6c, 0x0f, 0x34, 0xb9, 0x01, 0x43, + 0x93, 0xb6, 0x3f, 0xfd, 0xfe, 0xe5, 0x98, 0x33, 0x64, 0x80, 0x99, 0xed, 0xd3, 0x42, 0x32, 0x51, + 0x46, 0x0c, 0xea, 0xaf, 0x24, 0xcb, 0x84, 0x97, 0x4f, 0xc1, 0x0f, 0x51, 0x46, 0x88, 0xfb, 0xdf, + 0x4d, 0x96, 0x09, 0xef, 0xb8, 0x82, 0x1f, 0x6c, 0x26, 0xe1, 0x35, 0xce, 0xcf, 0x54, 0x98, 0xdd, + 0x36, 0xb5, 0xa6, 0xb7, 0x5a, 0xd4, 0x5a, 0xa5, 0xca, 0x57, 0x63, 0x33, 0x49, 0x3a, 0x19, 0x9b, + 0x49, 0xd2, 0x31, 0xe4, 0x07, 0xe0, 0xc2, 0x3d, 0xbd, 0x65, 0x1a, 0x21, 0xce, 0x4f, 0x81, 0xae, + 0xfc, 0x54, 0x2e, 0xba, 0x9b, 0xce, 0xa0, 0x63, 0xbb, 0xe9, 0x0c, 0x14, 0x99, 0x07, 0x82, 0xcb, + 0x68, 0x30, 0x5b, 0xb0, 0xf5, 0x59, 0xf9, 0xf7, 0x72, 0x51, 0x3b, 0x35, 0x49, 0xc2, 0xec, 0xd4, + 0x24, 0x94, 0x34, 0xb2, 0x13, 0x99, 0x28, 0x3f, 0x9d, 0x8b, 0x9e, 0xd6, 0x64, 0x11, 0xce, 0xf6, + 0x69, 0xd9, 0xd9, 0x50, 0x6e, 0xc1, 0x78, 0x7d, 0xa9, 0x36, 0x33, 0x33, 0x5d, 0xbf, 0x57, 0xab, + 0xe2, 0x2b, 0x0a, 0x43, 0xf9, 0x99, 0xd8, 0x8a, 0x15, 0x27, 0x60, 0x2b, 0x56, 0x1c, 0x46, 0xde, + 0x80, 0x11, 0xd6, 0x7e, 0x36, 0x60, 0xf0, 0x93, 0xbf, 0x96, 0x8b, 0x9a, 0x53, 0x32, 0x92, 0x99, + 0x53, 0xf2, 0x6f, 0x52, 0x87, 0xb3, 0x4c, 0x8a, 0x4b, 0x0e, 0x7d, 0x40, 0x1d, 0x6a, 0x35, 0xfd, + 0x31, 0xfd, 0xb3, 0xb9, 0xa8, 0x95, 0x91, 0x46, 0xc4, 0xac, 0x8c, 0x34, 0x38, 0x59, 0x87, 0xcb, + 0xf1, 0x93, 0x20, 0xf9, 0x91, 0xac, 0xf2, 0x57, 0x72, 0x31, 0x63, 0xb8, 0x07, 0x31, 0x1a, 0xc3, + 0x3d, 0xf0, 0xc4, 0x82, 0x27, 0xc5, 0xb1, 0x8a, 0x70, 0xb8, 0x8c, 0xd7, 0xf6, 0x73, 0xbc, 0xb6, + 0x8f, 0x86, 0x0e, 0x81, 0x3d, 0xa8, 0x67, 0xfb, 0xb4, 0xde, 0xec, 0x98, 0x9e, 0x25, 0xd3, 0x75, + 0x28, 0x7f, 0x35, 0x97, 0xee, 0x91, 0x12, 0x71, 0x53, 0x4e, 0xcb, 0xf3, 0xf1, 0x6e, 0x56, 0xb2, + 0x09, 0xe5, 0xaf, 0xc5, 0xc6, 0x5b, 0x3a, 0x19, 0x1b, 0x6f, 0x19, 0xd9, 0x2a, 0x6e, 0xc3, 0x69, + 0xae, 0xd4, 0x4b, 0x3a, 0x0e, 0x43, 0x6b, 0x95, 0x1a, 0xca, 0xbf, 0x1f, 0x5b, 0xed, 0x12, 0x14, + 0xe8, 0xda, 0x13, 0x07, 0xb2, 0xa9, 0xbb, 0xde, 0xd1, 0x2d, 0x0b, 0x8f, 0x59, 0x95, 0xff, 0x20, + 0x36, 0x75, 0x87, 0x28, 0x74, 0xdc, 0x0d, 0x7e, 0x31, 0x4d, 0xe8, 0x95, 0xa8, 0x49, 0xf9, 0x0f, + 0x63, 0x9a, 0xd0, 0x8b, 0x98, 0x69, 0x42, 0xcf, 0xac, 0x4f, 0xf7, 0x32, 0x1e, 0xac, 0x2b, 0x5f, + 0x8f, 0xad, 0xc8, 0xa9, 0x54, 0x6c, 0x45, 0x4e, 0x7f, 0xef, 0x7e, 0x2f, 0xe3, 0xb1, 0xb7, 0xf2, + 0xf3, 0xbd, 0xf9, 0x86, 0x2b, 0x7d, 0xfa, 0x5b, 0xf1, 0x7b, 0x19, 0x0f, 0xa5, 0x95, 0xbf, 0xde, + 0x9b, 0x6f, 0xe8, 0xd8, 0x97, 0xfe, 0xce, 0xba, 0x91, 0xfd, 0xc8, 0x58, 0xf9, 0x1b, 0xf1, 0xa9, + 0x2b, 0x83, 0x10, 0xa7, 0xae, 0xac, 0x97, 0xca, 0x2b, 0x70, 0x91, 0x6b, 0xc8, 0x2d, 0x47, 0xef, + 0xac, 0xd5, 0xa9, 0xe7, 0x99, 0xd6, 0xaa, 0xbf, 0x13, 0xfb, 0x9b, 0xb9, 0xd8, 0xf1, 0x58, 0x16, + 0x25, 0x1e, 0x8f, 0x65, 0x21, 0x99, 0xf2, 0x26, 0x9e, 0x13, 0x2b, 0x7f, 0x2b, 0xa6, 0xbc, 0x09, + 0x0a, 0xa6, 0xbc, 0xc9, 0x57, 0xc8, 0xb7, 0x53, 0x5e, 0xcd, 0x2a, 0xff, 0x51, 0x36, 0xaf, 0xa0, + 0x7d, 0x29, 0x8f, 0x6d, 0x6f, 0xa7, 0x3c, 0x0e, 0x55, 0xfe, 0xe3, 0x6c, 0x5e, 0xa1, 0x0f, 0x52, + 0xf2, 0x4d, 0xe9, 0xbb, 0x70, 0x9e, 0xcf, 0xe6, 0x33, 0xd4, 0xa0, 0x91, 0x0f, 0xfd, 0x85, 0xd8, + 0xd8, 0x4f, 0x27, 0xc3, 0x23, 0xf7, 0x54, 0x4c, 0x1a, 0x6b, 0xd1, 0xd6, 0xbf, 0xbd, 0x03, 0xeb, + 0x70, 0x43, 0x90, 0x8e, 0x61, 0xeb, 0x8d, 0xfc, 0xf8, 0x4d, 0xf9, 0xc5, 0xd8, 0x7a, 0x23, 0x23, + 0xd1, 0x9d, 0x43, 0x7e, 0x29, 0xf7, 0x46, 0xf4, 0xa1, 0x97, 0xf2, 0x77, 0x52, 0x0b, 0x07, 0x1d, + 0x10, 0x7d, 0x15, 0xf6, 0x46, 0xf4, 0x51, 0x93, 0xf2, 0x4b, 0xa9, 0x85, 0x83, 0x0f, 0x88, 0xbe, + 0x80, 0x62, 0x5b, 0xa4, 0xae, 0x67, 0x73, 0x56, 0x91, 0xe9, 0xe1, 0xef, 0xc6, 0xb7, 0x48, 0xa9, + 0x64, 0xb8, 0x45, 0x4a, 0xc5, 0xa4, 0xb1, 0x16, 0x9f, 0xf7, 0xcb, 0x3b, 0xb0, 0x96, 0x36, 0x76, + 0xa9, 0x98, 0x34, 0xd6, 0xe2, 0xe3, 0xbf, 0xb1, 0x03, 0x6b, 0x69, 0x63, 0x97, 0x8a, 0x61, 0xe6, + 0x58, 0x88, 0xb9, 0x47, 0x1d, 0x37, 0x54, 0xbf, 0xff, 0x24, 0x66, 0x8e, 0x65, 0xd0, 0x31, 0x73, + 0x2c, 0x03, 0x95, 0xca, 0x5d, 0x08, 0xe5, 0x57, 0x76, 0xe2, 0x1e, 0xde, 0xcb, 0x64, 0xa0, 0x52, + 0xb9, 0x0b, 0xb9, 0xfc, 0xbd, 0x9d, 0xb8, 0x87, 0x17, 0x33, 0x19, 0x28, 0x66, 0x14, 0xd5, 0x3d, + 0xdd, 0x33, 0x9b, 0xb3, 0xb6, 0xeb, 0x49, 0x8b, 0xfc, 0x7f, 0x1a, 0x33, 0x8a, 0xd2, 0x88, 0x98, + 0x51, 0x94, 0x06, 0x4f, 0x32, 0x15, 0xd2, 0xf8, 0xd5, 0x9e, 0x4c, 0x43, 0x4b, 0x2b, 0x0d, 0x9e, + 0x64, 0x2a, 0x84, 0xf0, 0x9f, 0xf5, 0x64, 0x1a, 0x7a, 0xca, 0xa7, 0xc1, 0x99, 0x65, 0x3a, 0xe5, + 0xd8, 0x1b, 0xd6, 0x6d, 0xba, 0x41, 0x5b, 0xe2, 0xd3, 0x7f, 0x2d, 0x66, 0x99, 0xc6, 0x09, 0xf0, + 0x16, 0x25, 0x06, 0x8b, 0x32, 0x12, 0x9f, 0xfb, 0xeb, 0x99, 0x8c, 0xc2, 0x63, 0xa2, 0x38, 0x2c, + 0xca, 0x48, 0x7c, 0xe2, 0x6f, 0x64, 0x32, 0x0a, 0x8f, 0x89, 0xe2, 0x30, 0x52, 0x81, 0x31, 0x7c, + 0x2b, 0xa1, 0xbb, 0xbe, 0xe7, 0xe7, 0x6f, 0xe7, 0xa2, 0xb7, 0x5e, 0x51, 0xf4, 0x6c, 0x9f, 0x16, + 0x2b, 0x20, 0xb3, 0x10, 0x9f, 0xf4, 0xad, 0x0c, 0x16, 0xa1, 0xbf, 0x63, 0x14, 0x22, 0xb3, 0x10, + 0x1f, 0xf3, 0x9f, 0x67, 0xb0, 0x08, 0x1d, 0x1e, 0xa3, 0x10, 0xf2, 0x49, 0x18, 0xae, 0xcf, 0x2c, + 0x2f, 0xf9, 0xc9, 0x04, 0xff, 0x7e, 0x2e, 0xf6, 0xaa, 0x28, 0xc4, 0xe1, 0xab, 0xa2, 0xf0, 0x27, + 0xf9, 0x14, 0x8c, 0x4e, 0xd9, 0x96, 0xa7, 0x37, 0xfd, 0x0d, 0xe8, 0xef, 0xc4, 0xce, 0x50, 0x22, + 0xd8, 0xd9, 0x3e, 0x2d, 0x4a, 0x2e, 0x95, 0x17, 0x6d, 0xff, 0xdd, 0xf4, 0xf2, 0x41, 0xd3, 0xa3, + 0xe4, 0x6c, 0x46, 0xbb, 0x6f, 0x3b, 0xeb, 0x2d, 0x5b, 0x37, 0xfc, 0xf8, 0x95, 0xa2, 0x21, 0xff, + 0x20, 0x36, 0xa3, 0xa5, 0x93, 0xb1, 0x19, 0x2d, 0x1d, 0x93, 0xc6, 0x5a, 0x74, 0xd1, 0xb7, 0x77, + 0x60, 0x1d, 0xce, 0xc3, 0xe9, 0x98, 0x34, 0xd6, 0xe2, 0xf3, 0xff, 0xe1, 0x0e, 0xac, 0xc3, 0x79, + 0x38, 0x1d, 0x33, 0x39, 0x00, 0xfd, 0x78, 0xb6, 0x7d, 0xbb, 0x34, 0xf8, 0xcd, 0xdc, 0xf8, 0x6f, + 0xe6, 0x6e, 0x97, 0x06, 0x7f, 0x33, 0x37, 0xfe, 0x5b, 0xec, 0xff, 0xdf, 0xca, 0x8d, 0xff, 0x76, + 0x4e, 0xbb, 0x18, 0xce, 0x53, 0x95, 0x55, 0x6a, 0x79, 0x4b, 0x2d, 0x5d, 0xcc, 0xb2, 0xa9, 0x28, + 0xfe, 0x33, 0x15, 0x25, 0x32, 0xa9, 0x7d, 0x3d, 0x07, 0x23, 0x75, 0xcf, 0xa1, 0x7a, 0x5b, 0x04, + 0x26, 0xbc, 0x04, 0x83, 0xdc, 0x1b, 0xdd, 0x7f, 0x97, 0xaf, 0x05, 0xbf, 0xc9, 0x15, 0x18, 0x9b, + 0xd3, 0x5d, 0x0f, 0x9b, 0x58, 0xb3, 0x0c, 0xfa, 0x08, 0x5f, 0x62, 0x16, 0xb4, 0x18, 0x94, 0xcc, + 0x71, 0x3a, 0x5e, 0x0e, 0x63, 0xd1, 0x16, 0x76, 0x8c, 0xc7, 0x37, 0xf8, 0x9d, 0xad, 0x72, 0x1f, + 0x86, 0xdf, 0x8b, 0x95, 0x55, 0x7f, 0x3f, 0x07, 0x09, 0x3f, 0xf9, 0xfd, 0x07, 0xe0, 0x58, 0x84, + 0x53, 0xb1, 0xf8, 0xc7, 0xe2, 0x39, 0xe9, 0x2e, 0xc3, 0x23, 0xc7, 0x4b, 0x93, 0x8f, 0x05, 0xcf, + 0x18, 0xef, 0x6a, 0x73, 0x22, 0xd6, 0x22, 0x66, 0x09, 0xe9, 0x3a, 0x2d, 0x4d, 0x42, 0x89, 0x58, + 0x5a, 0xdf, 0x1b, 0x0f, 0x83, 0xbb, 0x92, 0x2b, 0x22, 0x1a, 0x48, 0x2e, 0x8c, 0xd0, 0xd8, 0x75, + 0xa9, 0x23, 0x47, 0x68, 0xc4, 0xe8, 0x1f, 0x9f, 0x82, 0x91, 0x5a, 0xbb, 0x43, 0x1d, 0xd7, 0xb6, + 0x74, 0xcf, 0x76, 0x44, 0xec, 0x03, 0x8c, 0x52, 0x60, 0x4a, 0x70, 0x39, 0x4a, 0x81, 0x4c, 0x4f, + 0xae, 0xf9, 0x89, 0x0e, 0x0b, 0x18, 0x56, 0x17, 0xdf, 0x18, 0xc7, 0xf3, 0xdc, 0x73, 0x0a, 0x46, + 0x7a, 0xd7, 0xd5, 0xf1, 0xc1, 0x6b, 0x40, 0xda, 0x65, 0x00, 0x99, 0x14, 0x29, 0xc8, 0xf3, 0x50, + 0xc2, 0x0b, 0x42, 0x17, 0x13, 0x98, 0x8a, 0xb8, 0x91, 0x2d, 0x84, 0xc8, 0x11, 0x2a, 0x38, 0x0d, + 0xb9, 0x03, 0xe3, 0xa1, 0xf7, 0xc3, 0x2d, 0xc7, 0xee, 0x76, 0xfc, 0x94, 0x45, 0xe5, 0xed, 0xad, + 0xf2, 0x13, 0xeb, 0x01, 0xae, 0xb1, 0x8a, 0x48, 0x89, 0x45, 0xa2, 0x20, 0x99, 0x85, 0x53, 0x21, + 0x8c, 0x89, 0xc8, 0x4f, 0x95, 0x86, 0x69, 0x6a, 0x25, 0x5e, 0x4c, 0x9c, 0x91, 0x34, 0xb5, 0xb1, + 0x62, 0xa4, 0x06, 0x03, 0x7e, 0xd0, 0xc8, 0xc1, 0x1d, 0x95, 0xf4, 0x8c, 0x08, 0x1a, 0x39, 0x20, + 0x87, 0x8b, 0xf4, 0xcb, 0x93, 0x19, 0x18, 0xd3, 0xec, 0xae, 0x47, 0x97, 0x6d, 0x71, 0x6c, 0x20, + 0x82, 0x93, 0x62, 0x9b, 0x1c, 0x86, 0x69, 0x78, 0x76, 0xa3, 0xc9, 0x71, 0x72, 0x9a, 0xff, 0x68, + 0x29, 0xb2, 0x00, 0xa7, 0x13, 0x7e, 0x22, 0xf8, 0x3e, 0x76, 0x88, 0x87, 0xff, 0x93, 0x3e, 0x2f, + 0xc9, 0x2c, 0x59, 0x94, 0xfc, 0x68, 0x0e, 0x4a, 0xcb, 0x8e, 0x6e, 0x7a, 0xae, 0x78, 0x2b, 0x7b, + 0x6e, 0x62, 0xc3, 0xd1, 0x3b, 0x4c, 0x3f, 0x26, 0x30, 0x6e, 0xf2, 0x3d, 0xbd, 0xd5, 0xa5, 0xee, + 0xe4, 0x7d, 0xf6, 0x75, 0xff, 0xfd, 0x56, 0xf9, 0x0d, 0x1e, 0x65, 0x64, 0xa2, 0x69, 0xb7, 0xaf, + 0xaf, 0x3a, 0xfa, 0x43, 0xd3, 0x43, 0x9b, 0x5f, 0x6f, 0x5d, 0xf7, 0x68, 0x0b, 0x0f, 0xbd, 0xaf, + 0xeb, 0x1d, 0xf3, 0x3a, 0xc6, 0xe7, 0xbf, 0x1e, 0x70, 0xe2, 0x35, 0x30, 0x15, 0xf0, 0xf0, 0x2f, + 0x59, 0x05, 0x38, 0x8e, 0x2c, 0x00, 0x88, 0x4f, 0xad, 0x74, 0x3a, 0xe2, 0xe1, 0xad, 0x74, 0x54, + 0xec, 0x63, 0xb8, 0x62, 0x07, 0x02, 0xd3, 0x3b, 0x52, 0x4c, 0x6a, 0x4d, 0xe2, 0xc0, 0xb4, 0x60, + 0x59, 0xb4, 0xc8, 0x17, 0xd3, 0x68, 0x28, 0x71, 0xbf, 0xb1, 0x29, 0x42, 0x8a, 0x17, 0x23, 0x2b, + 0x70, 0x4a, 0xf0, 0x0d, 0x32, 0xd8, 0x8c, 0x45, 0x67, 0x85, 0x18, 0x9a, 0x2b, 0x6d, 0xd0, 0x46, + 0x43, 0x80, 0xe5, 0x3a, 0x62, 0x25, 0xc8, 0x64, 0x98, 0x71, 0x7b, 0x41, 0x6f, 0x53, 0x57, 0x39, + 0x85, 0x1a, 0x7b, 0x79, 0x7b, 0xab, 0xac, 0xf8, 0xe5, 0x31, 0x7e, 0xaa, 0x2c, 0xba, 0x68, 0x11, + 0x99, 0x07, 0xd7, 0xfa, 0xf1, 0x14, 0x1e, 0x71, 0x9d, 0x8f, 0x16, 0x21, 0x53, 0x30, 0x1a, 0xbc, + 0xfb, 0xb9, 0x7b, 0xb7, 0x56, 0xc5, 0x97, 0xbd, 0x22, 0x84, 0x6e, 0x2c, 0xc7, 0x8c, 0xcc, 0x24, + 0x52, 0x46, 0x8a, 0xc4, 0xc2, 0x9f, 0xfa, 0xc6, 0x22, 0xb1, 0x74, 0x52, 0x22, 0xb1, 0x2c, 0x91, + 0xb7, 0x60, 0xb8, 0x72, 0xbf, 0x2e, 0x22, 0xcc, 0xb8, 0xca, 0x99, 0x30, 0x61, 0x99, 0xbe, 0xe1, + 0x36, 0xfc, 0x68, 0x34, 0x72, 0xd3, 0x65, 0x7a, 0x32, 0x0d, 0x63, 0x11, 0xd7, 0x41, 0x57, 0x39, + 0x8b, 0x1c, 0xb0, 0xe5, 0x3a, 0x62, 0x1a, 0x8e, 0x40, 0xc9, 0xc3, 0x2b, 0x5a, 0x88, 0x69, 0x4d, + 0xd5, 0x74, 0x31, 0xf9, 0x93, 0x46, 0x31, 0x98, 0x0d, 0xbe, 0x13, 0x1e, 0xe4, 0x5a, 0x63, 0x08, + 0x54, 0xc3, 0xe1, 0x38, 0xb9, 0x47, 0x63, 0xc5, 0xc8, 0x7b, 0x40, 0x30, 0x5d, 0x14, 0x35, 0xfc, + 0x9b, 0xe4, 0x5a, 0xd5, 0x55, 0xce, 0x63, 0xfc, 0x78, 0x12, 0x8f, 0x6f, 0x51, 0xab, 0x4e, 0x5e, + 0x11, 0xd3, 0xc7, 0x53, 0x3a, 0x2f, 0xd5, 0xf0, 0x63, 0x5b, 0x34, 0xcc, 0x48, 0x2e, 0xed, 0x14, + 0xae, 0x64, 0x03, 0x2e, 0x2c, 0x39, 0xf4, 0xa1, 0x69, 0x77, 0x5d, 0x7f, 0xf9, 0xf0, 0xe7, 0xad, + 0x0b, 0x3b, 0xce, 0x5b, 0xcf, 0x88, 0x8a, 0xcf, 0x75, 0x1c, 0xfa, 0xb0, 0xe1, 0x47, 0x0d, 0x8f, + 0x04, 0xbd, 0xcd, 0xe2, 0x8e, 0x19, 0xc1, 0xdf, 0xef, 0x3a, 0x54, 0xc0, 0x4d, 0xea, 0x2a, 0x4a, + 0x38, 0xd5, 0xf2, 0x40, 0x47, 0x66, 0x80, 0x8b, 0x64, 0x04, 0x8f, 0x16, 0x23, 0x1a, 0x90, 0x5b, + 0x53, 0xbe, 0x57, 0x41, 0xa5, 0xc9, 0xf3, 0x26, 0x2b, 0x17, 0x91, 0x99, 0xca, 0xc4, 0xb2, 0xda, + 0x0c, 0x32, 0x08, 0x34, 0x74, 0x81, 0x97, 0xc5, 0x92, 0x2c, 0x4d, 0xe6, 0x60, 0x7c, 0xc9, 0xc1, + 0x33, 0xce, 0x3b, 0x74, 0x73, 0xc9, 0x6e, 0x99, 0xcd, 0x4d, 0x7c, 0xae, 0x2c, 0xa6, 0xca, 0x0e, + 0xc7, 0x35, 0xd6, 0xe9, 0x66, 0xa3, 0x83, 0x58, 0x79, 0x59, 0x89, 0x97, 0x94, 0x23, 0x7a, 0x3f, + 0xb1, 0xbb, 0x88, 0xde, 0x14, 0xc6, 0x85, 0x4f, 0xc2, 0x23, 0x8f, 0x5a, 0x6c, 0xa9, 0x77, 0xc5, + 0xd3, 0x64, 0x25, 0xe6, 0xc3, 0x10, 0xe0, 0xf9, 0xd4, 0x21, 0x46, 0x19, 0x0d, 0xc0, 0x72, 0xc3, + 0xe2, 0x45, 0x92, 0x61, 0xaf, 0x9f, 0xdc, 0x47, 0xd8, 0xeb, 0xff, 0xbd, 0x20, 0xcf, 0xbf, 0xe4, + 0x32, 0x14, 0xa5, 0xac, 0x54, 0x18, 0xd3, 0x17, 0x23, 0xf8, 0x17, 0x45, 0xa8, 0xf2, 0x21, 0x61, + 0xbb, 0x04, 0xb1, 0x96, 0x30, 0x0d, 0x69, 0x18, 0xe7, 0x55, 0x0b, 0x09, 0x30, 0x05, 0x64, 0x77, + 0xa5, 0x65, 0x36, 0x31, 0xaf, 0x43, 0x41, 0x8a, 0x7f, 0x82, 0x50, 0x9e, 0xd6, 0x41, 0x22, 0x21, + 0x37, 0x60, 0xd8, 0x3f, 0x5b, 0x0f, 0x63, 0x5a, 0x63, 0xb8, 0x7f, 0x31, 0x5b, 0x8b, 0x6c, 0x02, + 0x12, 0x11, 0x79, 0x1d, 0x20, 0x9c, 0x0e, 0x84, 0xa5, 0x85, 0x4b, 0x85, 0x3c, 0x7b, 0xc8, 0x4b, + 0x45, 0x48, 0xcd, 0x26, 0x4e, 0x59, 0x1d, 0xfd, 0xa4, 0xb7, 0x38, 0x71, 0x46, 0x74, 0x58, 0x56, + 0x90, 0x68, 0x11, 0xb2, 0x08, 0xa7, 0x13, 0x1a, 0x28, 0x22, 0x60, 0x3f, 0xb3, 0xbd, 0x55, 0x7e, + 0x32, 0x45, 0x7d, 0xe5, 0x85, 0x39, 0x51, 0x96, 0x3c, 0x0b, 0x85, 0xbb, 0x5a, 0x4d, 0x44, 0xe1, + 0xe5, 0x01, 0x9c, 0x23, 0x11, 0xb5, 0x18, 0x96, 0xbc, 0x06, 0xc0, 0xb3, 0xdc, 0x2c, 0xd9, 0x8e, + 0x87, 0x16, 0xc5, 0xe8, 0xe4, 0x45, 0x36, 0x96, 0x79, 0x16, 0x9c, 0x06, 0x5b, 0xc6, 0xe4, 0x8f, + 0x0e, 0x89, 0xd5, 0x3f, 0x9f, 0x4f, 0x2c, 0x6b, 0x4c, 0xf0, 0xa2, 0x15, 0x52, 0xe7, 0xa3, 0xe0, + 0xfd, 0xa6, 0x73, 0xc1, 0x4b, 0x44, 0xe4, 0x2a, 0x0c, 0x2e, 0xb1, 0x49, 0xa5, 0x69, 0xb7, 0x84, + 0x2a, 0x60, 0x28, 0xb6, 0x8e, 0x80, 0x69, 0x01, 0x96, 0xdc, 0x90, 0xd2, 0x3c, 0x4b, 0x31, 0xf1, + 0xfd, 0x34, 0xcf, 0xf1, 0xe0, 0xf0, 0x98, 0xf0, 0xf9, 0x46, 0x2c, 0x6d, 0x9c, 0x28, 0x93, 0xb2, + 0xa4, 0x86, 0x69, 0xe2, 0x02, 0x83, 0xb6, 0x7f, 0x27, 0x83, 0x56, 0xfd, 0x9d, 0x5c, 0x72, 0x88, + 0x92, 0x9b, 0xc9, 0xf0, 0xd4, 0xb8, 0x7e, 0x05, 0x40, 0xb9, 0xd6, 0x20, 0x50, 0x75, 0x24, 0xd0, + 0x74, 0x7e, 0xdf, 0x81, 0xa6, 0x0b, 0x7b, 0x0c, 0x34, 0xad, 0xfe, 0x3f, 0xc5, 0x9e, 0xee, 0xf7, + 0x47, 0x12, 0x90, 0xf0, 0x35, 0xb6, 0x29, 0x63, 0xb5, 0x57, 0xdc, 0xc4, 0xd6, 0x82, 0x7b, 0x17, + 0x37, 0x74, 0x3e, 0x2a, 0x5d, 0x2d, 0x4a, 0x49, 0xde, 0x86, 0x11, 0xff, 0x03, 0x30, 0x80, 0xb9, + 0x14, 0x78, 0x3b, 0x58, 0x10, 0x63, 0xa1, 0xbe, 0x23, 0x05, 0xc8, 0xcb, 0x30, 0x84, 0xe6, 0x50, + 0x47, 0x6f, 0xfa, 0xd1, 0xed, 0x79, 0x38, 0x7c, 0x1f, 0x28, 0x07, 0xdd, 0x0b, 0x28, 0xc9, 0xe7, + 0xa1, 0x24, 0x52, 0xbc, 0x94, 0x70, 0x89, 0xbe, 0xbe, 0x8b, 0xf7, 0x0a, 0x13, 0x72, 0x7a, 0x17, + 0xbe, 0xc1, 0x41, 0x40, 0x64, 0x83, 0xc3, 0x33, 0xbb, 0x2c, 0xc3, 0x99, 0x25, 0x87, 0x1a, 0xf8, + 0x32, 0x66, 0xfa, 0x51, 0xc7, 0x11, 0xc9, 0x77, 0xf8, 0x04, 0x81, 0xeb, 0x5b, 0xc7, 0x47, 0xb3, + 0x95, 0x57, 0xe0, 0xe5, 0x10, 0xdb, 0x29, 0xc5, 0x99, 0xd1, 0xc3, 0x5b, 0x72, 0x87, 0x6e, 0x6e, + 0xd8, 0x8e, 0xc1, 0xf3, 0xd3, 0x88, 0xa9, 0x5f, 0x08, 0x7a, 0x5d, 0xa0, 0x64, 0xa3, 0x27, 0x5a, + 0xe8, 0xd2, 0x6b, 0x30, 0xbc, 0xdf, 0x14, 0x29, 0xbf, 0x92, 0xcf, 0x78, 0xc8, 0xf6, 0xf8, 0x66, + 0xa9, 0x0c, 0x52, 0xa7, 0xf7, 0x67, 0xa4, 0x4e, 0xff, 0xd3, 0x7c, 0xc6, 0x2b, 0xbd, 0xc7, 0x3a, + 0xc5, 0x71, 0x20, 0x8c, 0x68, 0x8a, 0xe3, 0x30, 0xbb, 0xb4, 0x69, 0x68, 0x32, 0x51, 0x2c, 0x19, + 0x7a, 0x69, 0xc7, 0x64, 0xe8, 0xbf, 0x50, 0xe8, 0xf5, 0x8a, 0xf1, 0x44, 0xf6, 0x7b, 0x91, 0xfd, + 0x0d, 0x18, 0x0e, 0x24, 0x5b, 0xab, 0xa2, 0xbd, 0x34, 0x1a, 0x24, 0x64, 0xe2, 0x60, 0x2c, 0x23, + 0x11, 0x91, 0x6b, 0xbc, 0xad, 0x75, 0xf3, 0x7d, 0x9e, 0x1a, 0x64, 0x54, 0x24, 0x7d, 0xd0, 0x3d, + 0xbd, 0xe1, 0x9a, 0xef, 0x53, 0x2d, 0x40, 0x63, 0xd4, 0xd7, 0xb4, 0x07, 0x9d, 0x27, 0x7d, 0xb4, + 0xfb, 0x3e, 0x4a, 0x11, 0x22, 0x7f, 0xc4, 0x7a, 0x22, 0xc4, 0x3d, 0x08, 0xf1, 0x4f, 0xf2, 0xa9, + 0x4f, 0x7e, 0x4f, 0x84, 0xb8, 0x97, 0xd9, 0xe2, 0x79, 0x18, 0xd2, 0xec, 0x0d, 0x77, 0x0a, 0xf7, + 0x44, 0x7c, 0xae, 0xc0, 0x89, 0xda, 0xb1, 0x37, 0xdc, 0x06, 0xee, 0x76, 0xb4, 0x90, 0x40, 0xfd, + 0x5e, 0xbe, 0xc7, 0xa3, 0xe8, 0x13, 0xc1, 0x7f, 0x90, 0x4b, 0xe4, 0xaf, 0xe7, 0x23, 0x8f, 0xae, + 0x1f, 0x5f, 0x61, 0x5f, 0x07, 0xa8, 0x37, 0xd7, 0x68, 0x5b, 0x97, 0xd2, 0xab, 0xe1, 0x91, 0x85, + 0x8b, 0x50, 0x91, 0x96, 0x3b, 0x24, 0x51, 0xbf, 0x99, 0x8f, 0xbd, 0x3a, 0x3f, 0x91, 0xdd, 0xae, + 0x65, 0x17, 0x68, 0x9d, 0x78, 0x48, 0x7f, 0x22, 0xb9, 0xdd, 0x4a, 0xee, 0xc7, 0xf2, 0xb1, 0x98, + 0x03, 0x8f, 0xad, 0xec, 0xd8, 0x00, 0x4c, 0xc6, 0x42, 0x78, 0x6c, 0x35, 0xe9, 0x79, 0x18, 0x12, + 0x72, 0x08, 0x96, 0x0a, 0x3e, 0xef, 0x73, 0x20, 0x1e, 0xd0, 0x06, 0x04, 0xea, 0x5f, 0xc8, 0x43, + 0x34, 0x16, 0xc4, 0x63, 0xaa, 0x43, 0xbf, 0x9e, 0x8f, 0x46, 0xc1, 0x78, 0x7c, 0xf5, 0x67, 0x02, + 0xa0, 0xde, 0x5d, 0x69, 0x8a, 0x20, 0xca, 0xfd, 0xd2, 0x09, 0x7f, 0x00, 0xd5, 0x24, 0x0a, 0xf5, + 0xff, 0xcd, 0xa7, 0x86, 0xe6, 0x78, 0x7c, 0x05, 0xf8, 0x12, 0x9e, 0x8a, 0x37, 0xad, 0x70, 0x22, + 0xc7, 0x43, 0x48, 0x36, 0xfe, 0x12, 0x39, 0x39, 0x7d, 0x42, 0xf2, 0xc9, 0x14, 0x73, 0x0d, 0x33, + 0x86, 0x84, 0xe6, 0x9a, 0x7c, 0x98, 0x2f, 0x19, 0x6e, 0xbf, 0x97, 0xdf, 0x29, 0x92, 0xc9, 0xe3, + 0xbc, 0xaa, 0x0e, 0x2c, 0xe9, 0x9b, 0x18, 0x71, 0x93, 0xf5, 0xc4, 0x08, 0xcf, 0x18, 0xd9, 0xe1, + 0x20, 0xf9, 0xda, 0x4e, 0x50, 0xa9, 0xff, 0xa2, 0x3f, 0x3d, 0x8c, 0xc6, 0xe3, 0x2b, 0xc2, 0xcb, + 0x50, 0x5c, 0xd2, 0xbd, 0x35, 0xa1, 0xc9, 0x78, 0x1b, 0xd8, 0xd1, 0xbd, 0x35, 0x0d, 0xa1, 0xe4, + 0x1a, 0x0c, 0x6a, 0xfa, 0x06, 0x3f, 0xf3, 0x2c, 0x85, 0xd9, 0x3c, 0x1d, 0x7d, 0xa3, 0xc1, 0xcf, + 0x3d, 0x03, 0x34, 0x51, 0x83, 0x6c, 0xb2, 0xfc, 0xe4, 0x1b, 0x53, 0x19, 0xf2, 0x6c, 0xb2, 0x41, + 0x0e, 0xd9, 0xcb, 0x50, 0x9c, 0xb4, 0x8d, 0x4d, 0xbc, 0xf9, 0x1a, 0xe1, 0x95, 0xad, 0xd8, 0xc6, + 0xa6, 0x86, 0x50, 0xf2, 0xe3, 0x39, 0x18, 0x98, 0xa5, 0xba, 0xc1, 0x46, 0xc8, 0x50, 0x2f, 0x87, + 0x95, 0xcf, 0x1c, 0x8e, 0xc3, 0xca, 0xe9, 0x35, 0x5e, 0x99, 0xac, 0x28, 0xa2, 0x7e, 0x72, 0x0b, + 0x06, 0xa7, 0x74, 0x8f, 0xae, 0xda, 0xce, 0x26, 0xba, 0xe0, 0x8c, 0x85, 0x4f, 0x31, 0x22, 0xfa, + 0xe3, 0x13, 0xf1, 0x9b, 0xb1, 0xa6, 0xf8, 0xa5, 0x05, 0x85, 0x99, 0x58, 0xf8, 0xcd, 0x9c, 0xc8, + 0x9c, 0x8e, 0x62, 0xe1, 0x57, 0x78, 0x9a, 0xc0, 0x84, 0xc7, 0xca, 0x23, 0xe9, 0xc7, 0xca, 0x68, + 0x3d, 0xa2, 0x9b, 0x1e, 0xe6, 0x70, 0x1d, 0xc5, 0x45, 0x9f, 0x5b, 0x8f, 0x08, 0xc5, 0x14, 0xae, + 0x9a, 0x44, 0xa2, 0x7e, 0xb7, 0x1f, 0x52, 0x1f, 0xdd, 0x9f, 0x28, 0xf9, 0x89, 0x92, 0x87, 0x4a, + 0x5e, 0x4d, 0x28, 0xf9, 0xa5, 0x64, 0x18, 0x87, 0x0f, 0xa9, 0x86, 0x7f, 0xad, 0x98, 0x08, 0x02, + 0xf3, 0x78, 0xef, 0x2e, 0x43, 0xe9, 0xf5, 0xef, 0x28, 0xbd, 0x60, 0x40, 0x94, 0x76, 0x1c, 0x10, + 0x03, 0xbb, 0x1d, 0x10, 0x83, 0x99, 0x03, 0x22, 0x54, 0x90, 0xa1, 0x4c, 0x05, 0xa9, 0x89, 0x41, + 0x03, 0xbd, 0x73, 0xd1, 0x5c, 0xde, 0xde, 0x2a, 0x8f, 0xb1, 0xd1, 0x94, 0x9a, 0x84, 0x06, 0x59, + 0xa8, 0xbf, 0x5f, 0xec, 0x11, 0xb9, 0xe9, 0x48, 0x74, 0xe4, 0x25, 0x28, 0x54, 0x3a, 0x1d, 0xa1, + 0x1f, 0x67, 0xa4, 0xa0, 0x51, 0x19, 0xa5, 0x18, 0x35, 0x79, 0x1d, 0x0a, 0x95, 0xfb, 0xf5, 0x78, + 0xfe, 0x99, 0xca, 0xfd, 0xba, 0xf8, 0x92, 0xcc, 0xb2, 0xf7, 0xeb, 0xe4, 0xcd, 0x30, 0x10, 0xec, + 0x5a, 0xd7, 0x5a, 0x17, 0x1b, 0x45, 0xe1, 0xa9, 0xeb, 0x7b, 0xf2, 0x34, 0x19, 0x8a, 0x6d, 0x17, + 0x63, 0xb4, 0x31, 0x6d, 0x2a, 0xed, 0x5e, 0x9b, 0x06, 0x76, 0xd4, 0xa6, 0xc1, 0xdd, 0x6a, 0xd3, + 0xd0, 0x2e, 0xb4, 0x09, 0x76, 0xd4, 0xa6, 0xe1, 0x83, 0x6b, 0x53, 0x07, 0x2e, 0x25, 0xa3, 0xed, + 0x05, 0x1a, 0xa1, 0x01, 0x49, 0x62, 0x85, 0x63, 0x09, 0x5e, 0xfd, 0x77, 0x39, 0xb6, 0xb1, 0x81, + 0xe8, 0x86, 0xcb, 0xf0, 0xb2, 0x6b, 0x5b, 0xb2, 0xb4, 0xfa, 0x2b, 0xf9, 0xec, 0x20, 0x81, 0xc7, + 0x73, 0x8a, 0xfb, 0xc1, 0x54, 0x29, 0x15, 0xa3, 0x41, 0x1b, 0xb2, 0xa5, 0x1c, 0x63, 0x9b, 0x26, + 0xb3, 0x6f, 0xe4, 0xb3, 0x22, 0x17, 0x1e, 0x48, 0x62, 0x1f, 0x4d, 0x3a, 0xc3, 0xa1, 0x8b, 0xbf, + 0x1b, 0xf5, 0x82, 0x9b, 0x81, 0x11, 0x59, 0x88, 0x42, 0x4a, 0xbb, 0x11, 0x70, 0xa4, 0x1c, 0x79, + 0x33, 0x48, 0x13, 0x24, 0xf9, 0xc7, 0xa0, 0xa7, 0x9b, 0x3f, 0x66, 0x63, 0xee, 0x31, 0x32, 0x39, + 0x79, 0x1e, 0x4a, 0x33, 0x18, 0x77, 0x5f, 0x1e, 0xec, 0x3c, 0x12, 0xbf, 0xec, 0xb5, 0xc2, 0x69, + 0xd4, 0xdf, 0xc9, 0xc1, 0x99, 0x3b, 0xdd, 0x15, 0x2a, 0x1c, 0xed, 0x82, 0x36, 0xbc, 0x07, 0xc0, + 0xc0, 0xc2, 0x61, 0x26, 0x87, 0x0e, 0x33, 0x1f, 0x97, 0x23, 0x1c, 0xc6, 0x0a, 0x4c, 0x84, 0xd4, + 0xdc, 0x59, 0xe6, 0x49, 0xdf, 0xe7, 0x74, 0xbd, 0xbb, 0x42, 0x1b, 0x09, 0xaf, 0x19, 0x89, 0xfb, + 0xa5, 0xb7, 0xb8, 0x37, 0xff, 0x7e, 0x1d, 0x54, 0x7e, 0x39, 0x9f, 0x19, 0x54, 0xf2, 0xd8, 0xe6, + 0x6a, 0xfd, 0x5c, 0x6a, 0xaf, 0xc4, 0x73, 0xb6, 0xa6, 0x90, 0xc4, 0x38, 0xa6, 0x71, 0x49, 0x17, + 0xd8, 0x31, 0xcf, 0x20, 0xfc, 0x81, 0x0a, 0xec, 0x8f, 0x72, 0x99, 0xc1, 0x3f, 0x8f, 0xab, 0xc0, + 0xd4, 0xff, 0xa5, 0xe0, 0xc7, 0x1c, 0x3d, 0xd0, 0x27, 0x3c, 0x0f, 0x43, 0x22, 0xf4, 0x42, 0xd4, + 0x4f, 0x58, 0x1c, 0x1b, 0xe2, 0x31, 0x74, 0x40, 0xc0, 0x4c, 0x0a, 0xc9, 0x89, 0x59, 0xf2, 0x13, + 0x96, 0x1c, 0x98, 0x35, 0x89, 0x84, 0x19, 0x0d, 0xd3, 0x8f, 0x4c, 0x0f, 0x2d, 0x10, 0xd6, 0x97, + 0x05, 0x6e, 0x34, 0xd0, 0x47, 0xa6, 0xc7, 0xed, 0x8f, 0x00, 0xcd, 0x0c, 0x02, 0x6e, 0x8b, 0x88, + 0x79, 0x0f, 0x0d, 0x02, 0x6e, 0xaa, 0x68, 0x02, 0xc3, 0x5a, 0x2b, 0x9c, 0x6f, 0x85, 0x4b, 0x8b, + 0x68, 0xad, 0x70, 0xd7, 0xc5, 0xd6, 0x06, 0x04, 0x8c, 0xa3, 0x46, 0x57, 0x43, 0x27, 0x3e, 0xe4, + 0xe8, 0x20, 0x44, 0x13, 0x18, 0x72, 0x03, 0xc6, 0xea, 0x9e, 0x6e, 0x19, 0xba, 0x63, 0x2c, 0x76, + 0xbd, 0x4e, 0xd7, 0x93, 0x0d, 0x60, 0xd7, 0x33, 0xec, 0xae, 0xa7, 0xc5, 0x28, 0xc8, 0x27, 0x60, + 0xd4, 0x87, 0x4c, 0x3b, 0x8e, 0xed, 0xc8, 0x56, 0x8e, 0xeb, 0x19, 0xd4, 0x71, 0xb4, 0x28, 0x01, + 0xf9, 0x24, 0x8c, 0xd6, 0xac, 0x87, 0x76, 0x93, 0x87, 0x1f, 0xd0, 0xe6, 0x84, 0xcd, 0x83, 0x2f, + 0xc6, 0xcc, 0x00, 0xd1, 0xe8, 0x3a, 0x2d, 0x2d, 0x4a, 0xa8, 0x6e, 0xe7, 0x93, 0xa1, 0x59, 0x1f, + 0xdf, 0x0d, 0xd2, 0xb5, 0xa8, 0xe3, 0x1e, 0x7a, 0xab, 0xa2, 0xf1, 0x29, 0xfb, 0x0d, 0x73, 0x1b, + 0xf4, 0x06, 0x0c, 0xde, 0xa1, 0x9b, 0xdc, 0xc7, 0xb4, 0x14, 0xba, 0x25, 0xaf, 0x0b, 0x98, 0x7c, + 0xba, 0xeb, 0xd3, 0xa9, 0xdf, 0xca, 0x27, 0x83, 0xce, 0x3e, 0xbe, 0xc2, 0xfe, 0x04, 0x0c, 0xa0, + 0x28, 0x6b, 0xfe, 0xf5, 0x02, 0x0a, 0x10, 0xc5, 0x1d, 0xf5, 0x76, 0xf6, 0xc9, 0xd4, 0x9f, 0x2f, + 0xc5, 0x23, 0x11, 0x3f, 0xbe, 0xd2, 0x7b, 0x03, 0x86, 0xa7, 0x6c, 0xcb, 0x35, 0x5d, 0x8f, 0x5a, + 0x4d, 0x5f, 0x61, 0xd1, 0xf1, 0xbf, 0x19, 0x82, 0x65, 0x1b, 0x50, 0xa2, 0xde, 0x8f, 0xf2, 0x92, + 0x57, 0x60, 0x08, 0x45, 0x8e, 0x36, 0x27, 0x9f, 0xf0, 0xf0, 0x66, 0x62, 0x85, 0x01, 0xe3, 0x16, + 0x67, 0x48, 0x4a, 0xee, 0xc2, 0xe0, 0xd4, 0x9a, 0xd9, 0x32, 0x1c, 0x6a, 0xa1, 0x6f, 0xb2, 0x14, + 0xf0, 0x25, 0xda, 0x97, 0x13, 0xf8, 0x2f, 0xd2, 0xf2, 0xe6, 0x34, 0x45, 0xb1, 0xc8, 0x63, 0x31, + 0x01, 0xbb, 0xf4, 0xd3, 0x79, 0x80, 0xb0, 0x00, 0x79, 0x1a, 0xf2, 0x41, 0xa6, 0x70, 0x74, 0x89, + 0x89, 0x68, 0x50, 0x1e, 0x97, 0x0a, 0x31, 0xb6, 0xf3, 0x3b, 0x8e, 0xed, 0xbb, 0x50, 0xe2, 0xa7, + 0x6b, 0xe8, 0xb5, 0x2e, 0x05, 0x47, 0xcd, 0x6c, 0xf0, 0x04, 0xd2, 0x73, 0x5b, 0x1a, 0x2d, 0xcf, + 0x88, 0x07, 0x38, 0x67, 0x76, 0xa9, 0x09, 0xfd, 0xf8, 0x17, 0xb9, 0x02, 0xc5, 0x65, 0x3f, 0x11, + 0xf0, 0x28, 0x9f, 0xa5, 0x63, 0xf2, 0x43, 0x3c, 0xeb, 0xa6, 0x29, 0xdb, 0xf2, 0x58, 0xd5, 0xd8, + 0xea, 0x11, 0x21, 0x17, 0x01, 0x8b, 0xc8, 0x45, 0xc0, 0xd4, 0xff, 0x2a, 0x9f, 0x12, 0x23, 0xfb, + 0xf1, 0x1d, 0x26, 0xaf, 0x01, 0xe0, 0xcb, 0x73, 0x26, 0x4f, 0xff, 0x39, 0x08, 0x8e, 0x12, 0x64, + 0x84, 0x6a, 0x1b, 0xd9, 0x76, 0x84, 0xc4, 0xea, 0x3f, 0xca, 0x25, 0x02, 0x2b, 0x1f, 0x48, 0x8e, + 0xb2, 0x55, 0x96, 0xdf, 0xa7, 0x19, 0xeb, 0xf7, 0x45, 0x61, 0x6f, 0x7d, 0x11, 0xfd, 0x96, 0x43, + 0xb0, 0x4c, 0x8f, 0xf2, 0x5b, 0xbe, 0x9b, 0x4f, 0x0b, 0x33, 0x7d, 0x3c, 0x55, 0xfc, 0x66, 0x60, + 0x94, 0x16, 0x63, 0x81, 0xfd, 0x11, 0x1a, 0x4f, 0x56, 0x2e, 0xcc, 0xd4, 0x2f, 0xc0, 0xa9, 0x58, + 0xf0, 0x65, 0x91, 0x37, 0xfa, 0x4a, 0xef, 0x28, 0xce, 0xd9, 0x31, 0x0b, 0x22, 0x64, 0xea, 0xff, + 0x97, 0xeb, 0x1d, 0x7a, 0xfb, 0xc8, 0x55, 0x27, 0x45, 0x00, 0x85, 0x3f, 0x1b, 0x01, 0x1c, 0xc2, + 0x36, 0xf8, 0x78, 0x0b, 0xe0, 0x43, 0x32, 0x79, 0x7c, 0xd0, 0x02, 0xf8, 0xf9, 0xdc, 0x8e, 0x91, + 0xd3, 0x8f, 0x5a, 0x06, 0xea, 0xff, 0x98, 0x4b, 0x8d, 0x70, 0x7e, 0xa0, 0x76, 0xbd, 0x09, 0x25, + 0xee, 0xc2, 0x23, 0x5a, 0x25, 0xe5, 0x84, 0x63, 0xd0, 0x8c, 0xf2, 0xa2, 0x0c, 0x99, 0x83, 0x01, + 0xde, 0x06, 0x43, 0xf4, 0xc6, 0x47, 0x7a, 0x84, 0x59, 0x37, 0xb2, 0x26, 0x47, 0x81, 0x56, 0x7f, + 0x37, 0x97, 0x08, 0xb8, 0x7e, 0x84, 0xdf, 0x16, 0x4e, 0xd5, 0x85, 0xdd, 0x4f, 0xd5, 0xea, 0x3f, + 0xcf, 0xa7, 0xc7, 0x7b, 0x3f, 0xc2, 0x0f, 0x39, 0x8c, 0xe3, 0xb4, 0xfd, 0xad, 0x5b, 0xcb, 0x30, + 0x16, 0x95, 0x85, 0x58, 0xb6, 0x9e, 0x4a, 0x8f, 0x7a, 0x9f, 0xd1, 0x8a, 0x18, 0x0f, 0xf5, 0x3b, + 0xb9, 0x64, 0xa8, 0xfa, 0x23, 0x9f, 0x9f, 0xf6, 0xa7, 0x2d, 0xd1, 0x4f, 0xf9, 0x90, 0xac, 0x35, + 0x87, 0xf1, 0x29, 0x1f, 0x92, 0x55, 0x63, 0x7f, 0x9f, 0xf2, 0x8b, 0xf9, 0xac, 0x48, 0xff, 0x47, + 0xfe, 0x41, 0x9f, 0x95, 0x85, 0xcc, 0x5b, 0x26, 0x3e, 0xed, 0xe9, 0xac, 0xd0, 0xfa, 0x19, 0x3c, + 0x13, 0x7c, 0xf6, 0x37, 0xc6, 0x53, 0x85, 0xf5, 0x21, 0x51, 0xe4, 0xe3, 0x21, 0xac, 0x0f, 0xc9, + 0x50, 0xf9, 0xf0, 0x09, 0xeb, 0x37, 0xf3, 0xbb, 0x4d, 0x2f, 0x71, 0x22, 0xbc, 0x84, 0xf0, 0xbe, + 0x92, 0x4f, 0xa6, 0x3d, 0x39, 0x72, 0x31, 0xcd, 0x40, 0x49, 0x24, 0x60, 0xc9, 0x14, 0x0e, 0xc7, + 0x67, 0x59, 0x34, 0xe2, 0x3b, 0x6e, 0x82, 0xb8, 0xc8, 0xd9, 0x9d, 0x48, 0x38, 0xad, 0xfa, 0xbd, + 0x5c, 0x2c, 0x47, 0xc8, 0x91, 0x1c, 0x21, 0xec, 0x6b, 0x49, 0x22, 0x6f, 0xf9, 0x87, 0x99, 0xc5, + 0x58, 0x8c, 0xf6, 0xe0, 0x7b, 0xaa, 0xd4, 0xd3, 0xcd, 0x56, 0xbc, 0xbc, 0x88, 0x3f, 0xf0, 0xad, + 0x3c, 0x9c, 0x4e, 0x90, 0x92, 0x2b, 0x91, 0x88, 0x3f, 0x78, 0x2c, 0x19, 0x73, 0x54, 0xe7, 0xb1, + 0x7f, 0xf6, 0x70, 0x92, 0x7a, 0x05, 0x8a, 0x55, 0x7d, 0x93, 0x7f, 0x5b, 0x3f, 0x67, 0x69, 0xe8, + 0x9b, 0xf2, 0x89, 0x1b, 0xe2, 0xc9, 0x0a, 0x9c, 0xe3, 0xf7, 0x21, 0xa6, 0x6d, 0x2d, 0x9b, 0x6d, + 0x5a, 0xb3, 0xe6, 0xcd, 0x56, 0xcb, 0x74, 0xc5, 0xa5, 0xde, 0xf3, 0xdb, 0x5b, 0xe5, 0xab, 0x9e, + 0xed, 0xe9, 0xad, 0x06, 0xf5, 0xc9, 0x1a, 0x9e, 0xd9, 0xa6, 0x0d, 0xd3, 0x6a, 0xb4, 0x91, 0x52, + 0x62, 0x99, 0xce, 0x8a, 0xd4, 0x78, 0x38, 0xfe, 0x7a, 0x53, 0xb7, 0x2c, 0x6a, 0xd4, 0xac, 0xc9, + 0x4d, 0x8f, 0xf2, 0xcb, 0xc0, 0x02, 0x3f, 0x12, 0xe4, 0xef, 0xd0, 0x39, 0x9a, 0x31, 0x5e, 0x61, + 0x04, 0x5a, 0x4a, 0x21, 0xf5, 0xb7, 0x8a, 0x29, 0xe9, 0x61, 0x8e, 0x91, 0xfa, 0xf8, 0x3d, 0x5d, + 0xdc, 0xa1, 0xa7, 0xaf, 0xc3, 0x80, 0x88, 0x77, 0x2c, 0x2e, 0x18, 0xd0, 0x71, 0xfe, 0x21, 0x07, + 0xc9, 0x37, 0x34, 0x82, 0x8a, 0xb4, 0xe0, 0xd2, 0x32, 0xeb, 0xa6, 0xf4, 0xce, 0x2c, 0xed, 0xa3, + 0x33, 0x7b, 0xf0, 0x23, 0xef, 0xc2, 0x05, 0xc4, 0xa6, 0x74, 0xeb, 0x00, 0x56, 0x85, 0xa1, 0xb4, + 0x78, 0x55, 0xe9, 0x9d, 0x9b, 0x55, 0x9e, 0x7c, 0x16, 0x46, 0x82, 0x01, 0x62, 0x52, 0x57, 0xdc, + 0x5c, 0xf4, 0x18, 0x67, 0x3c, 0x4e, 0x1d, 0x03, 0xa3, 0xbb, 0x5a, 0x34, 0xd6, 0x59, 0x84, 0x97, + 0xfa, 0x3f, 0xe4, 0x7a, 0xa5, 0xa9, 0x39, 0xf2, 0x59, 0xf9, 0x2d, 0x18, 0x30, 0xf8, 0x47, 0x09, + 0x9d, 0xea, 0x9d, 0xc8, 0x86, 0x93, 0x6a, 0x7e, 0x19, 0xf5, 0x9f, 0xe5, 0x7a, 0x66, 0xc7, 0x39, + 0xee, 0x9f, 0xf7, 0x95, 0x42, 0xc6, 0xe7, 0x89, 0x49, 0xf4, 0x1a, 0x8c, 0x9b, 0x61, 0xf8, 0xfe, + 0x46, 0x18, 0xea, 0x4a, 0x3b, 0x25, 0xc1, 0x71, 0x74, 0xdd, 0x84, 0xc0, 0x61, 0xcb, 0xf1, 0xbd, + 0xd1, 0xdc, 0x46, 0xd7, 0x31, 0xf9, 0xb8, 0xd4, 0xce, 0xba, 0x31, 0x57, 0x35, 0xf7, 0xae, 0x63, + 0xb2, 0x0a, 0x74, 0x6f, 0x8d, 0x5a, 0x7a, 0x63, 0xc3, 0x76, 0xd6, 0x31, 0x18, 0x2a, 0x1f, 0x9c, + 0xda, 0x29, 0x0e, 0xbf, 0xef, 0x83, 0xc9, 0xb3, 0x30, 0xba, 0xda, 0xea, 0xd2, 0x20, 0xfc, 0x24, + 0xbf, 0xeb, 0xd3, 0x46, 0x18, 0x30, 0xb8, 0x21, 0x79, 0x12, 0x00, 0x89, 0x3c, 0xcc, 0x5d, 0x84, + 0x17, 0x7b, 0xda, 0x10, 0x83, 0x2c, 0x8b, 0xee, 0xba, 0xc4, 0xb5, 0x9a, 0x0b, 0xa9, 0xd1, 0xb2, + 0xad, 0xd5, 0x86, 0x47, 0x9d, 0x36, 0x36, 0x14, 0x9d, 0x19, 0xb4, 0xf3, 0x48, 0x81, 0x57, 0x27, + 0xee, 0x9c, 0x6d, 0xad, 0x2e, 0x53, 0xa7, 0xcd, 0x9a, 0xfa, 0x3c, 0x10, 0xd1, 0x54, 0x07, 0x0f, + 0x3d, 0xf8, 0xc7, 0xa1, 0x37, 0x83, 0x26, 0x3e, 0x82, 0x9f, 0x86, 0xe0, 0x87, 0x95, 0x61, 0x98, + 0xc7, 0xe0, 0xe3, 0x42, 0x43, 0x17, 0x06, 0x0d, 0x38, 0x08, 0xe5, 0x75, 0x1e, 0x84, 0x77, 0x05, + 0xf7, 0x20, 0xd7, 0xc4, 0x2f, 0xf5, 0x4b, 0x85, 0xb4, 0x84, 0x3e, 0x07, 0x52, 0xb4, 0x70, 0x5a, + 0xcd, 0xef, 0x69, 0x5a, 0x3d, 0x65, 0x75, 0xdb, 0x0d, 0xbd, 0xd3, 0x69, 0x3c, 0x30, 0x5b, 0xf8, + 0x84, 0x0b, 0x17, 0x3e, 0x6d, 0xd4, 0xea, 0xb6, 0x2b, 0x9d, 0xce, 0x0c, 0x07, 0x92, 0xe7, 0xe0, + 0x34, 0xa3, 0xc3, 0x4e, 0x0a, 0x28, 0x8b, 0x48, 0xc9, 0x18, 0x60, 0x10, 0x5b, 0x9f, 0xf6, 0x22, + 0x0c, 0x0a, 0x9e, 0x7c, 0xad, 0xea, 0xd7, 0x06, 0x38, 0x33, 0x97, 0xf5, 0x5c, 0xc0, 0x86, 0x4f, + 0xae, 0xfd, 0xda, 0x90, 0x5f, 0x1e, 0x43, 0x35, 0x5b, 0xdd, 0x36, 0x8f, 0xbe, 0x35, 0x80, 0xc8, + 0xe0, 0x37, 0xb9, 0x02, 0x63, 0x8c, 0x4b, 0x20, 0x30, 0x1e, 0xdd, 0xb6, 0x5f, 0x8b, 0x41, 0xc9, + 0x0d, 0x38, 0x1b, 0x81, 0x70, 0x1b, 0x94, 0x3f, 0x49, 0xe8, 0xd7, 0x52, 0x71, 0xea, 0x37, 0x0b, + 0xd1, 0x34, 0x43, 0x47, 0xd0, 0x11, 0x17, 0x60, 0xc0, 0x76, 0x56, 0x1b, 0x5d, 0xa7, 0x25, 0xc6, + 0x5e, 0xc9, 0x76, 0x56, 0xef, 0x3a, 0x2d, 0x72, 0x0e, 0x4a, 0xac, 0x77, 0x4c, 0x43, 0x0c, 0xb1, + 0x7e, 0xbd, 0xd3, 0xa9, 0x19, 0xa4, 0xc2, 0x3b, 0x04, 0x23, 0xa3, 0x36, 0x9a, 0xb8, 0xb5, 0xe7, + 0x4e, 0x09, 0xfd, 0x7c, 0xc5, 0x4b, 0x20, 0xb1, 0x9f, 0x30, 0x5e, 0x2a, 0x3f, 0x08, 0x88, 0xb1, + 0x30, 0x70, 0x5b, 0x62, 0xf0, 0x3e, 0x89, 0xb3, 0x10, 0xc8, 0x90, 0x05, 0xdf, 0xc4, 0x18, 0xa4, + 0x0a, 0x24, 0xa4, 0x6a, 0xdb, 0x86, 0xf9, 0xc0, 0xa4, 0xfc, 0x05, 0x49, 0x3f, 0xbf, 0xf8, 0x4d, + 0x62, 0xb5, 0x71, 0x9f, 0xc9, 0xbc, 0x80, 0x90, 0x37, 0xb8, 0x12, 0x72, 0x3a, 0x5c, 0xfb, 0x78, + 0xdf, 0x72, 0x3b, 0x2d, 0x86, 0x42, 0xcd, 0xc4, 0xf2, 0xb8, 0x10, 0xaa, 0x7f, 0xb3, 0x98, 0xcc, + 0x35, 0x75, 0x24, 0x76, 0xcd, 0x2c, 0x80, 0x48, 0x25, 0x17, 0x5e, 0xae, 0x5d, 0x92, 0xe2, 0xc6, + 0x0b, 0x4c, 0x06, 0x0f, 0xa9, 0x2c, 0xb9, 0x06, 0x83, 0xfc, 0x8b, 0x6a, 0x55, 0x61, 0xef, 0xa0, + 0x8b, 0x98, 0xdb, 0x31, 0x1f, 0x3c, 0x40, 0x7f, 0xb2, 0x00, 0x4d, 0xae, 0xc0, 0x40, 0x75, 0xa1, + 0x5e, 0xaf, 0x2c, 0xf8, 0x37, 0xc5, 0xf8, 0x96, 0xc5, 0xb0, 0xdc, 0x86, 0xab, 0x5b, 0xae, 0xe6, + 0x23, 0xc9, 0xb3, 0x50, 0xaa, 0x2d, 0x21, 0x19, 0x7f, 0xa1, 0x39, 0xbc, 0xbd, 0x55, 0x1e, 0x30, + 0x3b, 0x9c, 0x4a, 0xa0, 0xb0, 0xde, 0x7b, 0xb5, 0xaa, 0xe4, 0x2e, 0xc1, 0xeb, 0x7d, 0x68, 0x1a, + 0x78, 0xed, 0xac, 0x05, 0x68, 0xf2, 0x32, 0x8c, 0xd4, 0xa9, 0x63, 0xea, 0xad, 0x85, 0x2e, 0x6e, + 0x15, 0xa5, 0x88, 0x8f, 0x2e, 0xc2, 0x1b, 0x16, 0x22, 0xb4, 0x08, 0x19, 0xb9, 0x0c, 0xc5, 0x59, + 0xd3, 0xf2, 0x9f, 0x4b, 0xa0, 0x3f, 0xfd, 0x9a, 0x69, 0x79, 0x1a, 0x42, 0xc9, 0xb3, 0x50, 0xb8, + 0xbd, 0x5c, 0x13, 0x9e, 0x60, 0xc8, 0xeb, 0x3d, 0x2f, 0x12, 0x3d, 0xf2, 0xf6, 0x72, 0x8d, 0xbc, + 0x0c, 0x43, 0x6c, 0x11, 0xa3, 0x56, 0x93, 0xba, 0xca, 0x30, 0x7e, 0x0c, 0x0f, 0x59, 0xe8, 0x03, + 0x65, 0x9f, 0x8e, 0x80, 0x52, 0xfd, 0x3f, 0xf2, 0xe9, 0xc9, 0xc0, 0x8e, 0x60, 0xa8, 0xef, 0xf3, + 0x16, 0x39, 0xa6, 0x60, 0xc5, 0x03, 0x28, 0xd8, 0x03, 0x38, 0x55, 0x31, 0xda, 0xa6, 0x55, 0xc1, + 0x9f, 0xee, 0xfc, 0x4c, 0x05, 0xa7, 0x0e, 0xe9, 0x29, 0x60, 0x0c, 0x2d, 0xbe, 0x87, 0xc7, 0x25, + 0x66, 0xa8, 0x86, 0xce, 0x71, 0x8d, 0xf6, 0x03, 0xbd, 0xd1, 0xe4, 0x79, 0xb4, 0xb4, 0x38, 0x53, + 0xf5, 0xa7, 0xf2, 0x3b, 0xe4, 0x2f, 0x7b, 0x1c, 0xa5, 0xaf, 0x7e, 0x35, 0xdf, 0x3b, 0x85, 0xdc, + 0x63, 0x29, 0x94, 0x3f, 0xc9, 0xa7, 0x24, 0x74, 0x3b, 0x90, 0x24, 0xae, 0xc1, 0x20, 0x67, 0x13, + 0xb8, 0xf1, 0xe2, 0x6c, 0xc6, 0x95, 0x15, 0x67, 0x51, 0x1f, 0x4d, 0x16, 0xe0, 0x6c, 0xe5, 0xc1, + 0x03, 0xda, 0xf4, 0xc2, 0x08, 0xd5, 0x0b, 0x61, 0xc0, 0x57, 0x1e, 0x91, 0x57, 0xe0, 0xc3, 0x08, + 0xd7, 0x18, 0xd8, 0x24, 0xb5, 0x1c, 0x59, 0x86, 0xf3, 0x71, 0x78, 0x9d, 0x6f, 0x01, 0x8a, 0x52, + 0x90, 0xde, 0x04, 0x47, 0xfe, 0x9f, 0x96, 0x51, 0x36, 0xad, 0x95, 0x38, 0x55, 0xf7, 0xf7, 0x6a, + 0x25, 0xce, 0xdb, 0xa9, 0xe5, 0xd4, 0x6f, 0x15, 0xe4, 0xbc, 0x77, 0x8f, 0xaf, 0xc3, 0xd5, 0xcd, + 0x88, 0x9b, 0xf5, 0x6e, 0x87, 0xcc, 0xcb, 0x22, 0x5a, 0x89, 0xd1, 0x75, 0x7c, 0x8f, 0xc4, 0x20, + 0x5a, 0x02, 0x02, 0xe5, 0x75, 0x28, 0xa0, 0x24, 0x35, 0x28, 0x56, 0x9c, 0x55, 0x6e, 0xde, 0xee, + 0xf4, 0x80, 0x4b, 0x77, 0x56, 0xdd, 0xf4, 0x07, 0x5c, 0x8c, 0x85, 0xfa, 0x97, 0xf3, 0x3d, 0x52, + 0xd5, 0x3d, 0x96, 0x93, 0xc8, 0xcf, 0xe5, 0xb3, 0x92, 0xce, 0x1d, 0x57, 0xd7, 0xb1, 0x0f, 0x58, + 0x38, 0xc7, 0xdb, 0xaf, 0xee, 0x10, 0x85, 0xf3, 0x87, 0xf9, 0xac, 0x0c, 0x7a, 0x27, 0xc2, 0xd9, + 0xdf, 0x04, 0x99, 0x2a, 0xd2, 0xc7, 0xd8, 0xe6, 0x96, 0x55, 0xa1, 0x7f, 0x9f, 0xee, 0x53, 0x69, + 0x22, 0x3d, 0x19, 0xc2, 0x07, 0xd2, 0xd2, 0x3f, 0xca, 0x67, 0x66, 0x8a, 0x3c, 0x91, 0xe9, 0x61, + 0xca, 0xf4, 0x64, 0xe8, 0x1f, 0x68, 0xe8, 0xa7, 0xca, 0xf4, 0x64, 0xec, 0x1f, 0x48, 0x4f, 0xff, + 0x20, 0x9f, 0x9e, 0x0b, 0xf5, 0x08, 0x94, 0xf4, 0x30, 0x3c, 0x1c, 0xfd, 0x6e, 0x28, 0x1e, 0xa8, + 0x1b, 0xfa, 0x0f, 0x60, 0x45, 0x25, 0x05, 0x7a, 0x64, 0xa3, 0xfe, 0xfb, 0x55, 0xa0, 0x87, 0x30, + 0xe4, 0x1f, 0x67, 0x81, 0xfe, 0x44, 0x21, 0x99, 0xff, 0xf7, 0x71, 0x5d, 0x93, 0x9c, 0x7d, 0xae, + 0x49, 0x7e, 0x39, 0xf2, 0x36, 0x9c, 0x0a, 0x65, 0x29, 0x47, 0x19, 0xc3, 0xeb, 0xa3, 0x26, 0x43, + 0x35, 0xde, 0x63, 0x38, 0x11, 0x0e, 0x27, 0x4e, 0xad, 0x7e, 0xaf, 0x90, 0x4c, 0xa2, 0x7c, 0xd2, + 0x1b, 0xfb, 0xec, 0x8d, 0xbb, 0x70, 0x7e, 0xaa, 0xeb, 0x38, 0xd4, 0xf2, 0xd2, 0x3b, 0x05, 0x0f, + 0xef, 0x9b, 0x9c, 0xa2, 0x91, 0xec, 0x9c, 0x8c, 0xc2, 0x8c, 0xad, 0x78, 0xdd, 0x10, 0x67, 0x3b, + 0x10, 0xb2, 0xed, 0x72, 0x8a, 0x34, 0xb6, 0xe9, 0x85, 0xd5, 0xdf, 0xcb, 0x27, 0xd3, 0x5e, 0x9f, + 0x74, 0xfd, 0xfe, 0xba, 0x5e, 0xfd, 0x52, 0x21, 0x9e, 0xfa, 0xfb, 0x64, 0x81, 0xd8, 0x7f, 0x77, + 0xf8, 0x92, 0xc4, 0x71, 0x23, 0x7d, 0x85, 0x0f, 0xcf, 0xfa, 0x0a, 0x1f, 0xaf, 0xfe, 0x72, 0x31, + 0x9e, 0x46, 0xfd, 0xa4, 0x3b, 0x8e, 0xae, 0x3b, 0xc8, 0x22, 0x9c, 0x15, 0x73, 0x9b, 0x0f, 0xc2, + 0x74, 0x13, 0x62, 0xfe, 0xe2, 0x59, 0xeb, 0xc4, 0xb4, 0xd8, 0x75, 0xa9, 0xd3, 0xf0, 0x74, 0x77, + 0xbd, 0x81, 0xf9, 0x29, 0xb4, 0xd4, 0x82, 0x8c, 0xa1, 0x98, 0xd5, 0xa2, 0x0c, 0x07, 0x43, 0x86, + 0xfe, 0x84, 0x98, 0x60, 0x98, 0x56, 0x50, 0xfd, 0xf5, 0x1c, 0x8c, 0xc7, 0x3f, 0x87, 0x4c, 0xc0, + 0x20, 0xfb, 0x1d, 0x3c, 0xbb, 0x97, 0xd2, 0x69, 0x73, 0x8e, 0xfc, 0x4a, 0xde, 0xa7, 0x21, 0xaf, + 0xc0, 0x10, 0x7a, 0x3f, 0x60, 0x81, 0x7c, 0x18, 0xed, 0x20, 0x2c, 0x80, 0x39, 0x5e, 0x79, 0xb1, + 0x90, 0x94, 0xbc, 0x01, 0xc3, 0xb5, 0xd0, 0xcd, 0x4b, 0xdc, 0x79, 0xa1, 0x77, 0xa9, 0x54, 0x32, + 0x24, 0xd0, 0x64, 0x6a, 0xf5, 0x3b, 0xf9, 0x78, 0xba, 0xff, 0x13, 0x55, 0xdf, 0xa7, 0x69, 0xfa, + 0x2b, 0x05, 0x18, 0x9d, 0xb2, 0x2d, 0x4f, 0x6f, 0x7a, 0x27, 0xe7, 0x4f, 0x07, 0xd9, 0xd7, 0x93, + 0x32, 0xf4, 0x4f, 0xb7, 0x75, 0xb3, 0x25, 0x0c, 0x1f, 0x8c, 0xc9, 0x4a, 0x19, 0x40, 0xe3, 0x70, + 0x72, 0x0b, 0x23, 0x91, 0x30, 0x49, 0x07, 0xbe, 0x2e, 0x63, 0x61, 0xf8, 0x4a, 0x09, 0x25, 0x12, + 0xb8, 0x72, 0x00, 0x1f, 0x39, 0x72, 0x49, 0xb9, 0xcf, 0x4e, 0xce, 0x62, 0x8e, 0x49, 0x9f, 0x7d, + 0xad, 0x00, 0xe7, 0xef, 0xdb, 0xce, 0x7a, 0xcb, 0xd6, 0x0d, 0x3f, 0x13, 0xee, 0xc9, 0x80, 0x13, + 0x9d, 0xf7, 0xe7, 0xe0, 0x6c, 0x5c, 0x36, 0x55, 0x26, 0x8d, 0xfe, 0xde, 0xd7, 0xd5, 0x13, 0xdb, + 0x5b, 0xe5, 0xa7, 0x37, 0x44, 0xc1, 0x30, 0x1d, 0x37, 0xab, 0x2c, 0xf5, 0x02, 0x3b, 0xb5, 0x92, + 0xd4, 0x9e, 0xf9, 0x90, 0x3c, 0xc4, 0x7b, 0xcc, 0x7b, 0xe6, 0xe7, 0xf2, 0xc9, 0x9e, 0x39, 0x99, + 0xf0, 0x38, 0xc5, 0x73, 0xf3, 0xdc, 0x46, 0xbd, 0x63, 0x5a, 0x06, 0xb9, 0x08, 0xe7, 0xee, 0xd6, + 0xa7, 0xb5, 0xc6, 0x9d, 0xda, 0x42, 0xb5, 0x71, 0x77, 0xa1, 0xbe, 0x34, 0x3d, 0x55, 0x9b, 0xa9, + 0x4d, 0x57, 0xc7, 0xfb, 0xc8, 0x19, 0x38, 0x15, 0xa2, 0x66, 0xef, 0xce, 0x57, 0x16, 0xc6, 0x73, + 0xe4, 0x34, 0x8c, 0x86, 0xc0, 0xc9, 0xc5, 0xe5, 0xf1, 0xfc, 0x73, 0x1f, 0x83, 0x61, 0xf4, 0x4b, + 0xe7, 0x7e, 0x74, 0x64, 0x04, 0x06, 0x17, 0x27, 0xeb, 0xd3, 0xda, 0x3d, 0x64, 0x02, 0x50, 0xaa, + 0x4e, 0x2f, 0x30, 0x86, 0xb9, 0xe7, 0xfe, 0xef, 0x1c, 0x40, 0x7d, 0x66, 0x79, 0x49, 0x10, 0x0e, + 0xc3, 0x40, 0x6d, 0xe1, 0x5e, 0x65, 0xae, 0xc6, 0xe8, 0x06, 0xa1, 0xb8, 0xb8, 0x34, 0xcd, 0x6a, + 0x18, 0x82, 0xfe, 0xa9, 0xb9, 0xc5, 0xfa, 0xf4, 0x78, 0x9e, 0x01, 0xb5, 0xe9, 0x4a, 0x75, 0xbc, + 0xc0, 0x80, 0xf7, 0xb5, 0xda, 0xf2, 0xf4, 0x78, 0x91, 0xfd, 0x39, 0x57, 0x5f, 0xae, 0x2c, 0x8f, + 0xf7, 0xb3, 0x3f, 0x67, 0xf0, 0xcf, 0x12, 0x63, 0x56, 0x9f, 0x5e, 0xc6, 0x1f, 0x03, 0xac, 0x09, + 0x33, 0xfe, 0xaf, 0x41, 0x86, 0x62, 0xac, 0xab, 0x35, 0x6d, 0x7c, 0x88, 0xfd, 0x60, 0x2c, 0xd9, + 0x0f, 0x60, 0x8d, 0xd3, 0xa6, 0xe7, 0x17, 0xef, 0x4d, 0x8f, 0x0f, 0x33, 0x5e, 0xf3, 0x77, 0x18, + 0x78, 0x84, 0xfd, 0xa9, 0xcd, 0xb3, 0x3f, 0x47, 0x19, 0x27, 0x6d, 0xba, 0x32, 0xb7, 0x54, 0x59, + 0x9e, 0x1d, 0x1f, 0x63, 0xed, 0x41, 0x9e, 0xa7, 0x78, 0xc9, 0x85, 0xca, 0xfc, 0xf4, 0xf8, 0xb8, + 0xa0, 0xa9, 0xce, 0xd5, 0x16, 0xee, 0x8c, 0x9f, 0xc6, 0x86, 0xbc, 0x3b, 0x8f, 0x3f, 0x08, 0x2b, + 0x80, 0x7f, 0x9d, 0x79, 0xee, 0x07, 0xa0, 0xb4, 0x58, 0x47, 0xf3, 0xf5, 0x02, 0x9c, 0x59, 0xac, + 0x37, 0x96, 0xdf, 0x5d, 0x9a, 0x8e, 0xc9, 0xfb, 0x34, 0x8c, 0xfa, 0x88, 0xb9, 0xda, 0xc2, 0xdd, + 0xcf, 0x70, 0x69, 0xfb, 0xa0, 0xf9, 0xca, 0xd4, 0x62, 0x7d, 0x3c, 0xcf, 0x7a, 0xc5, 0x07, 0xdd, + 0xaf, 0x2d, 0x54, 0x17, 0xef, 0xd7, 0xc7, 0x0b, 0xcf, 0x3d, 0x84, 0x11, 0x9e, 0x60, 0x7b, 0xd1, + 0x31, 0x57, 0x4d, 0x8b, 0x3c, 0x09, 0x17, 0xab, 0xd3, 0xf7, 0x6a, 0x53, 0xd3, 0x8d, 0x45, 0xad, + 0x76, 0xab, 0xb6, 0x10, 0xab, 0xe9, 0x1c, 0x9c, 0x8e, 0xa2, 0x2b, 0x4b, 0xb5, 0xf1, 0x1c, 0x39, + 0x0f, 0x24, 0x0a, 0xbe, 0x5d, 0x99, 0x9f, 0x19, 0xcf, 0x13, 0x05, 0xce, 0x46, 0xe1, 0xb5, 0x85, + 0xe5, 0xbb, 0x0b, 0xd3, 0xe3, 0x85, 0xe7, 0xfe, 0x46, 0x0e, 0xce, 0xa5, 0x26, 0x61, 0x20, 0x2a, + 0x3c, 0x35, 0x3d, 0x57, 0xa9, 0x2f, 0xd7, 0xa6, 0xea, 0xd3, 0x15, 0x6d, 0x6a, 0xb6, 0x31, 0x55, + 0x59, 0x9e, 0xbe, 0xb5, 0xa8, 0xbd, 0xdb, 0xb8, 0x35, 0xbd, 0x30, 0xad, 0x55, 0xe6, 0xc6, 0xfb, + 0xc8, 0xb3, 0x50, 0xce, 0xa0, 0xa9, 0x4f, 0x4f, 0xdd, 0xd5, 0x6a, 0xcb, 0xef, 0x8e, 0xe7, 0xc8, + 0x33, 0xf0, 0x64, 0x26, 0x11, 0xfb, 0x3d, 0x9e, 0x27, 0x4f, 0xc1, 0xa5, 0x2c, 0x92, 0x77, 0xe6, + 0xc6, 0x0b, 0xcf, 0xfd, 0x6c, 0x0e, 0x48, 0x32, 0x8a, 0x3e, 0x79, 0x1a, 0x2e, 0x33, 0xbd, 0x68, + 0x64, 0x37, 0xf0, 0x19, 0x78, 0x32, 0x95, 0x42, 0x6a, 0x5e, 0x19, 0x9e, 0xc8, 0x20, 0x11, 0x8d, + 0xbb, 0x0c, 0x4a, 0x3a, 0x01, 0x36, 0xed, 0xd7, 0x72, 0x70, 0x2e, 0xd5, 0x75, 0x95, 0x5c, 0x85, + 0x8f, 0x54, 0xaa, 0xf3, 0xac, 0x6f, 0xa6, 0x96, 0x6b, 0x8b, 0x0b, 0xf5, 0xc6, 0xfc, 0x4c, 0xa5, + 0xc1, 0xb4, 0xef, 0x6e, 0x3d, 0xd6, 0x9b, 0x57, 0x40, 0xed, 0x41, 0x39, 0x35, 0x5b, 0x59, 0xb8, + 0xc5, 0x86, 0x1f, 0xf9, 0x08, 0x3c, 0x9d, 0x49, 0x37, 0xbd, 0x50, 0x99, 0x9c, 0x9b, 0xae, 0x8e, + 0xe7, 0xc9, 0x47, 0xe1, 0x99, 0x4c, 0xaa, 0x6a, 0xad, 0xce, 0xc9, 0x0a, 0xcf, 0xe9, 0x11, 0xeb, + 0x86, 0x7d, 0xe5, 0xd4, 0xe2, 0xc2, 0x72, 0x65, 0x6a, 0x39, 0x4d, 0xb3, 0x2f, 0xc2, 0xb9, 0x08, + 0x76, 0xf2, 0x6e, 0xbd, 0xb6, 0x30, 0x5d, 0xaf, 0x8f, 0xe7, 0x12, 0xa8, 0x40, 0xb4, 0xf9, 0xc9, + 0xea, 0x77, 0xfe, 0xa7, 0xa7, 0xfa, 0xbe, 0xf3, 0xc7, 0x4f, 0xe5, 0xfe, 0xf0, 0x8f, 0x9f, 0xca, + 0xfd, 0xf3, 0x3f, 0x7e, 0x2a, 0xf7, 0xd9, 0x1b, 0x7b, 0x49, 0xc0, 0xc0, 0x67, 0xc6, 0x95, 0x12, + 0x2e, 0x30, 0x2f, 0xfd, 0xff, 0x01, 0x00, 0x00, 0xff, 0xff, 0x21, 0x79, 0xa6, 0xb2, 0xb9, 0x8c, + 0x01, 0x00, } func (m *Metadata) Marshal() (dAtA []byte, err error) { @@ -20081,6 +20460,26 @@ func (m *PortForward) MarshalToSizedBuffer(dAtA []byte) (int, error) { i -= len(m.XXX_unrecognized) copy(dAtA[i:], m.XXX_unrecognized) } + { + size, err := m.KubernetesPodMetadata.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintEvents(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x3a + { + size, err := m.KubernetesClusterMetadata.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintEvents(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x32 if len(m.Addr) > 0 { i -= len(m.Addr) copy(dAtA[i:], m.Addr) @@ -20479,63 +20878,63 @@ func (m *SFTPAttributes) MarshalToSizedBuffer(dAtA []byte) (int, error) { copy(dAtA[i:], m.XXX_unrecognized) } if m.ModificationTime != nil { - n154, err154 := github_com_gogo_protobuf_types.StdTimeMarshalTo(*m.ModificationTime, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(*m.ModificationTime):]) - if err154 != nil { - return 0, err154 - } - i -= n154 - i = encodeVarintEvents(dAtA, i, uint64(n154)) - i-- - dAtA[i] = 0x32 - } - if m.AccessTime != nil { - n155, err155 := github_com_gogo_protobuf_types.StdTimeMarshalTo(*m.AccessTime, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(*m.AccessTime):]) - if err155 != nil { - return 0, err155 - } - i -= n155 - i = encodeVarintEvents(dAtA, i, uint64(n155)) - i-- - dAtA[i] = 0x2a - } - if m.Permissions != nil { - n156, err156 := github_com_gogo_protobuf_types.StdUInt32MarshalTo(*m.Permissions, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdUInt32(*m.Permissions):]) + n156, err156 := github_com_gogo_protobuf_types.StdTimeMarshalTo(*m.ModificationTime, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(*m.ModificationTime):]) if err156 != nil { return 0, err156 } i -= n156 i = encodeVarintEvents(dAtA, i, uint64(n156)) i-- - dAtA[i] = 0x22 + dAtA[i] = 0x32 } - if m.GID != nil { - n157, err157 := github_com_gogo_protobuf_types.StdUInt32MarshalTo(*m.GID, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdUInt32(*m.GID):]) + if m.AccessTime != nil { + n157, err157 := github_com_gogo_protobuf_types.StdTimeMarshalTo(*m.AccessTime, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(*m.AccessTime):]) if err157 != nil { return 0, err157 } i -= n157 i = encodeVarintEvents(dAtA, i, uint64(n157)) i-- - dAtA[i] = 0x1a + dAtA[i] = 0x2a } - if m.UID != nil { - n158, err158 := github_com_gogo_protobuf_types.StdUInt32MarshalTo(*m.UID, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdUInt32(*m.UID):]) + if m.Permissions != nil { + n158, err158 := github_com_gogo_protobuf_types.StdUInt32MarshalTo(*m.Permissions, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdUInt32(*m.Permissions):]) if err158 != nil { return 0, err158 } i -= n158 i = encodeVarintEvents(dAtA, i, uint64(n158)) i-- - dAtA[i] = 0x12 + dAtA[i] = 0x22 } - if m.FileSize != nil { - n159, err159 := github_com_gogo_protobuf_types.StdUInt64MarshalTo(*m.FileSize, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdUInt64(*m.FileSize):]) + if m.GID != nil { + n159, err159 := github_com_gogo_protobuf_types.StdUInt32MarshalTo(*m.GID, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdUInt32(*m.GID):]) if err159 != nil { return 0, err159 } i -= n159 i = encodeVarintEvents(dAtA, i, uint64(n159)) i-- + dAtA[i] = 0x1a + } + if m.UID != nil { + n160, err160 := github_com_gogo_protobuf_types.StdUInt32MarshalTo(*m.UID, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdUInt32(*m.UID):]) + if err160 != nil { + return 0, err160 + } + i -= n160 + i = encodeVarintEvents(dAtA, i, uint64(n160)) + i-- + dAtA[i] = 0x12 + } + if m.FileSize != nil { + n161, err161 := github_com_gogo_protobuf_types.StdUInt64MarshalTo(*m.FileSize, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdUInt64(*m.FileSize):]) + if err161 != nil { + return 0, err161 + } + i -= n161 + i = encodeVarintEvents(dAtA, i, uint64(n161)) + i-- dAtA[i] = 0xa } return len(dAtA) - i, nil @@ -24613,20 +25012,20 @@ func (m *DatabaseSessionEnd) MarshalToSizedBuffer(dAtA []byte) (int, error) { i -= len(m.XXX_unrecognized) copy(dAtA[i:], m.XXX_unrecognized) } - n358, err358 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.EndTime, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.EndTime):]) - if err358 != nil { - return 0, err358 + n360, err360 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.EndTime, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.EndTime):]) + if err360 != nil { + return 0, err360 } - i -= n358 - i = encodeVarintEvents(dAtA, i, uint64(n358)) + i -= n360 + i = encodeVarintEvents(dAtA, i, uint64(n360)) i-- dAtA[i] = 0x32 - n359, err359 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.StartTime, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.StartTime):]) - if err359 != nil { - return 0, err359 + n361, err361 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.StartTime, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.StartTime):]) + if err361 != nil { + return 0, err361 } - i -= n359 - i = encodeVarintEvents(dAtA, i, uint64(n359)) + i -= n361 + i = encodeVarintEvents(dAtA, i, uint64(n361)) i-- dAtA[i] = 0x2a { @@ -25293,20 +25692,20 @@ func (m *WindowsDesktopSessionEnd) MarshalToSizedBuffer(dAtA []byte) (int, error i-- dAtA[i] = 0x5a } - n392, err392 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.EndTime, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.EndTime):]) - if err392 != nil { - return 0, err392 + n394, err394 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.EndTime, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.EndTime):]) + if err394 != nil { + return 0, err394 } - i -= n392 - i = encodeVarintEvents(dAtA, i, uint64(n392)) + i -= n394 + i = encodeVarintEvents(dAtA, i, uint64(n394)) i-- dAtA[i] = 0x52 - n393, err393 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.StartTime, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.StartTime):]) - if err393 != nil { - return 0, err393 + n395, err395 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.StartTime, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.StartTime):]) + if err395 != nil { + return 0, err395 } - i -= n393 - i = encodeVarintEvents(dAtA, i, uint64(n393)) + i -= n395 + i = encodeVarintEvents(dAtA, i, uint64(n395)) i-- dAtA[i] = 0x4a if len(m.DesktopLabels) > 0 { @@ -25640,12 +26039,12 @@ func (m *InstanceJoin) MarshalToSizedBuffer(dAtA []byte) (int, error) { } i-- dAtA[i] = 0x52 - n407, err407 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.TokenExpires, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.TokenExpires):]) - if err407 != nil { - return 0, err407 + n409, err409 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.TokenExpires, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.TokenExpires):]) + if err409 != nil { + return 0, err409 } - i -= n407 - i = encodeVarintEvents(dAtA, i, uint64(n407)) + i -= n409 + i = encodeVarintEvents(dAtA, i, uint64(n409)) i-- dAtA[i] = 0x4a if m.Attributes != nil { @@ -31272,6 +31671,121 @@ func (m *OneOf_SFTPSummary) MarshalToSizedBuffer(dAtA []byte) (int, error) { } return len(dAtA) - i, nil } +func (m *OneOf_ContactCreate) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *OneOf_ContactCreate) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + if m.ContactCreate != nil { + { + size, err := m.ContactCreate.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintEvents(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xc + i-- + dAtA[i] = 0x82 + } + return len(dAtA) - i, nil +} +func (m *OneOf_ContactDelete) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *OneOf_ContactDelete) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + if m.ContactDelete != nil { + { + size, err := m.ContactDelete.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintEvents(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xc + i-- + dAtA[i] = 0x8a + } + return len(dAtA) - i, nil +} +func (m *OneOf_WorkloadIdentityCreate) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *OneOf_WorkloadIdentityCreate) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + if m.WorkloadIdentityCreate != nil { + { + size, err := m.WorkloadIdentityCreate.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintEvents(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xc + i-- + dAtA[i] = 0x92 + } + return len(dAtA) - i, nil +} +func (m *OneOf_WorkloadIdentityUpdate) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *OneOf_WorkloadIdentityUpdate) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + if m.WorkloadIdentityUpdate != nil { + { + size, err := m.WorkloadIdentityUpdate.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintEvents(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xc + i-- + dAtA[i] = 0x9a + } + return len(dAtA) - i, nil +} +func (m *OneOf_WorkloadIdentityDelete) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *OneOf_WorkloadIdentityDelete) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + if m.WorkloadIdentityDelete != nil { + { + size, err := m.WorkloadIdentityDelete.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintEvents(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xc + i-- + dAtA[i] = 0xa2 + } + return len(dAtA) - i, nil +} func (m *StreamStatus) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -31296,12 +31810,12 @@ func (m *StreamStatus) MarshalToSizedBuffer(dAtA []byte) (int, error) { i -= len(m.XXX_unrecognized) copy(dAtA[i:], m.XXX_unrecognized) } - n656, err656 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.LastUploadTime, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.LastUploadTime):]) - if err656 != nil { - return 0, err656 + n663, err663 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.LastUploadTime, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.LastUploadTime):]) + if err663 != nil { + return 0, err663 } - i -= n656 - i = encodeVarintEvents(dAtA, i, uint64(n656)) + i -= n663 + i = encodeVarintEvents(dAtA, i, uint64(n663)) i-- dAtA[i] = 0x1a if m.LastEventIndex != 0 { @@ -31460,12 +31974,12 @@ func (m *Identity) MarshalToSizedBuffer(dAtA []byte) (int, error) { dAtA[i] = 0xc2 } } - n660, err660 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.PreviousIdentityExpires, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.PreviousIdentityExpires):]) - if err660 != nil { - return 0, err660 + n667, err667 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.PreviousIdentityExpires, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.PreviousIdentityExpires):]) + if err667 != nil { + return 0, err667 } - i -= n660 - i = encodeVarintEvents(dAtA, i, uint64(n660)) + i -= n667 + i = encodeVarintEvents(dAtA, i, uint64(n667)) i-- dAtA[i] = 0x1 i-- @@ -31613,12 +32127,12 @@ func (m *Identity) MarshalToSizedBuffer(dAtA []byte) (int, error) { i-- dAtA[i] = 0x4a } - n664, err664 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Expires, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Expires):]) - if err664 != nil { - return 0, err664 + n671, err671 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Expires, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Expires):]) + if err671 != nil { + return 0, err671 } - i -= n664 - i = encodeVarintEvents(dAtA, i, uint64(n664)) + i -= n671 + i = encodeVarintEvents(dAtA, i, uint64(n671)) i-- dAtA[i] = 0x42 if len(m.KubernetesUsers) > 0 { @@ -38246,6 +38760,409 @@ func (m *UserTaskDelete) MarshalToSizedBuffer(dAtA []byte) (int, error) { return len(dAtA) - i, nil } +func (m *ContactCreate) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *ContactCreate) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *ContactCreate) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.XXX_unrecognized != nil { + i -= len(m.XXX_unrecognized) + copy(dAtA[i:], m.XXX_unrecognized) + } + if m.ContactType != 0 { + i = encodeVarintEvents(dAtA, i, uint64(m.ContactType)) + i-- + dAtA[i] = 0x38 + } + if len(m.Email) > 0 { + i -= len(m.Email) + copy(dAtA[i:], m.Email) + i = encodeVarintEvents(dAtA, i, uint64(len(m.Email))) + i-- + dAtA[i] = 0x32 + } + { + size, err := m.Status.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintEvents(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x2a + { + size, err := m.ConnectionMetadata.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintEvents(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x22 + { + size, err := m.UserMetadata.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintEvents(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x1a + { + size, err := m.ResourceMetadata.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintEvents(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + { + size, err := m.Metadata.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintEvents(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + +func (m *ContactDelete) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *ContactDelete) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *ContactDelete) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.XXX_unrecognized != nil { + i -= len(m.XXX_unrecognized) + copy(dAtA[i:], m.XXX_unrecognized) + } + if m.ContactType != 0 { + i = encodeVarintEvents(dAtA, i, uint64(m.ContactType)) + i-- + dAtA[i] = 0x38 + } + if len(m.Email) > 0 { + i -= len(m.Email) + copy(dAtA[i:], m.Email) + i = encodeVarintEvents(dAtA, i, uint64(len(m.Email))) + i-- + dAtA[i] = 0x32 + } + { + size, err := m.Status.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintEvents(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x2a + { + size, err := m.ConnectionMetadata.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintEvents(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x22 + { + size, err := m.UserMetadata.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintEvents(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x1a + { + size, err := m.ResourceMetadata.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintEvents(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + { + size, err := m.Metadata.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintEvents(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + +func (m *WorkloadIdentityCreate) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *WorkloadIdentityCreate) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *WorkloadIdentityCreate) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.XXX_unrecognized != nil { + i -= len(m.XXX_unrecognized) + copy(dAtA[i:], m.XXX_unrecognized) + } + if m.WorkloadIdentityData != nil { + { + size, err := m.WorkloadIdentityData.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintEvents(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x2a + } + { + size, err := m.ConnectionMetadata.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintEvents(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x22 + { + size, err := m.UserMetadata.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintEvents(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x1a + { + size, err := m.ResourceMetadata.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintEvents(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + { + size, err := m.Metadata.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintEvents(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + +func (m *WorkloadIdentityUpdate) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *WorkloadIdentityUpdate) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *WorkloadIdentityUpdate) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.XXX_unrecognized != nil { + i -= len(m.XXX_unrecognized) + copy(dAtA[i:], m.XXX_unrecognized) + } + if m.WorkloadIdentityData != nil { + { + size, err := m.WorkloadIdentityData.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintEvents(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x2a + } + { + size, err := m.ConnectionMetadata.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintEvents(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x22 + { + size, err := m.UserMetadata.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintEvents(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x1a + { + size, err := m.ResourceMetadata.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintEvents(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + { + size, err := m.Metadata.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintEvents(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + +func (m *WorkloadIdentityDelete) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *WorkloadIdentityDelete) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *WorkloadIdentityDelete) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.XXX_unrecognized != nil { + i -= len(m.XXX_unrecognized) + copy(dAtA[i:], m.XXX_unrecognized) + } + { + size, err := m.ConnectionMetadata.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintEvents(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x22 + { + size, err := m.UserMetadata.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintEvents(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x1a + { + size, err := m.ResourceMetadata.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintEvents(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + { + size, err := m.Metadata.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintEvents(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + func encodeVarintEvents(dAtA []byte, offset int, v uint64) int { offset -= sovEvents(v) base := offset @@ -39786,6 +40703,10 @@ func (m *PortForward) Size() (n int) { if l > 0 { n += 1 + l + sovEvents(uint64(l)) } + l = m.KubernetesClusterMetadata.Size() + n += 1 + l + sovEvents(uint64(l)) + l = m.KubernetesPodMetadata.Size() + n += 1 + l + sovEvents(uint64(l)) if m.XXX_unrecognized != nil { n += len(m.XXX_unrecognized) } @@ -44400,6 +45321,66 @@ func (m *OneOf_SFTPSummary) Size() (n int) { } return n } +func (m *OneOf_ContactCreate) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.ContactCreate != nil { + l = m.ContactCreate.Size() + n += 2 + l + sovEvents(uint64(l)) + } + return n +} +func (m *OneOf_ContactDelete) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.ContactDelete != nil { + l = m.ContactDelete.Size() + n += 2 + l + sovEvents(uint64(l)) + } + return n +} +func (m *OneOf_WorkloadIdentityCreate) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.WorkloadIdentityCreate != nil { + l = m.WorkloadIdentityCreate.Size() + n += 2 + l + sovEvents(uint64(l)) + } + return n +} +func (m *OneOf_WorkloadIdentityUpdate) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.WorkloadIdentityUpdate != nil { + l = m.WorkloadIdentityUpdate.Size() + n += 2 + l + sovEvents(uint64(l)) + } + return n +} +func (m *OneOf_WorkloadIdentityDelete) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.WorkloadIdentityDelete != nil { + l = m.WorkloadIdentityDelete.Size() + n += 2 + l + sovEvents(uint64(l)) + } + return n +} func (m *StreamStatus) Size() (n int) { if m == nil { return 0 @@ -46886,6 +47867,132 @@ func (m *UserTaskDelete) Size() (n int) { return n } +func (m *ContactCreate) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = m.Metadata.Size() + n += 1 + l + sovEvents(uint64(l)) + l = m.ResourceMetadata.Size() + n += 1 + l + sovEvents(uint64(l)) + l = m.UserMetadata.Size() + n += 1 + l + sovEvents(uint64(l)) + l = m.ConnectionMetadata.Size() + n += 1 + l + sovEvents(uint64(l)) + l = m.Status.Size() + n += 1 + l + sovEvents(uint64(l)) + l = len(m.Email) + if l > 0 { + n += 1 + l + sovEvents(uint64(l)) + } + if m.ContactType != 0 { + n += 1 + sovEvents(uint64(m.ContactType)) + } + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} + +func (m *ContactDelete) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = m.Metadata.Size() + n += 1 + l + sovEvents(uint64(l)) + l = m.ResourceMetadata.Size() + n += 1 + l + sovEvents(uint64(l)) + l = m.UserMetadata.Size() + n += 1 + l + sovEvents(uint64(l)) + l = m.ConnectionMetadata.Size() + n += 1 + l + sovEvents(uint64(l)) + l = m.Status.Size() + n += 1 + l + sovEvents(uint64(l)) + l = len(m.Email) + if l > 0 { + n += 1 + l + sovEvents(uint64(l)) + } + if m.ContactType != 0 { + n += 1 + sovEvents(uint64(m.ContactType)) + } + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} + +func (m *WorkloadIdentityCreate) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = m.Metadata.Size() + n += 1 + l + sovEvents(uint64(l)) + l = m.ResourceMetadata.Size() + n += 1 + l + sovEvents(uint64(l)) + l = m.UserMetadata.Size() + n += 1 + l + sovEvents(uint64(l)) + l = m.ConnectionMetadata.Size() + n += 1 + l + sovEvents(uint64(l)) + if m.WorkloadIdentityData != nil { + l = m.WorkloadIdentityData.Size() + n += 1 + l + sovEvents(uint64(l)) + } + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} + +func (m *WorkloadIdentityUpdate) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = m.Metadata.Size() + n += 1 + l + sovEvents(uint64(l)) + l = m.ResourceMetadata.Size() + n += 1 + l + sovEvents(uint64(l)) + l = m.UserMetadata.Size() + n += 1 + l + sovEvents(uint64(l)) + l = m.ConnectionMetadata.Size() + n += 1 + l + sovEvents(uint64(l)) + if m.WorkloadIdentityData != nil { + l = m.WorkloadIdentityData.Size() + n += 1 + l + sovEvents(uint64(l)) + } + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} + +func (m *WorkloadIdentityDelete) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = m.Metadata.Size() + n += 1 + l + sovEvents(uint64(l)) + l = m.ResourceMetadata.Size() + n += 1 + l + sovEvents(uint64(l)) + l = m.UserMetadata.Size() + n += 1 + l + sovEvents(uint64(l)) + l = m.ConnectionMetadata.Size() + n += 1 + l + sovEvents(uint64(l)) + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} + func sovEvents(x uint64) (n int) { return (math_bits.Len64(x|1) + 6) / 7 } @@ -58877,60 +59984,126 @@ func (m *PortForward) Unmarshal(dAtA []byte) error { } m.Addr = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipEvents(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthEvents - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *X11Forward) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowEvents - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: X11Forward: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: X11Forward: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: + case 6: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Metadata", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field KubernetesClusterMetadata", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvents + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthEvents + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthEvents + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.KubernetesClusterMetadata.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 7: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field KubernetesPodMetadata", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvents + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthEvents + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthEvents + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.KubernetesPodMetadata.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipEvents(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthEvents + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *X11Forward) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvents + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: X11Forward: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: X11Forward: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Metadata", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -85603,62 +86776,11 @@ func (m *OneOf) Unmarshal(dAtA []byte) error { } m.Event = &OneOf_SFTPSummary{v} iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipEvents(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthEvents - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *StreamStatus) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowEvents - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: StreamStatus: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: StreamStatus: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: + case 192: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field UploadID", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field ContactCreate", wireType) } - var stringLen uint64 + var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowEvents @@ -85668,46 +86790,30 @@ func (m *StreamStatus) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + msglen |= int(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { + if msglen < 0 { return ErrInvalidLengthEvents } - postIndex := iNdEx + intStringLen + postIndex := iNdEx + msglen if postIndex < 0 { return ErrInvalidLengthEvents } if postIndex > l { return io.ErrUnexpectedEOF } - m.UploadID = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 2: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field LastEventIndex", wireType) - } - m.LastEventIndex = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowEvents - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - m.LastEventIndex |= int64(b&0x7F) << shift - if b < 0x80 { - break - } + v := &ContactCreate{} + if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err } - case 3: + m.Event = &OneOf_ContactCreate{v} + iNdEx = postIndex + case 193: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field LastUploadTime", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field ContactDelete", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -85734,64 +86840,15 @@ func (m *StreamStatus) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if err := github_com_gogo_protobuf_types.StdTimeUnmarshal(&m.LastUploadTime, dAtA[iNdEx:postIndex]); err != nil { + v := &ContactDelete{} + if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } + m.Event = &OneOf_ContactDelete{v} iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipEvents(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthEvents - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *SessionUpload) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowEvents - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: SessionUpload: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: SessionUpload: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: + case 194: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Metadata", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field WorkloadIdentityCreate", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -85818,13 +86875,15 @@ func (m *SessionUpload) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if err := m.Metadata.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + v := &WorkloadIdentityCreate{} + if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } + m.Event = &OneOf_WorkloadIdentityCreate{v} iNdEx = postIndex - case 2: + case 195: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field SessionMetadata", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field WorkloadIdentityUpdate", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -85851,15 +86910,17 @@ func (m *SessionUpload) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if err := m.SessionMetadata.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + v := &WorkloadIdentityUpdate{} + if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } + m.Event = &OneOf_WorkloadIdentityUpdate{v} iNdEx = postIndex - case 5: + case 196: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field SessionURL", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field WorkloadIdentityDelete", wireType) } - var stringLen uint64 + var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowEvents @@ -85869,23 +86930,26 @@ func (m *SessionUpload) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + msglen |= int(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { + if msglen < 0 { return ErrInvalidLengthEvents } - postIndex := iNdEx + intStringLen + postIndex := iNdEx + msglen if postIndex < 0 { return ErrInvalidLengthEvents } if postIndex > l { return io.ErrUnexpectedEOF } - m.SessionURL = string(dAtA[iNdEx:postIndex]) + v := &WorkloadIdentityDelete{} + if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + m.Event = &OneOf_WorkloadIdentityDelete{v} iNdEx = postIndex default: iNdEx = preIndex @@ -85909,7 +86973,7 @@ func (m *SessionUpload) Unmarshal(dAtA []byte) error { } return nil } -func (m *Identity) Unmarshal(dAtA []byte) error { +func (m *StreamStatus) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -85932,15 +86996,15 @@ func (m *Identity) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: Identity: wiretype end group for non-group") + return fmt.Errorf("proto: StreamStatus: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: Identity: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: StreamStatus: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field User", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field UploadID", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -85968,13 +87032,13 @@ func (m *Identity) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.User = string(dAtA[iNdEx:postIndex]) + m.UploadID = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Impersonator", wireType) + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field LastEventIndex", wireType) } - var stringLen uint64 + m.LastEventIndex = 0 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowEvents @@ -85984,29 +87048,16 @@ func (m *Identity) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + m.LastEventIndex |= int64(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthEvents - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthEvents - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Impersonator = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex case 3: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Roles", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field LastUploadTime", wireType) } - var stringLen uint64 + var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowEvents @@ -86016,29 +87067,81 @@ func (m *Identity) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + msglen |= int(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { + if msglen < 0 { return ErrInvalidLengthEvents } - postIndex := iNdEx + intStringLen + postIndex := iNdEx + msglen if postIndex < 0 { return ErrInvalidLengthEvents } if postIndex > l { return io.ErrUnexpectedEOF } - m.Roles = append(m.Roles, string(dAtA[iNdEx:postIndex])) + if err := github_com_gogo_protobuf_types.StdTimeUnmarshal(&m.LastUploadTime, dAtA[iNdEx:postIndex]); err != nil { + return err + } iNdEx = postIndex - case 4: + default: + iNdEx = preIndex + skippy, err := skipEvents(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthEvents + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *SessionUpload) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvents + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: SessionUpload: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: SessionUpload: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Usage", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Metadata", wireType) } - var stringLen uint64 + var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowEvents @@ -86048,29 +87151,30 @@ func (m *Identity) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + msglen |= int(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { + if msglen < 0 { return ErrInvalidLengthEvents } - postIndex := iNdEx + intStringLen + postIndex := iNdEx + msglen if postIndex < 0 { return ErrInvalidLengthEvents } if postIndex > l { return io.ErrUnexpectedEOF } - m.Usage = append(m.Usage, string(dAtA[iNdEx:postIndex])) + if err := m.Metadata.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } iNdEx = postIndex - case 5: + case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Logins", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field SessionMetadata", wireType) } - var stringLen uint64 + var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowEvents @@ -86080,27 +87184,28 @@ func (m *Identity) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + msglen |= int(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { + if msglen < 0 { return ErrInvalidLengthEvents } - postIndex := iNdEx + intStringLen + postIndex := iNdEx + msglen if postIndex < 0 { return ErrInvalidLengthEvents } if postIndex > l { return io.ErrUnexpectedEOF } - m.Logins = append(m.Logins, string(dAtA[iNdEx:postIndex])) + if err := m.SessionMetadata.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } iNdEx = postIndex - case 6: + case 5: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field KubernetesGroups", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field SessionURL", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -86128,11 +87233,62 @@ func (m *Identity) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.KubernetesGroups = append(m.KubernetesGroups, string(dAtA[iNdEx:postIndex])) + m.SessionURL = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex - case 7: + default: + iNdEx = preIndex + skippy, err := skipEvents(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthEvents + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *Identity) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvents + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: Identity: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Identity: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field KubernetesUsers", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field User", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -86160,13 +87316,13 @@ func (m *Identity) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.KubernetesUsers = append(m.KubernetesUsers, string(dAtA[iNdEx:postIndex])) + m.User = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex - case 8: + case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Expires", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Impersonator", wireType) } - var msglen int + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowEvents @@ -86176,28 +87332,27 @@ func (m *Identity) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - msglen |= int(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } - if msglen < 0 { + intStringLen := int(stringLen) + if intStringLen < 0 { return ErrInvalidLengthEvents } - postIndex := iNdEx + msglen + postIndex := iNdEx + intStringLen if postIndex < 0 { return ErrInvalidLengthEvents } if postIndex > l { return io.ErrUnexpectedEOF } - if err := github_com_gogo_protobuf_types.StdTimeUnmarshal(&m.Expires, dAtA[iNdEx:postIndex]); err != nil { - return err - } + m.Impersonator = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex - case 9: + case 3: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field RouteToCluster", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Roles", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -86225,11 +87380,11 @@ func (m *Identity) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.RouteToCluster = string(dAtA[iNdEx:postIndex]) + m.Roles = append(m.Roles, string(dAtA[iNdEx:postIndex])) iNdEx = postIndex - case 10: + case 4: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field KubernetesCluster", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Usage", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -86257,13 +87412,13 @@ func (m *Identity) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.KubernetesCluster = string(dAtA[iNdEx:postIndex]) + m.Usage = append(m.Usage, string(dAtA[iNdEx:postIndex])) iNdEx = postIndex - case 11: + case 5: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Traits", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Logins", wireType) } - var msglen int + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowEvents @@ -86273,30 +87428,29 @@ func (m *Identity) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - msglen |= int(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } - if msglen < 0 { + intStringLen := int(stringLen) + if intStringLen < 0 { return ErrInvalidLengthEvents } - postIndex := iNdEx + msglen + postIndex := iNdEx + intStringLen if postIndex < 0 { return ErrInvalidLengthEvents } if postIndex > l { return io.ErrUnexpectedEOF } - if err := m.Traits.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } + m.Logins = append(m.Logins, string(dAtA[iNdEx:postIndex])) iNdEx = postIndex - case 12: + case 6: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field RouteToApp", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field KubernetesGroups", wireType) } - var msglen int + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowEvents @@ -86306,31 +87460,27 @@ func (m *Identity) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - msglen |= int(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } - if msglen < 0 { + intStringLen := int(stringLen) + if intStringLen < 0 { return ErrInvalidLengthEvents } - postIndex := iNdEx + msglen + postIndex := iNdEx + intStringLen if postIndex < 0 { return ErrInvalidLengthEvents } if postIndex > l { return io.ErrUnexpectedEOF } - if m.RouteToApp == nil { - m.RouteToApp = &RouteToApp{} - } - if err := m.RouteToApp.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } + m.KubernetesGroups = append(m.KubernetesGroups, string(dAtA[iNdEx:postIndex])) iNdEx = postIndex - case 13: + case 7: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field TeleportCluster", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field KubernetesUsers", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -86358,11 +87508,11 @@ func (m *Identity) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.TeleportCluster = string(dAtA[iNdEx:postIndex]) + m.KubernetesUsers = append(m.KubernetesUsers, string(dAtA[iNdEx:postIndex])) iNdEx = postIndex - case 14: + case 8: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field RouteToDatabase", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Expires", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -86389,16 +87539,13 @@ func (m *Identity) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if m.RouteToDatabase == nil { - m.RouteToDatabase = &RouteToDatabase{} - } - if err := m.RouteToDatabase.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if err := github_com_gogo_protobuf_types.StdTimeUnmarshal(&m.Expires, dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex - case 15: + case 9: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field DatabaseNames", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field RouteToCluster", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -86426,11 +87573,11 @@ func (m *Identity) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.DatabaseNames = append(m.DatabaseNames, string(dAtA[iNdEx:postIndex])) + m.RouteToCluster = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex - case 16: + case 10: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field DatabaseUsers", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field KubernetesCluster", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -86458,13 +87605,13 @@ func (m *Identity) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.DatabaseUsers = append(m.DatabaseUsers, string(dAtA[iNdEx:postIndex])) + m.KubernetesCluster = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex - case 17: + case 11: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field MFADeviceUUID", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Traits", wireType) } - var stringLen uint64 + var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowEvents @@ -86474,29 +87621,30 @@ func (m *Identity) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + msglen |= int(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { + if msglen < 0 { return ErrInvalidLengthEvents } - postIndex := iNdEx + intStringLen + postIndex := iNdEx + msglen if postIndex < 0 { return ErrInvalidLengthEvents } if postIndex > l { return io.ErrUnexpectedEOF } - m.MFADeviceUUID = string(dAtA[iNdEx:postIndex]) + if err := m.Traits.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } iNdEx = postIndex - case 18: + case 12: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ClientIP", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field RouteToApp", wireType) } - var stringLen uint64 + var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowEvents @@ -86506,27 +87654,31 @@ func (m *Identity) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + msglen |= int(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { + if msglen < 0 { return ErrInvalidLengthEvents } - postIndex := iNdEx + intStringLen + postIndex := iNdEx + msglen if postIndex < 0 { return ErrInvalidLengthEvents } if postIndex > l { return io.ErrUnexpectedEOF } - m.ClientIP = string(dAtA[iNdEx:postIndex]) + if m.RouteToApp == nil { + m.RouteToApp = &RouteToApp{} + } + if err := m.RouteToApp.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } iNdEx = postIndex - case 19: + case 13: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field AWSRoleARNs", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field TeleportCluster", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -86554,13 +87706,13 @@ func (m *Identity) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.AWSRoleARNs = append(m.AWSRoleARNs, string(dAtA[iNdEx:postIndex])) + m.TeleportCluster = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex - case 20: + case 14: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field AccessRequests", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field RouteToDatabase", wireType) } - var stringLen uint64 + var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowEvents @@ -86570,49 +87722,33 @@ func (m *Identity) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + msglen |= int(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { + if msglen < 0 { return ErrInvalidLengthEvents } - postIndex := iNdEx + intStringLen + postIndex := iNdEx + msglen if postIndex < 0 { return ErrInvalidLengthEvents } if postIndex > l { return io.ErrUnexpectedEOF } - m.AccessRequests = append(m.AccessRequests, string(dAtA[iNdEx:postIndex])) - iNdEx = postIndex - case 21: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field DisallowReissue", wireType) + if m.RouteToDatabase == nil { + m.RouteToDatabase = &RouteToDatabase{} } - var v int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowEvents - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - v |= int(b&0x7F) << shift - if b < 0x80 { - break - } + if err := m.RouteToDatabase.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err } - m.DisallowReissue = bool(v != 0) - case 22: + iNdEx = postIndex + case 15: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field AllowedResourceIDs", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field DatabaseNames", wireType) } - var msglen int + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowEvents @@ -86622,31 +87758,29 @@ func (m *Identity) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - msglen |= int(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } - if msglen < 0 { + intStringLen := int(stringLen) + if intStringLen < 0 { return ErrInvalidLengthEvents } - postIndex := iNdEx + msglen + postIndex := iNdEx + intStringLen if postIndex < 0 { return ErrInvalidLengthEvents } if postIndex > l { return io.ErrUnexpectedEOF } - m.AllowedResourceIDs = append(m.AllowedResourceIDs, ResourceID{}) - if err := m.AllowedResourceIDs[len(m.AllowedResourceIDs)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } + m.DatabaseNames = append(m.DatabaseNames, string(dAtA[iNdEx:postIndex])) iNdEx = postIndex - case 23: + case 16: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field PreviousIdentityExpires", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field DatabaseUsers", wireType) } - var msglen int + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowEvents @@ -86656,28 +87790,27 @@ func (m *Identity) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - msglen |= int(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } - if msglen < 0 { + intStringLen := int(stringLen) + if intStringLen < 0 { return ErrInvalidLengthEvents } - postIndex := iNdEx + msglen + postIndex := iNdEx + intStringLen if postIndex < 0 { return ErrInvalidLengthEvents } if postIndex > l { return io.ErrUnexpectedEOF } - if err := github_com_gogo_protobuf_types.StdTimeUnmarshal(&m.PreviousIdentityExpires, dAtA[iNdEx:postIndex]); err != nil { - return err - } + m.DatabaseUsers = append(m.DatabaseUsers, string(dAtA[iNdEx:postIndex])) iNdEx = postIndex - case 24: + case 17: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field AzureIdentities", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field MFADeviceUUID", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -86705,11 +87838,11 @@ func (m *Identity) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.AzureIdentities = append(m.AzureIdentities, string(dAtA[iNdEx:postIndex])) + m.MFADeviceUUID = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex - case 25: + case 18: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field GCPServiceAccounts", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field ClientIP", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -86737,11 +87870,11 @@ func (m *Identity) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.GCPServiceAccounts = append(m.GCPServiceAccounts, string(dAtA[iNdEx:postIndex])) + m.ClientIP = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex - case 26: + case 19: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field PrivateKeyPolicy", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field AWSRoleARNs", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -86769,11 +87902,11 @@ func (m *Identity) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.PrivateKeyPolicy = string(dAtA[iNdEx:postIndex]) + m.AWSRoleARNs = append(m.AWSRoleARNs, string(dAtA[iNdEx:postIndex])) iNdEx = postIndex - case 27: + case 20: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field BotName", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field AccessRequests", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -86801,11 +87934,31 @@ func (m *Identity) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.BotName = string(dAtA[iNdEx:postIndex]) + m.AccessRequests = append(m.AccessRequests, string(dAtA[iNdEx:postIndex])) iNdEx = postIndex - case 28: + case 21: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field DisallowReissue", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvents + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.DisallowReissue = bool(v != 0) + case 22: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field DeviceExtensions", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field AllowedResourceIDs", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -86832,18 +87985,16 @@ func (m *Identity) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if m.DeviceExtensions == nil { - m.DeviceExtensions = &DeviceExtensions{} - } - if err := m.DeviceExtensions.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + m.AllowedResourceIDs = append(m.AllowedResourceIDs, ResourceID{}) + if err := m.AllowedResourceIDs[len(m.AllowedResourceIDs)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex - case 29: + case 23: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field BotInstanceID", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field PreviousIdentityExpires", wireType) } - var stringLen uint64 + var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowEvents @@ -86853,78 +88004,28 @@ func (m *Identity) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + msglen |= int(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { + if msglen < 0 { return ErrInvalidLengthEvents } - postIndex := iNdEx + intStringLen + postIndex := iNdEx + msglen if postIndex < 0 { return ErrInvalidLengthEvents } if postIndex > l { return io.ErrUnexpectedEOF } - m.BotInstanceID = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipEvents(dAtA[iNdEx:]) - if err != nil { + if err := github_com_gogo_protobuf_types.StdTimeUnmarshal(&m.PreviousIdentityExpires, dAtA[iNdEx:postIndex]); err != nil { return err } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthEvents - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *RouteToApp) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowEvents - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: RouteToApp: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: RouteToApp: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: + iNdEx = postIndex + case 24: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field AzureIdentities", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -86952,11 +88053,11 @@ func (m *RouteToApp) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Name = string(dAtA[iNdEx:postIndex]) + m.AzureIdentities = append(m.AzureIdentities, string(dAtA[iNdEx:postIndex])) iNdEx = postIndex - case 2: + case 25: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field SessionID", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field GCPServiceAccounts", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -86984,11 +88085,11 @@ func (m *RouteToApp) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.SessionID = string(dAtA[iNdEx:postIndex]) + m.GCPServiceAccounts = append(m.GCPServiceAccounts, string(dAtA[iNdEx:postIndex])) iNdEx = postIndex - case 3: + case 26: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field PublicAddr", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field PrivateKeyPolicy", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -87016,43 +88117,11 @@ func (m *RouteToApp) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.PublicAddr = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 4: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ClusterName", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowEvents - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthEvents - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthEvents - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.ClusterName = string(dAtA[iNdEx:postIndex]) + m.PrivateKeyPolicy = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex - case 5: + case 27: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field AWSRoleARN", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field BotName", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -87080,13 +88149,13 @@ func (m *RouteToApp) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.AWSRoleARN = string(dAtA[iNdEx:postIndex]) + m.BotName = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex - case 6: + case 28: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field AzureIdentity", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field DeviceExtensions", wireType) } - var stringLen uint64 + var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowEvents @@ -87096,59 +88165,31 @@ func (m *RouteToApp) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + msglen |= int(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { + if msglen < 0 { return ErrInvalidLengthEvents } - postIndex := iNdEx + intStringLen + postIndex := iNdEx + msglen if postIndex < 0 { return ErrInvalidLengthEvents } if postIndex > l { return io.ErrUnexpectedEOF } - m.AzureIdentity = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 7: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field GCPServiceAccount", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowEvents - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthEvents - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthEvents + if m.DeviceExtensions == nil { + m.DeviceExtensions = &DeviceExtensions{} } - if postIndex > l { - return io.ErrUnexpectedEOF + if err := m.DeviceExtensions.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err } - m.GCPServiceAccount = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex - case 8: + case 29: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field URI", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field BotInstanceID", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -87176,27 +88217,8 @@ func (m *RouteToApp) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.URI = string(dAtA[iNdEx:postIndex]) + m.BotInstanceID = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex - case 9: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field TargetPort", wireType) - } - m.TargetPort = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowEvents - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - m.TargetPort |= uint32(b&0x7F) << shift - if b < 0x80 { - break - } - } default: iNdEx = preIndex skippy, err := skipEvents(dAtA[iNdEx:]) @@ -87219,7 +88241,7 @@ func (m *RouteToApp) Unmarshal(dAtA []byte) error { } return nil } -func (m *RouteToDatabase) Unmarshal(dAtA []byte) error { +func (m *RouteToApp) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -87242,15 +88264,15 @@ func (m *RouteToDatabase) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: RouteToDatabase: wiretype end group for non-group") + return fmt.Errorf("proto: RouteToApp: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: RouteToDatabase: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: RouteToApp: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ServiceName", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -87278,11 +88300,11 @@ func (m *RouteToDatabase) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.ServiceName = string(dAtA[iNdEx:postIndex]) + m.Name = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Protocol", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field SessionID", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -87310,11 +88332,11 @@ func (m *RouteToDatabase) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Protocol = string(dAtA[iNdEx:postIndex]) + m.SessionID = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 3: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Username", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field PublicAddr", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -87342,11 +88364,11 @@ func (m *RouteToDatabase) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Username = string(dAtA[iNdEx:postIndex]) + m.PublicAddr = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 4: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Database", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field ClusterName", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -87374,11 +88396,11 @@ func (m *RouteToDatabase) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Database = string(dAtA[iNdEx:postIndex]) + m.ClusterName = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 5: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Roles", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field AWSRoleARN", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -87406,62 +88428,11 @@ func (m *RouteToDatabase) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Roles = append(m.Roles, string(dAtA[iNdEx:postIndex])) + m.AWSRoleARN = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipEvents(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthEvents - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *DeviceExtensions) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowEvents - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: DeviceExtensions: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: DeviceExtensions: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: + case 6: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field DeviceId", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field AzureIdentity", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -87489,11 +88460,11 @@ func (m *DeviceExtensions) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.DeviceId = string(dAtA[iNdEx:postIndex]) + m.AzureIdentity = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex - case 2: + case 7: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field AssetTag", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field GCPServiceAccount", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -87521,11 +88492,11 @@ func (m *DeviceExtensions) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.AssetTag = string(dAtA[iNdEx:postIndex]) + m.GCPServiceAccount = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex - case 3: + case 8: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field CredentialId", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field URI", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -87553,8 +88524,27 @@ func (m *DeviceExtensions) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.CredentialId = string(dAtA[iNdEx:postIndex]) + m.URI = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex + case 9: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field TargetPort", wireType) + } + m.TargetPort = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvents + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.TargetPort |= uint32(b&0x7F) << shift + if b < 0x80 { + break + } + } default: iNdEx = preIndex skippy, err := skipEvents(dAtA[iNdEx:]) @@ -87577,7 +88567,7 @@ func (m *DeviceExtensions) Unmarshal(dAtA []byte) error { } return nil } -func (m *AccessRequestResourceSearch) Unmarshal(dAtA []byte) error { +func (m *RouteToDatabase) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -87600,17 +88590,17 @@ func (m *AccessRequestResourceSearch) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: AccessRequestResourceSearch: wiretype end group for non-group") + return fmt.Errorf("proto: RouteToDatabase: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: AccessRequestResourceSearch: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: RouteToDatabase: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Metadata", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field ServiceName", wireType) } - var msglen int + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowEvents @@ -87620,30 +88610,29 @@ func (m *AccessRequestResourceSearch) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - msglen |= int(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } - if msglen < 0 { + intStringLen := int(stringLen) + if intStringLen < 0 { return ErrInvalidLengthEvents } - postIndex := iNdEx + msglen + postIndex := iNdEx + intStringLen if postIndex < 0 { return ErrInvalidLengthEvents } if postIndex > l { return io.ErrUnexpectedEOF } - if err := m.Metadata.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } + m.ServiceName = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field UserMetadata", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Protocol", wireType) } - var msglen int + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowEvents @@ -87653,28 +88642,27 @@ func (m *AccessRequestResourceSearch) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - msglen |= int(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } - if msglen < 0 { + intStringLen := int(stringLen) + if intStringLen < 0 { return ErrInvalidLengthEvents } - postIndex := iNdEx + msglen + postIndex := iNdEx + intStringLen if postIndex < 0 { return ErrInvalidLengthEvents } if postIndex > l { return io.ErrUnexpectedEOF } - if err := m.UserMetadata.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } + m.Protocol = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 3: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field SearchAsRoles", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Username", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -87702,11 +88690,11 @@ func (m *AccessRequestResourceSearch) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.SearchAsRoles = append(m.SearchAsRoles, string(dAtA[iNdEx:postIndex])) + m.Username = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 4: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ResourceType", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Database", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -87734,11 +88722,11 @@ func (m *AccessRequestResourceSearch) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.ResourceType = string(dAtA[iNdEx:postIndex]) + m.Database = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 5: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Namespace", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Roles", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -87766,13 +88754,64 @@ func (m *AccessRequestResourceSearch) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Namespace = string(dAtA[iNdEx:postIndex]) + m.Roles = append(m.Roles, string(dAtA[iNdEx:postIndex])) iNdEx = postIndex - case 6: + default: + iNdEx = preIndex + skippy, err := skipEvents(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthEvents + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *DeviceExtensions) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvents + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: DeviceExtensions: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: DeviceExtensions: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Labels", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field DeviceId", wireType) } - var msglen int + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowEvents @@ -87782,122 +88821,27 @@ func (m *AccessRequestResourceSearch) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - msglen |= int(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } - if msglen < 0 { + intStringLen := int(stringLen) + if intStringLen < 0 { return ErrInvalidLengthEvents } - postIndex := iNdEx + msglen + postIndex := iNdEx + intStringLen if postIndex < 0 { return ErrInvalidLengthEvents } if postIndex > l { return io.ErrUnexpectedEOF } - if m.Labels == nil { - m.Labels = make(map[string]string) - } - var mapkey string - var mapvalue string - for iNdEx < postIndex { - entryPreIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowEvents - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - if fieldNum == 1 { - var stringLenmapkey uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowEvents - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLenmapkey |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLenmapkey := int(stringLenmapkey) - if intStringLenmapkey < 0 { - return ErrInvalidLengthEvents - } - postStringIndexmapkey := iNdEx + intStringLenmapkey - if postStringIndexmapkey < 0 { - return ErrInvalidLengthEvents - } - if postStringIndexmapkey > l { - return io.ErrUnexpectedEOF - } - mapkey = string(dAtA[iNdEx:postStringIndexmapkey]) - iNdEx = postStringIndexmapkey - } else if fieldNum == 2 { - var stringLenmapvalue uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowEvents - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLenmapvalue |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLenmapvalue := int(stringLenmapvalue) - if intStringLenmapvalue < 0 { - return ErrInvalidLengthEvents - } - postStringIndexmapvalue := iNdEx + intStringLenmapvalue - if postStringIndexmapvalue < 0 { - return ErrInvalidLengthEvents - } - if postStringIndexmapvalue > l { - return io.ErrUnexpectedEOF - } - mapvalue = string(dAtA[iNdEx:postStringIndexmapvalue]) - iNdEx = postStringIndexmapvalue - } else { - iNdEx = entryPreIndex - skippy, err := skipEvents(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthEvents - } - if (iNdEx + skippy) > postIndex { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - m.Labels[mapkey] = mapvalue + m.DeviceId = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex - case 7: + case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field PredicateExpression", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field AssetTag", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -87925,11 +88869,11 @@ func (m *AccessRequestResourceSearch) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.PredicateExpression = string(dAtA[iNdEx:postIndex]) + m.AssetTag = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex - case 8: + case 3: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field SearchKeywords", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field CredentialId", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -87957,7 +88901,7 @@ func (m *AccessRequestResourceSearch) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.SearchKeywords = append(m.SearchKeywords, string(dAtA[iNdEx:postIndex])) + m.CredentialId = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex default: iNdEx = preIndex @@ -87981,7 +88925,7 @@ func (m *AccessRequestResourceSearch) Unmarshal(dAtA []byte) error { } return nil } -func (m *MySQLStatementPrepare) Unmarshal(dAtA []byte) error { +func (m *AccessRequestResourceSearch) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -88004,10 +88948,10 @@ func (m *MySQLStatementPrepare) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: MySQLStatementPrepare: wiretype end group for non-group") + return fmt.Errorf("proto: AccessRequestResourceSearch: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: MySQLStatementPrepare: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: AccessRequestResourceSearch: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: @@ -88078,9 +89022,9 @@ func (m *MySQLStatementPrepare) Unmarshal(dAtA []byte) error { iNdEx = postIndex case 3: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field SessionMetadata", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field SearchAsRoles", wireType) } - var msglen int + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowEvents @@ -88090,28 +89034,91 @@ func (m *MySQLStatementPrepare) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - msglen |= int(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } - if msglen < 0 { + intStringLen := int(stringLen) + if intStringLen < 0 { return ErrInvalidLengthEvents } - postIndex := iNdEx + msglen + postIndex := iNdEx + intStringLen if postIndex < 0 { return ErrInvalidLengthEvents } if postIndex > l { return io.ErrUnexpectedEOF } - if err := m.SessionMetadata.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } + m.SearchAsRoles = append(m.SearchAsRoles, string(dAtA[iNdEx:postIndex])) iNdEx = postIndex case 4: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field DatabaseMetadata", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field ResourceType", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvents + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthEvents + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthEvents + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ResourceType = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Namespace", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvents + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthEvents + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthEvents + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Namespace = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 6: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Labels", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -88138,13 +89145,107 @@ func (m *MySQLStatementPrepare) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if err := m.DatabaseMetadata.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err + if m.Labels == nil { + m.Labels = make(map[string]string) } + var mapkey string + var mapvalue string + for iNdEx < postIndex { + entryPreIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvents + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + if fieldNum == 1 { + var stringLenmapkey uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvents + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLenmapkey |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLenmapkey := int(stringLenmapkey) + if intStringLenmapkey < 0 { + return ErrInvalidLengthEvents + } + postStringIndexmapkey := iNdEx + intStringLenmapkey + if postStringIndexmapkey < 0 { + return ErrInvalidLengthEvents + } + if postStringIndexmapkey > l { + return io.ErrUnexpectedEOF + } + mapkey = string(dAtA[iNdEx:postStringIndexmapkey]) + iNdEx = postStringIndexmapkey + } else if fieldNum == 2 { + var stringLenmapvalue uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvents + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLenmapvalue |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLenmapvalue := int(stringLenmapvalue) + if intStringLenmapvalue < 0 { + return ErrInvalidLengthEvents + } + postStringIndexmapvalue := iNdEx + intStringLenmapvalue + if postStringIndexmapvalue < 0 { + return ErrInvalidLengthEvents + } + if postStringIndexmapvalue > l { + return io.ErrUnexpectedEOF + } + mapvalue = string(dAtA[iNdEx:postStringIndexmapvalue]) + iNdEx = postStringIndexmapvalue + } else { + iNdEx = entryPreIndex + skippy, err := skipEvents(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthEvents + } + if (iNdEx + skippy) > postIndex { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + m.Labels[mapkey] = mapvalue iNdEx = postIndex - case 5: + case 7: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Query", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field PredicateExpression", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -88172,7 +89273,39 @@ func (m *MySQLStatementPrepare) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Query = string(dAtA[iNdEx:postIndex]) + m.PredicateExpression = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 8: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field SearchKeywords", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvents + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthEvents + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthEvents + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.SearchKeywords = append(m.SearchKeywords, string(dAtA[iNdEx:postIndex])) iNdEx = postIndex default: iNdEx = preIndex @@ -88196,7 +89329,7 @@ func (m *MySQLStatementPrepare) Unmarshal(dAtA []byte) error { } return nil } -func (m *MySQLStatementExecute) Unmarshal(dAtA []byte) error { +func (m *MySQLStatementPrepare) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -88219,10 +89352,10 @@ func (m *MySQLStatementExecute) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: MySQLStatementExecute: wiretype end group for non-group") + return fmt.Errorf("proto: MySQLStatementPrepare: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: MySQLStatementExecute: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: MySQLStatementPrepare: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: @@ -88358,27 +89491,8 @@ func (m *MySQLStatementExecute) Unmarshal(dAtA []byte) error { } iNdEx = postIndex case 5: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field StatementID", wireType) - } - m.StatementID = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowEvents - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - m.StatementID |= uint32(b&0x7F) << shift - if b < 0x80 { - break - } - } - case 6: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Parameters", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Query", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -88406,7 +89520,7 @@ func (m *MySQLStatementExecute) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Parameters = append(m.Parameters, string(dAtA[iNdEx:postIndex])) + m.Query = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex default: iNdEx = preIndex @@ -88430,7 +89544,7 @@ func (m *MySQLStatementExecute) Unmarshal(dAtA []byte) error { } return nil } -func (m *MySQLStatementSendLongData) Unmarshal(dAtA []byte) error { +func (m *MySQLStatementExecute) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -88453,10 +89567,10 @@ func (m *MySQLStatementSendLongData) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: MySQLStatementSendLongData: wiretype end group for non-group") + return fmt.Errorf("proto: MySQLStatementExecute: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: MySQLStatementSendLongData: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: MySQLStatementExecute: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: @@ -88611,10 +89725,10 @@ func (m *MySQLStatementSendLongData) Unmarshal(dAtA []byte) error { } } case 6: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field ParameterID", wireType) + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Parameters", wireType) } - m.ParameterID = 0 + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowEvents @@ -88624,30 +89738,24 @@ func (m *MySQLStatementSendLongData) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - m.ParameterID |= uint32(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } - case 7: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field DataSize", wireType) + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthEvents } - m.DataSize = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowEvents - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - m.DataSize |= uint32(b&0x7F) << shift - if b < 0x80 { - break - } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthEvents + } + if postIndex > l { + return io.ErrUnexpectedEOF } + m.Parameters = append(m.Parameters, string(dAtA[iNdEx:postIndex])) + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipEvents(dAtA[iNdEx:]) @@ -88670,7 +89778,7 @@ func (m *MySQLStatementSendLongData) Unmarshal(dAtA []byte) error { } return nil } -func (m *MySQLStatementClose) Unmarshal(dAtA []byte) error { +func (m *MySQLStatementSendLongData) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -88693,10 +89801,10 @@ func (m *MySQLStatementClose) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: MySQLStatementClose: wiretype end group for non-group") + return fmt.Errorf("proto: MySQLStatementSendLongData: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: MySQLStatementClose: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: MySQLStatementSendLongData: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: @@ -88850,6 +89958,44 @@ func (m *MySQLStatementClose) Unmarshal(dAtA []byte) error { break } } + case 6: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field ParameterID", wireType) + } + m.ParameterID = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvents + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.ParameterID |= uint32(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 7: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field DataSize", wireType) + } + m.DataSize = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvents + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.DataSize |= uint32(b&0x7F) << shift + if b < 0x80 { + break + } + } default: iNdEx = preIndex skippy, err := skipEvents(dAtA[iNdEx:]) @@ -88872,7 +90018,7 @@ func (m *MySQLStatementClose) Unmarshal(dAtA []byte) error { } return nil } -func (m *MySQLStatementReset) Unmarshal(dAtA []byte) error { +func (m *MySQLStatementClose) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -88895,10 +90041,10 @@ func (m *MySQLStatementReset) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: MySQLStatementReset: wiretype end group for non-group") + return fmt.Errorf("proto: MySQLStatementClose: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: MySQLStatementReset: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: MySQLStatementClose: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: @@ -89074,7 +90220,7 @@ func (m *MySQLStatementReset) Unmarshal(dAtA []byte) error { } return nil } -func (m *MySQLStatementFetch) Unmarshal(dAtA []byte) error { +func (m *MySQLStatementReset) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -89097,10 +90243,10 @@ func (m *MySQLStatementFetch) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: MySQLStatementFetch: wiretype end group for non-group") + return fmt.Errorf("proto: MySQLStatementReset: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: MySQLStatementFetch: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: MySQLStatementReset: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: @@ -89254,25 +90400,6 @@ func (m *MySQLStatementFetch) Unmarshal(dAtA []byte) error { break } } - case 6: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field RowsCount", wireType) - } - m.RowsCount = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowEvents - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - m.RowsCount |= uint32(b&0x7F) << shift - if b < 0x80 { - break - } - } default: iNdEx = preIndex skippy, err := skipEvents(dAtA[iNdEx:]) @@ -89295,7 +90422,7 @@ func (m *MySQLStatementFetch) Unmarshal(dAtA []byte) error { } return nil } -func (m *MySQLStatementBulkExecute) Unmarshal(dAtA []byte) error { +func (m *MySQLStatementFetch) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -89318,10 +90445,10 @@ func (m *MySQLStatementBulkExecute) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: MySQLStatementBulkExecute: wiretype end group for non-group") + return fmt.Errorf("proto: MySQLStatementFetch: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: MySQLStatementBulkExecute: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: MySQLStatementFetch: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: @@ -89476,10 +90603,10 @@ func (m *MySQLStatementBulkExecute) Unmarshal(dAtA []byte) error { } } case 6: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Parameters", wireType) + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field RowsCount", wireType) } - var stringLen uint64 + m.RowsCount = 0 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowEvents @@ -89489,24 +90616,11 @@ func (m *MySQLStatementBulkExecute) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + m.RowsCount |= uint32(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthEvents - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthEvents - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Parameters = append(m.Parameters, string(dAtA[iNdEx:postIndex])) - iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipEvents(dAtA[iNdEx:]) @@ -89529,7 +90643,7 @@ func (m *MySQLStatementBulkExecute) Unmarshal(dAtA []byte) error { } return nil } -func (m *MySQLInitDB) Unmarshal(dAtA []byte) error { +func (m *MySQLStatementBulkExecute) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -89552,10 +90666,10 @@ func (m *MySQLInitDB) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: MySQLInitDB: wiretype end group for non-group") + return fmt.Errorf("proto: MySQLStatementBulkExecute: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: MySQLInitDB: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: MySQLStatementBulkExecute: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: @@ -89691,8 +90805,27 @@ func (m *MySQLInitDB) Unmarshal(dAtA []byte) error { } iNdEx = postIndex case 5: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field StatementID", wireType) + } + m.StatementID = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvents + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.StatementID |= uint32(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 6: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field SchemaName", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Parameters", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -89720,7 +90853,7 @@ func (m *MySQLInitDB) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.SchemaName = string(dAtA[iNdEx:postIndex]) + m.Parameters = append(m.Parameters, string(dAtA[iNdEx:postIndex])) iNdEx = postIndex default: iNdEx = preIndex @@ -89744,7 +90877,7 @@ func (m *MySQLInitDB) Unmarshal(dAtA []byte) error { } return nil } -func (m *MySQLCreateDB) Unmarshal(dAtA []byte) error { +func (m *MySQLInitDB) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -89767,10 +90900,10 @@ func (m *MySQLCreateDB) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: MySQLCreateDB: wiretype end group for non-group") + return fmt.Errorf("proto: MySQLInitDB: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: MySQLCreateDB: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: MySQLInitDB: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: @@ -89959,7 +91092,7 @@ func (m *MySQLCreateDB) Unmarshal(dAtA []byte) error { } return nil } -func (m *MySQLDropDB) Unmarshal(dAtA []byte) error { +func (m *MySQLCreateDB) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -89982,10 +91115,10 @@ func (m *MySQLDropDB) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: MySQLDropDB: wiretype end group for non-group") + return fmt.Errorf("proto: MySQLCreateDB: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: MySQLDropDB: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: MySQLCreateDB: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: @@ -90174,7 +91307,7 @@ func (m *MySQLDropDB) Unmarshal(dAtA []byte) error { } return nil } -func (m *MySQLShutDown) Unmarshal(dAtA []byte) error { +func (m *MySQLDropDB) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -90197,10 +91330,10 @@ func (m *MySQLShutDown) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: MySQLShutDown: wiretype end group for non-group") + return fmt.Errorf("proto: MySQLDropDB: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: MySQLShutDown: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: MySQLDropDB: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: @@ -90335,6 +91468,38 @@ func (m *MySQLShutDown) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field SchemaName", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvents + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthEvents + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthEvents + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.SchemaName = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipEvents(dAtA[iNdEx:]) @@ -90357,7 +91522,7 @@ func (m *MySQLShutDown) Unmarshal(dAtA []byte) error { } return nil } -func (m *MySQLProcessKill) Unmarshal(dAtA []byte) error { +func (m *MySQLShutDown) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -90380,10 +91545,10 @@ func (m *MySQLProcessKill) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: MySQLProcessKill: wiretype end group for non-group") + return fmt.Errorf("proto: MySQLShutDown: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: MySQLProcessKill: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: MySQLShutDown: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: @@ -90518,25 +91683,6 @@ func (m *MySQLProcessKill) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex - case 5: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field ProcessID", wireType) - } - m.ProcessID = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowEvents - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - m.ProcessID |= uint32(b&0x7F) << shift - if b < 0x80 { - break - } - } default: iNdEx = preIndex skippy, err := skipEvents(dAtA[iNdEx:]) @@ -90559,7 +91705,7 @@ func (m *MySQLProcessKill) Unmarshal(dAtA []byte) error { } return nil } -func (m *MySQLDebug) Unmarshal(dAtA []byte) error { +func (m *MySQLProcessKill) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -90582,10 +91728,10 @@ func (m *MySQLDebug) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: MySQLDebug: wiretype end group for non-group") + return fmt.Errorf("proto: MySQLProcessKill: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: MySQLDebug: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: MySQLProcessKill: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: @@ -90720,6 +91866,25 @@ func (m *MySQLDebug) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex + case 5: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field ProcessID", wireType) + } + m.ProcessID = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvents + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.ProcessID |= uint32(b&0x7F) << shift + if b < 0x80 { + break + } + } default: iNdEx = preIndex skippy, err := skipEvents(dAtA[iNdEx:]) @@ -90742,7 +91907,7 @@ func (m *MySQLDebug) Unmarshal(dAtA []byte) error { } return nil } -func (m *MySQLRefresh) Unmarshal(dAtA []byte) error { +func (m *MySQLDebug) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -90765,10 +91930,10 @@ func (m *MySQLRefresh) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: MySQLRefresh: wiretype end group for non-group") + return fmt.Errorf("proto: MySQLDebug: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: MySQLRefresh: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: MySQLDebug: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: @@ -90903,38 +92068,6 @@ func (m *MySQLRefresh) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex - case 5: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Subcommand", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowEvents - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthEvents - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthEvents - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Subcommand = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipEvents(dAtA[iNdEx:]) @@ -90957,7 +92090,7 @@ func (m *MySQLRefresh) Unmarshal(dAtA []byte) error { } return nil } -func (m *SQLServerRPCRequest) Unmarshal(dAtA []byte) error { +func (m *MySQLRefresh) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -90980,10 +92113,10 @@ func (m *SQLServerRPCRequest) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: SQLServerRPCRequest: wiretype end group for non-group") + return fmt.Errorf("proto: MySQLRefresh: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: SQLServerRPCRequest: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: MySQLRefresh: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: @@ -91120,39 +92253,7 @@ func (m *SQLServerRPCRequest) Unmarshal(dAtA []byte) error { iNdEx = postIndex case 5: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Procname", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowEvents - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthEvents - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthEvents - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Procname = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 6: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Parameters", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Subcommand", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -91180,7 +92281,7 @@ func (m *SQLServerRPCRequest) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Parameters = append(m.Parameters, string(dAtA[iNdEx:postIndex])) + m.Subcommand = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex default: iNdEx = preIndex @@ -91204,7 +92305,7 @@ func (m *SQLServerRPCRequest) Unmarshal(dAtA []byte) error { } return nil } -func (m *DatabaseSessionMalformedPacket) Unmarshal(dAtA []byte) error { +func (m *SQLServerRPCRequest) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -91227,10 +92328,10 @@ func (m *DatabaseSessionMalformedPacket) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: DatabaseSessionMalformedPacket: wiretype end group for non-group") + return fmt.Errorf("proto: SQLServerRPCRequest: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: DatabaseSessionMalformedPacket: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: SQLServerRPCRequest: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: @@ -91367,9 +92468,9 @@ func (m *DatabaseSessionMalformedPacket) Unmarshal(dAtA []byte) error { iNdEx = postIndex case 5: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Payload", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Procname", wireType) } - var byteLen int + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowEvents @@ -91379,25 +92480,55 @@ func (m *DatabaseSessionMalformedPacket) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - byteLen |= int(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } - if byteLen < 0 { + intStringLen := int(stringLen) + if intStringLen < 0 { return ErrInvalidLengthEvents } - postIndex := iNdEx + byteLen + postIndex := iNdEx + intStringLen if postIndex < 0 { return ErrInvalidLengthEvents } if postIndex > l { return io.ErrUnexpectedEOF } - m.Payload = append(m.Payload[:0], dAtA[iNdEx:postIndex]...) - if m.Payload == nil { - m.Payload = []byte{} + m.Procname = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 6: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Parameters", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvents + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthEvents + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthEvents + } + if postIndex > l { + return io.ErrUnexpectedEOF } + m.Parameters = append(m.Parameters, string(dAtA[iNdEx:postIndex])) iNdEx = postIndex default: iNdEx = preIndex @@ -91421,7 +92552,7 @@ func (m *DatabaseSessionMalformedPacket) Unmarshal(dAtA []byte) error { } return nil } -func (m *ElasticsearchRequest) Unmarshal(dAtA []byte) error { +func (m *DatabaseSessionMalformedPacket) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -91444,10 +92575,10 @@ func (m *ElasticsearchRequest) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: ElasticsearchRequest: wiretype end group for non-group") + return fmt.Errorf("proto: DatabaseSessionMalformedPacket: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: ElasticsearchRequest: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: DatabaseSessionMalformedPacket: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: @@ -91584,9 +92715,9 @@ func (m *ElasticsearchRequest) Unmarshal(dAtA []byte) error { iNdEx = postIndex case 5: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Path", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Payload", wireType) } - var stringLen uint64 + var byteLen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowEvents @@ -91596,29 +92727,82 @@ func (m *ElasticsearchRequest) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + byteLen |= int(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { + if byteLen < 0 { return ErrInvalidLengthEvents } - postIndex := iNdEx + intStringLen + postIndex := iNdEx + byteLen if postIndex < 0 { return ErrInvalidLengthEvents } if postIndex > l { return io.ErrUnexpectedEOF } - m.Path = string(dAtA[iNdEx:postIndex]) + m.Payload = append(m.Payload[:0], dAtA[iNdEx:postIndex]...) + if m.Payload == nil { + m.Payload = []byte{} + } iNdEx = postIndex - case 6: + default: + iNdEx = preIndex + skippy, err := skipEvents(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthEvents + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *ElasticsearchRequest) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvents + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: ElasticsearchRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ElasticsearchRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field RawQuery", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Metadata", wireType) } - var stringLen uint64 + var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowEvents @@ -91628,29 +92812,30 @@ func (m *ElasticsearchRequest) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + msglen |= int(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { + if msglen < 0 { return ErrInvalidLengthEvents } - postIndex := iNdEx + intStringLen + postIndex := iNdEx + msglen if postIndex < 0 { return ErrInvalidLengthEvents } if postIndex > l { return io.ErrUnexpectedEOF } - m.RawQuery = string(dAtA[iNdEx:postIndex]) + if err := m.Metadata.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } iNdEx = postIndex - case 7: + case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Method", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field UserMetadata", wireType) } - var stringLen uint64 + var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowEvents @@ -91660,29 +92845,30 @@ func (m *ElasticsearchRequest) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + msglen |= int(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { + if msglen < 0 { return ErrInvalidLengthEvents } - postIndex := iNdEx + intStringLen + postIndex := iNdEx + msglen if postIndex < 0 { return ErrInvalidLengthEvents } if postIndex > l { return io.ErrUnexpectedEOF } - m.Method = string(dAtA[iNdEx:postIndex]) + if err := m.UserMetadata.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } iNdEx = postIndex - case 8: + case 3: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Body", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field SessionMetadata", wireType) } - var byteLen int + var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowEvents @@ -91692,29 +92878,191 @@ func (m *ElasticsearchRequest) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - byteLen |= int(b&0x7F) << shift + msglen |= int(b&0x7F) << shift if b < 0x80 { break } } - if byteLen < 0 { + if msglen < 0 { return ErrInvalidLengthEvents } - postIndex := iNdEx + byteLen + postIndex := iNdEx + msglen if postIndex < 0 { return ErrInvalidLengthEvents } if postIndex > l { return io.ErrUnexpectedEOF } - m.Body = append(m.Body[:0], dAtA[iNdEx:postIndex]...) - if m.Body == nil { - m.Body = []byte{} + if err := m.SessionMetadata.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err } iNdEx = postIndex - case 9: + case 4: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Headers", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field DatabaseMetadata", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvents + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthEvents + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthEvents + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.DatabaseMetadata.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Path", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvents + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthEvents + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthEvents + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Path = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 6: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field RawQuery", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvents + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthEvents + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthEvents + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.RawQuery = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 7: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Method", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvents + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthEvents + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthEvents + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Method = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 8: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Body", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvents + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthEvents + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthEvents + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Body = append(m.Body[:0], dAtA[iNdEx:postIndex]...) + if m.Body == nil { + m.Body = []byte{} + } + iNdEx = postIndex + case 9: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Headers", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -94018,7 +95366,699 @@ func (m *KubernetesClusterUpdate) Unmarshal(dAtA []byte) error { iNdEx = postIndex case 3: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ResourceMetadata", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field ResourceMetadata", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvents + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthEvents + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthEvents + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.ResourceMetadata.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field KubeClusterMetadata", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvents + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthEvents + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthEvents + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.KubeClusterMetadata.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipEvents(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthEvents + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *KubernetesClusterDelete) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvents + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: KubernetesClusterDelete: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: KubernetesClusterDelete: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Metadata", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvents + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthEvents + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthEvents + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.Metadata.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field UserMetadata", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvents + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthEvents + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthEvents + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.UserMetadata.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ResourceMetadata", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvents + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthEvents + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthEvents + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.ResourceMetadata.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipEvents(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthEvents + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *SSMRun) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvents + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: SSMRun: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: SSMRun: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Metadata", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvents + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthEvents + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthEvents + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.Metadata.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field CommandID", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvents + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthEvents + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthEvents + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.CommandID = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field InstanceID", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvents + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthEvents + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthEvents + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.InstanceID = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 4: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field ExitCode", wireType) + } + m.ExitCode = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvents + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.ExitCode |= int64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Status", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvents + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthEvents + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthEvents + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Status = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 6: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field AccountID", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvents + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthEvents + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthEvents + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.AccountID = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 7: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Region", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvents + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthEvents + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthEvents + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Region = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 8: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field StandardOutput", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvents + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthEvents + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthEvents + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.StandardOutput = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 9: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field StandardError", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvents + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthEvents + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthEvents + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.StandardError = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 10: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field InvocationURL", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvents + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthEvents + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthEvents + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.InvocationURL = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipEvents(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthEvents + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *CassandraPrepare) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvents + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: CassandraPrepare: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: CassandraPrepare: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Metadata", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvents + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthEvents + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthEvents + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.Metadata.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field UserMetadata", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvents + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthEvents + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthEvents + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.UserMetadata.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field SessionMetadata", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -94045,13 +96085,13 @@ func (m *KubernetesClusterUpdate) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if err := m.ResourceMetadata.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if err := m.SessionMetadata.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex case 4: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field KubeClusterMetadata", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field DatabaseMetadata", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -94078,10 +96118,74 @@ func (m *KubernetesClusterUpdate) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if err := m.KubeClusterMetadata.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if err := m.DatabaseMetadata.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Query", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvents + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthEvents + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthEvents + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Query = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 6: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Keyspace", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvents + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthEvents + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthEvents + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Keyspace = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipEvents(dAtA[iNdEx:]) @@ -94104,7 +96208,7 @@ func (m *KubernetesClusterUpdate) Unmarshal(dAtA []byte) error { } return nil } -func (m *KubernetesClusterDelete) Unmarshal(dAtA []byte) error { +func (m *CassandraExecute) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -94127,10 +96231,10 @@ func (m *KubernetesClusterDelete) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: KubernetesClusterDelete: wiretype end group for non-group") + return fmt.Errorf("proto: CassandraExecute: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: KubernetesClusterDelete: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: CassandraExecute: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: @@ -94201,7 +96305,7 @@ func (m *KubernetesClusterDelete) Unmarshal(dAtA []byte) error { iNdEx = postIndex case 3: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ResourceMetadata", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field SessionMetadata", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -94228,10 +96332,75 @@ func (m *KubernetesClusterDelete) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if err := m.ResourceMetadata.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if err := m.SessionMetadata.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field DatabaseMetadata", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvents + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthEvents + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthEvents + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.DatabaseMetadata.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field QueryId", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvents + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthEvents + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthEvents + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.QueryId = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipEvents(dAtA[iNdEx:]) @@ -94254,7 +96423,7 @@ func (m *KubernetesClusterDelete) Unmarshal(dAtA []byte) error { } return nil } -func (m *SSMRun) Unmarshal(dAtA []byte) error { +func (m *CassandraBatch) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -94277,10 +96446,10 @@ func (m *SSMRun) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: SSMRun: wiretype end group for non-group") + return fmt.Errorf("proto: CassandraBatch: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: SSMRun: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: CassandraBatch: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: @@ -94318,9 +96487,9 @@ func (m *SSMRun) Unmarshal(dAtA []byte) error { iNdEx = postIndex case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field CommandID", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field UserMetadata", wireType) } - var stringLen uint64 + var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowEvents @@ -94330,29 +96499,30 @@ func (m *SSMRun) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + msglen |= int(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { + if msglen < 0 { return ErrInvalidLengthEvents } - postIndex := iNdEx + intStringLen + postIndex := iNdEx + msglen if postIndex < 0 { return ErrInvalidLengthEvents } if postIndex > l { return io.ErrUnexpectedEOF } - m.CommandID = string(dAtA[iNdEx:postIndex]) + if err := m.UserMetadata.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } iNdEx = postIndex case 3: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field InstanceID", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field SessionMetadata", wireType) } - var stringLen uint64 + var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowEvents @@ -94362,48 +96532,30 @@ func (m *SSMRun) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + msglen |= int(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { + if msglen < 0 { return ErrInvalidLengthEvents } - postIndex := iNdEx + intStringLen + postIndex := iNdEx + msglen if postIndex < 0 { return ErrInvalidLengthEvents } if postIndex > l { return io.ErrUnexpectedEOF } - m.InstanceID = string(dAtA[iNdEx:postIndex]) + if err := m.SessionMetadata.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } iNdEx = postIndex case 4: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field ExitCode", wireType) - } - m.ExitCode = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowEvents - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - m.ExitCode |= int64(b&0x7F) << shift - if b < 0x80 { - break - } - } - case 5: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Status", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field DatabaseMetadata", wireType) } - var stringLen uint64 + var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowEvents @@ -94413,59 +96565,28 @@ func (m *SSMRun) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + msglen |= int(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { + if msglen < 0 { return ErrInvalidLengthEvents } - postIndex := iNdEx + intStringLen + postIndex := iNdEx + msglen if postIndex < 0 { return ErrInvalidLengthEvents } if postIndex > l { return io.ErrUnexpectedEOF } - m.Status = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 6: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field AccountID", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowEvents - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthEvents - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthEvents - } - if postIndex > l { - return io.ErrUnexpectedEOF + if err := m.DatabaseMetadata.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err } - m.AccountID = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex - case 7: + case 5: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Region", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Consistency", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -94493,11 +96614,11 @@ func (m *SSMRun) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Region = string(dAtA[iNdEx:postIndex]) + m.Consistency = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex - case 8: + case 6: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field StandardOutput", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Keyspace", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -94525,11 +96646,11 @@ func (m *SSMRun) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.StandardOutput = string(dAtA[iNdEx:postIndex]) + m.Keyspace = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex - case 9: + case 7: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field StandardError", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field BatchType", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -94557,13 +96678,13 @@ func (m *SSMRun) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.StandardError = string(dAtA[iNdEx:postIndex]) + m.BatchType = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex - case 10: + case 8: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field InvocationURL", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Children", wireType) } - var stringLen uint64 + var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowEvents @@ -94573,23 +96694,25 @@ func (m *SSMRun) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + msglen |= int(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { + if msglen < 0 { return ErrInvalidLengthEvents } - postIndex := iNdEx + intStringLen + postIndex := iNdEx + msglen if postIndex < 0 { return ErrInvalidLengthEvents } if postIndex > l { return io.ErrUnexpectedEOF } - m.InvocationURL = string(dAtA[iNdEx:postIndex]) + m.Children = append(m.Children, &CassandraBatch_BatchChild{}) + if err := m.Children[len(m.Children)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } iNdEx = postIndex default: iNdEx = preIndex @@ -94613,7 +96736,7 @@ func (m *SSMRun) Unmarshal(dAtA []byte) error { } return nil } -func (m *CassandraPrepare) Unmarshal(dAtA []byte) error { +func (m *CassandraBatch_BatchChild) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -94636,17 +96759,17 @@ func (m *CassandraPrepare) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: CassandraPrepare: wiretype end group for non-group") + return fmt.Errorf("proto: BatchChild: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: CassandraPrepare: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: BatchChild: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Metadata", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field ID", wireType) } - var msglen int + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowEvents @@ -94656,30 +96779,29 @@ func (m *CassandraPrepare) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - msglen |= int(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } - if msglen < 0 { + intStringLen := int(stringLen) + if intStringLen < 0 { return ErrInvalidLengthEvents } - postIndex := iNdEx + msglen + postIndex := iNdEx + intStringLen if postIndex < 0 { return ErrInvalidLengthEvents } if postIndex > l { return io.ErrUnexpectedEOF } - if err := m.Metadata.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } + m.ID = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field UserMetadata", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Query", wireType) } - var msglen int + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowEvents @@ -94689,28 +96811,27 @@ func (m *CassandraPrepare) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - msglen |= int(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } - if msglen < 0 { + intStringLen := int(stringLen) + if intStringLen < 0 { return ErrInvalidLengthEvents } - postIndex := iNdEx + msglen + postIndex := iNdEx + intStringLen if postIndex < 0 { return ErrInvalidLengthEvents } if postIndex > l { return io.ErrUnexpectedEOF } - if err := m.UserMetadata.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } + m.Query = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 3: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field SessionMetadata", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Values", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -94737,48 +96858,67 @@ func (m *CassandraPrepare) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if err := m.SessionMetadata.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + m.Values = append(m.Values, &CassandraBatch_BatchChild_Value{}) + if err := m.Values[len(m.Values)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex - case 4: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field DatabaseMetadata", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowEvents - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } + default: + iNdEx = preIndex + skippy, err := skipEvents(dAtA[iNdEx:]) + if err != nil { + return err } - if msglen < 0 { + if (skippy < 0) || (iNdEx+skippy) < 0 { return ErrInvalidLengthEvents } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthEvents + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF } - if postIndex > l { + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *CassandraBatch_BatchChild_Value) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvents + } + if iNdEx >= l { return io.ErrUnexpectedEOF } - if err := m.DatabaseMetadata.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break } - iNdEx = postIndex - case 5: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Query", wireType) + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: Value: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Value: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Type", wireType) } - var stringLen uint64 + m.Type = 0 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowEvents @@ -94788,29 +96928,16 @@ func (m *CassandraPrepare) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + m.Type |= uint32(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthEvents - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthEvents - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Query = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 6: + case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Keyspace", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Contents", wireType) } - var stringLen uint64 + var byteLen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowEvents @@ -94820,23 +96947,25 @@ func (m *CassandraPrepare) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + byteLen |= int(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { + if byteLen < 0 { return ErrInvalidLengthEvents } - postIndex := iNdEx + intStringLen + postIndex := iNdEx + byteLen if postIndex < 0 { return ErrInvalidLengthEvents } if postIndex > l { return io.ErrUnexpectedEOF } - m.Keyspace = string(dAtA[iNdEx:postIndex]) + m.Contents = append(m.Contents[:0], dAtA[iNdEx:postIndex]...) + if m.Contents == nil { + m.Contents = []byte{} + } iNdEx = postIndex default: iNdEx = preIndex @@ -94860,7 +96989,7 @@ func (m *CassandraPrepare) Unmarshal(dAtA []byte) error { } return nil } -func (m *CassandraExecute) Unmarshal(dAtA []byte) error { +func (m *CassandraRegister) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -94883,10 +97012,10 @@ func (m *CassandraExecute) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: CassandraExecute: wiretype end group for non-group") + return fmt.Errorf("proto: CassandraRegister: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: CassandraExecute: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: CassandraRegister: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: @@ -95023,7 +97152,7 @@ func (m *CassandraExecute) Unmarshal(dAtA []byte) error { iNdEx = postIndex case 5: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field QueryId", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field EventTypes", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -95051,7 +97180,7 @@ func (m *CassandraExecute) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.QueryId = string(dAtA[iNdEx:postIndex]) + m.EventTypes = append(m.EventTypes, string(dAtA[iNdEx:postIndex])) iNdEx = postIndex default: iNdEx = preIndex @@ -95075,7 +97204,7 @@ func (m *CassandraExecute) Unmarshal(dAtA []byte) error { } return nil } -func (m *CassandraBatch) Unmarshal(dAtA []byte) error { +func (m *LoginRuleCreate) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -95098,10 +97227,10 @@ func (m *CassandraBatch) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: CassandraBatch: wiretype end group for non-group") + return fmt.Errorf("proto: LoginRuleCreate: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: CassandraBatch: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: LoginRuleCreate: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: @@ -95133,79 +97262,13 @@ func (m *CassandraBatch) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if err := m.Metadata.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field UserMetadata", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowEvents - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthEvents - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthEvents - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if err := m.UserMetadata.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 3: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field SessionMetadata", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowEvents - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthEvents - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthEvents - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if err := m.SessionMetadata.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if err := m.Metadata.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex - case 4: + case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field DatabaseMetadata", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field ResourceMetadata", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -95232,15 +97295,15 @@ func (m *CassandraBatch) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if err := m.DatabaseMetadata.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if err := m.ResourceMetadata.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex - case 5: + case 3: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Consistency", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field UserMetadata", wireType) } - var stringLen uint64 + var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowEvents @@ -95250,29 +97313,81 @@ func (m *CassandraBatch) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + msglen |= int(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { + if msglen < 0 { return ErrInvalidLengthEvents } - postIndex := iNdEx + intStringLen + postIndex := iNdEx + msglen if postIndex < 0 { return ErrInvalidLengthEvents } if postIndex > l { return io.ErrUnexpectedEOF } - m.Consistency = string(dAtA[iNdEx:postIndex]) + if err := m.UserMetadata.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } iNdEx = postIndex - case 6: + default: + iNdEx = preIndex + skippy, err := skipEvents(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthEvents + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *LoginRuleDelete) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvents + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: LoginRuleDelete: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: LoginRuleDelete: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Keyspace", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Metadata", wireType) } - var stringLen uint64 + var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowEvents @@ -95282,29 +97397,30 @@ func (m *CassandraBatch) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + msglen |= int(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { + if msglen < 0 { return ErrInvalidLengthEvents } - postIndex := iNdEx + intStringLen + postIndex := iNdEx + msglen if postIndex < 0 { return ErrInvalidLengthEvents } if postIndex > l { return io.ErrUnexpectedEOF } - m.Keyspace = string(dAtA[iNdEx:postIndex]) + if err := m.Metadata.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } iNdEx = postIndex - case 7: + case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field BatchType", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field ResourceMetadata", wireType) } - var stringLen uint64 + var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowEvents @@ -95314,27 +97430,28 @@ func (m *CassandraBatch) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + msglen |= int(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { + if msglen < 0 { return ErrInvalidLengthEvents } - postIndex := iNdEx + intStringLen + postIndex := iNdEx + msglen if postIndex < 0 { return ErrInvalidLengthEvents } if postIndex > l { return io.ErrUnexpectedEOF } - m.BatchType = string(dAtA[iNdEx:postIndex]) + if err := m.ResourceMetadata.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } iNdEx = postIndex - case 8: + case 3: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Children", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field UserMetadata", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -95361,8 +97478,7 @@ func (m *CassandraBatch) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Children = append(m.Children, &CassandraBatch_BatchChild{}) - if err := m.Children[len(m.Children)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if err := m.UserMetadata.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex @@ -95388,7 +97504,7 @@ func (m *CassandraBatch) Unmarshal(dAtA []byte) error { } return nil } -func (m *CassandraBatch_BatchChild) Unmarshal(dAtA []byte) error { +func (m *SAMLIdPAuthAttempt) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -95411,17 +97527,17 @@ func (m *CassandraBatch_BatchChild) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: BatchChild: wiretype end group for non-group") + return fmt.Errorf("proto: SAMLIdPAuthAttempt: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: BatchChild: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: SAMLIdPAuthAttempt: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ID", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Metadata", wireType) } - var stringLen uint64 + var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowEvents @@ -95431,29 +97547,30 @@ func (m *CassandraBatch_BatchChild) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + msglen |= int(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { + if msglen < 0 { return ErrInvalidLengthEvents } - postIndex := iNdEx + intStringLen + postIndex := iNdEx + msglen if postIndex < 0 { return ErrInvalidLengthEvents } if postIndex > l { return io.ErrUnexpectedEOF } - m.ID = string(dAtA[iNdEx:postIndex]) + if err := m.Metadata.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } iNdEx = postIndex case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Query", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field UserMetadata", wireType) } - var stringLen uint64 + var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowEvents @@ -95463,27 +97580,28 @@ func (m *CassandraBatch_BatchChild) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + msglen |= int(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { + if msglen < 0 { return ErrInvalidLengthEvents } - postIndex := iNdEx + intStringLen + postIndex := iNdEx + msglen if postIndex < 0 { return ErrInvalidLengthEvents } if postIndex > l { return io.ErrUnexpectedEOF } - m.Query = string(dAtA[iNdEx:postIndex]) + if err := m.UserMetadata.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } iNdEx = postIndex case 3: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Values", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field SessionMetadata", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -95510,67 +97628,15 @@ func (m *CassandraBatch_BatchChild) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Values = append(m.Values, &CassandraBatch_BatchChild_Value{}) - if err := m.Values[len(m.Values)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if err := m.SessionMetadata.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipEvents(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthEvents - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *CassandraBatch_BatchChild_Value) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowEvents - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: Value: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: Value: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field Type", wireType) + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Status", wireType) } - m.Type = 0 + var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowEvents @@ -95580,16 +97646,30 @@ func (m *CassandraBatch_BatchChild_Value) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - m.Type |= uint32(b&0x7F) << shift + msglen |= int(b&0x7F) << shift if b < 0x80 { break } } - case 2: + if msglen < 0 { + return ErrInvalidLengthEvents + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthEvents + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.Status.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 5: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Contents", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field SAMLIdPServiceProviderMetadata", wireType) } - var byteLen int + var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowEvents @@ -95599,24 +97679,23 @@ func (m *CassandraBatch_BatchChild_Value) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - byteLen |= int(b&0x7F) << shift + msglen |= int(b&0x7F) << shift if b < 0x80 { break } } - if byteLen < 0 { + if msglen < 0 { return ErrInvalidLengthEvents } - postIndex := iNdEx + byteLen + postIndex := iNdEx + msglen if postIndex < 0 { return ErrInvalidLengthEvents } if postIndex > l { return io.ErrUnexpectedEOF } - m.Contents = append(m.Contents[:0], dAtA[iNdEx:postIndex]...) - if m.Contents == nil { - m.Contents = []byte{} + if err := m.SAMLIdPServiceProviderMetadata.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err } iNdEx = postIndex default: @@ -95641,7 +97720,7 @@ func (m *CassandraBatch_BatchChild_Value) Unmarshal(dAtA []byte) error { } return nil } -func (m *CassandraRegister) Unmarshal(dAtA []byte) error { +func (m *SAMLIdPServiceProviderCreate) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -95664,10 +97743,10 @@ func (m *CassandraRegister) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: CassandraRegister: wiretype end group for non-group") + return fmt.Errorf("proto: SAMLIdPServiceProviderCreate: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: CassandraRegister: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: SAMLIdPServiceProviderCreate: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: @@ -95705,7 +97784,7 @@ func (m *CassandraRegister) Unmarshal(dAtA []byte) error { iNdEx = postIndex case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field UserMetadata", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field ResourceMetadata", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -95732,13 +97811,13 @@ func (m *CassandraRegister) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if err := m.UserMetadata.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if err := m.ResourceMetadata.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex case 3: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field SessionMetadata", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field SAMLIdPServiceProviderMetadata", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -95765,13 +97844,64 @@ func (m *CassandraRegister) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if err := m.SessionMetadata.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if err := m.SAMLIdPServiceProviderMetadata.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex - case 4: + default: + iNdEx = preIndex + skippy, err := skipEvents(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthEvents + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *SAMLIdPServiceProviderUpdate) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvents + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: SAMLIdPServiceProviderUpdate: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: SAMLIdPServiceProviderUpdate: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field DatabaseMetadata", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Metadata", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -95798,15 +97928,15 @@ func (m *CassandraRegister) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if err := m.DatabaseMetadata.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if err := m.Metadata.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex - case 5: + case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field EventTypes", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field ResourceMetadata", wireType) } - var stringLen uint64 + var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowEvents @@ -95816,23 +97946,57 @@ func (m *CassandraRegister) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + msglen |= int(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { + if msglen < 0 { return ErrInvalidLengthEvents } - postIndex := iNdEx + intStringLen + postIndex := iNdEx + msglen if postIndex < 0 { return ErrInvalidLengthEvents } if postIndex > l { return io.ErrUnexpectedEOF } - m.EventTypes = append(m.EventTypes, string(dAtA[iNdEx:postIndex])) + if err := m.ResourceMetadata.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field SAMLIdPServiceProviderMetadata", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvents + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthEvents + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthEvents + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.SAMLIdPServiceProviderMetadata.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } iNdEx = postIndex default: iNdEx = preIndex @@ -95856,7 +98020,7 @@ func (m *CassandraRegister) Unmarshal(dAtA []byte) error { } return nil } -func (m *LoginRuleCreate) Unmarshal(dAtA []byte) error { +func (m *SAMLIdPServiceProviderDelete) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -95879,10 +98043,10 @@ func (m *LoginRuleCreate) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: LoginRuleCreate: wiretype end group for non-group") + return fmt.Errorf("proto: SAMLIdPServiceProviderDelete: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: LoginRuleCreate: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: SAMLIdPServiceProviderDelete: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: @@ -95953,7 +98117,7 @@ func (m *LoginRuleCreate) Unmarshal(dAtA []byte) error { iNdEx = postIndex case 3: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field UserMetadata", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field SAMLIdPServiceProviderMetadata", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -95980,7 +98144,7 @@ func (m *LoginRuleCreate) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if err := m.UserMetadata.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if err := m.SAMLIdPServiceProviderMetadata.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex @@ -96006,7 +98170,7 @@ func (m *LoginRuleCreate) Unmarshal(dAtA []byte) error { } return nil } -func (m *LoginRuleDelete) Unmarshal(dAtA []byte) error { +func (m *SAMLIdPServiceProviderDeleteAll) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -96029,10 +98193,10 @@ func (m *LoginRuleDelete) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: LoginRuleDelete: wiretype end group for non-group") + return fmt.Errorf("proto: SAMLIdPServiceProviderDeleteAll: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: LoginRuleDelete: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: SAMLIdPServiceProviderDeleteAll: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: @@ -96101,39 +98265,6 @@ func (m *LoginRuleDelete) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex - case 3: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field UserMetadata", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowEvents - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthEvents - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthEvents - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if err := m.UserMetadata.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipEvents(dAtA[iNdEx:]) @@ -96156,7 +98287,7 @@ func (m *LoginRuleDelete) Unmarshal(dAtA []byte) error { } return nil } -func (m *SAMLIdPAuthAttempt) Unmarshal(dAtA []byte) error { +func (m *OktaResourcesUpdate) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -96179,10 +98310,10 @@ func (m *SAMLIdPAuthAttempt) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: SAMLIdPAuthAttempt: wiretype end group for non-group") + return fmt.Errorf("proto: OktaResourcesUpdate: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: SAMLIdPAuthAttempt: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: OktaResourcesUpdate: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: @@ -96220,7 +98351,7 @@ func (m *SAMLIdPAuthAttempt) Unmarshal(dAtA []byte) error { iNdEx = postIndex case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field UserMetadata", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field ServerMetadata", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -96247,13 +98378,13 @@ func (m *SAMLIdPAuthAttempt) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if err := m.UserMetadata.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if err := m.ServerMetadata.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex case 3: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field SessionMetadata", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field OktaResourcesUpdatedMetadata", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -96280,13 +98411,97 @@ func (m *SAMLIdPAuthAttempt) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if err := m.SessionMetadata.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if err := m.OktaResourcesUpdatedMetadata.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex - case 4: + default: + iNdEx = preIndex + skippy, err := skipEvents(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthEvents + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *OktaSyncFailure) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvents + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: OktaSyncFailure: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: OktaSyncFailure: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Status", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Metadata", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvents + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthEvents + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthEvents + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.Metadata.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ServerMetadata", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -96313,13 +98528,13 @@ func (m *SAMLIdPAuthAttempt) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if err := m.Status.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if err := m.ServerMetadata.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex - case 5: + case 3: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field SAMLIdPServiceProviderMetadata", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Status", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -96346,7 +98561,7 @@ func (m *SAMLIdPAuthAttempt) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if err := m.SAMLIdPServiceProviderMetadata.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if err := m.Status.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex @@ -96372,7 +98587,7 @@ func (m *SAMLIdPAuthAttempt) Unmarshal(dAtA []byte) error { } return nil } -func (m *SAMLIdPServiceProviderCreate) Unmarshal(dAtA []byte) error { +func (m *OktaAssignmentResult) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -96395,10 +98610,10 @@ func (m *SAMLIdPServiceProviderCreate) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: SAMLIdPServiceProviderCreate: wiretype end group for non-group") + return fmt.Errorf("proto: OktaAssignmentResult: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: SAMLIdPServiceProviderCreate: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: OktaAssignmentResult: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: @@ -96435,6 +98650,39 @@ func (m *SAMLIdPServiceProviderCreate) Unmarshal(dAtA []byte) error { } iNdEx = postIndex case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ServerMetadata", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvents + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthEvents + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthEvents + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.ServerMetadata.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 3: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field ResourceMetadata", wireType) } @@ -96467,9 +98715,9 @@ func (m *SAMLIdPServiceProviderCreate) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex - case 3: + case 4: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field SAMLIdPServiceProviderMetadata", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Status", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -96496,7 +98744,40 @@ func (m *SAMLIdPServiceProviderCreate) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if err := m.SAMLIdPServiceProviderMetadata.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if err := m.Status.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field OktaAssignmentMetadata", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvents + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthEvents + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthEvents + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.OktaAssignmentMetadata.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex @@ -96522,7 +98803,7 @@ func (m *SAMLIdPServiceProviderCreate) Unmarshal(dAtA []byte) error { } return nil } -func (m *SAMLIdPServiceProviderUpdate) Unmarshal(dAtA []byte) error { +func (m *AccessListCreate) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -96545,10 +98826,10 @@ func (m *SAMLIdPServiceProviderUpdate) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: SAMLIdPServiceProviderUpdate: wiretype end group for non-group") + return fmt.Errorf("proto: AccessListCreate: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: SAMLIdPServiceProviderUpdate: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: AccessListCreate: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: @@ -96619,7 +98900,7 @@ func (m *SAMLIdPServiceProviderUpdate) Unmarshal(dAtA []byte) error { iNdEx = postIndex case 3: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field SAMLIdPServiceProviderMetadata", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Status", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -96646,7 +98927,7 @@ func (m *SAMLIdPServiceProviderUpdate) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if err := m.SAMLIdPServiceProviderMetadata.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if err := m.Status.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex @@ -96672,7 +98953,7 @@ func (m *SAMLIdPServiceProviderUpdate) Unmarshal(dAtA []byte) error { } return nil } -func (m *SAMLIdPServiceProviderDelete) Unmarshal(dAtA []byte) error { +func (m *AccessListUpdate) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -96695,10 +98976,10 @@ func (m *SAMLIdPServiceProviderDelete) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: SAMLIdPServiceProviderDelete: wiretype end group for non-group") + return fmt.Errorf("proto: AccessListUpdate: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: SAMLIdPServiceProviderDelete: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: AccessListUpdate: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: @@ -96769,7 +99050,7 @@ func (m *SAMLIdPServiceProviderDelete) Unmarshal(dAtA []byte) error { iNdEx = postIndex case 3: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field SAMLIdPServiceProviderMetadata", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Status", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -96796,7 +99077,7 @@ func (m *SAMLIdPServiceProviderDelete) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if err := m.SAMLIdPServiceProviderMetadata.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if err := m.Status.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex @@ -96822,7 +99103,7 @@ func (m *SAMLIdPServiceProviderDelete) Unmarshal(dAtA []byte) error { } return nil } -func (m *SAMLIdPServiceProviderDeleteAll) Unmarshal(dAtA []byte) error { +func (m *AccessListDelete) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -96845,10 +99126,10 @@ func (m *SAMLIdPServiceProviderDeleteAll) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: SAMLIdPServiceProviderDeleteAll: wiretype end group for non-group") + return fmt.Errorf("proto: AccessListDelete: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: SAMLIdPServiceProviderDeleteAll: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: AccessListDelete: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: @@ -96917,6 +99198,39 @@ func (m *SAMLIdPServiceProviderDeleteAll) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Status", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvents + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthEvents + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthEvents + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.Status.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipEvents(dAtA[iNdEx:]) @@ -96939,7 +99253,7 @@ func (m *SAMLIdPServiceProviderDeleteAll) Unmarshal(dAtA []byte) error { } return nil } -func (m *OktaResourcesUpdate) Unmarshal(dAtA []byte) error { +func (m *AccessListMemberCreate) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -96962,10 +99276,10 @@ func (m *OktaResourcesUpdate) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: OktaResourcesUpdate: wiretype end group for non-group") + return fmt.Errorf("proto: AccessListMemberCreate: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: OktaResourcesUpdate: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: AccessListMemberCreate: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: @@ -97003,7 +99317,7 @@ func (m *OktaResourcesUpdate) Unmarshal(dAtA []byte) error { iNdEx = postIndex case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ServerMetadata", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field ResourceMetadata", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -97030,13 +99344,13 @@ func (m *OktaResourcesUpdate) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if err := m.ServerMetadata.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if err := m.ResourceMetadata.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex case 3: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field OktaResourcesUpdatedMetadata", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field AccessListMemberMetadata", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -97063,7 +99377,40 @@ func (m *OktaResourcesUpdate) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if err := m.OktaResourcesUpdatedMetadata.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if err := m.AccessListMemberMetadata.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Status", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvents + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthEvents + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthEvents + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.Status.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex @@ -97089,7 +99436,7 @@ func (m *OktaResourcesUpdate) Unmarshal(dAtA []byte) error { } return nil } -func (m *OktaSyncFailure) Unmarshal(dAtA []byte) error { +func (m *AccessListMemberUpdate) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -97112,10 +99459,10 @@ func (m *OktaSyncFailure) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: OktaSyncFailure: wiretype end group for non-group") + return fmt.Errorf("proto: AccessListMemberUpdate: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: OktaSyncFailure: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: AccessListMemberUpdate: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: @@ -97153,7 +99500,7 @@ func (m *OktaSyncFailure) Unmarshal(dAtA []byte) error { iNdEx = postIndex case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ServerMetadata", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field ResourceMetadata", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -97180,13 +99527,13 @@ func (m *OktaSyncFailure) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if err := m.ServerMetadata.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if err := m.ResourceMetadata.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex case 3: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Status", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field AccessListMemberMetadata", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -97213,64 +99560,13 @@ func (m *OktaSyncFailure) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if err := m.Status.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if err := m.AccessListMemberMetadata.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipEvents(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthEvents - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *OktaAssignmentResult) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowEvents - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: OktaAssignmentResult: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: OktaAssignmentResult: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: + case 4: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Metadata", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Status", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -97297,13 +99593,64 @@ func (m *OktaAssignmentResult) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if err := m.Metadata.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if err := m.Status.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex - case 2: + default: + iNdEx = preIndex + skippy, err := skipEvents(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthEvents + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *AccessListMemberDelete) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvents + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: AccessListMemberDelete: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: AccessListMemberDelete: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ServerMetadata", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Metadata", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -97330,11 +99677,11 @@ func (m *OktaAssignmentResult) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if err := m.ServerMetadata.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if err := m.Metadata.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex - case 3: + case 2: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field ResourceMetadata", wireType) } @@ -97367,9 +99714,9 @@ func (m *OktaAssignmentResult) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex - case 4: + case 3: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Status", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field AccessListMemberMetadata", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -97396,13 +99743,13 @@ func (m *OktaAssignmentResult) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if err := m.Status.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if err := m.AccessListMemberMetadata.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex - case 5: + case 4: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field OktaAssignmentMetadata", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Status", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -97429,7 +99776,7 @@ func (m *OktaAssignmentResult) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if err := m.OktaAssignmentMetadata.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if err := m.Status.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex @@ -97455,7 +99802,7 @@ func (m *OktaAssignmentResult) Unmarshal(dAtA []byte) error { } return nil } -func (m *AccessListCreate) Unmarshal(dAtA []byte) error { +func (m *AccessListMemberDeleteAllForAccessList) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -97478,10 +99825,10 @@ func (m *AccessListCreate) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: AccessListCreate: wiretype end group for non-group") + return fmt.Errorf("proto: AccessListMemberDeleteAllForAccessList: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: AccessListCreate: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: AccessListMemberDeleteAllForAccessList: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: @@ -97552,124 +99899,7 @@ func (m *AccessListCreate) Unmarshal(dAtA []byte) error { iNdEx = postIndex case 3: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Status", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowEvents - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthEvents - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthEvents - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if err := m.Status.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipEvents(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthEvents - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *AccessListUpdate) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowEvents - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: AccessListUpdate: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: AccessListUpdate: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Metadata", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowEvents - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthEvents - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthEvents - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if err := m.Metadata.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ResourceMetadata", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field AccessListMemberMetadata", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -97696,11 +99926,11 @@ func (m *AccessListUpdate) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if err := m.ResourceMetadata.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if err := m.AccessListMemberMetadata.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex - case 3: + case 4: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field Status", wireType) } @@ -97755,7 +99985,7 @@ func (m *AccessListUpdate) Unmarshal(dAtA []byte) error { } return nil } -func (m *AccessListDelete) Unmarshal(dAtA []byte) error { +func (m *AccessListReview) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -97778,10 +100008,10 @@ func (m *AccessListDelete) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: AccessListDelete: wiretype end group for non-group") + return fmt.Errorf("proto: AccessListReview: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: AccessListDelete: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: AccessListReview: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: @@ -97851,6 +100081,39 @@ func (m *AccessListDelete) Unmarshal(dAtA []byte) error { } iNdEx = postIndex case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field AccessListReviewMetadata", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvents + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthEvents + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthEvents + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.AccessListReviewMetadata.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 4: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field Status", wireType) } @@ -97905,7 +100168,7 @@ func (m *AccessListDelete) Unmarshal(dAtA []byte) error { } return nil } -func (m *AccessListMemberCreate) Unmarshal(dAtA []byte) error { +func (m *AuditQueryRun) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -97928,10 +100191,10 @@ func (m *AccessListMemberCreate) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: AccessListMemberCreate: wiretype end group for non-group") + return fmt.Errorf("proto: AuditQueryRun: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: AccessListMemberCreate: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: AuditQueryRun: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: @@ -97969,7 +100232,7 @@ func (m *AccessListMemberCreate) Unmarshal(dAtA []byte) error { iNdEx = postIndex case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ResourceMetadata", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field UserMetadata", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -97996,13 +100259,13 @@ func (m *AccessListMemberCreate) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if err := m.ResourceMetadata.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if err := m.UserMetadata.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex case 3: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field AccessListMemberMetadata", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Status", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -98029,13 +100292,13 @@ func (m *AccessListMemberCreate) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if err := m.AccessListMemberMetadata.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if err := m.Status.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex case 4: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Status", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field AuditQueryDetails", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -98062,7 +100325,7 @@ func (m *AccessListMemberCreate) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if err := m.Status.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if err := m.AuditQueryDetails.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex @@ -98088,7 +100351,7 @@ func (m *AccessListMemberCreate) Unmarshal(dAtA []byte) error { } return nil } -func (m *AccessListMemberUpdate) Unmarshal(dAtA []byte) error { +func (m *AuditQueryDetails) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -98111,17 +100374,17 @@ func (m *AccessListMemberUpdate) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: AccessListMemberUpdate: wiretype end group for non-group") + return fmt.Errorf("proto: AuditQueryDetails: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: AccessListMemberUpdate: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: AuditQueryDetails: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Metadata", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) } - var msglen int + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowEvents @@ -98131,30 +100394,29 @@ func (m *AccessListMemberUpdate) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - msglen |= int(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } - if msglen < 0 { + intStringLen := int(stringLen) + if intStringLen < 0 { return ErrInvalidLengthEvents } - postIndex := iNdEx + msglen + postIndex := iNdEx + intStringLen if postIndex < 0 { return ErrInvalidLengthEvents } if postIndex > l { return io.ErrUnexpectedEOF } - if err := m.Metadata.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } + m.Name = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ResourceMetadata", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Query", wireType) } - var msglen int + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowEvents @@ -98164,30 +100426,29 @@ func (m *AccessListMemberUpdate) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - msglen |= int(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } - if msglen < 0 { + intStringLen := int(stringLen) + if intStringLen < 0 { return ErrInvalidLengthEvents } - postIndex := iNdEx + msglen + postIndex := iNdEx + intStringLen if postIndex < 0 { return ErrInvalidLengthEvents } if postIndex > l { return io.ErrUnexpectedEOF } - if err := m.ResourceMetadata.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } + m.Query = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 3: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field AccessListMemberMetadata", wireType) + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Days", wireType) } - var msglen int + m.Days = 0 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowEvents @@ -98197,30 +100458,16 @@ func (m *AccessListMemberUpdate) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - msglen |= int(b&0x7F) << shift + m.Days |= int32(b&0x7F) << shift if b < 0x80 { break } } - if msglen < 0 { - return ErrInvalidLengthEvents - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthEvents - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if err := m.AccessListMemberMetadata.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex case 4: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Status", wireType) + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field ExecutionTimeInMillis", wireType) } - var msglen int + m.ExecutionTimeInMillis = 0 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowEvents @@ -98230,25 +100477,30 @@ func (m *AccessListMemberUpdate) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - msglen |= int(b&0x7F) << shift + m.ExecutionTimeInMillis |= int64(b&0x7F) << shift if b < 0x80 { break } } - if msglen < 0 { - return ErrInvalidLengthEvents - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthEvents - } - if postIndex > l { - return io.ErrUnexpectedEOF + case 5: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field DataScannedInBytes", wireType) } - if err := m.Status.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err + m.DataScannedInBytes = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvents + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.DataScannedInBytes |= int64(b&0x7F) << shift + if b < 0x80 { + break + } } - iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipEvents(dAtA[iNdEx:]) @@ -98271,7 +100523,7 @@ func (m *AccessListMemberUpdate) Unmarshal(dAtA []byte) error { } return nil } -func (m *AccessListMemberDelete) Unmarshal(dAtA []byte) error { +func (m *SecurityReportRun) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -98294,10 +100546,10 @@ func (m *AccessListMemberDelete) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: AccessListMemberDelete: wiretype end group for non-group") + return fmt.Errorf("proto: SecurityReportRun: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: AccessListMemberDelete: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: SecurityReportRun: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: @@ -98335,7 +100587,7 @@ func (m *AccessListMemberDelete) Unmarshal(dAtA []byte) error { iNdEx = postIndex case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ResourceMetadata", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field UserMetadata", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -98362,13 +100614,13 @@ func (m *AccessListMemberDelete) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if err := m.ResourceMetadata.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if err := m.UserMetadata.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex case 3: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field AccessListMemberMetadata", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Status", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -98395,13 +100647,115 @@ func (m *AccessListMemberDelete) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if err := m.AccessListMemberMetadata.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if err := m.Status.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex case 4: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Status", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvents + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthEvents + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthEvents + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Name = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Version", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvents + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthEvents + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthEvents + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Version = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 6: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field TotalExecutionTimeInMillis", wireType) + } + m.TotalExecutionTimeInMillis = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvents + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.TotalExecutionTimeInMillis |= int64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 7: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field TotalDataScannedInBytes", wireType) + } + m.TotalDataScannedInBytes = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvents + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.TotalDataScannedInBytes |= int64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 8: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field AuditQueries", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -98428,7 +100782,8 @@ func (m *AccessListMemberDelete) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if err := m.Status.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + m.AuditQueries = append(m.AuditQueries, &AuditQueryDetails{}) + if err := m.AuditQueries[len(m.AuditQueries)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex @@ -98454,7 +100809,7 @@ func (m *AccessListMemberDelete) Unmarshal(dAtA []byte) error { } return nil } -func (m *AccessListMemberDeleteAllForAccessList) Unmarshal(dAtA []byte) error { +func (m *ExternalAuditStorageEnable) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -98477,10 +100832,10 @@ func (m *AccessListMemberDeleteAllForAccessList) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: AccessListMemberDeleteAllForAccessList: wiretype end group for non-group") + return fmt.Errorf("proto: ExternalAuditStorageEnable: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: AccessListMemberDeleteAllForAccessList: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: ExternalAuditStorageEnable: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: @@ -98545,46 +100900,13 @@ func (m *AccessListMemberDeleteAllForAccessList) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if err := m.ResourceMetadata.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 3: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field AccessListMemberMetadata", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowEvents - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthEvents - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthEvents - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if err := m.AccessListMemberMetadata.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if err := m.ResourceMetadata.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex - case 4: + case 3: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Status", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Details", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -98611,7 +100933,10 @@ func (m *AccessListMemberDeleteAllForAccessList) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if err := m.Status.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if m.Details == nil { + m.Details = &ExternalAuditStorageDetails{} + } + if err := m.Details.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex @@ -98637,7 +100962,7 @@ func (m *AccessListMemberDeleteAllForAccessList) Unmarshal(dAtA []byte) error { } return nil } -func (m *AccessListReview) Unmarshal(dAtA []byte) error { +func (m *ExternalAuditStorageDisable) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -98660,10 +100985,10 @@ func (m *AccessListReview) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: AccessListReview: wiretype end group for non-group") + return fmt.Errorf("proto: ExternalAuditStorageDisable: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: AccessListReview: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: ExternalAuditStorageDisable: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: @@ -98734,7 +101059,7 @@ func (m *AccessListReview) Unmarshal(dAtA []byte) error { iNdEx = postIndex case 3: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field AccessListReviewMetadata", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Details", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -98761,40 +101086,10 @@ func (m *AccessListReview) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if err := m.AccessListReviewMetadata.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 4: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Status", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowEvents - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthEvents - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthEvents - } - if postIndex > l { - return io.ErrUnexpectedEOF + if m.Details == nil { + m.Details = &ExternalAuditStorageDetails{} } - if err := m.Status.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if err := m.Details.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex @@ -98820,7 +101115,7 @@ func (m *AccessListReview) Unmarshal(dAtA []byte) error { } return nil } -func (m *AuditQueryRun) Unmarshal(dAtA []byte) error { +func (m *ExternalAuditStorageDetails) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -98843,17 +101138,17 @@ func (m *AuditQueryRun) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: AuditQueryRun: wiretype end group for non-group") + return fmt.Errorf("proto: ExternalAuditStorageDetails: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: AuditQueryRun: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: ExternalAuditStorageDetails: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { - case 1: + case 3: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Metadata", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field IntegrationName", wireType) } - var msglen int + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowEvents @@ -98863,30 +101158,29 @@ func (m *AuditQueryRun) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - msglen |= int(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } - if msglen < 0 { + intStringLen := int(stringLen) + if intStringLen < 0 { return ErrInvalidLengthEvents } - postIndex := iNdEx + msglen + postIndex := iNdEx + intStringLen if postIndex < 0 { return ErrInvalidLengthEvents } if postIndex > l { return io.ErrUnexpectedEOF } - if err := m.Metadata.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } + m.IntegrationName = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex - case 2: + case 4: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field UserMetadata", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field SessionRecordingsUri", wireType) } - var msglen int + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowEvents @@ -98896,30 +101190,29 @@ func (m *AuditQueryRun) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - msglen |= int(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } - if msglen < 0 { + intStringLen := int(stringLen) + if intStringLen < 0 { return ErrInvalidLengthEvents } - postIndex := iNdEx + msglen + postIndex := iNdEx + intStringLen if postIndex < 0 { return ErrInvalidLengthEvents } if postIndex > l { return io.ErrUnexpectedEOF } - if err := m.UserMetadata.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } + m.SessionRecordingsUri = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex - case 3: + case 5: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Status", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field AthenaWorkgroup", wireType) } - var msglen int + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowEvents @@ -98929,30 +101222,29 @@ func (m *AuditQueryRun) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - msglen |= int(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } - if msglen < 0 { + intStringLen := int(stringLen) + if intStringLen < 0 { return ErrInvalidLengthEvents } - postIndex := iNdEx + msglen + postIndex := iNdEx + intStringLen if postIndex < 0 { return ErrInvalidLengthEvents } if postIndex > l { return io.ErrUnexpectedEOF } - if err := m.Status.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } + m.AthenaWorkgroup = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex - case 4: + case 6: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field AuditQueryDetails", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field GlueDatabase", wireType) } - var msglen int + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowEvents @@ -98962,79 +101254,27 @@ func (m *AuditQueryRun) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - msglen |= int(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } - if msglen < 0 { + intStringLen := int(stringLen) + if intStringLen < 0 { return ErrInvalidLengthEvents } - postIndex := iNdEx + msglen + postIndex := iNdEx + intStringLen if postIndex < 0 { return ErrInvalidLengthEvents } if postIndex > l { return io.ErrUnexpectedEOF } - if err := m.AuditQueryDetails.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } + m.GlueDatabase = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipEvents(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthEvents - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *AuditQueryDetails) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowEvents - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: AuditQueryDetails: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: AuditQueryDetails: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: + case 7: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field GlueTable", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -99062,11 +101302,11 @@ func (m *AuditQueryDetails) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Name = string(dAtA[iNdEx:postIndex]) + m.GlueTable = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex - case 2: + case 8: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Query", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field AuditEventsLongTermUri", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -99094,13 +101334,13 @@ func (m *AuditQueryDetails) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Query = string(dAtA[iNdEx:postIndex]) + m.AuditEventsLongTermUri = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex - case 3: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field Days", wireType) + case 9: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field AthenaResultsUri", wireType) } - m.Days = 0 + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowEvents @@ -99110,16 +101350,29 @@ func (m *AuditQueryDetails) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - m.Days |= int32(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } - case 4: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field ExecutionTimeInMillis", wireType) + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthEvents } - m.ExecutionTimeInMillis = 0 + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthEvents + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.AthenaResultsUri = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 10: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field PolicyName", wireType) + } + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowEvents @@ -99129,16 +101382,29 @@ func (m *AuditQueryDetails) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - m.ExecutionTimeInMillis |= int64(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } - case 5: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field DataScannedInBytes", wireType) + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthEvents } - m.DataScannedInBytes = 0 + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthEvents + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.PolicyName = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 11: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Region", wireType) + } + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowEvents @@ -99148,11 +101414,24 @@ func (m *AuditQueryDetails) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - m.DataScannedInBytes |= int64(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthEvents + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthEvents + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Region = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipEvents(dAtA[iNdEx:]) @@ -99175,7 +101454,7 @@ func (m *AuditQueryDetails) Unmarshal(dAtA []byte) error { } return nil } -func (m *SecurityReportRun) Unmarshal(dAtA []byte) error { +func (m *OktaAccessListSync) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -99198,10 +101477,10 @@ func (m *SecurityReportRun) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: SecurityReportRun: wiretype end group for non-group") + return fmt.Errorf("proto: OktaAccessListSync: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: SecurityReportRun: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: OktaAccessListSync: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: @@ -99239,7 +101518,7 @@ func (m *SecurityReportRun) Unmarshal(dAtA []byte) error { iNdEx = postIndex case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field UserMetadata", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Status", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -99266,15 +101545,15 @@ func (m *SecurityReportRun) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if err := m.UserMetadata.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if err := m.Status.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex case 3: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Status", wireType) + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field NumAppFilters", wireType) } - var msglen int + m.NumAppFilters = 0 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowEvents @@ -99284,30 +101563,16 @@ func (m *SecurityReportRun) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - msglen |= int(b&0x7F) << shift + m.NumAppFilters |= int32(b&0x7F) << shift if b < 0x80 { break } } - if msglen < 0 { - return ErrInvalidLengthEvents - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthEvents - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if err := m.Status.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex case 4: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field NumGroupFilters", wireType) } - var stringLen uint64 + m.NumGroupFilters = 0 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowEvents @@ -99317,29 +101582,16 @@ func (m *SecurityReportRun) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + m.NumGroupFilters |= int32(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthEvents - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthEvents - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Name = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex case 5: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Version", wireType) + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field NumApps", wireType) } - var stringLen uint64 + m.NumApps = 0 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowEvents @@ -99349,29 +101601,16 @@ func (m *SecurityReportRun) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + m.NumApps |= int32(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthEvents - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthEvents - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Version = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex case 6: if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field TotalExecutionTimeInMillis", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field NumGroups", wireType) } - m.TotalExecutionTimeInMillis = 0 + m.NumGroups = 0 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowEvents @@ -99381,16 +101620,16 @@ func (m *SecurityReportRun) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - m.TotalExecutionTimeInMillis |= int64(b&0x7F) << shift + m.NumGroups |= int32(b&0x7F) << shift if b < 0x80 { break } } case 7: if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field TotalDataScannedInBytes", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field NumRoles", wireType) } - m.TotalDataScannedInBytes = 0 + m.NumRoles = 0 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowEvents @@ -99400,16 +101639,16 @@ func (m *SecurityReportRun) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - m.TotalDataScannedInBytes |= int64(b&0x7F) << shift + m.NumRoles |= int32(b&0x7F) << shift if b < 0x80 { break } } case 8: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field AuditQueries", wireType) + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field NumAccessLists", wireType) } - var msglen int + m.NumAccessLists = 0 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowEvents @@ -99419,26 +101658,30 @@ func (m *SecurityReportRun) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - msglen |= int(b&0x7F) << shift + m.NumAccessLists |= int32(b&0x7F) << shift if b < 0x80 { break } } - if msglen < 0 { - return ErrInvalidLengthEvents - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthEvents - } - if postIndex > l { - return io.ErrUnexpectedEOF + case 9: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field NumAccessListMembers", wireType) } - m.AuditQueries = append(m.AuditQueries, &AuditQueryDetails{}) - if err := m.AuditQueries[len(m.AuditQueries)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err + m.NumAccessListMembers = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvents + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.NumAccessListMembers |= int32(b&0x7F) << shift + if b < 0x80 { + break + } } - iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipEvents(dAtA[iNdEx:]) @@ -99461,7 +101704,7 @@ func (m *SecurityReportRun) Unmarshal(dAtA []byte) error { } return nil } -func (m *ExternalAuditStorageEnable) Unmarshal(dAtA []byte) error { +func (m *OktaUserSync) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -99484,10 +101727,10 @@ func (m *ExternalAuditStorageEnable) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: ExternalAuditStorageEnable: wiretype end group for non-group") + return fmt.Errorf("proto: OktaUserSync: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: ExternalAuditStorageEnable: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: OktaUserSync: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: @@ -99525,7 +101768,7 @@ func (m *ExternalAuditStorageEnable) Unmarshal(dAtA []byte) error { iNdEx = postIndex case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ResourceMetadata", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Status", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -99552,15 +101795,15 @@ func (m *ExternalAuditStorageEnable) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if err := m.ResourceMetadata.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if err := m.Status.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex case 3: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Details", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field OrgUrl", wireType) } - var msglen int + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowEvents @@ -99570,28 +101813,132 @@ func (m *ExternalAuditStorageEnable) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - msglen |= int(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } - if msglen < 0 { + intStringLen := int(stringLen) + if intStringLen < 0 { return ErrInvalidLengthEvents } - postIndex := iNdEx + msglen + postIndex := iNdEx + intStringLen if postIndex < 0 { return ErrInvalidLengthEvents } if postIndex > l { return io.ErrUnexpectedEOF } - if m.Details == nil { - m.Details = &ExternalAuditStorageDetails{} + m.OrgUrl = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field AppId", wireType) } - if err := m.Details.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvents + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthEvents + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthEvents + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.AppId = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex + case 5: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field NumUsersCreated", wireType) + } + m.NumUsersCreated = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvents + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.NumUsersCreated |= int32(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 6: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field NumUsersDeleted", wireType) + } + m.NumUsersDeleted = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvents + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.NumUsersDeleted |= int32(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 7: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field NumUsersModified", wireType) + } + m.NumUsersModified = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvents + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.NumUsersModified |= int32(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 8: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field NumUsersTotal", wireType) + } + m.NumUsersTotal = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvents + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.NumUsersTotal |= int32(b&0x7F) << shift + if b < 0x80 { + break + } + } default: iNdEx = preIndex skippy, err := skipEvents(dAtA[iNdEx:]) @@ -99614,7 +101961,7 @@ func (m *ExternalAuditStorageEnable) Unmarshal(dAtA []byte) error { } return nil } -func (m *ExternalAuditStorageDisable) Unmarshal(dAtA []byte) error { +func (m *SPIFFESVIDIssued) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -99637,10 +101984,10 @@ func (m *ExternalAuditStorageDisable) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: ExternalAuditStorageDisable: wiretype end group for non-group") + return fmt.Errorf("proto: SPIFFESVIDIssued: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: ExternalAuditStorageDisable: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: SPIFFESVIDIssued: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: @@ -99678,7 +102025,7 @@ func (m *ExternalAuditStorageDisable) Unmarshal(dAtA []byte) error { iNdEx = postIndex case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ResourceMetadata", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field UserMetadata", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -99705,13 +102052,13 @@ func (m *ExternalAuditStorageDisable) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if err := m.ResourceMetadata.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if err := m.UserMetadata.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex case 3: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Details", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field ConnectionMetadata", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -99738,99 +102085,13 @@ func (m *ExternalAuditStorageDisable) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if m.Details == nil { - m.Details = &ExternalAuditStorageDetails{} - } - if err := m.Details.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipEvents(dAtA[iNdEx:]) - if err != nil { + if err := m.ConnectionMetadata.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthEvents - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *ExternalAuditStorageDetails) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowEvents - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: ExternalAuditStorageDetails: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: ExternalAuditStorageDetails: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 3: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field IntegrationName", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowEvents - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthEvents - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthEvents - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.IntegrationName = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 4: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field SessionRecordingsUri", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field SPIFFEID", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -99858,11 +102119,11 @@ func (m *ExternalAuditStorageDetails) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.SessionRecordingsUri = string(dAtA[iNdEx:postIndex]) + m.SPIFFEID = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 5: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field AthenaWorkgroup", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field DNSSANs", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -99890,11 +102151,11 @@ func (m *ExternalAuditStorageDetails) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.AthenaWorkgroup = string(dAtA[iNdEx:postIndex]) + m.DNSSANs = append(m.DNSSANs, string(dAtA[iNdEx:postIndex])) iNdEx = postIndex case 6: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field GlueDatabase", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field IPSANs", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -99922,11 +102183,11 @@ func (m *ExternalAuditStorageDetails) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.GlueDatabase = string(dAtA[iNdEx:postIndex]) + m.IPSANs = append(m.IPSANs, string(dAtA[iNdEx:postIndex])) iNdEx = postIndex case 7: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field GlueTable", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field SVIDType", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -99954,11 +102215,11 @@ func (m *ExternalAuditStorageDetails) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.GlueTable = string(dAtA[iNdEx:postIndex]) + m.SVIDType = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 8: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field AuditEventsLongTermUri", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field SerialNumber", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -99986,11 +102247,11 @@ func (m *ExternalAuditStorageDetails) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.AuditEventsLongTermUri = string(dAtA[iNdEx:postIndex]) + m.SerialNumber = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 9: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field AthenaResultsUri", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Hint", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -100018,11 +102279,11 @@ func (m *ExternalAuditStorageDetails) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.AthenaResultsUri = string(dAtA[iNdEx:postIndex]) + m.Hint = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 10: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field PolicyName", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field JTI", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -100050,11 +102311,11 @@ func (m *ExternalAuditStorageDetails) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.PolicyName = string(dAtA[iNdEx:postIndex]) + m.JTI = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 11: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Region", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Audiences", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -100082,7 +102343,7 @@ func (m *ExternalAuditStorageDetails) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Region = string(dAtA[iNdEx:postIndex]) + m.Audiences = append(m.Audiences, string(dAtA[iNdEx:postIndex])) iNdEx = postIndex default: iNdEx = preIndex @@ -100106,7 +102367,7 @@ func (m *ExternalAuditStorageDetails) Unmarshal(dAtA []byte) error { } return nil } -func (m *OktaAccessListSync) Unmarshal(dAtA []byte) error { +func (m *AuthPreferenceUpdate) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -100129,10 +102390,10 @@ func (m *OktaAccessListSync) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: OktaAccessListSync: wiretype end group for non-group") + return fmt.Errorf("proto: AuthPreferenceUpdate: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: OktaAccessListSync: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: AuthPreferenceUpdate: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: @@ -100202,10 +102463,10 @@ func (m *OktaAccessListSync) Unmarshal(dAtA []byte) error { } iNdEx = postIndex case 3: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field NumAppFilters", wireType) + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field UserMetadata", wireType) } - m.NumAppFilters = 0 + var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowEvents @@ -100215,54 +102476,30 @@ func (m *OktaAccessListSync) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - m.NumAppFilters |= int32(b&0x7F) << shift + msglen |= int(b&0x7F) << shift if b < 0x80 { break } } - case 4: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field NumGroupFilters", wireType) + if msglen < 0 { + return ErrInvalidLengthEvents } - m.NumGroupFilters = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowEvents - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - m.NumGroupFilters |= int32(b&0x7F) << shift - if b < 0x80 { - break - } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthEvents } - case 5: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field NumApps", wireType) + if postIndex > l { + return io.ErrUnexpectedEOF } - m.NumApps = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowEvents - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - m.NumApps |= int32(b&0x7F) << shift - if b < 0x80 { - break - } + if err := m.UserMetadata.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err } - case 6: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field NumGroups", wireType) + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ConnectionMetadata", wireType) } - m.NumGroups = 0 + var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowEvents @@ -100272,54 +102509,30 @@ func (m *OktaAccessListSync) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - m.NumGroups |= int32(b&0x7F) << shift + msglen |= int(b&0x7F) << shift if b < 0x80 { break } } - case 7: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field NumRoles", wireType) + if msglen < 0 { + return ErrInvalidLengthEvents } - m.NumRoles = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowEvents - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - m.NumRoles |= int32(b&0x7F) << shift - if b < 0x80 { - break - } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthEvents } - case 8: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field NumAccessLists", wireType) + if postIndex > l { + return io.ErrUnexpectedEOF } - m.NumAccessLists = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowEvents - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - m.NumAccessLists |= int32(b&0x7F) << shift - if b < 0x80 { - break - } + if err := m.ConnectionMetadata.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err } - case 9: + iNdEx = postIndex + case 5: if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field NumAccessListMembers", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field AdminActionsMFA", wireType) } - m.NumAccessListMembers = 0 + m.AdminActionsMFA = 0 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowEvents @@ -100329,7 +102542,7 @@ func (m *OktaAccessListSync) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - m.NumAccessListMembers |= int32(b&0x7F) << shift + m.AdminActionsMFA |= AdminActionsMFAStatus(b&0x7F) << shift if b < 0x80 { break } @@ -100356,7 +102569,7 @@ func (m *OktaAccessListSync) Unmarshal(dAtA []byte) error { } return nil } -func (m *OktaUserSync) Unmarshal(dAtA []byte) error { +func (m *ClusterNetworkingConfigUpdate) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -100379,10 +102592,10 @@ func (m *OktaUserSync) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: OktaUserSync: wiretype end group for non-group") + return fmt.Errorf("proto: ClusterNetworkingConfigUpdate: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: OktaUserSync: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: ClusterNetworkingConfigUpdate: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: @@ -100453,9 +102666,9 @@ func (m *OktaUserSync) Unmarshal(dAtA []byte) error { iNdEx = postIndex case 3: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field OrgUrl", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field UserMetadata", wireType) } - var stringLen uint64 + var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowEvents @@ -100465,29 +102678,30 @@ func (m *OktaUserSync) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + msglen |= int(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { + if msglen < 0 { return ErrInvalidLengthEvents } - postIndex := iNdEx + intStringLen + postIndex := iNdEx + msglen if postIndex < 0 { return ErrInvalidLengthEvents } if postIndex > l { return io.ErrUnexpectedEOF } - m.OrgUrl = string(dAtA[iNdEx:postIndex]) + if err := m.UserMetadata.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } iNdEx = postIndex case 4: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field AppId", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field ConnectionMetadata", wireType) } - var stringLen uint64 + var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowEvents @@ -100497,29 +102711,81 @@ func (m *OktaUserSync) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + msglen |= int(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { + if msglen < 0 { return ErrInvalidLengthEvents } - postIndex := iNdEx + intStringLen + postIndex := iNdEx + msglen if postIndex < 0 { return ErrInvalidLengthEvents } if postIndex > l { return io.ErrUnexpectedEOF } - m.AppId = string(dAtA[iNdEx:postIndex]) + if err := m.ConnectionMetadata.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } iNdEx = postIndex - case 5: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field NumUsersCreated", wireType) + default: + iNdEx = preIndex + skippy, err := skipEvents(dAtA[iNdEx:]) + if err != nil { + return err } - m.NumUsersCreated = 0 + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthEvents + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *SessionRecordingConfigUpdate) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvents + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: SessionRecordingConfigUpdate: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: SessionRecordingConfigUpdate: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Metadata", wireType) + } + var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowEvents @@ -100529,16 +102795,30 @@ func (m *OktaUserSync) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - m.NumUsersCreated |= int32(b&0x7F) << shift + msglen |= int(b&0x7F) << shift if b < 0x80 { break } } - case 6: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field NumUsersDeleted", wireType) + if msglen < 0 { + return ErrInvalidLengthEvents } - m.NumUsersDeleted = 0 + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthEvents + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.Metadata.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Status", wireType) + } + var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowEvents @@ -100548,16 +102828,30 @@ func (m *OktaUserSync) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - m.NumUsersDeleted |= int32(b&0x7F) << shift + msglen |= int(b&0x7F) << shift if b < 0x80 { break } } - case 7: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field NumUsersModified", wireType) + if msglen < 0 { + return ErrInvalidLengthEvents } - m.NumUsersModified = 0 + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthEvents + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.Status.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field UserMetadata", wireType) + } + var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowEvents @@ -100567,16 +102861,30 @@ func (m *OktaUserSync) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - m.NumUsersModified |= int32(b&0x7F) << shift + msglen |= int(b&0x7F) << shift if b < 0x80 { break } } - case 8: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field NumUsersTotal", wireType) + if msglen < 0 { + return ErrInvalidLengthEvents } - m.NumUsersTotal = 0 + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthEvents + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.UserMetadata.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ConnectionMetadata", wireType) + } + var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowEvents @@ -100586,11 +102894,25 @@ func (m *OktaUserSync) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - m.NumUsersTotal |= int32(b&0x7F) << shift + msglen |= int(b&0x7F) << shift if b < 0x80 { break } } + if msglen < 0 { + return ErrInvalidLengthEvents + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthEvents + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.ConnectionMetadata.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipEvents(dAtA[iNdEx:]) @@ -100613,7 +102935,7 @@ func (m *OktaUserSync) Unmarshal(dAtA []byte) error { } return nil } -func (m *SPIFFESVIDIssued) Unmarshal(dAtA []byte) error { +func (m *AccessPathChanged) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -100636,10 +102958,10 @@ func (m *SPIFFESVIDIssued) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: SPIFFESVIDIssued: wiretype end group for non-group") + return fmt.Errorf("proto: AccessPathChanged: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: SPIFFESVIDIssued: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: AccessPathChanged: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: @@ -100677,9 +102999,9 @@ func (m *SPIFFESVIDIssued) Unmarshal(dAtA []byte) error { iNdEx = postIndex case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field UserMetadata", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field ChangeID", wireType) } - var msglen int + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowEvents @@ -100689,30 +103011,29 @@ func (m *SPIFFESVIDIssued) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - msglen |= int(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } - if msglen < 0 { + intStringLen := int(stringLen) + if intStringLen < 0 { return ErrInvalidLengthEvents } - postIndex := iNdEx + msglen + postIndex := iNdEx + intStringLen if postIndex < 0 { return ErrInvalidLengthEvents } if postIndex > l { return io.ErrUnexpectedEOF } - if err := m.UserMetadata.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } + m.ChangeID = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 3: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ConnectionMetadata", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field AffectedResourceName", wireType) } - var msglen int + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowEvents @@ -100722,28 +103043,27 @@ func (m *SPIFFESVIDIssued) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - msglen |= int(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } - if msglen < 0 { + intStringLen := int(stringLen) + if intStringLen < 0 { return ErrInvalidLengthEvents } - postIndex := iNdEx + msglen + postIndex := iNdEx + intStringLen if postIndex < 0 { return ErrInvalidLengthEvents } if postIndex > l { return io.ErrUnexpectedEOF } - if err := m.ConnectionMetadata.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } + m.AffectedResourceName = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 4: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field SPIFFEID", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field AffectedResourceSource", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -100771,11 +103091,11 @@ func (m *SPIFFESVIDIssued) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.SPIFFEID = string(dAtA[iNdEx:postIndex]) + m.AffectedResourceSource = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 5: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field DNSSANs", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field AffectedResourceType", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -100803,13 +103123,64 @@ func (m *SPIFFESVIDIssued) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.DNSSANs = append(m.DNSSANs, string(dAtA[iNdEx:postIndex])) + m.AffectedResourceType = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex - case 6: + default: + iNdEx = preIndex + skippy, err := skipEvents(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthEvents + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *SpannerRPC) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvents + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: SpannerRPC: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: SpannerRPC: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field IPSANs", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Metadata", wireType) } - var stringLen uint64 + var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowEvents @@ -100819,29 +103190,30 @@ func (m *SPIFFESVIDIssued) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + msglen |= int(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { + if msglen < 0 { return ErrInvalidLengthEvents } - postIndex := iNdEx + intStringLen + postIndex := iNdEx + msglen if postIndex < 0 { return ErrInvalidLengthEvents } if postIndex > l { return io.ErrUnexpectedEOF } - m.IPSANs = append(m.IPSANs, string(dAtA[iNdEx:postIndex])) + if err := m.Metadata.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } iNdEx = postIndex - case 7: + case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field SVIDType", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field UserMetadata", wireType) } - var stringLen uint64 + var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowEvents @@ -100851,29 +103223,30 @@ func (m *SPIFFESVIDIssued) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + msglen |= int(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { + if msglen < 0 { return ErrInvalidLengthEvents } - postIndex := iNdEx + intStringLen + postIndex := iNdEx + msglen if postIndex < 0 { return ErrInvalidLengthEvents } if postIndex > l { return io.ErrUnexpectedEOF } - m.SVIDType = string(dAtA[iNdEx:postIndex]) + if err := m.UserMetadata.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } iNdEx = postIndex - case 8: + case 3: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field SerialNumber", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field SessionMetadata", wireType) } - var stringLen uint64 + var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowEvents @@ -100883,29 +103256,30 @@ func (m *SPIFFESVIDIssued) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + msglen |= int(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { + if msglen < 0 { return ErrInvalidLengthEvents } - postIndex := iNdEx + intStringLen + postIndex := iNdEx + msglen if postIndex < 0 { return ErrInvalidLengthEvents } if postIndex > l { return io.ErrUnexpectedEOF } - m.SerialNumber = string(dAtA[iNdEx:postIndex]) + if err := m.SessionMetadata.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } iNdEx = postIndex - case 9: + case 4: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Hint", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field DatabaseMetadata", wireType) } - var stringLen uint64 + var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowEvents @@ -100915,29 +103289,30 @@ func (m *SPIFFESVIDIssued) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + msglen |= int(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { + if msglen < 0 { return ErrInvalidLengthEvents } - postIndex := iNdEx + intStringLen + postIndex := iNdEx + msglen if postIndex < 0 { return ErrInvalidLengthEvents } if postIndex > l { return io.ErrUnexpectedEOF } - m.Hint = string(dAtA[iNdEx:postIndex]) + if err := m.DatabaseMetadata.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } iNdEx = postIndex - case 10: + case 5: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field JTI", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Status", wireType) } - var stringLen uint64 + var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowEvents @@ -100947,27 +103322,28 @@ func (m *SPIFFESVIDIssued) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + msglen |= int(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { + if msglen < 0 { return ErrInvalidLengthEvents } - postIndex := iNdEx + intStringLen + postIndex := iNdEx + msglen if postIndex < 0 { return ErrInvalidLengthEvents } if postIndex > l { return io.ErrUnexpectedEOF } - m.JTI = string(dAtA[iNdEx:postIndex]) + if err := m.Status.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } iNdEx = postIndex - case 11: + case 6: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Audiences", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Procedure", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -100995,7 +103371,43 @@ func (m *SPIFFESVIDIssued) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Audiences = append(m.Audiences, string(dAtA[iNdEx:postIndex])) + m.Procedure = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 7: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Args", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvents + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthEvents + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthEvents + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Args == nil { + m.Args = &Struct{} + } + if err := m.Args.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } iNdEx = postIndex default: iNdEx = preIndex @@ -101019,7 +103431,7 @@ func (m *SPIFFESVIDIssued) Unmarshal(dAtA []byte) error { } return nil } -func (m *AuthPreferenceUpdate) Unmarshal(dAtA []byte) error { +func (m *AccessGraphSettingsUpdate) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -101042,10 +103454,10 @@ func (m *AuthPreferenceUpdate) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: AuthPreferenceUpdate: wiretype end group for non-group") + return fmt.Errorf("proto: AccessGraphSettingsUpdate: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: AuthPreferenceUpdate: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: AccessGraphSettingsUpdate: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: @@ -101180,25 +103592,6 @@ func (m *AuthPreferenceUpdate) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex - case 5: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field AdminActionsMFA", wireType) - } - m.AdminActionsMFA = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowEvents - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - m.AdminActionsMFA |= AdminActionsMFAStatus(b&0x7F) << shift - if b < 0x80 { - break - } - } default: iNdEx = preIndex skippy, err := skipEvents(dAtA[iNdEx:]) @@ -101221,7 +103614,7 @@ func (m *AuthPreferenceUpdate) Unmarshal(dAtA []byte) error { } return nil } -func (m *ClusterNetworkingConfigUpdate) Unmarshal(dAtA []byte) error { +func (m *SPIFFEFederationCreate) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -101244,10 +103637,10 @@ func (m *ClusterNetworkingConfigUpdate) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: ClusterNetworkingConfigUpdate: wiretype end group for non-group") + return fmt.Errorf("proto: SPIFFEFederationCreate: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: ClusterNetworkingConfigUpdate: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: SPIFFEFederationCreate: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: @@ -101285,7 +103678,7 @@ func (m *ClusterNetworkingConfigUpdate) Unmarshal(dAtA []byte) error { iNdEx = postIndex case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Status", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field ResourceMetadata", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -101312,7 +103705,7 @@ func (m *ClusterNetworkingConfigUpdate) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if err := m.Status.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if err := m.ResourceMetadata.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex @@ -101404,7 +103797,7 @@ func (m *ClusterNetworkingConfigUpdate) Unmarshal(dAtA []byte) error { } return nil } -func (m *SessionRecordingConfigUpdate) Unmarshal(dAtA []byte) error { +func (m *SPIFFEFederationDelete) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -101427,10 +103820,10 @@ func (m *SessionRecordingConfigUpdate) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: SessionRecordingConfigUpdate: wiretype end group for non-group") + return fmt.Errorf("proto: SPIFFEFederationDelete: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: SessionRecordingConfigUpdate: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: SPIFFEFederationDelete: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: @@ -101468,7 +103861,7 @@ func (m *SessionRecordingConfigUpdate) Unmarshal(dAtA []byte) error { iNdEx = postIndex case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Status", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field ResourceMetadata", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -101495,7 +103888,7 @@ func (m *SessionRecordingConfigUpdate) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if err := m.Status.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if err := m.ResourceMetadata.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex @@ -101587,7 +103980,7 @@ func (m *SessionRecordingConfigUpdate) Unmarshal(dAtA []byte) error { } return nil } -func (m *AccessPathChanged) Unmarshal(dAtA []byte) error { +func (m *AutoUpdateConfigCreate) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -101610,10 +104003,10 @@ func (m *AccessPathChanged) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: AccessPathChanged: wiretype end group for non-group") + return fmt.Errorf("proto: AutoUpdateConfigCreate: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: AccessPathChanged: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: AutoUpdateConfigCreate: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: @@ -101651,9 +104044,9 @@ func (m *AccessPathChanged) Unmarshal(dAtA []byte) error { iNdEx = postIndex case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ChangeID", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field ResourceMetadata", wireType) } - var stringLen uint64 + var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowEvents @@ -101663,29 +104056,30 @@ func (m *AccessPathChanged) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + msglen |= int(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { + if msglen < 0 { return ErrInvalidLengthEvents } - postIndex := iNdEx + intStringLen + postIndex := iNdEx + msglen if postIndex < 0 { return ErrInvalidLengthEvents } if postIndex > l { return io.ErrUnexpectedEOF } - m.ChangeID = string(dAtA[iNdEx:postIndex]) + if err := m.ResourceMetadata.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } iNdEx = postIndex case 3: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field AffectedResourceName", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field UserMetadata", wireType) } - var stringLen uint64 + var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowEvents @@ -101695,29 +104089,30 @@ func (m *AccessPathChanged) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + msglen |= int(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { + if msglen < 0 { return ErrInvalidLengthEvents } - postIndex := iNdEx + intStringLen + postIndex := iNdEx + msglen if postIndex < 0 { return ErrInvalidLengthEvents } if postIndex > l { return io.ErrUnexpectedEOF } - m.AffectedResourceName = string(dAtA[iNdEx:postIndex]) + if err := m.UserMetadata.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } iNdEx = postIndex case 4: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field AffectedResourceSource", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field ConnectionMetadata", wireType) } - var stringLen uint64 + var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowEvents @@ -101727,29 +104122,30 @@ func (m *AccessPathChanged) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + msglen |= int(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { + if msglen < 0 { return ErrInvalidLengthEvents } - postIndex := iNdEx + intStringLen + postIndex := iNdEx + msglen if postIndex < 0 { return ErrInvalidLengthEvents } if postIndex > l { return io.ErrUnexpectedEOF } - m.AffectedResourceSource = string(dAtA[iNdEx:postIndex]) + if err := m.ConnectionMetadata.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } iNdEx = postIndex case 5: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field AffectedResourceType", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Status", wireType) } - var stringLen uint64 + var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowEvents @@ -101759,23 +104155,24 @@ func (m *AccessPathChanged) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + msglen |= int(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { + if msglen < 0 { return ErrInvalidLengthEvents } - postIndex := iNdEx + intStringLen + postIndex := iNdEx + msglen if postIndex < 0 { return ErrInvalidLengthEvents } if postIndex > l { return io.ErrUnexpectedEOF } - m.AffectedResourceType = string(dAtA[iNdEx:postIndex]) + if err := m.Status.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } iNdEx = postIndex default: iNdEx = preIndex @@ -101799,7 +104196,7 @@ func (m *AccessPathChanged) Unmarshal(dAtA []byte) error { } return nil } -func (m *SpannerRPC) Unmarshal(dAtA []byte) error { +func (m *AutoUpdateConfigUpdate) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -101822,10 +104219,10 @@ func (m *SpannerRPC) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: SpannerRPC: wiretype end group for non-group") + return fmt.Errorf("proto: AutoUpdateConfigUpdate: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: SpannerRPC: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: AutoUpdateConfigUpdate: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: @@ -101863,7 +104260,7 @@ func (m *SpannerRPC) Unmarshal(dAtA []byte) error { iNdEx = postIndex case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field UserMetadata", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Status", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -101890,13 +104287,13 @@ func (m *SpannerRPC) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if err := m.UserMetadata.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if err := m.Status.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex case 3: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field SessionMetadata", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field UserMetadata", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -101923,13 +104320,13 @@ func (m *SpannerRPC) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if err := m.SessionMetadata.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if err := m.UserMetadata.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex case 4: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field DatabaseMetadata", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field ConnectionMetadata", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -101956,78 +104353,13 @@ func (m *SpannerRPC) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if err := m.DatabaseMetadata.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if err := m.ConnectionMetadata.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex case 5: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Status", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowEvents - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthEvents - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthEvents - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if err := m.Status.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 6: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Procedure", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowEvents - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthEvents - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthEvents - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Procedure = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 7: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Args", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field ResourceMetadata", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -102054,10 +104386,7 @@ func (m *SpannerRPC) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if m.Args == nil { - m.Args = &Struct{} - } - if err := m.Args.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if err := m.ResourceMetadata.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex @@ -102083,7 +104412,7 @@ func (m *SpannerRPC) Unmarshal(dAtA []byte) error { } return nil } -func (m *AccessGraphSettingsUpdate) Unmarshal(dAtA []byte) error { +func (m *AutoUpdateConfigDelete) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -102106,10 +104435,10 @@ func (m *AccessGraphSettingsUpdate) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: AccessGraphSettingsUpdate: wiretype end group for non-group") + return fmt.Errorf("proto: AutoUpdateConfigDelete: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: AccessGraphSettingsUpdate: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: AutoUpdateConfigDelete: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: @@ -102147,7 +104476,7 @@ func (m *AccessGraphSettingsUpdate) Unmarshal(dAtA []byte) error { iNdEx = postIndex case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Status", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field ResourceMetadata", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -102174,7 +104503,7 @@ func (m *AccessGraphSettingsUpdate) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if err := m.Status.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if err := m.ResourceMetadata.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex @@ -102244,6 +104573,39 @@ func (m *AccessGraphSettingsUpdate) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Status", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvents + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthEvents + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthEvents + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.Status.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipEvents(dAtA[iNdEx:]) @@ -102266,7 +104628,7 @@ func (m *AccessGraphSettingsUpdate) Unmarshal(dAtA []byte) error { } return nil } -func (m *SPIFFEFederationCreate) Unmarshal(dAtA []byte) error { +func (m *AutoUpdateVersionCreate) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -102289,10 +104651,10 @@ func (m *SPIFFEFederationCreate) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: SPIFFEFederationCreate: wiretype end group for non-group") + return fmt.Errorf("proto: AutoUpdateVersionCreate: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: SPIFFEFederationCreate: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: AutoUpdateVersionCreate: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: @@ -102427,6 +104789,39 @@ func (m *SPIFFEFederationCreate) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Status", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvents + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthEvents + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthEvents + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.Status.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipEvents(dAtA[iNdEx:]) @@ -102449,7 +104844,7 @@ func (m *SPIFFEFederationCreate) Unmarshal(dAtA []byte) error { } return nil } -func (m *SPIFFEFederationDelete) Unmarshal(dAtA []byte) error { +func (m *AutoUpdateVersionUpdate) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -102472,10 +104867,10 @@ func (m *SPIFFEFederationDelete) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: SPIFFEFederationDelete: wiretype end group for non-group") + return fmt.Errorf("proto: AutoUpdateVersionUpdate: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: SPIFFEFederationDelete: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: AutoUpdateVersionUpdate: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: @@ -102513,7 +104908,7 @@ func (m *SPIFFEFederationDelete) Unmarshal(dAtA []byte) error { iNdEx = postIndex case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ResourceMetadata", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Status", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -102540,7 +104935,7 @@ func (m *SPIFFEFederationDelete) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if err := m.ResourceMetadata.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if err := m.Status.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex @@ -102610,6 +105005,39 @@ func (m *SPIFFEFederationDelete) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ResourceMetadata", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvents + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthEvents + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthEvents + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.ResourceMetadata.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipEvents(dAtA[iNdEx:]) @@ -102632,7 +105060,7 @@ func (m *SPIFFEFederationDelete) Unmarshal(dAtA []byte) error { } return nil } -func (m *AutoUpdateConfigCreate) Unmarshal(dAtA []byte) error { +func (m *AutoUpdateVersionDelete) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -102655,10 +105083,10 @@ func (m *AutoUpdateConfigCreate) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: AutoUpdateConfigCreate: wiretype end group for non-group") + return fmt.Errorf("proto: AutoUpdateVersionDelete: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: AutoUpdateConfigCreate: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: AutoUpdateVersionDelete: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: @@ -102848,7 +105276,7 @@ func (m *AutoUpdateConfigCreate) Unmarshal(dAtA []byte) error { } return nil } -func (m *AutoUpdateConfigUpdate) Unmarshal(dAtA []byte) error { +func (m *StaticHostUserCreate) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -102871,10 +105299,10 @@ func (m *AutoUpdateConfigUpdate) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: AutoUpdateConfigUpdate: wiretype end group for non-group") + return fmt.Errorf("proto: StaticHostUserCreate: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: AutoUpdateConfigUpdate: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: StaticHostUserCreate: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: @@ -102945,7 +105373,7 @@ func (m *AutoUpdateConfigUpdate) Unmarshal(dAtA []byte) error { iNdEx = postIndex case 3: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field UserMetadata", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field ResourceMetadata", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -102972,13 +105400,13 @@ func (m *AutoUpdateConfigUpdate) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if err := m.UserMetadata.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if err := m.ResourceMetadata.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex case 4: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ConnectionMetadata", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field UserMetadata", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -103005,13 +105433,13 @@ func (m *AutoUpdateConfigUpdate) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if err := m.ConnectionMetadata.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if err := m.UserMetadata.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex case 5: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ResourceMetadata", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field ConnectionMetadata", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -103038,7 +105466,7 @@ func (m *AutoUpdateConfigUpdate) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if err := m.ResourceMetadata.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if err := m.ConnectionMetadata.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex @@ -103064,7 +105492,7 @@ func (m *AutoUpdateConfigUpdate) Unmarshal(dAtA []byte) error { } return nil } -func (m *AutoUpdateConfigDelete) Unmarshal(dAtA []byte) error { +func (m *StaticHostUserUpdate) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -103087,10 +105515,10 @@ func (m *AutoUpdateConfigDelete) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: AutoUpdateConfigDelete: wiretype end group for non-group") + return fmt.Errorf("proto: StaticHostUserUpdate: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: AutoUpdateConfigDelete: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: StaticHostUserUpdate: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: @@ -103128,7 +105556,7 @@ func (m *AutoUpdateConfigDelete) Unmarshal(dAtA []byte) error { iNdEx = postIndex case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ResourceMetadata", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Status", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -103155,13 +105583,13 @@ func (m *AutoUpdateConfigDelete) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if err := m.ResourceMetadata.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if err := m.Status.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex case 3: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field UserMetadata", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field ResourceMetadata", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -103188,13 +105616,13 @@ func (m *AutoUpdateConfigDelete) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if err := m.UserMetadata.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if err := m.ResourceMetadata.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex case 4: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ConnectionMetadata", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field UserMetadata", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -103221,13 +105649,13 @@ func (m *AutoUpdateConfigDelete) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if err := m.ConnectionMetadata.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if err := m.UserMetadata.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex case 5: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Status", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field ConnectionMetadata", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -103254,7 +105682,7 @@ func (m *AutoUpdateConfigDelete) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if err := m.Status.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if err := m.ConnectionMetadata.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex @@ -103280,7 +105708,7 @@ func (m *AutoUpdateConfigDelete) Unmarshal(dAtA []byte) error { } return nil } -func (m *AutoUpdateVersionCreate) Unmarshal(dAtA []byte) error { +func (m *StaticHostUserDelete) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -103303,10 +105731,10 @@ func (m *AutoUpdateVersionCreate) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: AutoUpdateVersionCreate: wiretype end group for non-group") + return fmt.Errorf("proto: StaticHostUserDelete: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: AutoUpdateVersionCreate: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: StaticHostUserDelete: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: @@ -103344,7 +105772,7 @@ func (m *AutoUpdateVersionCreate) Unmarshal(dAtA []byte) error { iNdEx = postIndex case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ResourceMetadata", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Status", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -103371,13 +105799,13 @@ func (m *AutoUpdateVersionCreate) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if err := m.ResourceMetadata.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if err := m.Status.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex case 3: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field UserMetadata", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field ResourceMetadata", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -103404,13 +105832,13 @@ func (m *AutoUpdateVersionCreate) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if err := m.UserMetadata.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if err := m.ResourceMetadata.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex case 4: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ConnectionMetadata", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field UserMetadata", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -103437,13 +105865,13 @@ func (m *AutoUpdateVersionCreate) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if err := m.ConnectionMetadata.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if err := m.UserMetadata.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex case 5: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Status", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field ConnectionMetadata", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -103470,7 +105898,7 @@ func (m *AutoUpdateVersionCreate) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if err := m.Status.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if err := m.ConnectionMetadata.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex @@ -103496,7 +105924,7 @@ func (m *AutoUpdateVersionCreate) Unmarshal(dAtA []byte) error { } return nil } -func (m *AutoUpdateVersionUpdate) Unmarshal(dAtA []byte) error { +func (m *CrownJewelCreate) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -103519,10 +105947,10 @@ func (m *AutoUpdateVersionUpdate) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: AutoUpdateVersionUpdate: wiretype end group for non-group") + return fmt.Errorf("proto: CrownJewelCreate: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: AutoUpdateVersionUpdate: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: CrownJewelCreate: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: @@ -103690,6 +106118,38 @@ func (m *AutoUpdateVersionUpdate) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex + case 6: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field CrownJewelQuery", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvents + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthEvents + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthEvents + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.CrownJewelQuery = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipEvents(dAtA[iNdEx:]) @@ -103712,7 +106172,7 @@ func (m *AutoUpdateVersionUpdate) Unmarshal(dAtA []byte) error { } return nil } -func (m *AutoUpdateVersionDelete) Unmarshal(dAtA []byte) error { +func (m *CrownJewelUpdate) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -103735,10 +106195,10 @@ func (m *AutoUpdateVersionDelete) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: AutoUpdateVersionDelete: wiretype end group for non-group") + return fmt.Errorf("proto: CrownJewelUpdate: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: AutoUpdateVersionDelete: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: CrownJewelUpdate: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: @@ -103776,7 +106236,7 @@ func (m *AutoUpdateVersionDelete) Unmarshal(dAtA []byte) error { iNdEx = postIndex case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ResourceMetadata", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Status", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -103803,7 +106263,7 @@ func (m *AutoUpdateVersionDelete) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if err := m.ResourceMetadata.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if err := m.Status.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex @@ -103875,7 +106335,7 @@ func (m *AutoUpdateVersionDelete) Unmarshal(dAtA []byte) error { iNdEx = postIndex case 5: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Status", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field ResourceMetadata", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -103902,10 +106362,74 @@ func (m *AutoUpdateVersionDelete) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if err := m.Status.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if err := m.ResourceMetadata.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex + case 6: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field CurrentCrownJewelQuery", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvents + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthEvents + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthEvents + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.CurrentCrownJewelQuery = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 7: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field UpdatedCrownJewelQuery", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvents + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthEvents + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthEvents + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.UpdatedCrownJewelQuery = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipEvents(dAtA[iNdEx:]) @@ -103928,7 +106452,7 @@ func (m *AutoUpdateVersionDelete) Unmarshal(dAtA []byte) error { } return nil } -func (m *StaticHostUserCreate) Unmarshal(dAtA []byte) error { +func (m *CrownJewelDelete) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -103951,10 +106475,10 @@ func (m *StaticHostUserCreate) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: StaticHostUserCreate: wiretype end group for non-group") + return fmt.Errorf("proto: CrownJewelDelete: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: StaticHostUserCreate: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: CrownJewelDelete: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: @@ -104024,39 +106548,6 @@ func (m *StaticHostUserCreate) Unmarshal(dAtA []byte) error { } iNdEx = postIndex case 3: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ResourceMetadata", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowEvents - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthEvents - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthEvents - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if err := m.ResourceMetadata.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 4: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field UserMetadata", wireType) } @@ -104089,7 +106580,7 @@ func (m *StaticHostUserCreate) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex - case 5: + case 4: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field ConnectionMetadata", wireType) } @@ -104122,6 +106613,39 @@ func (m *StaticHostUserCreate) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ResourceMetadata", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvents + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthEvents + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthEvents + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.ResourceMetadata.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipEvents(dAtA[iNdEx:]) @@ -104144,7 +106668,7 @@ func (m *StaticHostUserCreate) Unmarshal(dAtA []byte) error { } return nil } -func (m *StaticHostUserUpdate) Unmarshal(dAtA []byte) error { +func (m *UserTaskCreate) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -104167,10 +106691,10 @@ func (m *StaticHostUserUpdate) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: StaticHostUserUpdate: wiretype end group for non-group") + return fmt.Errorf("proto: UserTaskCreate: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: StaticHostUserUpdate: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: UserTaskCreate: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: @@ -104338,6 +106862,39 @@ func (m *StaticHostUserUpdate) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex + case 6: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field UserTaskMetadata", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvents + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthEvents + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthEvents + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.UserTaskMetadata.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipEvents(dAtA[iNdEx:]) @@ -104360,7 +106917,7 @@ func (m *StaticHostUserUpdate) Unmarshal(dAtA []byte) error { } return nil } -func (m *StaticHostUserDelete) Unmarshal(dAtA []byte) error { +func (m *UserTaskUpdate) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -104383,10 +106940,10 @@ func (m *StaticHostUserDelete) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: StaticHostUserDelete: wiretype end group for non-group") + return fmt.Errorf("proto: UserTaskUpdate: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: StaticHostUserDelete: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: UserTaskUpdate: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: @@ -104554,60 +107111,9 @@ func (m *StaticHostUserDelete) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipEvents(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthEvents - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *CrownJewelCreate) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowEvents - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: CrownJewelCreate: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: CrownJewelCreate: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: + case 6: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Metadata", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field UserTaskMetadata", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -104634,15 +107140,15 @@ func (m *CrownJewelCreate) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if err := m.Metadata.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if err := m.UserTaskMetadata.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex - case 2: + case 7: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Status", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field CurrentUserTaskState", wireType) } - var msglen int + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowEvents @@ -104652,30 +107158,29 @@ func (m *CrownJewelCreate) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - msglen |= int(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } - if msglen < 0 { + intStringLen := int(stringLen) + if intStringLen < 0 { return ErrInvalidLengthEvents } - postIndex := iNdEx + msglen + postIndex := iNdEx + intStringLen if postIndex < 0 { return ErrInvalidLengthEvents } if postIndex > l { return io.ErrUnexpectedEOF } - if err := m.Status.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } + m.CurrentUserTaskState = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex - case 3: + case 8: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field UserMetadata", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field UpdatedUserTaskState", wireType) } - var msglen int + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowEvents @@ -104685,30 +107190,80 @@ func (m *CrownJewelCreate) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - msglen |= int(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } - if msglen < 0 { + intStringLen := int(stringLen) + if intStringLen < 0 { return ErrInvalidLengthEvents } - postIndex := iNdEx + msglen + postIndex := iNdEx + intStringLen if postIndex < 0 { return ErrInvalidLengthEvents } if postIndex > l { return io.ErrUnexpectedEOF } - if err := m.UserMetadata.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + m.UpdatedUserTaskState = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipEvents(dAtA[iNdEx:]) + if err != nil { return err } - iNdEx = postIndex - case 4: + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthEvents + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *UserTaskMetadata) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvents + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: UserTaskMetadata: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: UserTaskMetadata: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ConnectionMetadata", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field TaskType", wireType) } - var msglen int + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowEvents @@ -104718,30 +107273,29 @@ func (m *CrownJewelCreate) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - msglen |= int(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } - if msglen < 0 { + intStringLen := int(stringLen) + if intStringLen < 0 { return ErrInvalidLengthEvents } - postIndex := iNdEx + msglen + postIndex := iNdEx + intStringLen if postIndex < 0 { return ErrInvalidLengthEvents } if postIndex > l { return io.ErrUnexpectedEOF } - if err := m.ConnectionMetadata.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } + m.TaskType = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex - case 5: + case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ResourceMetadata", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field IssueType", wireType) } - var msglen int + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowEvents @@ -104751,28 +107305,27 @@ func (m *CrownJewelCreate) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - msglen |= int(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } - if msglen < 0 { + intStringLen := int(stringLen) + if intStringLen < 0 { return ErrInvalidLengthEvents } - postIndex := iNdEx + msglen + postIndex := iNdEx + intStringLen if postIndex < 0 { return ErrInvalidLengthEvents } if postIndex > l { return io.ErrUnexpectedEOF } - if err := m.ResourceMetadata.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } + m.IssueType = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex - case 6: + case 3: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field CrownJewelQuery", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Integration", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -104800,7 +107353,7 @@ func (m *CrownJewelCreate) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.CrownJewelQuery = string(dAtA[iNdEx:postIndex]) + m.Integration = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex default: iNdEx = preIndex @@ -104824,7 +107377,7 @@ func (m *CrownJewelCreate) Unmarshal(dAtA []byte) error { } return nil } -func (m *CrownJewelUpdate) Unmarshal(dAtA []byte) error { +func (m *UserTaskDelete) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -104847,10 +107400,10 @@ func (m *CrownJewelUpdate) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: CrownJewelUpdate: wiretype end group for non-group") + return fmt.Errorf("proto: UserTaskDelete: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: CrownJewelUpdate: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: UserTaskDelete: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: @@ -104921,7 +107474,7 @@ func (m *CrownJewelUpdate) Unmarshal(dAtA []byte) error { iNdEx = postIndex case 3: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field UserMetadata", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field ResourceMetadata", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -104948,13 +107501,13 @@ func (m *CrownJewelUpdate) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if err := m.UserMetadata.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if err := m.ResourceMetadata.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex case 4: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ConnectionMetadata", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field UserMetadata", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -104981,13 +107534,13 @@ func (m *CrownJewelUpdate) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if err := m.ConnectionMetadata.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if err := m.UserMetadata.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex case 5: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ResourceMetadata", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field ConnectionMetadata", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -105014,74 +107567,10 @@ func (m *CrownJewelUpdate) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if err := m.ResourceMetadata.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if err := m.ConnectionMetadata.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex - case 6: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field CurrentCrownJewelQuery", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowEvents - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthEvents - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthEvents - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.CurrentCrownJewelQuery = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 7: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field UpdatedCrownJewelQuery", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowEvents - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthEvents - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthEvents - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.UpdatedCrownJewelQuery = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipEvents(dAtA[iNdEx:]) @@ -105104,7 +107593,7 @@ func (m *CrownJewelUpdate) Unmarshal(dAtA []byte) error { } return nil } -func (m *CrownJewelDelete) Unmarshal(dAtA []byte) error { +func (m *ContactCreate) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -105127,10 +107616,10 @@ func (m *CrownJewelDelete) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: CrownJewelDelete: wiretype end group for non-group") + return fmt.Errorf("proto: ContactCreate: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: CrownJewelDelete: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: ContactCreate: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: @@ -105168,7 +107657,7 @@ func (m *CrownJewelDelete) Unmarshal(dAtA []byte) error { iNdEx = postIndex case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Status", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field ResourceMetadata", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -105195,7 +107684,7 @@ func (m *CrownJewelDelete) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if err := m.Status.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if err := m.ResourceMetadata.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex @@ -105267,7 +107756,7 @@ func (m *CrownJewelDelete) Unmarshal(dAtA []byte) error { iNdEx = postIndex case 5: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ResourceMetadata", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Status", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -105294,10 +107783,61 @@ func (m *CrownJewelDelete) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if err := m.ResourceMetadata.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if err := m.Status.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex + case 6: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Email", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvents + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthEvents + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthEvents + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Email = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 7: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field ContactType", wireType) + } + m.ContactType = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvents + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.ContactType |= ContactType(b&0x7F) << shift + if b < 0x80 { + break + } + } default: iNdEx = preIndex skippy, err := skipEvents(dAtA[iNdEx:]) @@ -105320,7 +107860,7 @@ func (m *CrownJewelDelete) Unmarshal(dAtA []byte) error { } return nil } -func (m *UserTaskCreate) Unmarshal(dAtA []byte) error { +func (m *ContactDelete) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -105343,10 +107883,10 @@ func (m *UserTaskCreate) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: UserTaskCreate: wiretype end group for non-group") + return fmt.Errorf("proto: ContactDelete: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: UserTaskCreate: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: ContactDelete: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: @@ -105383,39 +107923,6 @@ func (m *UserTaskCreate) Unmarshal(dAtA []byte) error { } iNdEx = postIndex case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Status", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowEvents - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthEvents - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthEvents - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if err := m.Status.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 3: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field ResourceMetadata", wireType) } @@ -105448,7 +107955,7 @@ func (m *UserTaskCreate) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex - case 4: + case 3: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field UserMetadata", wireType) } @@ -105481,7 +107988,7 @@ func (m *UserTaskCreate) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex - case 5: + case 4: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field ConnectionMetadata", wireType) } @@ -105514,93 +108021,9 @@ func (m *UserTaskCreate) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex - case 6: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field UserTaskMetadata", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowEvents - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthEvents - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthEvents - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if err := m.UserTaskMetadata.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipEvents(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthEvents - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *UserTaskUpdate) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowEvents - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: UserTaskUpdate: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: UserTaskUpdate: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: + case 5: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Metadata", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Status", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -105627,15 +108050,15 @@ func (m *UserTaskUpdate) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if err := m.Metadata.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if err := m.Status.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex - case 2: + case 6: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Status", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Email", wireType) } - var msglen int + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowEvents @@ -105645,30 +108068,29 @@ func (m *UserTaskUpdate) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - msglen |= int(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } - if msglen < 0 { + intStringLen := int(stringLen) + if intStringLen < 0 { return ErrInvalidLengthEvents } - postIndex := iNdEx + msglen + postIndex := iNdEx + intStringLen if postIndex < 0 { return ErrInvalidLengthEvents } if postIndex > l { return io.ErrUnexpectedEOF } - if err := m.Status.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } + m.Email = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex - case 3: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ResourceMetadata", wireType) + case 7: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field ContactType", wireType) } - var msglen int + m.ContactType = 0 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowEvents @@ -105678,28 +108100,65 @@ func (m *UserTaskUpdate) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - msglen |= int(b&0x7F) << shift + m.ContactType |= ContactType(b&0x7F) << shift if b < 0x80 { break } } - if msglen < 0 { - return ErrInvalidLengthEvents + default: + iNdEx = preIndex + skippy, err := skipEvents(dAtA[iNdEx:]) + if err != nil { + return err } - postIndex := iNdEx + msglen - if postIndex < 0 { + if (skippy < 0) || (iNdEx+skippy) < 0 { return ErrInvalidLengthEvents } - if postIndex > l { + if (iNdEx + skippy) > l { return io.ErrUnexpectedEOF } - if err := m.ResourceMetadata.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *WorkloadIdentityCreate) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvents } - iNdEx = postIndex - case 4: + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: WorkloadIdentityCreate: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: WorkloadIdentityCreate: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field UserMetadata", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Metadata", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -105726,13 +108185,13 @@ func (m *UserTaskUpdate) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if err := m.UserMetadata.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if err := m.Metadata.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex - case 5: + case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ConnectionMetadata", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field ResourceMetadata", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -105759,13 +108218,13 @@ func (m *UserTaskUpdate) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if err := m.ConnectionMetadata.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if err := m.ResourceMetadata.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex - case 6: + case 3: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field UserTaskMetadata", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field UserMetadata", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -105792,15 +108251,15 @@ func (m *UserTaskUpdate) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if err := m.UserTaskMetadata.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if err := m.UserMetadata.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex - case 7: + case 4: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field CurrentUserTaskState", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field ConnectionMetadata", wireType) } - var stringLen uint64 + var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowEvents @@ -105810,29 +108269,30 @@ func (m *UserTaskUpdate) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + msglen |= int(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { + if msglen < 0 { return ErrInvalidLengthEvents } - postIndex := iNdEx + intStringLen + postIndex := iNdEx + msglen if postIndex < 0 { return ErrInvalidLengthEvents } if postIndex > l { return io.ErrUnexpectedEOF } - m.CurrentUserTaskState = string(dAtA[iNdEx:postIndex]) + if err := m.ConnectionMetadata.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } iNdEx = postIndex - case 8: + case 5: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field UpdatedUserTaskState", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field WorkloadIdentityData", wireType) } - var stringLen uint64 + var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowEvents @@ -105842,23 +108302,27 @@ func (m *UserTaskUpdate) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + msglen |= int(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { + if msglen < 0 { return ErrInvalidLengthEvents } - postIndex := iNdEx + intStringLen + postIndex := iNdEx + msglen if postIndex < 0 { return ErrInvalidLengthEvents } if postIndex > l { return io.ErrUnexpectedEOF } - m.UpdatedUserTaskState = string(dAtA[iNdEx:postIndex]) + if m.WorkloadIdentityData == nil { + m.WorkloadIdentityData = &Struct{} + } + if err := m.WorkloadIdentityData.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } iNdEx = postIndex default: iNdEx = preIndex @@ -105882,7 +108346,7 @@ func (m *UserTaskUpdate) Unmarshal(dAtA []byte) error { } return nil } -func (m *UserTaskMetadata) Unmarshal(dAtA []byte) error { +func (m *WorkloadIdentityUpdate) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -105905,17 +108369,17 @@ func (m *UserTaskMetadata) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: UserTaskMetadata: wiretype end group for non-group") + return fmt.Errorf("proto: WorkloadIdentityUpdate: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: UserTaskMetadata: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: WorkloadIdentityUpdate: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field TaskType", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Metadata", wireType) } - var stringLen uint64 + var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowEvents @@ -105925,29 +108389,30 @@ func (m *UserTaskMetadata) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + msglen |= int(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { + if msglen < 0 { return ErrInvalidLengthEvents } - postIndex := iNdEx + intStringLen + postIndex := iNdEx + msglen if postIndex < 0 { return ErrInvalidLengthEvents } if postIndex > l { return io.ErrUnexpectedEOF } - m.TaskType = string(dAtA[iNdEx:postIndex]) + if err := m.Metadata.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } iNdEx = postIndex case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field IssueType", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field ResourceMetadata", wireType) } - var stringLen uint64 + var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowEvents @@ -105957,29 +108422,30 @@ func (m *UserTaskMetadata) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + msglen |= int(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { + if msglen < 0 { return ErrInvalidLengthEvents } - postIndex := iNdEx + intStringLen + postIndex := iNdEx + msglen if postIndex < 0 { return ErrInvalidLengthEvents } if postIndex > l { return io.ErrUnexpectedEOF } - m.IssueType = string(dAtA[iNdEx:postIndex]) + if err := m.ResourceMetadata.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } iNdEx = postIndex case 3: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Integration", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field UserMetadata", wireType) } - var stringLen uint64 + var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowEvents @@ -105989,23 +108455,93 @@ func (m *UserTaskMetadata) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + msglen |= int(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { + if msglen < 0 { return ErrInvalidLengthEvents } - postIndex := iNdEx + intStringLen + postIndex := iNdEx + msglen if postIndex < 0 { return ErrInvalidLengthEvents } if postIndex > l { return io.ErrUnexpectedEOF } - m.Integration = string(dAtA[iNdEx:postIndex]) + if err := m.UserMetadata.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ConnectionMetadata", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvents + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthEvents + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthEvents + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.ConnectionMetadata.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field WorkloadIdentityData", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvents + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthEvents + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthEvents + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.WorkloadIdentityData == nil { + m.WorkloadIdentityData = &Struct{} + } + if err := m.WorkloadIdentityData.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } iNdEx = postIndex default: iNdEx = preIndex @@ -106029,7 +108565,7 @@ func (m *UserTaskMetadata) Unmarshal(dAtA []byte) error { } return nil } -func (m *UserTaskDelete) Unmarshal(dAtA []byte) error { +func (m *WorkloadIdentityDelete) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -106052,10 +108588,10 @@ func (m *UserTaskDelete) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: UserTaskDelete: wiretype end group for non-group") + return fmt.Errorf("proto: WorkloadIdentityDelete: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: UserTaskDelete: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: WorkloadIdentityDelete: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: @@ -106092,39 +108628,6 @@ func (m *UserTaskDelete) Unmarshal(dAtA []byte) error { } iNdEx = postIndex case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Status", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowEvents - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthEvents - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthEvents - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if err := m.Status.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 3: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field ResourceMetadata", wireType) } @@ -106157,7 +108660,7 @@ func (m *UserTaskDelete) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex - case 4: + case 3: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field UserMetadata", wireType) } @@ -106190,7 +108693,7 @@ func (m *UserTaskDelete) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex - case 5: + case 4: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field ConnectionMetadata", wireType) } diff --git a/api/types/events/oneof.go b/api/types/events/oneof.go index 6e856b3c5f2b2..18c15a094d94e 100644 --- a/api/types/events/oneof.go +++ b/api/types/events/oneof.go @@ -790,6 +790,26 @@ func ToOneOf(in AuditEvent) (*OneOf, error) { out.Event = &OneOf_AutoUpdateVersionDelete{ AutoUpdateVersionDelete: e, } + case *ContactCreate: + out.Event = &OneOf_ContactCreate{ + ContactCreate: e, + } + case *ContactDelete: + out.Event = &OneOf_ContactDelete{ + ContactDelete: e, + } + case *WorkloadIdentityCreate: + out.Event = &OneOf_WorkloadIdentityCreate{ + WorkloadIdentityCreate: e, + } + case *WorkloadIdentityUpdate: + out.Event = &OneOf_WorkloadIdentityUpdate{ + WorkloadIdentityUpdate: e, + } + case *WorkloadIdentityDelete: + out.Event = &OneOf_WorkloadIdentityDelete{ + WorkloadIdentityDelete: e, + } default: slog.ErrorContext(context.Background(), "Attempted to convert dynamic event of unknown type into protobuf event.", "event_type", in.GetType()) unknown := &Unknown{} diff --git a/api/types/kubernetes_test.go b/api/types/kubernetes_test.go index 5d3a81210bef7..1763da9e114f5 100644 --- a/api/types/kubernetes_test.go +++ b/api/types/kubernetes_test.go @@ -30,7 +30,7 @@ func TestKubeClustersSorter(t *testing.T) { servers := make([]KubeCluster, len(testVals)) for i := 0; i < len(testVals); i++ { var err error - servers[i], err = NewKubernetesClusterV3FromLegacyCluster("_", &KubernetesCluster{ + servers[i], err = NewKubernetesClusterV3FromLegacyCluster("", &KubernetesCluster{ Name: testVals[i], }) require.NoError(t, err) diff --git a/api/types/maintenance.go b/api/types/maintenance.go index 9cab6a9ad4765..65d2f7271c6fc 100644 --- a/api/types/maintenance.go +++ b/api/types/maintenance.go @@ -45,10 +45,10 @@ var validWeekdays = [7]time.Weekday{ time.Saturday, } -// parseWeekday attempts to interpret a string as a time.Weekday. In the interest of flexibility, +// ParseWeekday attempts to interpret a string as a time.Weekday. In the interest of flexibility, // parsing is case-insensitive and supports the common three-letter shorthand accepted by many // common scheduling utilites (e.g. contab, systemd timers). -func parseWeekday(s string) (day time.Weekday, ok bool) { +func ParseWeekday(s string) (day time.Weekday, ok bool) { for _, w := range validWeekdays { if strings.EqualFold(w.String(), s) || strings.EqualFold(w.String()[:3], s) { return w, true @@ -75,7 +75,7 @@ func (w *AgentUpgradeWindow) generator(from time.Time) func() (start time.Time, var weekdays []time.Weekday for _, d := range w.Weekdays { - if p, ok := parseWeekday(d); ok { + if p, ok := ParseWeekday(d); ok { weekdays = append(weekdays, p) } } @@ -203,7 +203,7 @@ func (m *ClusterMaintenanceConfigV1) CheckAndSetDefaults() error { } for _, day := range m.Spec.AgentUpgrades.Weekdays { - if _, ok := parseWeekday(day); !ok { + if _, ok := ParseWeekday(day); !ok { return trace.BadParameter("invalid weekday in agent upgrade window: %q", day) } } diff --git a/api/types/maintenance_test.go b/api/types/maintenance_test.go index 203006a8dee37..40296dbd60f9a 100644 --- a/api/types/maintenance_test.go +++ b/api/types/maintenance_test.go @@ -205,7 +205,7 @@ func TestWeekdayParser(t *testing.T) { } for _, tt := range tts { - day, ok := parseWeekday(tt.input) + day, ok := ParseWeekday(tt.input) if tt.fail { require.False(t, ok) continue diff --git a/api/types/namespace.go b/api/types/namespace.go index 41e4b3e4fe7c0..a6fbd02de22b3 100644 --- a/api/types/namespace.go +++ b/api/types/namespace.go @@ -143,3 +143,17 @@ func IsValidNamespace(s string) bool { } var validNamespace = regexp.MustCompile(`^[A-Za-z0-9]+$`) + +// ValidateNamespaceDefault ensures that the namespace is the "default" +// namespace. +// This is a precursor to a hard-removal of namespaces. +func ValidateNamespaceDefault(ns string) error { + if ns == defaults.Namespace { + return nil + } + + const message = "" + + "namespace %q invalid, custom namespaces are deprecated; " + + "the namespace field should be omitted or set to %q" + return trace.BadParameter(message, ns, defaults.Namespace) +} diff --git a/api/types/presence.go b/api/types/presence.go index 764f467199894..b27b3b232cce2 100644 --- a/api/types/presence.go +++ b/api/types/presence.go @@ -67,9 +67,13 @@ func (s *KeepAlive) CheckAndSetDefaults() error { if s.IsEmpty() { return trace.BadParameter("missing resource name") } + if s.Namespace == "" { s.Namespace = defaults.Namespace } + if err := ValidateNamespaceDefault(s.Namespace); err != nil { + return trace.Wrap(err) + } return nil } diff --git a/api/types/resource.go b/api/types/resource.go index ec87a72c97a8c..ad5beaceb786b 100644 --- a/api/types/resource.go +++ b/api/types/resource.go @@ -139,6 +139,20 @@ type EnrichedResource struct { RequiresRequest bool } +// EnrichedResources is a wrapper of []*EnrichedResource. +// A EnrichedResource is a [ResourceWithLabels] wrapped with additional +// user-specific information. +type EnrichedResources []*EnrichedResource + +// ToResourcesWithLabels converts to ResourcesWithLabels. +func (r EnrichedResources) ToResourcesWithLabels() ResourcesWithLabels { + ret := make(ResourcesWithLabels, 0, len(r)) + for _, resource := range r { + ret = append(ret, resource.ResourceWithLabels) + } + return ret +} + // ResourcesWithLabels is a list of labeled resources. type ResourcesWithLabels []ResourceWithLabels @@ -464,9 +478,13 @@ func (m *Metadata) CheckAndSetDefaults() error { if m.Name == "" { return trace.BadParameter("missing parameter Name") } + if m.Namespace == "" { m.Namespace = defaults.Namespace } + if err := ValidateNamespaceDefault(m.Namespace); err != nil { + return trace.Wrap(err) + } // adjust expires time to UTC if it's set if m.Expires != nil { @@ -509,7 +527,7 @@ func MatchKinds(resource ResourceWithLabels, kinds []string) bool { } resourceKind := resource.GetKind() switch resourceKind { - case KindApp, KindSAMLIdPServiceProvider: + case KindApp, KindSAMLIdPServiceProvider, KindIdentityCenterAccount: return slices.Contains(kinds, KindApp) default: return slices.Contains(kinds, resourceKind) @@ -686,8 +704,11 @@ func FriendlyName(resource ResourceWithLabels) string { return resource.GetMetadata().Description } - if hn, ok := resource.(interface{ GetHostname() string }); ok { - return hn.GetHostname() + switch rr := resource.(type) { + case interface{ GetHostname() string }: + return rr.GetHostname() + case interface{ GetDisplayName() string }: + return rr.GetDisplayName() } return "" diff --git a/api/types/resource_153.go b/api/types/resource_153.go index 969509d7e910e..a09c39451cd3d 100644 --- a/api/types/resource_153.go +++ b/api/types/resource_153.go @@ -21,6 +21,7 @@ import ( "google.golang.org/protobuf/types/known/timestamppb" headerv1 "github.com/gravitational/teleport/api/gen/proto/go/teleport/header/v1" + "github.com/gravitational/teleport/api/utils" ) // ResourceMetadata is the smallest interface that defines a Teleport resource. @@ -89,9 +90,9 @@ func (r *legacyToResource153Adapter) GetKind() string { return r.inner.GetKind() } -func (r *legacyToResource153Adapter) GetMetadata() *headerv1.Metadata { - md := r.inner.GetMetadata() - +// LegacyTo153Metadata converts a legacy [Metadata] object an RFD153-style +// [headerv1.Metadata] block +func LegacyTo153Metadata(md Metadata) *headerv1.Metadata { var expires *timestamppb.Timestamp if md.Expires != nil { expires = timestamppb.New(*md.Expires) @@ -107,6 +108,10 @@ func (r *legacyToResource153Adapter) GetMetadata() *headerv1.Metadata { } } +func (r *legacyToResource153Adapter) GetMetadata() *headerv1.Metadata { + return LegacyTo153Metadata(r.inner.GetMetadata()) +} + func (r *legacyToResource153Adapter) GetSubKind() string { return r.inner.GetSubKind() } @@ -116,7 +121,8 @@ func (r *legacyToResource153Adapter) GetVersion() string { } // Resource153ToLegacy transforms an RFD 153 style resource into a legacy -// [Resource] type. +// [Resource] type. Implements [ResourceWithLabels] and CloneResource (where the) +// wrapped resource supports cloning). // // Note that CheckAndSetDefaults is a noop for the returned resource and // SetSubKind is not implemented and panics on use. @@ -130,6 +136,8 @@ type Resource153Unwrapper interface { Unwrap() Resource153 } +// resource153ToLegacyAdapter wraps a new-style resource in a type implementing +// the legacy resource interfaces type resource153ToLegacyAdapter struct { inner Resource153 } @@ -162,9 +170,9 @@ func (r *resource153ToLegacyAdapter) GetKind() string { return r.inner.GetKind() } -func (r *resource153ToLegacyAdapter) GetMetadata() Metadata { - md := r.inner.GetMetadata() - +// Metadata153ToLegacy converts RFD153-style resource metadata to legacy +// metadata. +func Metadata153ToLegacy(md *headerv1.Metadata) Metadata { // use zero time.time{} for zero *timestamppb.Timestamp, instead of 01/01/1970. expires := md.Expires.AsTime() if md.Expires == nil { @@ -181,6 +189,10 @@ func (r *resource153ToLegacyAdapter) GetMetadata() Metadata { } } +func (r *resource153ToLegacyAdapter) GetMetadata() Metadata { + return Metadata153ToLegacy(r.inner.GetMetadata()) +} + func (r *resource153ToLegacyAdapter) GetName() string { return r.inner.GetMetadata().Name } @@ -212,3 +224,127 @@ func (r *resource153ToLegacyAdapter) SetRevision(rev string) { func (r *resource153ToLegacyAdapter) SetSubKind(subKind string) { panic("interface Resource153 does not implement SetSubKind") } + +// Resource153ToResourceWithLabels wraps a [Resource153]-style resource in +// the legacy [Resource] and [ResourceWithLabels] interfaces. +// +// The same caveats that apply to [Resource153ToLegacy] apply. +func Resource153ToResourceWithLabels(r Resource153) ResourceWithLabels { + return &resource153ToResourceWithLabelsAdapter{ + resource153ToLegacyAdapter{ + inner: r, + }, + } +} + +// resource153ToResourceWithLabelsAdapter wraps a new-style resource in a +// type implementing the legacy resource interfaces +type resource153ToResourceWithLabelsAdapter struct { + resource153ToLegacyAdapter +} + +// Origin implements ResourceWithLabels for the adapter. +func (r *resource153ToResourceWithLabelsAdapter) Origin() string { + m := r.inner.GetMetadata() + if m == nil { + return "" + } + return m.Labels[OriginLabel] +} + +// SetOrigin implements ResourceWithLabels for the adapter. +func (r *resource153ToResourceWithLabelsAdapter) SetOrigin(origin string) { + m := r.inner.GetMetadata() + if m == nil { + return + } + m.Labels[OriginLabel] = origin +} + +// GetLabel implements ResourceWithLabels for the adapter. +func (r *resource153ToResourceWithLabelsAdapter) GetLabel(key string) (value string, ok bool) { + m := r.inner.GetMetadata() + if m == nil { + return "", false + } + value, ok = m.Labels[key] + return +} + +// GetAllLabels implements ResourceWithLabels for the adapter. +func (r *resource153ToResourceWithLabelsAdapter) GetAllLabels() map[string]string { + m := r.inner.GetMetadata() + if m == nil { + return nil + } + return m.Labels +} + +// GetStaticLabels implements ResourceWithLabels for the adapter. +func (r *resource153ToResourceWithLabelsAdapter) GetStaticLabels() map[string]string { + return r.GetAllLabels() +} + +// SetStaticLabels implements ResourceWithLabels for the adapter. +func (r *resource153ToResourceWithLabelsAdapter) SetStaticLabels(labels map[string]string) { + m := r.inner.GetMetadata() + if m == nil { + return + } + m.Labels = labels +} + +// MatchSearch implements ResourceWithLabels for the adapter. If the underlying +// type exposes a MatchSearch method, this method will defer to that, otherwise +// it will match against the resource label values and name. +func (r *resource153ToResourceWithLabelsAdapter) MatchSearch(searchValues []string) bool { + if matcher, ok := r.inner.(interface{ MatchSearch([]string) bool }); ok { + return matcher.MatchSearch(searchValues) + } + fieldVals := append(utils.MapToStrings(r.GetAllLabels()), r.GetName()) + return MatchSearch(fieldVals, searchValues, nil) +} + +// ClonableResource153 adds a restriction on [Resource153] such that implementors +// must have a CloneResource() method. +type ClonableResource153 interface { + Resource153 + CloneResource() ClonableResource153 +} + +// UnifiedResource represents the combined set of interfaces that a resource +// must implement to be used with the Teleport Unified Resource Cache +type UnifiedResource interface { + ResourceWithLabels + CloneResource() ResourceWithLabels +} + +// Resource153ToUnifiedResource wraps an RFD153-style resource in a type that +// implements the legacy [ResourceWithLabels] interface and is suitable for use +// with the Teleport Unified Resources Cache. +// +// The same caveats that apply to [Resource153ToLegacy] apply. +func Resource153ToUnifiedResource(r ClonableResource153) UnifiedResource { + return &resource153ToUnifiedResourceAdapter{ + resource153ToResourceWithLabelsAdapter: resource153ToResourceWithLabelsAdapter{ + resource153ToLegacyAdapter{ + inner: r, + }, + }, + } +} + +// resource153ToUnifiedResourceAdapter wraps a [resource153ToLegacyAdapter] to +// provide an implementation of [UnifiedResource] +type resource153ToUnifiedResourceAdapter struct { + resource153ToResourceWithLabelsAdapter +} + +// CloneResource clones the underlying resource and wraps it in +func (r *resource153ToUnifiedResourceAdapter) CloneResource() ResourceWithLabels { + // We assume that this type assertion will work because we force `inner` + // to implement ClonableResource153 in [Resource153ToUnifiedResource], which + // is the only externally-visible constructor function. + clone := r.inner.(ClonableResource153).CloneResource() + return Resource153ToUnifiedResource(clone) +} diff --git a/api/types/resource_153_test.go b/api/types/resource_153_test.go index 301ab9fa81c10..f6cbb14c9a64b 100644 --- a/api/types/resource_153_test.go +++ b/api/types/resource_153_test.go @@ -80,10 +80,10 @@ func TestResource153ToLegacy(t *testing.T) { } legacyResource := types.Resource153ToLegacy(bot) - // Unwrap gives the underlying resource back. t.Run("unwrap", func(t *testing.T) { - unwrapped := legacyResource.(interface{ Unwrap() types.Resource153 }).Unwrap() + unwrapper := legacyResource.(types.Resource153Unwrapper) + unwrapped := unwrapper.Unwrap() if diff := cmp.Diff(bot, unwrapped, protocmp.Transform()); diff != "" { t.Errorf("Unwrap mismatch (-want +got)\n%s", diff) } diff --git a/api/types/resource_test.go b/api/types/resource_test.go index 896ee3b78ecff..53b38ef33e145 100644 --- a/api/types/resource_test.go +++ b/api/types/resource_test.go @@ -266,7 +266,7 @@ func TestMatchSearch_ResourceSpecific(t *testing.T) { name: "kube cluster", matchingSearchVals: []string{"foo", "prod", "env"}, newResource: func(t *testing.T) ResourceWithLabels { - kc, err := NewKubernetesClusterV3FromLegacyCluster("_", &KubernetesCluster{ + kc, err := NewKubernetesClusterV3FromLegacyCluster("", &KubernetesCluster{ Name: "foo", StaticLabels: labels, }) diff --git a/api/types/role.go b/api/types/role.go index 6983047e51d47..6551921bc9aeb 100644 --- a/api/types/role.go +++ b/api/types/role.go @@ -284,6 +284,10 @@ type Role interface { GetGitHubPermissions(RoleConditionType) []GitHubPermission // SetGitHubPermissions sets the allow or deny GitHub-related permissions. SetGitHubPermissions(RoleConditionType, []GitHubPermission) + + // GetIdentityCenterAccountAssignments fetches the allow or deny Account + // Assignments for the role + GetIdentityCenterAccountAssignments(RoleConditionType) []IdentityCenterAccountAssignment } // NewRole constructs new standard V7 role. @@ -1067,8 +1071,9 @@ func (r *RoleV6) CheckAndSetDefaults() error { if len(r.Spec.Options.BPF) == 0 { r.Spec.Options.BPF = defaults.EnhancedEvents() } - if r.Spec.Allow.Namespaces == nil { - r.Spec.Allow.Namespaces = []string{defaults.Namespace} + if err := checkAndSetRoleConditionNamespaces(&r.Spec.Allow.Namespaces); err != nil { + // Using trace.BadParameter instead of trace.Wrap for a better error message. + return trace.BadParameter("allow: %s", err) } if r.Spec.Options.RecordSession == nil { r.Spec.Options.RecordSession = &RecordSession{ @@ -1171,8 +1176,9 @@ func (r *RoleV6) CheckAndSetDefaults() error { return trace.BadParameter("unrecognized role version: %v", r.Version) } - if r.Spec.Deny.Namespaces == nil { - r.Spec.Deny.Namespaces = []string{defaults.Namespace} + if err := checkAndSetRoleConditionNamespaces(&r.Spec.Deny.Namespaces); err != nil { + // Using trace.BadParameter instead of trace.Wrap for a better error message. + return trace.BadParameter("deny: %s", err) } // Validate request.kubernetes_resources fields are all valid. @@ -1318,6 +1324,27 @@ func (r *RoleV6) CheckAndSetDefaults() error { return nil } +func checkAndSetRoleConditionNamespaces(namespaces *[]string) error { + // If nil use the default. + // This distinguishes between nil and empty (in accordance to legacy code). + if *namespaces == nil { + *namespaces = []string{defaults.Namespace} + return nil + } + + for i, ns := range *namespaces { + if ns == Wildcard { + continue // OK, wildcard is accepted. + } + if err := ValidateNamespaceDefault(ns); err != nil { + // Using trace.BadParameter instead of trace.Wrap for a better error message. + return trace.BadParameter("namespaces[%d]: %s", i, err) + } + } + + return nil +} + // String returns the human readable representation of a role. func (r *RoleV6) String() string { options, _ := json.Marshal(r.Spec.Options) @@ -2061,6 +2088,15 @@ func (r *RoleV6) makeGitServerLabelMatchers(cond *RoleConditions) LabelMatchers } } +// GetIdentityCenterAccountAssignments fetches the allow or deny Identity Center +// Account Assignments for the role +func (r *RoleV6) GetIdentityCenterAccountAssignments(rct RoleConditionType) []IdentityCenterAccountAssignment { + if rct == Allow { + return r.Spec.Allow.AccountAssignments + } + return r.Spec.Deny.AccountAssignments +} + // LabelMatcherKinds is the complete list of resource kinds that support label // matchers. var LabelMatcherKinds = []string{ @@ -2286,3 +2322,8 @@ func (h *CreateDatabaseUserMode) UnmarshalJSON(data []byte) error { func (m CreateDatabaseUserMode) IsEnabled() bool { return m != CreateDatabaseUserMode_DB_USER_MODE_UNSPECIFIED && m != CreateDatabaseUserMode_DB_USER_MODE_OFF } + +// GetAccount fetches the Account ID from a Role Condition Account Assignment +func (a IdentityCenterAccountAssignment) GetAccount() string { + return a.Account +} diff --git a/api/types/server.go b/api/types/server.go index 6adc0516ad4f4..98b61911c8415 100644 --- a/api/types/server.go +++ b/api/types/server.go @@ -855,3 +855,12 @@ func GetGitHubOrgFromNodeAddr(addr string) (string, bool) { } return "", false } + +// GetOrganizationURL returns the URL to the GitHub organization. +func (m *GitHubServerMetadata) GetOrganizationURL() string { + if m == nil { + return "" + } + // Public github.com for now. + return fmt.Sprintf("%s/%s", GithubURL, m.Organization) +} diff --git a/api/types/types.pb.go b/api/types/types.pb.go index 685926464e0f8..6a74944d3b486 100644 --- a/api/types/types.pb.go +++ b/api/types/types.pb.go @@ -3531,7 +3531,10 @@ type IdentityCenterPermissionSet struct { // ARN is the fully-formed ARN of the Permission Set. ARN string `protobuf:"bytes,1,opt,name=ARN,proto3" json:"arn,omitempty"` // Name is the human-readable name of the Permission Set. - Name string `protobuf:"bytes,2,opt,name=Name,proto3" json:"name,omitempty"` + Name string `protobuf:"bytes,2,opt,name=Name,proto3" json:"name,omitempty"` + // AssignmentID is the ID of the Teelport Account Assignment resource that + // represents this permission being assigned on the enclosing Account. + AssignmentID string `protobuf:"bytes,3,opt,name=AssignmentID,proto3" json:"assignment_name,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` @@ -21884,1898 +21887,1899 @@ func init() { func init() { proto.RegisterFile("teleport/legacy/types/types.proto", fileDescriptor_9198ee693835762e) } var fileDescriptor_9198ee693835762e = []byte{ - // 30252 bytes of a gzipped FileDescriptorProto + // 30270 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xec, 0xbd, 0x6b, 0x70, 0x1c, 0x49, 0x7a, 0x20, 0x36, 0xdd, 0x8d, 0x47, 0xe3, 0xc3, 0xab, 0x91, 0x00, 0x49, 0x10, 0x33, 0x64, 0x73, 0x6a, 0x66, 0x38, 0xe4, 0x3c, 0xc8, 0x25, 0xb8, 0xc3, 0xdd, 0xd9, 0x79, 0x6d, 0xa3, 0x1b, 0x24, 0x9a, 0x04, 0x40, 0x6c, 0x35, 0x40, 0xec, 0x68, 0x1f, 0xb5, 0x85, 0xee, 0x04, 0x50, 0x83, 0xee, - 0xae, 0xde, 0xaa, 0x6a, 0x92, 0xd0, 0xde, 0x59, 0xef, 0x93, 0x15, 0xb2, 0x5e, 0x77, 0xd2, 0x69, - 0xcf, 0xa1, 0x93, 0x15, 0xf2, 0x9d, 0xad, 0x38, 0xc7, 0x29, 0x6c, 0xc9, 0xb2, 0xcf, 0x56, 0x58, - 0x96, 0x2e, 0xce, 0xb2, 0xac, 0x70, 0x9c, 0x14, 0xf6, 0xd9, 0x0e, 0xaf, 0x2f, 0x20, 0xcb, 0xf2, - 0x0f, 0x07, 0x22, 0x1c, 0x21, 0xf9, 0x22, 0x1c, 0xe1, 0xbd, 0xd0, 0x9d, 0x23, 0xbf, 0xcc, 0xac, - 0xca, 0xac, 0xaa, 0x6e, 0x34, 0x86, 0x1c, 0x9d, 0x38, 0xa1, 0x3f, 0x24, 0xfa, 0xcb, 0xef, 0xfb, - 0xb2, 0xf2, 0xfd, 0xe5, 0x97, 0xdf, 0x03, 0x5e, 0x0c, 0x68, 0x93, 0x76, 0x5c, 0x2f, 0xb8, 0xde, - 0xa4, 0x7b, 0x76, 0xfd, 0xf0, 0x7a, 0x70, 0xd8, 0xa1, 0x3e, 0xff, 0xf7, 0x5a, 0xc7, 0x73, 0x03, - 0x97, 0x0c, 0xe3, 0x8f, 0x85, 0xb9, 0x3d, 0x77, 0xcf, 0x45, 0xc8, 0x75, 0xf6, 0x17, 0x2f, 0x5c, - 0xb8, 0xb8, 0xe7, 0xba, 0x7b, 0x4d, 0x7a, 0x1d, 0x7f, 0xed, 0x74, 0x77, 0xaf, 0x37, 0xba, 0x9e, - 0x1d, 0x38, 0x6e, 0x5b, 0x94, 0x17, 0xe3, 0xe5, 0x81, 0xd3, 0xa2, 0x7e, 0x60, 0xb7, 0x3a, 0xbd, - 0x18, 0x3c, 0xf2, 0xec, 0x4e, 0x87, 0x7a, 0xa2, 0xf6, 0x85, 0xab, 0xe1, 0x07, 0xda, 0x41, 0xc0, - 0x28, 0x19, 0xf3, 0xeb, 0x0f, 0x6f, 0xa8, 0x3f, 0x05, 0xea, 0xad, 0x1e, 0x6d, 0xf1, 0xba, 0x7e, - 0x40, 0x1b, 0x56, 0x83, 0x3e, 0x74, 0xea, 0xd4, 0xf2, 0xe8, 0x37, 0xbb, 0x8e, 0x47, 0x5b, 0xb4, - 0x1d, 0x08, 0xba, 0x37, 0xd3, 0xe9, 0xe4, 0x87, 0xc4, 0xbe, 0xc8, 0xf8, 0xc5, 0x1c, 0x8c, 0xdd, - 0xa3, 0xb4, 0x53, 0x6a, 0x3a, 0x0f, 0x29, 0x79, 0x09, 0x86, 0xd6, 0xed, 0x16, 0x9d, 0xcf, 0x5c, - 0xca, 0x5c, 0x19, 0x5b, 0x9a, 0x3e, 0x3e, 0x2a, 0x8e, 0xfb, 0xd4, 0x7b, 0x48, 0x3d, 0xab, 0x6d, - 0xb7, 0xa8, 0x89, 0x85, 0xe4, 0x75, 0x18, 0x63, 0xff, 0xfb, 0x1d, 0xbb, 0x4e, 0xe7, 0xb3, 0x88, - 0x39, 0x79, 0x7c, 0x54, 0x1c, 0x6b, 0x4b, 0xa0, 0x19, 0x95, 0x93, 0x2a, 0x8c, 0x2e, 0x3f, 0xee, - 0x38, 0x1e, 0xf5, 0xe7, 0x87, 0x2e, 0x65, 0xae, 0x8c, 0x2f, 0x2e, 0x5c, 0xe3, 0x7d, 0x74, 0x4d, - 0xf6, 0xd1, 0xb5, 0x4d, 0xd9, 0x89, 0x4b, 0xb3, 0xbf, 0x77, 0x54, 0x7c, 0xee, 0xf8, 0xa8, 0x38, - 0x4a, 0x39, 0xc9, 0x4f, 0xff, 0x51, 0x31, 0x63, 0x4a, 0x7a, 0xf2, 0x2e, 0x0c, 0x6d, 0x1e, 0x76, - 0xe8, 0xfc, 0xd8, 0xa5, 0xcc, 0x95, 0xa9, 0xc5, 0x8b, 0xd7, 0xf8, 0xb0, 0x86, 0x1f, 0x1f, 0xfd, - 0xc5, 0xb0, 0x96, 0xf2, 0xc7, 0x47, 0xc5, 0x21, 0x86, 0x62, 0x22, 0x15, 0x79, 0x13, 0x46, 0x56, - 0x5c, 0x3f, 0xa8, 0x56, 0xe6, 0x01, 0x3f, 0xf9, 0xcc, 0xf1, 0x51, 0x71, 0x66, 0xdf, 0xf5, 0x03, - 0xcb, 0x69, 0xbc, 0xe1, 0xb6, 0x9c, 0x80, 0xb6, 0x3a, 0xc1, 0xa1, 0x29, 0x90, 0x8c, 0xc7, 0x30, - 0xa9, 0xf1, 0x23, 0xe3, 0x30, 0xba, 0xb5, 0x7e, 0x6f, 0xfd, 0xfe, 0xf6, 0x7a, 0xe1, 0x39, 0x92, - 0x87, 0xa1, 0xf5, 0xfb, 0x95, 0xe5, 0x42, 0x86, 0x8c, 0x42, 0xae, 0xb4, 0xb1, 0x51, 0xc8, 0x92, - 0x09, 0xc8, 0x57, 0x4a, 0x9b, 0xa5, 0xa5, 0x52, 0x6d, 0xb9, 0x90, 0x23, 0xb3, 0x30, 0xbd, 0x5d, - 0x5d, 0xaf, 0xdc, 0xdf, 0xae, 0x59, 0x95, 0xe5, 0xda, 0xbd, 0xcd, 0xfb, 0x1b, 0x85, 0x21, 0x32, - 0x05, 0x70, 0x6f, 0x6b, 0x69, 0xd9, 0x5c, 0x5f, 0xde, 0x5c, 0xae, 0x15, 0x86, 0xc9, 0x1c, 0x14, - 0x24, 0x89, 0x55, 0x5b, 0x36, 0x1f, 0x54, 0xcb, 0xcb, 0x85, 0x91, 0xbb, 0x43, 0xf9, 0x5c, 0x61, - 0xc8, 0x1c, 0x5d, 0xa5, 0xb6, 0x4f, 0xab, 0x15, 0xe3, 0xdf, 0xcf, 0x41, 0x7e, 0x8d, 0x06, 0x76, - 0xc3, 0x0e, 0x6c, 0xf2, 0x82, 0x36, 0x3e, 0xd8, 0x44, 0x65, 0x60, 0x5e, 0x4a, 0x0e, 0xcc, 0xf0, - 0xf1, 0x51, 0x31, 0xf3, 0xa6, 0x3a, 0x20, 0xef, 0xc0, 0x78, 0x85, 0xfa, 0x75, 0xcf, 0xe9, 0xb0, - 0xc9, 0x36, 0x9f, 0x43, 0xb4, 0xf3, 0xc7, 0x47, 0xc5, 0x33, 0x8d, 0x08, 0xac, 0x74, 0x88, 0x8a, - 0x4d, 0xaa, 0x30, 0xb2, 0x6a, 0xef, 0xd0, 0xa6, 0x3f, 0x3f, 0x7c, 0x29, 0x77, 0x65, 0x7c, 0xf1, - 0x79, 0x31, 0x08, 0xf2, 0x03, 0xaf, 0xf1, 0xd2, 0xe5, 0x76, 0xe0, 0x1d, 0x2e, 0xcd, 0x1d, 0x1f, - 0x15, 0x0b, 0x4d, 0x04, 0xa8, 0x1d, 0xcc, 0x51, 0x48, 0x2d, 0x9a, 0x18, 0x23, 0x27, 0x4e, 0x8c, - 0x0b, 0xbf, 0x77, 0x54, 0xcc, 0xb0, 0x01, 0x13, 0x13, 0x23, 0xe2, 0xa7, 0x4f, 0x91, 0x45, 0xc8, - 0x9b, 0xf4, 0xa1, 0xe3, 0xb3, 0x96, 0xe5, 0xb1, 0x65, 0x67, 0x8f, 0x8f, 0x8a, 0xc4, 0x13, 0x30, - 0xe5, 0x33, 0x42, 0xbc, 0x85, 0xb7, 0x61, 0x5c, 0xf9, 0x6a, 0x52, 0x80, 0xdc, 0x01, 0x3d, 0xe4, - 0x3d, 0x6c, 0xb2, 0x3f, 0xc9, 0x1c, 0x0c, 0x3f, 0xb4, 0x9b, 0x5d, 0xd1, 0xa5, 0x26, 0xff, 0xf1, - 0x85, 0xec, 0xe7, 0x33, 0x77, 0x87, 0xf2, 0xa3, 0x85, 0xbc, 0x99, 0xad, 0x56, 0x8c, 0xbf, 0x39, - 0x04, 0x79, 0xd3, 0xe5, 0x0b, 0x98, 0x5c, 0x85, 0xe1, 0x5a, 0x60, 0x07, 0x72, 0x98, 0x66, 0x8f, - 0x8f, 0x8a, 0xd3, 0x6c, 0x71, 0x53, 0xa5, 0x7e, 0x8e, 0xc1, 0x50, 0x37, 0xf6, 0x6d, 0x5f, 0x0e, - 0x17, 0xa2, 0x76, 0x18, 0x40, 0x45, 0x45, 0x0c, 0x72, 0x19, 0x86, 0xd6, 0xdc, 0x06, 0x15, 0x23, - 0x46, 0x8e, 0x8f, 0x8a, 0x53, 0x2d, 0xb7, 0xa1, 0x22, 0x62, 0x39, 0x79, 0x03, 0xc6, 0xca, 0x5d, - 0xcf, 0xa3, 0x6d, 0x36, 0xd7, 0x87, 0x10, 0x79, 0xea, 0xf8, 0xa8, 0x08, 0x75, 0x0e, 0xb4, 0x9c, - 0x86, 0x19, 0x21, 0xb0, 0x61, 0xa8, 0x05, 0xb6, 0x17, 0xd0, 0xc6, 0xfc, 0xf0, 0x40, 0xc3, 0xc0, - 0xd6, 0xe7, 0x8c, 0xcf, 0x49, 0xe2, 0xc3, 0x20, 0x38, 0x91, 0x15, 0x18, 0xbf, 0xe3, 0xd9, 0x75, - 0xba, 0x41, 0x3d, 0xc7, 0x6d, 0xe0, 0xf8, 0xe6, 0x96, 0x2e, 0x1f, 0x1f, 0x15, 0xcf, 0xee, 0x31, - 0xb0, 0xd5, 0x41, 0x78, 0x44, 0xfd, 0xdd, 0xa3, 0x62, 0xbe, 0x22, 0xb6, 0x5a, 0x53, 0x25, 0x25, - 0xdf, 0x60, 0x83, 0xe3, 0x07, 0xd8, 0xb5, 0xb4, 0x31, 0x3f, 0x7a, 0xe2, 0x27, 0x1a, 0xe2, 0x13, - 0xcf, 0x36, 0x6d, 0x3f, 0xb0, 0x3c, 0x4e, 0x17, 0xfb, 0x4e, 0x95, 0x25, 0xb9, 0x0f, 0xf9, 0x5a, - 0x7d, 0x9f, 0x36, 0xba, 0x4d, 0x8a, 0x53, 0x66, 0x7c, 0xf1, 0x9c, 0x98, 0xd4, 0x72, 0x3c, 0x65, - 0xf1, 0xd2, 0x82, 0xe0, 0x4d, 0x7c, 0x01, 0x51, 0xe7, 0x93, 0xc4, 0xfa, 0x42, 0xfe, 0xdb, 0xbf, - 0x54, 0x7c, 0xee, 0xfb, 0xff, 0xf9, 0xa5, 0xe7, 0x8c, 0xff, 0x3c, 0x0b, 0x85, 0x38, 0x13, 0xb2, - 0x0b, 0x93, 0x5b, 0x9d, 0x86, 0x1d, 0xd0, 0x72, 0xd3, 0xa1, 0xed, 0xc0, 0xc7, 0x49, 0xd2, 0xbf, - 0x4d, 0x2f, 0x8b, 0x7a, 0xe7, 0xbb, 0x48, 0x68, 0xd5, 0x39, 0x65, 0xac, 0x55, 0x3a, 0xdb, 0xa8, - 0x9e, 0x1a, 0x6e, 0xe0, 0x3e, 0xce, 0xb0, 0xd3, 0xd5, 0xc3, 0xb7, 0xfe, 0x1e, 0xf5, 0x08, 0xb6, - 0x62, 0x02, 0xb5, 0x1b, 0x3b, 0x87, 0x38, 0x33, 0x07, 0x9f, 0x40, 0x8c, 0x24, 0x65, 0x02, 0x31, - 0xb0, 0xf1, 0x7f, 0x66, 0x60, 0xca, 0xa4, 0xbe, 0xdb, 0xf5, 0xea, 0x74, 0x85, 0xda, 0x0d, 0xea, - 0xb1, 0xe9, 0x7f, 0xcf, 0x69, 0x37, 0xc4, 0x9a, 0xc2, 0xe9, 0x7f, 0xe0, 0xb4, 0xd5, 0xad, 0x1b, - 0xcb, 0xc9, 0x67, 0x60, 0xb4, 0xd6, 0xdd, 0x41, 0xd4, 0x6c, 0xb4, 0x03, 0xf8, 0xdd, 0x1d, 0x2b, - 0x86, 0x2e, 0xd1, 0xc8, 0x75, 0x18, 0x7d, 0x40, 0x3d, 0x3f, 0xda, 0x0d, 0xf1, 0x68, 0x78, 0xc8, - 0x41, 0x2a, 0x81, 0xc0, 0x22, 0x77, 0xa2, 0x1d, 0x59, 0x1c, 0x6a, 0xd3, 0xb1, 0x7d, 0x30, 0x9a, - 0x2a, 0x2d, 0x01, 0x51, 0xa7, 0x8a, 0xc4, 0x32, 0x7e, 0x26, 0x0b, 0x85, 0x8a, 0x1d, 0xd8, 0x3b, - 0xb6, 0x2f, 0xfa, 0xf3, 0xc1, 0x4d, 0xb6, 0xc7, 0x2b, 0x0d, 0xc5, 0x3d, 0x9e, 0x7d, 0xf9, 0xc7, - 0x6e, 0xde, 0x2b, 0xf1, 0xe6, 0x8d, 0xb3, 0x13, 0x56, 0x34, 0x2f, 0x6a, 0xd4, 0x7b, 0x27, 0x37, - 0xaa, 0x20, 0x1a, 0x95, 0x97, 0x8d, 0x8a, 0x9a, 0x42, 0xde, 0x83, 0xa1, 0x5a, 0x87, 0xd6, 0xc5, - 0x26, 0x22, 0xcf, 0x05, 0xbd, 0x71, 0x0c, 0xe1, 0xc1, 0xcd, 0xa5, 0x09, 0xc1, 0x66, 0xc8, 0xef, - 0xd0, 0xba, 0x89, 0x64, 0xca, 0xa2, 0xf9, 0x47, 0x39, 0x98, 0x4b, 0x23, 0x53, 0xdb, 0x31, 0xd2, - 0xa7, 0x1d, 0x57, 0x20, 0xcf, 0x8e, 0x70, 0x76, 0x2c, 0xe2, 0x76, 0x31, 0xb6, 0x34, 0xc1, 0x3e, - 0x79, 0x5f, 0xc0, 0xcc, 0xb0, 0x94, 0xbc, 0x14, 0x4a, 0x04, 0xf9, 0x88, 0x9f, 0x90, 0x08, 0xa4, - 0x1c, 0xc0, 0xc6, 0x5a, 0x2e, 0x61, 0x14, 0x1c, 0xa2, 0x6e, 0x91, 0xe0, 0x68, 0xac, 0x3d, 0x01, - 0xd1, 0x8e, 0x19, 0x79, 0x28, 0x2c, 0x43, 0x5e, 0x36, 0x6b, 0x7e, 0x02, 0x19, 0xcd, 0xc4, 0x3a, - 0xe9, 0xc1, 0x4d, 0x3e, 0x98, 0x0d, 0xf1, 0x5b, 0x65, 0x23, 0x71, 0xc8, 0x4d, 0xc8, 0x6f, 0x78, - 0xee, 0xe3, 0xc3, 0x6a, 0xc5, 0x9f, 0x9f, 0xbc, 0x94, 0xbb, 0x32, 0xb6, 0x74, 0xee, 0xf8, 0xa8, - 0x38, 0xdb, 0x61, 0x30, 0xcb, 0x69, 0xa8, 0x27, 0x6d, 0x88, 0x78, 0x77, 0x28, 0x9f, 0x29, 0x64, - 0xef, 0x0e, 0xe5, 0xb3, 0x85, 0x1c, 0x17, 0x2f, 0xee, 0x0e, 0xe5, 0x87, 0x0a, 0xc3, 0x77, 0x87, - 0xf2, 0xc3, 0x28, 0x70, 0x8c, 0x15, 0xe0, 0xee, 0x50, 0x7e, 0xbc, 0x30, 0xa1, 0x9d, 0xf6, 0xc8, - 0x20, 0x70, 0xeb, 0x6e, 0xd3, 0xcc, 0x6d, 0x99, 0x55, 0x73, 0xa4, 0x5c, 0x2a, 0x53, 0x2f, 0x30, - 0x73, 0xa5, 0xed, 0x9a, 0x39, 0x59, 0x39, 0x6c, 0xdb, 0x2d, 0xa7, 0xce, 0x8f, 0x4e, 0x33, 0x77, - 0xa7, 0xbc, 0x61, 0x94, 0x60, 0x2a, 0x6a, 0xcb, 0xaa, 0xe3, 0x07, 0xe4, 0x3a, 0x8c, 0x49, 0x08, - 0xdb, 0xe8, 0x72, 0xa9, 0xad, 0x36, 0x23, 0x1c, 0xe3, 0x77, 0xb3, 0x00, 0x51, 0xc9, 0x33, 0xba, - 0x16, 0x3e, 0xa7, 0xad, 0x85, 0x33, 0xf1, 0xb5, 0xd0, 0x73, 0x15, 0x90, 0x0f, 0x60, 0x84, 0x89, - 0x05, 0x5d, 0x29, 0x12, 0x9d, 0x8b, 0x93, 0x62, 0xe1, 0x83, 0x9b, 0x4b, 0x53, 0x82, 0x78, 0xc4, - 0x47, 0x88, 0x29, 0xc8, 0x94, 0x65, 0xf4, 0x8b, 0xa3, 0xd1, 0x60, 0x88, 0x05, 0x74, 0x05, 0xc2, - 0x01, 0x15, 0x1d, 0x8a, 0x2b, 0xa3, 0x23, 0x07, 0x39, 0x2c, 0x25, 0xe7, 0x81, 0x0d, 0xb8, 0xe8, - 0xd4, 0xd1, 0xe3, 0xa3, 0x62, 0xae, 0xeb, 0x39, 0x38, 0x09, 0xc8, 0x75, 0x10, 0xd3, 0x40, 0x74, - 0x20, 0x9b, 0x7d, 0x33, 0x75, 0xdb, 0xaa, 0x53, 0x2f, 0x88, 0x7a, 0x7c, 0x3e, 0x23, 0x67, 0x0b, - 0xe9, 0x80, 0x3e, 0x55, 0xe6, 0x87, 0x70, 0x1a, 0x5c, 0x49, 0xed, 0x95, 0x6b, 0x1a, 0x2a, 0x17, - 0x23, 0x2f, 0xc9, 0x53, 0xa9, 0xc1, 0xcb, 0xac, 0x84, 0x48, 0xa9, 0x57, 0x40, 0x6e, 0x02, 0x9b, - 0xa1, 0xa2, 0xf7, 0x41, 0xd4, 0x53, 0xda, 0xae, 0x2d, 0x9d, 0x11, 0x9c, 0x26, 0xed, 0x47, 0x2a, - 0x39, 0xc3, 0x26, 0xef, 0x00, 0x9b, 0xc2, 0xa2, 0xdf, 0x89, 0x20, 0xba, 0x53, 0xde, 0x28, 0x37, - 0xdd, 0x6e, 0xa3, 0xf6, 0xa5, 0xd5, 0x88, 0x78, 0xaf, 0xde, 0x51, 0x89, 0xef, 0x94, 0x37, 0xc8, - 0x3b, 0x30, 0x5c, 0xfa, 0xde, 0xae, 0x47, 0x85, 0x7c, 0x32, 0x21, 0xeb, 0x64, 0xb0, 0xa5, 0x73, - 0x82, 0x70, 0xda, 0x66, 0x3f, 0x55, 0xb9, 0x0e, 0xcb, 0x59, 0xcd, 0x9b, 0xab, 0x35, 0x21, 0x7b, - 0x90, 0x58, 0xb7, 0x6c, 0xae, 0x2a, 0x9f, 0x1d, 0x68, 0xad, 0x66, 0x54, 0xe4, 0x3a, 0x64, 0x4b, - 0x15, 0xbc, 0x11, 0x8d, 0x2f, 0x8e, 0xc9, 0x6a, 0x2b, 0x4b, 0x73, 0x82, 0x64, 0xc2, 0x56, 0x97, - 0x41, 0xb6, 0x54, 0x21, 0x4b, 0x30, 0xbc, 0x76, 0x58, 0xfb, 0xd2, 0xaa, 0xd8, 0xcc, 0x66, 0xe5, - 0xbc, 0x66, 0xb0, 0xfb, 0xb8, 0xec, 0xfd, 0xe8, 0x8b, 0x5b, 0x87, 0xfe, 0x37, 0x9b, 0xea, 0x17, - 0x23, 0x1a, 0xd9, 0x80, 0xb1, 0x52, 0xa3, 0xe5, 0xb4, 0xb7, 0x7c, 0xea, 0xcd, 0x8f, 0x23, 0x9f, - 0xf9, 0xd8, 0x77, 0x87, 0xe5, 0x4b, 0xf3, 0xc7, 0x47, 0xc5, 0x39, 0x9b, 0xfd, 0xb4, 0xba, 0x3e, - 0xf5, 0x14, 0x6e, 0x11, 0x13, 0xb2, 0x01, 0xb0, 0xe6, 0xb6, 0xf7, 0xdc, 0x52, 0xd0, 0xb4, 0xfd, - 0xd8, 0xf6, 0x18, 0x15, 0x84, 0xe2, 0xc3, 0x99, 0x16, 0x83, 0x59, 0x36, 0x03, 0x2a, 0x0c, 0x15, - 0x1e, 0xe4, 0x36, 0x8c, 0xdc, 0xf7, 0xec, 0x7a, 0x93, 0xce, 0x4f, 0x22, 0xb7, 0x39, 0xc1, 0x8d, - 0x03, 0x65, 0x4b, 0xe7, 0x05, 0xc3, 0x82, 0x8b, 0x60, 0xf5, 0x9a, 0xc2, 0x11, 0x17, 0xb6, 0x81, - 0x24, 0xe7, 0x64, 0xca, 0x25, 0xe1, 0x75, 0xf5, 0x92, 0x10, 0x2d, 0xfa, 0xb2, 0xdb, 0x6a, 0xd9, - 0xed, 0x06, 0xd2, 0x3e, 0x58, 0x54, 0xee, 0x0e, 0xc6, 0x37, 0x61, 0x26, 0xd1, 0x59, 0x27, 0xdc, - 0xef, 0xde, 0x87, 0xe9, 0x0a, 0xdd, 0xb5, 0xbb, 0xcd, 0x20, 0x3c, 0x49, 0xf8, 0x12, 0xc5, 0x9b, - 0x56, 0x83, 0x17, 0x59, 0xf2, 0xf8, 0x30, 0xe3, 0xc8, 0xc6, 0x7b, 0x30, 0xa9, 0x35, 0x9f, 0x5d, - 0x15, 0x4a, 0xdd, 0x86, 0x13, 0xe0, 0x40, 0x66, 0xa2, 0xab, 0x82, 0xcd, 0x80, 0x38, 0x5c, 0x66, - 0x84, 0x60, 0xfc, 0x3d, 0x55, 0x5a, 0x11, 0x3b, 0x11, 0xbb, 0x56, 0x8b, 0xfd, 0x20, 0x13, 0xc9, - 0x4e, 0x89, 0xfd, 0x20, 0xdc, 0x0d, 0xae, 0xf2, 0xb5, 0x99, 0x4d, 0xac, 0xcd, 0x71, 0x31, 0x12, - 0x39, 0xfb, 0x91, 0xcf, 0x57, 0x64, 0x38, 0x53, 0x73, 0x1f, 0x7f, 0xa6, 0x7e, 0x00, 0x13, 0x6b, - 0x76, 0xdb, 0xde, 0xa3, 0x0d, 0xd6, 0x02, 0xbe, 0xf7, 0x8c, 0x2d, 0x3d, 0x7f, 0x7c, 0x54, 0x3c, - 0xd7, 0xe2, 0x70, 0x6c, 0xa5, 0x3a, 0x89, 0x34, 0x02, 0x72, 0x43, 0xae, 0xec, 0xe1, 0x94, 0x95, - 0x3d, 0x29, 0x6a, 0x1f, 0xc6, 0x95, 0x2d, 0xd6, 0xb3, 0xf1, 0xdb, 0x63, 0xd8, 0x46, 0xf2, 0x06, - 0x8c, 0x98, 0x74, 0x8f, 0x1d, 0x35, 0x99, 0x68, 0x90, 0x3c, 0x84, 0xa8, 0x1d, 0xc3, 0x71, 0x50, - 0xce, 0xa0, 0x0d, 0x7f, 0xdf, 0xd9, 0x0d, 0x44, 0xef, 0x84, 0x72, 0x86, 0x00, 0x2b, 0x72, 0x86, - 0x80, 0xe8, 0xd7, 0x59, 0x0e, 0x63, 0xbb, 0x9f, 0x59, 0xa9, 0x89, 0x4e, 0x93, 0x3d, 0x6c, 0x56, - 0x94, 0x6d, 0xc4, 0xd3, 0xa4, 0x04, 0x86, 0x4d, 0x6e, 0xc1, 0x58, 0xa9, 0x5e, 0x77, 0xbb, 0xca, - 0x9d, 0x91, 0xaf, 0x5b, 0x0e, 0xd4, 0x55, 0x24, 0x11, 0x2a, 0xa9, 0xc1, 0xf8, 0x32, 0xbb, 0x68, - 0x39, 0x65, 0xbb, 0xbe, 0x2f, 0x3b, 0x49, 0xee, 0x61, 0x4a, 0x49, 0xb4, 0x72, 0x29, 0x02, 0xeb, - 0x0c, 0xa8, 0x2a, 0x19, 0x14, 0x5c, 0xb2, 0x09, 0xe3, 0x35, 0x5a, 0xf7, 0x68, 0x50, 0x0b, 0x5c, - 0x8f, 0xc6, 0xb6, 0x64, 0xa5, 0x64, 0xe9, 0xa2, 0xbc, 0xeb, 0xf9, 0x08, 0xb4, 0x7c, 0x06, 0x55, - 0xb9, 0x2a, 0xc8, 0x5c, 0x68, 0x6f, 0xb9, 0xde, 0x61, 0x65, 0x49, 0x6c, 0xd3, 0xd1, 0x99, 0xce, - 0xc1, 0xaa, 0xd0, 0xce, 0x20, 0x8d, 0x1d, 0x5d, 0x68, 0xe7, 0x58, 0x38, 0x52, 0x95, 0x1a, 0xca, - 0x56, 0x62, 0xd3, 0x9e, 0x8e, 0x7a, 0x19, 0xc1, 0xca, 0x48, 0x35, 0x7c, 0x94, 0xcc, 0xb4, 0x91, - 0x12, 0x58, 0xa4, 0x03, 0x44, 0x8e, 0x1a, 0x17, 0x74, 0x9b, 0xd4, 0xf7, 0xc5, 0x5e, 0x7e, 0x3e, - 0x36, 0xf8, 0x11, 0xc2, 0xd2, 0x2b, 0x82, 0xf9, 0x05, 0x39, 0x0d, 0xc4, 0x3d, 0x8d, 0x15, 0x2a, - 0xf5, 0xa4, 0xf0, 0x26, 0x6f, 0x03, 0x2c, 0x3f, 0x0e, 0xa8, 0xd7, 0xb6, 0x9b, 0xa1, 0x1e, 0x0c, - 0x55, 0x3f, 0x54, 0x40, 0xf5, 0x81, 0x56, 0x90, 0x49, 0x19, 0x26, 0x4b, 0xbe, 0xdf, 0x6d, 0x51, - 0xd3, 0x6d, 0xd2, 0x92, 0xb9, 0x8e, 0xfb, 0xfe, 0xd8, 0xd2, 0x85, 0xe3, 0xa3, 0xe2, 0x79, 0x1b, - 0x0b, 0x2c, 0xcf, 0x6d, 0x52, 0xcb, 0xf6, 0xd4, 0xd9, 0xad, 0xd3, 0x90, 0xfb, 0x00, 0xf7, 0x3b, - 0xb4, 0x5d, 0xa3, 0xb6, 0x57, 0xdf, 0x8f, 0x6d, 0xf3, 0x51, 0xc1, 0xd2, 0x0b, 0xa2, 0x85, 0x73, - 0x6e, 0x87, 0xb6, 0x7d, 0x84, 0xa9, 0x5f, 0x15, 0x61, 0x92, 0x6d, 0x98, 0xae, 0x96, 0xd6, 0x36, - 0xdc, 0xa6, 0x53, 0x3f, 0x14, 0x92, 0xd3, 0x14, 0x6a, 0x07, 0xcf, 0x0a, 0xae, 0xb1, 0x52, 0xbe, - 0x3d, 0x39, 0x76, 0xcb, 0xea, 0x20, 0xd4, 0x12, 0xf2, 0x53, 0x9c, 0x0b, 0xf9, 0x90, 0xcd, 0x41, - 0x9f, 0x09, 0x83, 0x9b, 0xf6, 0x9e, 0x3f, 0x3f, 0xad, 0x69, 0xbb, 0x4a, 0xdb, 0xb5, 0x6b, 0x4a, - 0x29, 0x17, 0x53, 0x16, 0xf8, 0x44, 0x44, 0xa8, 0x15, 0xd8, 0x7b, 0xbe, 0x3e, 0x11, 0x43, 0x6c, - 0x72, 0x17, 0xa0, 0xe2, 0xd6, 0xbb, 0x2d, 0xda, 0x0e, 0x2a, 0x4b, 0xf3, 0x05, 0xfd, 0x2a, 0x10, - 0x16, 0x44, 0x5b, 0x5b, 0xc3, 0xad, 0x6b, 0x33, 0x51, 0xa1, 0x5e, 0x78, 0x1f, 0x0a, 0xf1, 0x0f, - 0x39, 0xa5, 0x02, 0x6b, 0xb2, 0x30, 0xa5, 0xb4, 0x7e, 0xf9, 0xb1, 0xe3, 0x07, 0xbe, 0xf1, 0x2d, - 0x6d, 0x05, 0xb2, 0xdd, 0xe1, 0x1e, 0x3d, 0xdc, 0xf0, 0xe8, 0xae, 0xf3, 0x58, 0x6c, 0x66, 0xb8, - 0x3b, 0x1c, 0xd0, 0x43, 0xab, 0x83, 0x50, 0x75, 0x77, 0x08, 0x51, 0xc9, 0x67, 0x21, 0x7f, 0x6f, - 0xad, 0x76, 0x8f, 0x1e, 0x56, 0x2b, 0xe2, 0xa0, 0xe2, 0x64, 0x2d, 0xdf, 0x62, 0xa4, 0xda, 0x5c, - 0x0b, 0x31, 0x8d, 0xa5, 0x68, 0x27, 0x64, 0x35, 0x97, 0x9b, 0x5d, 0x3f, 0xa0, 0x5e, 0xb5, 0xa2, - 0xd6, 0x5c, 0xe7, 0xc0, 0xd8, 0xbe, 0x14, 0xa2, 0x1a, 0xff, 0x3a, 0x8b, 0xbb, 0x20, 0x9b, 0xf0, - 0xd5, 0xb6, 0x1f, 0xd8, 0xed, 0x3a, 0x0d, 0x19, 0xe0, 0x84, 0x77, 0x04, 0x34, 0x36, 0xe1, 0x23, - 0x64, 0xbd, 0xea, 0xec, 0xc0, 0x55, 0xb3, 0x2a, 0xa5, 0xe6, 0xa2, 0x5a, 0x51, 0xd5, 0xab, 0x9e, - 0x80, 0xc6, 0xaa, 0x8c, 0x90, 0xc9, 0x65, 0x18, 0xad, 0x96, 0xd6, 0x4a, 0xdd, 0x60, 0x1f, 0xf7, - 0xe0, 0x3c, 0x97, 0xcf, 0xd9, 0x6c, 0xb5, 0xbb, 0xc1, 0xbe, 0x29, 0x0b, 0xc9, 0x75, 0xbc, 0xf7, - 0xb4, 0x69, 0xc0, 0xd5, 0xb0, 0xe2, 0xd0, 0xf5, 0x39, 0x28, 0x76, 0xed, 0x61, 0x20, 0xf2, 0x1a, - 0x0c, 0x3f, 0xd8, 0x28, 0x57, 0x2b, 0xe2, 0xe2, 0x8c, 0x27, 0xd1, 0xc3, 0x4e, 0x5d, 0xff, 0x12, - 0x8e, 0x42, 0x96, 0x61, 0xaa, 0x46, 0xeb, 0x5d, 0xcf, 0x09, 0x0e, 0xef, 0x78, 0x6e, 0xb7, 0xe3, - 0xcf, 0x8f, 0x62, 0x1d, 0xb8, 0xd2, 0x7d, 0x51, 0x62, 0xed, 0x61, 0x91, 0x42, 0x1d, 0x23, 0x32, - 0x7e, 0x27, 0x13, 0x6d, 0x93, 0xe4, 0xb2, 0x26, 0xd6, 0xa0, 0xee, 0x86, 0x89, 0x35, 0xaa, 0xee, - 0x06, 0x05, 0x1c, 0x13, 0x48, 0xb9, 0xeb, 0x07, 0x6e, 0x6b, 0xb9, 0xdd, 0xe8, 0xb8, 0x4e, 0x3b, - 0x40, 0x2a, 0xde, 0xf9, 0xc6, 0xf1, 0x51, 0xf1, 0x62, 0x1d, 0x4b, 0x2d, 0x2a, 0x8a, 0xad, 0x18, - 0x97, 0x14, 0xea, 0x27, 0x18, 0x0f, 0xe3, 0xf7, 0xb3, 0xda, 0xf1, 0xc6, 0x3e, 0xcf, 0xa4, 0x9d, - 0xa6, 0x53, 0xc7, 0x1b, 0x3d, 0x36, 0x34, 0x9c, 0x55, 0xf8, 0x79, 0x5e, 0x54, 0xca, 0x7b, 0x48, - 0xe7, 0x9d, 0x42, 0x4d, 0xbe, 0x08, 0x13, 0x4c, 0xd2, 0x10, 0x3f, 0xfd, 0xf9, 0x2c, 0x76, 0xf6, - 0x0b, 0xa8, 0x85, 0xf3, 0xa9, 0x17, 0xb2, 0xd1, 0x44, 0x14, 0x95, 0x82, 0x34, 0x60, 0x7e, 0xd3, - 0xb3, 0xdb, 0xbe, 0x13, 0x2c, 0xb7, 0xeb, 0xde, 0x21, 0x4a, 0x46, 0xcb, 0x6d, 0x7b, 0xa7, 0x49, - 0x1b, 0xd8, 0xdc, 0xfc, 0xd2, 0x95, 0xe3, 0xa3, 0xe2, 0xcb, 0x01, 0xc7, 0xb1, 0x68, 0x88, 0x64, - 0x51, 0x8e, 0xa5, 0x70, 0xee, 0xc9, 0x89, 0x49, 0x52, 0xb2, 0x5b, 0xf1, 0x11, 0x86, 0x0b, 0x09, - 0x28, 0x49, 0x85, 0xa3, 0xc1, 0xf6, 0x30, 0xf5, 0x33, 0x55, 0x02, 0xe3, 0xff, 0xcd, 0x44, 0x07, - 0x30, 0x79, 0x17, 0xc6, 0xc5, 0x8a, 0x51, 0xe6, 0x05, 0xee, 0xa0, 0x72, 0x79, 0xc5, 0x46, 0x56, - 0x45, 0x67, 0xf7, 0xfe, 0x52, 0x79, 0x55, 0x99, 0x1b, 0x78, 0xef, 0xb7, 0xeb, 0xcd, 0x38, 0x95, - 0x44, 0x63, 0x93, 0x60, 0x73, 0xb5, 0xa6, 0xf7, 0x0a, 0x4e, 0x82, 0xa0, 0xe9, 0xa7, 0x74, 0x83, - 0x82, 0xfc, 0xe4, 0x0d, 0xff, 0x5f, 0x32, 0x69, 0xe7, 0x3c, 0x59, 0x82, 0xc9, 0x6d, 0xd7, 0x3b, - 0xc0, 0xf1, 0x55, 0x3a, 0x01, 0x47, 0xfe, 0x91, 0x2c, 0x88, 0x37, 0x48, 0x27, 0x51, 0xbf, 0x4d, - 0xe9, 0x0d, 0xfd, 0xdb, 0x62, 0x1c, 0x34, 0x02, 0x36, 0x0e, 0x21, 0xc7, 0x70, 0x75, 0xe0, 0x38, - 0x44, 0x9f, 0xa0, 0x4d, 0x61, 0x15, 0xdd, 0xf8, 0xaf, 0x32, 0xea, 0x79, 0xce, 0x3a, 0xb9, 0xe2, - 0xb6, 0x6c, 0xa7, 0xad, 0x34, 0x87, 0x3f, 0x2c, 0x21, 0x34, 0xfe, 0x25, 0x0a, 0x32, 0xb9, 0x09, - 0x79, 0xfe, 0x2b, 0xdc, 0x6b, 0x51, 0xab, 0x25, 0x08, 0xf5, 0x83, 0x42, 0x22, 0x26, 0x46, 0x26, - 0x77, 0xda, 0x91, 0xf9, 0xed, 0x8c, 0x7a, 0x14, 0x7f, 0xdc, 0xc3, 0x26, 0x76, 0xc8, 0x64, 0x4f, - 0x73, 0xc8, 0x3c, 0x71, 0x13, 0xbe, 0x3f, 0x03, 0xe3, 0x8a, 0x96, 0x82, 0xb5, 0x61, 0xc3, 0x73, - 0x3f, 0xa2, 0xf5, 0x40, 0x6f, 0x43, 0x87, 0x03, 0x63, 0x6d, 0x08, 0x51, 0x9f, 0xa0, 0x0d, 0xc6, - 0x9f, 0x65, 0xc4, 0x1d, 0x69, 0xe0, 0x6d, 0x5e, 0xdf, 0x92, 0xb3, 0xa7, 0x39, 0x22, 0xbf, 0x08, - 0xc3, 0x26, 0x6d, 0x38, 0xbe, 0xb8, 0xdf, 0xcc, 0xa8, 0xf7, 0x31, 0x2c, 0x88, 0xe4, 0x26, 0x8f, - 0xfd, 0x54, 0xcf, 0x37, 0x2c, 0x67, 0x82, 0x6c, 0xd5, 0xbf, 0xdd, 0xa4, 0x8f, 0x1d, 0xbe, 0x18, - 0xc5, 0x51, 0x8b, 0xc7, 0x9b, 0xe3, 0x5b, 0xbb, 0xac, 0x44, 0x48, 0xd4, 0xea, 0xc2, 0xd3, 0x68, - 0x8c, 0x0f, 0x01, 0xa2, 0x2a, 0xc9, 0x3d, 0x28, 0x88, 0xd9, 0xe0, 0xb4, 0xf7, 0xb8, 0x20, 0x25, - 0xfa, 0xa0, 0x78, 0x7c, 0x54, 0x7c, 0xbe, 0x1e, 0x96, 0x09, 0xa9, 0x53, 0xe1, 0x9b, 0x20, 0x34, - 0xfe, 0xc3, 0x2c, 0x64, 0x4b, 0x38, 0x20, 0xf7, 0xe8, 0x61, 0x60, 0xef, 0xdc, 0x76, 0x9a, 0xda, - 0x62, 0x3a, 0x40, 0xa8, 0xb5, 0xeb, 0x68, 0xea, 0x0a, 0x05, 0x99, 0x2d, 0xa6, 0x7b, 0xde, 0xce, - 0x5b, 0x48, 0xa8, 0x2c, 0xa6, 0x03, 0x6f, 0xe7, 0xad, 0x38, 0x59, 0x88, 0x48, 0x0c, 0x18, 0xe1, - 0x0b, 0x4b, 0xcc, 0x41, 0x38, 0x3e, 0x2a, 0x8e, 0xf0, 0xf5, 0x67, 0x8a, 0x12, 0x72, 0x1e, 0x72, - 0xb5, 0x8d, 0x75, 0xb1, 0x03, 0xa2, 0x5a, 0xd0, 0xef, 0xb4, 0x4d, 0x06, 0x63, 0x75, 0xae, 0x56, - 0x4a, 0x1b, 0xa8, 0x08, 0x18, 0x8e, 0xea, 0x6c, 0x36, 0xec, 0x4e, 0x5c, 0x15, 0x10, 0x22, 0x92, - 0xf7, 0x60, 0xfc, 0x5e, 0xa5, 0xbc, 0xe2, 0xfa, 0x7c, 0xf7, 0x1a, 0x89, 0x26, 0xff, 0x41, 0xa3, - 0x6e, 0xa1, 0x26, 0x3e, 0x7e, 0x0c, 0x28, 0xf8, 0xc6, 0x8f, 0x64, 0x61, 0x5c, 0xd1, 0x93, 0x91, - 0xcf, 0x8a, 0x07, 0xd2, 0x8c, 0x76, 0x03, 0x50, 0x30, 0x58, 0x29, 0x57, 0xaa, 0xb4, 0xdc, 0x06, - 0x15, 0xcf, 0xa5, 0x91, 0x02, 0x23, 0x3b, 0x88, 0x02, 0xe3, 0x6d, 0x00, 0x3e, 0x07, 0xf0, 0x93, - 0x15, 0x71, 0x42, 0xb1, 0x93, 0x50, 0xc7, 0x25, 0x42, 0x26, 0x0f, 0x60, 0x76, 0xd3, 0xeb, 0xfa, - 0x41, 0xed, 0xd0, 0x0f, 0x68, 0x8b, 0x71, 0xdb, 0x70, 0xdd, 0xa6, 0x98, 0x7f, 0x2f, 0x1f, 0x1f, - 0x15, 0x2f, 0xa1, 0x71, 0x87, 0xe5, 0x63, 0x39, 0x7e, 0x80, 0xd5, 0x71, 0x5d, 0x55, 0xad, 0x91, - 0xc6, 0xc0, 0x30, 0x61, 0x42, 0x55, 0x8a, 0xb0, 0x93, 0x45, 0x3c, 0x26, 0x09, 0x55, 0xb7, 0x72, - 0xb2, 0x88, 0xaf, 0x4c, 0x3e, 0x6e, 0xe9, 0x24, 0xc6, 0x67, 0x55, 0x85, 0xdc, 0xa0, 0x0b, 0xdb, - 0xf8, 0xc1, 0x4c, 0xb4, 0x8d, 0x3c, 0xb8, 0x41, 0xde, 0x81, 0x11, 0xfe, 0x78, 0x27, 0xde, 0x38, - 0xcf, 0x84, 0x97, 0x5a, 0xf5, 0x65, 0x8f, 0x6b, 0xc2, 0xff, 0x90, 0x3f, 0xf0, 0x3f, 0x67, 0x0a, - 0x92, 0x50, 0x89, 0xae, 0xeb, 0xd3, 0x24, 0x77, 0x54, 0x17, 0xdf, 0x48, 0x53, 0xa2, 0x1b, 0x3f, - 0x31, 0x0c, 0x53, 0x3a, 0x9a, 0xfa, 0xc2, 0x97, 0x19, 0xe8, 0x85, 0xef, 0x8b, 0x90, 0x67, 0xfd, - 0xe1, 0xd4, 0xa9, 0x94, 0xc8, 0x5e, 0xc6, 0xa7, 0x05, 0x01, 0xd3, 0x5e, 0xae, 0x81, 0x0f, 0x07, - 0xbb, 0xe3, 0x9a, 0x21, 0x15, 0x59, 0x54, 0x9e, 0xa1, 0x72, 0x91, 0x90, 0x22, 0x9f, 0xa1, 0xd4, - 0xf5, 0x10, 0x3e, 0x48, 0xbd, 0x09, 0x23, 0x4c, 0xbe, 0x0f, 0x55, 0x30, 0xf8, 0x95, 0x4c, 0xf4, - 0x8f, 0x99, 0xa8, 0x70, 0x24, 0xb2, 0x0d, 0xf9, 0x55, 0xdb, 0x0f, 0x6a, 0x94, 0xb6, 0x07, 0x78, - 0xbb, 0x2f, 0x8a, 0xae, 0x9a, 0xc5, 0x87, 0x71, 0x9f, 0xd2, 0x76, 0xec, 0xf1, 0x35, 0x64, 0x46, - 0xbe, 0x06, 0x50, 0x76, 0xdb, 0x81, 0xe7, 0x36, 0x57, 0xdd, 0xbd, 0xf9, 0x11, 0xbc, 0xfb, 0x5e, - 0x8c, 0x0d, 0x40, 0x84, 0xc0, 0xaf, 0xbf, 0xa1, 0x82, 0xa7, 0xce, 0x0b, 0xac, 0xa6, 0xbb, 0xa7, - 0xae, 0x83, 0x08, 0x9f, 0xdc, 0x86, 0x82, 0x54, 0x2c, 0x6c, 0x75, 0xf6, 0x3c, 0x9c, 0x20, 0xa3, - 0x91, 0xe4, 0x41, 0x1f, 0x07, 0x56, 0x57, 0xc0, 0xd5, 0x9d, 0x32, 0x4e, 0x43, 0xbe, 0x0a, 0xe7, - 0xe2, 0x30, 0x39, 0xca, 0xf9, 0x48, 0x26, 0x57, 0xd9, 0xa5, 0xcc, 0xfb, 0x5e, 0x2c, 0xc8, 0x1d, - 0x98, 0x66, 0x1d, 0xb2, 0x46, 0x6d, 0xbf, 0xcb, 0x0d, 0xac, 0x84, 0x6a, 0xe6, 0x82, 0xd4, 0x44, - 0xf1, 0x55, 0xd8, 0x74, 0xeb, 0x07, 0x0a, 0x92, 0x19, 0xa7, 0x32, 0x8e, 0xb2, 0x70, 0x36, 0x1d, - 0x97, 0x7c, 0x1f, 0x9c, 0x11, 0xfd, 0xd2, 0xa4, 0x9e, 0x82, 0x33, 0x80, 0x4d, 0xc0, 0x9b, 0xa2, - 0xbf, 0x5f, 0xac, 0x87, 0x0c, 0xc2, 0x8d, 0x83, 0xb1, 0x88, 0x0d, 0x6e, 0x7a, 0x3d, 0xe4, 0x1b, - 0x30, 0xae, 0x56, 0x9b, 0x1d, 0xdc, 0xbc, 0xa2, 0x4f, 0x5d, 0x2a, 0x4b, 0x62, 0xc3, 0xb4, 0x49, - 0xbf, 0xd9, 0xa5, 0x7e, 0x20, 0x0d, 0x3c, 0xc4, 0xd1, 0x7d, 0x3e, 0x51, 0x8b, 0x44, 0x08, 0xf5, - 0x3f, 0x05, 0x8f, 0x53, 0x5a, 0xd2, 0x0c, 0xef, 0xdb, 0x8c, 0x7d, 0x9c, 0x9f, 0xf1, 0xdd, 0x2c, - 0x9c, 0xeb, 0x31, 0x2d, 0xd9, 0xce, 0x85, 0x82, 0x95, 0xb2, 0x73, 0xc5, 0xe4, 0x29, 0x6e, 0x1d, - 0x76, 0x09, 0xb2, 0x42, 0x14, 0x19, 0x5a, 0x2a, 0x1c, 0x1f, 0x15, 0x27, 0xb4, 0x15, 0x97, 0xad, - 0x56, 0xc8, 0x5d, 0x18, 0x62, 0xdd, 0x30, 0x80, 0x91, 0x83, 0xd4, 0xfe, 0x4d, 0x05, 0x8e, 0xba, - 0xd0, 0xb1, 0x6f, 0x90, 0x07, 0xf9, 0x2c, 0xe4, 0x36, 0x37, 0x57, 0x71, 0x95, 0xe7, 0x70, 0x96, - 0x4e, 0x06, 0x41, 0x53, 0xdb, 0x54, 0x26, 0x19, 0x6d, 0xd8, 0x23, 0x26, 0x43, 0x27, 0x5f, 0x8e, - 0x19, 0x5f, 0xbd, 0xd6, 0x7f, 0x49, 0x0e, 0x6e, 0x8b, 0xf5, 0x04, 0x26, 0x50, 0xc6, 0x2f, 0x64, - 0xa3, 0xdd, 0xf6, 0xb6, 0xd3, 0x0c, 0xa8, 0x47, 0x16, 0xf8, 0xe6, 0x19, 0x89, 0xd1, 0x66, 0xf8, - 0x9b, 0xcc, 0x47, 0x3b, 0x31, 0x67, 0x15, 0x6e, 0xb9, 0xaf, 0x29, 0x5b, 0x6e, 0x0e, 0xb7, 0xdc, - 0xa9, 0x9e, 0x9b, 0xeb, 0x6b, 0x29, 0x3b, 0x08, 0x6e, 0x99, 0x29, 0xbb, 0xc4, 0xcb, 0x30, 0xb9, - 0xee, 0x2e, 0x3f, 0x0e, 0x42, 0x44, 0xb6, 0x55, 0xe6, 0x4d, 0x1d, 0xc8, 0x38, 0xde, 0x6f, 0x36, - 0xa8, 0xb7, 0xb9, 0x6f, 0xb7, 0x35, 0x2b, 0x03, 0x33, 0x01, 0x67, 0xb8, 0xeb, 0xf4, 0x91, 0x8e, - 0x3b, 0xca, 0x71, 0xe3, 0x70, 0xe3, 0x07, 0xb2, 0xb2, 0x33, 0x1e, 0x2c, 0x3e, 0xa3, 0xaf, 0xd9, - 0x6f, 0x69, 0xaf, 0xd9, 0xb3, 0xa1, 0x1e, 0x3e, 0x34, 0xcd, 0x58, 0x3c, 0xc1, 0xa2, 0xe3, 0xef, - 0x8d, 0xc0, 0x84, 0x8a, 0xce, 0xfa, 0xa1, 0xd4, 0x68, 0x78, 0x6a, 0x3f, 0xd8, 0x8d, 0x86, 0x67, - 0x22, 0x54, 0x33, 0xe0, 0xc8, 0xf5, 0x35, 0xe0, 0xf8, 0x3a, 0x8c, 0x95, 0x5b, 0x0d, 0xed, 0x59, - 0xd9, 0x48, 0xf9, 0xbc, 0x6b, 0x21, 0x12, 0x5f, 0x0b, 0xa1, 0x7a, 0xb9, 0xde, 0x6a, 0x24, 0x1f, - 0x93, 0x23, 0x96, 0x9a, 0xed, 0xc7, 0xf0, 0x93, 0xd8, 0x7e, 0xdc, 0x82, 0xb1, 0x2d, 0x9f, 0x6e, - 0x76, 0xdb, 0x6d, 0xda, 0xc4, 0x69, 0x95, 0xe7, 0xb7, 0xb2, 0xae, 0x4f, 0xad, 0x00, 0xa1, 0xea, - 0x07, 0x84, 0xa8, 0xea, 0x00, 0x8f, 0xf6, 0x19, 0xe0, 0x9b, 0x90, 0xdf, 0xa0, 0xd4, 0xc3, 0x3e, - 0x1d, 0x8f, 0x84, 0xef, 0x0e, 0xa5, 0x9e, 0xc5, 0x3a, 0x56, 0xb3, 0x09, 0x11, 0x88, 0x9a, 0x21, - 0xc9, 0xc4, 0x80, 0x86, 0x24, 0xe4, 0x45, 0x98, 0xe8, 0x74, 0x77, 0x9a, 0x4e, 0x1d, 0xf9, 0x0a, - 0x0b, 0x14, 0x73, 0x9c, 0xc3, 0x18, 0x5b, 0x9f, 0x7c, 0x19, 0x26, 0xf1, 0x36, 0x1a, 0x4e, 0xb9, - 0x29, 0xed, 0xfd, 0x55, 0x2b, 0xe3, 0x32, 0x69, 0x9d, 0x81, 0xac, 0x14, 0x43, 0x29, 0x9d, 0x11, - 0xb9, 0x0b, 0xa3, 0x7b, 0x4e, 0x60, 0xed, 0x77, 0x77, 0xe6, 0xa7, 0x35, 0x2b, 0xa3, 0x3b, 0x4e, - 0xb0, 0xd2, 0xdd, 0xe1, 0x43, 0x1e, 0xb2, 0xc6, 0x1d, 0x6f, 0xcf, 0x09, 0xf6, 0xbb, 0xaa, 0xf2, - 0x7c, 0x64, 0x0f, 0x71, 0x17, 0x6a, 0x30, 0xa5, 0xcf, 0x8a, 0xa7, 0xf0, 0xa4, 0x1b, 0x1a, 0xd8, - 0xe4, 0x0b, 0x63, 0x77, 0x87, 0xf2, 0x50, 0x18, 0xe7, 0xa6, 0x35, 0x26, 0x6c, 0x84, 0xfd, 0x63, - 0x92, 0x7b, 0xdd, 0x1d, 0xea, 0xb5, 0x69, 0x40, 0x7d, 0x71, 0xf5, 0xf3, 0xcd, 0xa1, 0x52, 0xa7, - 0xe3, 0x1b, 0xff, 0x69, 0x16, 0x46, 0x4b, 0xdb, 0xb5, 0x6a, 0x7b, 0xd7, 0xc5, 0x87, 0xd9, 0xf0, - 0x3d, 0x4e, 0x7d, 0x98, 0x0d, 0xdf, 0xe3, 0xd4, 0x57, 0xb8, 0xeb, 0x29, 0x97, 0x77, 0xb4, 0xdd, - 0x56, 0x2e, 0xef, 0x9a, 0xda, 0x21, 0x7a, 0x9a, 0xcc, 0x0d, 0xf0, 0x34, 0x19, 0x6a, 0x8f, 0x87, - 0x4e, 0xd6, 0x1e, 0xbf, 0x03, 0xe3, 0xd5, 0x76, 0x40, 0xf7, 0xbc, 0x68, 0xd5, 0x84, 0x8a, 0x84, - 0x10, 0xac, 0x5e, 0xe8, 0x14, 0x6c, 0x36, 0x25, 0xb9, 0xc6, 0x3a, 0xd4, 0x54, 0xe3, 0x94, 0xe4, - 0x8a, 0xed, 0x98, 0x16, 0x48, 0x22, 0x1a, 0x95, 0xd8, 0x7c, 0x93, 0xe6, 0x1f, 0x5c, 0x84, 0x9a, - 0x8a, 0x9e, 0x6c, 0x58, 0xc7, 0x2e, 0xcd, 0xa4, 0x9b, 0x7f, 0x18, 0x7f, 0x2b, 0x03, 0x73, 0x69, - 0xd3, 0x88, 0xbc, 0x0f, 0x13, 0xae, 0xb7, 0x67, 0xb7, 0x9d, 0xef, 0xe5, 0x2d, 0x52, 0x54, 0x95, - 0x2a, 0x5c, 0x55, 0xd0, 0xa8, 0x70, 0xd6, 0x21, 0x4a, 0xcb, 0x75, 0xcd, 0x4a, 0x6a, 0x87, 0x28, - 0x60, 0xe3, 0x47, 0xb3, 0x30, 0x5e, 0xea, 0x74, 0x9e, 0x71, 0xd3, 0xc0, 0xcf, 0x6b, 0x07, 0x88, - 0xbc, 0x97, 0x87, 0xed, 0x1a, 0xc8, 0x2a, 0xf0, 0x57, 0xb3, 0x30, 0x1d, 0xa3, 0x50, 0xbf, 0x3e, - 0x33, 0xa0, 0x41, 0x60, 0x76, 0x40, 0x83, 0xc0, 0xdc, 0x60, 0x06, 0x81, 0x43, 0x4f, 0x72, 0x28, - 0xbc, 0x0a, 0xb9, 0x52, 0xa7, 0x13, 0x37, 0x2c, 0xe8, 0x74, 0x1e, 0xdc, 0xe4, 0xba, 0x15, 0xbb, - 0xd3, 0x31, 0x19, 0x86, 0xb6, 0x53, 0x8f, 0x0c, 0xb8, 0x53, 0x1b, 0x6f, 0xc2, 0x18, 0xf2, 0x42, - 0x33, 0xbc, 0x4b, 0x80, 0x5b, 0x8c, 0xb0, 0xc0, 0xd3, 0xea, 0x12, 0x9b, 0xcf, 0xbf, 0xcc, 0xc0, - 0x30, 0xfe, 0x7e, 0x46, 0xe7, 0xd8, 0xa2, 0x36, 0xc7, 0x0a, 0xca, 0x1c, 0x1b, 0x64, 0x76, 0xfd, - 0x83, 0x1c, 0x40, 0xf9, 0xbe, 0x59, 0xe3, 0x2a, 0x38, 0x72, 0x1b, 0xa6, 0xed, 0x66, 0xd3, 0x7d, - 0x44, 0x1b, 0x96, 0xeb, 0x39, 0x7b, 0x4e, 0x9b, 0xf7, 0x9c, 0x7c, 0xed, 0xd6, 0x8b, 0xd4, 0x37, - 0x30, 0x51, 0x74, 0x9f, 0x97, 0xa8, 0x7c, 0x5a, 0x34, 0xd8, 0x77, 0x1b, 0x52, 0x99, 0xa0, 0xf1, - 0x11, 0x45, 0x29, 0x7c, 0xd6, 0x78, 0x89, 0xca, 0x67, 0x1f, 0x95, 0x23, 0x52, 0x42, 0xd6, 0xf8, - 0x88, 0xa2, 0x14, 0x3e, 0x5c, 0xa3, 0xe2, 0x93, 0x55, 0x98, 0x41, 0x88, 0x55, 0xf7, 0x68, 0x83, - 0xb6, 0x03, 0xc7, 0x6e, 0xfa, 0x42, 0xfd, 0x84, 0x8a, 0xca, 0x44, 0xa1, 0x7a, 0xfd, 0xc6, 0xc2, - 0x72, 0x54, 0x46, 0xae, 0xc1, 0x68, 0xcb, 0x7e, 0x6c, 0xd9, 0x7b, 0xdc, 0xee, 0x63, 0x92, 0xab, - 0x2b, 0x04, 0x48, 0x3d, 0x46, 0x5a, 0xf6, 0xe3, 0xd2, 0x1e, 0x65, 0xad, 0xa0, 0x8f, 0x3b, 0xae, - 0xaf, 0xb4, 0x62, 0x24, 0x6a, 0x45, 0xac, 0x48, 0x6d, 0x85, 0x28, 0x12, 0xad, 0x30, 0x3e, 0x82, - 0xe7, 0xab, 0xf8, 0x11, 0xc1, 0x61, 0x99, 0xb6, 0x03, 0xea, 0x6d, 0x50, 0xaf, 0xe5, 0xe0, 0x23, - 0x78, 0x8d, 0x06, 0xe4, 0x25, 0xc8, 0x95, 0xcc, 0x75, 0x31, 0x7d, 0xf9, 0x76, 0xaf, 0x99, 0x24, - 0xb0, 0xd2, 0x50, 0xa1, 0x95, 0x3d, 0x41, 0xa1, 0xf5, 0x9f, 0x65, 0x60, 0xa6, 0xd4, 0xe9, 0xe8, - 0xf5, 0xe9, 0xd6, 0x32, 0x99, 0xc1, 0xad, 0x65, 0x1c, 0x98, 0xd2, 0xbe, 0x95, 0x4f, 0x87, 0x48, - 0x68, 0xed, 0xd3, 0x2c, 0xde, 0x49, 0x9d, 0x10, 0x64, 0xf9, 0xfa, 0x53, 0x6f, 0x8c, 0xb1, 0xf1, - 0xef, 0x8d, 0xe2, 0xfa, 0x17, 0x3b, 0xa5, 0xb0, 0xe7, 0xcc, 0xa4, 0xd8, 0x73, 0xbe, 0x0d, 0x8a, - 0x74, 0xa2, 0x1e, 0x4f, 0x8a, 0x9c, 0xa7, 0xea, 0x71, 0x22, 0x64, 0x72, 0x10, 0xb7, 0xec, 0xcc, - 0x61, 0x6b, 0x5e, 0x8a, 0x2f, 0xbe, 0xa7, 0x62, 0xd4, 0xb9, 0x02, 0xa4, 0xda, 0xc6, 0xe7, 0x67, - 0x5a, 0x3b, 0x70, 0x3a, 0x0f, 0xa8, 0xe7, 0xec, 0x1e, 0x8a, 0xc9, 0x8b, 0x9d, 0xef, 0x88, 0x52, - 0xcb, 0x3f, 0x70, 0x3a, 0xd6, 0x43, 0x2c, 0x37, 0x53, 0x68, 0xc8, 0x07, 0x30, 0x6a, 0xd2, 0x47, - 0x9e, 0x13, 0x48, 0x7b, 0xa5, 0xa9, 0x50, 0x2d, 0x89, 0x50, 0x3e, 0x8f, 0x3d, 0xfe, 0x43, 0xdd, - 0xd1, 0x44, 0x39, 0x59, 0xe4, 0x02, 0x06, 0xb7, 0x4b, 0x9a, 0x8c, 0x5a, 0x5b, 0xda, 0xae, 0xf5, - 0x92, 0x2f, 0xc8, 0x55, 0x18, 0x46, 0x29, 0x45, 0xc8, 0xf1, 0xe8, 0xe7, 0x83, 0x72, 0xaf, 0x2a, - 0x42, 0x21, 0x06, 0xb9, 0x08, 0x10, 0xbe, 0xef, 0xfa, 0xf3, 0x79, 0x94, 0xb0, 0x15, 0x48, 0x5c, - 0xc4, 0x1a, 0x3b, 0x95, 0x88, 0xb5, 0x0a, 0x05, 0x93, 0xbb, 0x0c, 0x36, 0x4a, 0x1d, 0x7c, 0x44, - 0xf4, 0xe7, 0x01, 0x57, 0xe1, 0xa5, 0xe3, 0xa3, 0xe2, 0x0b, 0xc2, 0x9d, 0xb0, 0x61, 0xd9, 0x1d, - 0xfe, 0xf6, 0xa8, 0x6d, 0x01, 0x71, 0x4a, 0xf2, 0x36, 0x0c, 0xb1, 0x6d, 0x53, 0xd8, 0x80, 0xca, - 0xc7, 0x98, 0x68, 0x27, 0xe5, 0x2b, 0xab, 0xee, 0x6a, 0xeb, 0x19, 0x49, 0x88, 0x05, 0x53, 0xfa, - 0x74, 0x17, 0xe6, 0x40, 0xf3, 0x51, 0x7f, 0xea, 0xe5, 0xe2, 0x85, 0x46, 0xc0, 0xac, 0x3a, 0x02, - 0xd5, 0x15, 0x10, 0x5b, 0xa4, 0xcb, 0x90, 0xdf, 0x2c, 0x6f, 0x6c, 0xb8, 0x5e, 0xc0, 0xaf, 0x29, - 0xd1, 0xa9, 0xc0, 0x60, 0xa6, 0xdd, 0xde, 0xa3, 0xfc, 0x1c, 0x0d, 0xea, 0x1d, 0xab, 0xc3, 0xd0, - 0xd4, 0x73, 0x54, 0x92, 0x7e, 0x72, 0xf6, 0x9f, 0xbf, 0x9a, 0x85, 0x97, 0x42, 0x89, 0xe6, 0xbe, - 0x57, 0x2b, 0xad, 0xad, 0x56, 0x1b, 0x1b, 0x42, 0xc5, 0xb1, 0xe1, 0xb9, 0x0f, 0x9d, 0x06, 0xf5, - 0x1e, 0xdc, 0x38, 0xe1, 0x3c, 0x5e, 0xe5, 0xcb, 0x9c, 0xbf, 0x64, 0x65, 0x35, 0x4b, 0x39, 0x45, - 0x70, 0x14, 0xdb, 0x53, 0xa7, 0x93, 0x78, 0xd8, 0x5a, 0x79, 0xce, 0x8c, 0x18, 0x90, 0x1f, 0xcc, - 0xc0, 0xd9, 0xf4, 0x0f, 0x11, 0x6a, 0xaf, 0xa2, 0xbc, 0x5e, 0xf7, 0xf8, 0xda, 0xa5, 0x57, 0x8f, - 0x8f, 0x8a, 0x2f, 0xf9, 0x76, 0xab, 0x69, 0x39, 0x0d, 0x5e, 0x9b, 0x53, 0xa7, 0x56, 0x47, 0x20, - 0x68, 0xf5, 0xf6, 0xa8, 0xe9, 0x0b, 0x20, 0x8f, 0xe5, 0xf9, 0xcc, 0x12, 0x40, 0x5e, 0x3e, 0x16, - 0x18, 0xbf, 0x91, 0x01, 0x65, 0x09, 0xe6, 0x4d, 0xda, 0x70, 0x3c, 0x5a, 0x0f, 0xc4, 0xd1, 0x2c, - 0xfc, 0xfc, 0x38, 0x2c, 0x66, 0x18, 0x89, 0x30, 0xf2, 0x3e, 0x8c, 0x8a, 0x23, 0x44, 0x6c, 0xbb, - 0x72, 0xe9, 0x8a, 0x67, 0x08, 0xee, 0x10, 0x9a, 0x38, 0x7e, 0x24, 0x11, 0xdb, 0xf5, 0xef, 0x6e, - 0x6f, 0x96, 0x9b, 0xb6, 0xd3, 0xf2, 0x85, 0x28, 0x83, 0xdd, 0xfa, 0xd1, 0xa3, 0xc0, 0xaa, 0x23, - 0x54, 0xdd, 0xf5, 0x43, 0x54, 0xe3, 0x8e, 0x7c, 0x05, 0x39, 0xc1, 0xba, 0xb7, 0x08, 0xc3, 0x0f, - 0x22, 0x1d, 0xdb, 0xd2, 0xd8, 0xf1, 0x51, 0x91, 0x4f, 0x17, 0x93, 0xc3, 0x8d, 0xaf, 0xc0, 0x58, - 0x38, 0x75, 0x19, 0x2f, 0xf6, 0x03, 0x79, 0x4d, 0x72, 0x5e, 0x6c, 0x12, 0x9b, 0x08, 0x65, 0x62, - 0xda, 0x72, 0xbb, 0x81, 0x08, 0x59, 0x44, 0xc0, 0xee, 0xa1, 0xed, 0x06, 0xce, 0x74, 0xb5, 0x75, - 0x02, 0xcd, 0xf8, 0xf1, 0x0c, 0x4c, 0xe9, 0x93, 0x95, 0x5c, 0x83, 0x11, 0xe1, 0xc0, 0x97, 0x41, - 0x45, 0x25, 0xe3, 0x31, 0xc2, 0x5d, 0xf7, 0x34, 0x87, 0x3d, 0x81, 0xc5, 0x24, 0x3d, 0xc1, 0x41, - 0x88, 0x39, 0x28, 0xe9, 0xd5, 0x39, 0xc8, 0x94, 0x65, 0xc4, 0x60, 0x97, 0x4f, 0xbf, 0xdb, 0x0c, - 0xd4, 0x97, 0x46, 0x0f, 0x21, 0xa6, 0x28, 0x31, 0xca, 0x30, 0xc2, 0x37, 0xd4, 0x98, 0xc9, 0x62, - 0xe6, 0x14, 0x26, 0x8b, 0xc6, 0x51, 0x06, 0xa0, 0x56, 0x5b, 0xb9, 0x47, 0x0f, 0x37, 0x6c, 0x07, - 0x4f, 0x6d, 0x7e, 0x78, 0xdd, 0x13, 0x2b, 0x77, 0x42, 0x3c, 0x8d, 0xf3, 0x83, 0xee, 0x80, 0x1e, - 0x6a, 0x4f, 0xe3, 0x12, 0x15, 0x4f, 0x48, 0xcf, 0x79, 0x68, 0x07, 0x94, 0x11, 0x66, 0x91, 0x90, - 0x9f, 0x90, 0x1c, 0x1a, 0xa3, 0x54, 0x90, 0xc9, 0xd7, 0x60, 0x2a, 0xfa, 0x15, 0x3e, 0xf0, 0x4f, - 0x85, 0xbb, 0x83, 0x5e, 0xb8, 0x74, 0xf1, 0xf8, 0xa8, 0xb8, 0xa0, 0x70, 0x8d, 0x3f, 0xfd, 0xc7, - 0x98, 0x19, 0xbf, 0x9c, 0x41, 0xb3, 0x16, 0xd9, 0xc0, 0xcb, 0x30, 0x14, 0x1a, 0x62, 0x4f, 0x88, - 0xad, 0x57, 0x7f, 0xc4, 0xc4, 0x72, 0x26, 0x21, 0x45, 0x2d, 0xc1, 0x03, 0x4b, 0x6f, 0x01, 0x2b, - 0x25, 0x77, 0x60, 0x74, 0xa0, 0x6f, 0xc6, 0x89, 0x95, 0xf2, 0xad, 0x92, 0x1a, 0x47, 0xe1, 0xee, - 0xf6, 0xe6, 0xa7, 0x77, 0x14, 0x7e, 0x2a, 0x0b, 0xd3, 0xac, 0x5f, 0x4b, 0xdd, 0x60, 0xdf, 0xf5, - 0x9c, 0xe0, 0xf0, 0x99, 0xd5, 0xf4, 0xbe, 0xab, 0x5d, 0xa2, 0x16, 0xe4, 0x11, 0xa6, 0xb6, 0x6d, - 0x20, 0x85, 0xef, 0x7f, 0x3f, 0x0c, 0xb3, 0x29, 0x54, 0xe4, 0x0d, 0xed, 0x31, 0x66, 0x5e, 0x3a, - 0xe8, 0x7f, 0xf7, 0xa8, 0x38, 0x21, 0xd1, 0x37, 0x23, 0x87, 0xfd, 0x45, 0xdd, 0x46, 0x8c, 0xf7, - 0x14, 0xbe, 0xcd, 0xa8, 0x36, 0x62, 0xba, 0x65, 0xd8, 0x55, 0x18, 0x36, 0xdd, 0x26, 0x95, 0x76, - 0x91, 0x28, 0x66, 0x79, 0x0c, 0xa0, 0xd9, 0x81, 0x30, 0x00, 0x59, 0x81, 0x51, 0xf6, 0xc7, 0x9a, - 0xdd, 0x11, 0x2f, 0x9c, 0x24, 0xbc, 0xc6, 0x23, 0xb4, 0xe3, 0xb4, 0xf7, 0xd4, 0x9b, 0x7c, 0x93, - 0x5a, 0x2d, 0xbb, 0xa3, 0xc9, 0x83, 0x1c, 0x51, 0xd3, 0x08, 0xe4, 0x7b, 0x6b, 0x04, 0x32, 0x27, - 0x6a, 0x04, 0x76, 0x01, 0x6a, 0xce, 0x5e, 0xdb, 0x69, 0xef, 0x95, 0x9a, 0x7b, 0x22, 0xcc, 0xc1, - 0xd5, 0xde, 0xa3, 0x70, 0x2d, 0x42, 0xc6, 0x89, 0xfb, 0x3c, 0x9a, 0x21, 0x70, 0x98, 0x65, 0x37, - 0xf7, 0x34, 0x77, 0x2c, 0x85, 0x33, 0x59, 0x07, 0x28, 0xd5, 0x03, 0xe7, 0x21, 0x9b, 0xc2, 0xbe, - 0x10, 0xde, 0xe4, 0x27, 0x97, 0x4b, 0xf7, 0xe8, 0x21, 0x5e, 0x38, 0xe4, 0x83, 0xae, 0x8d, 0xa8, - 0x6c, 0x25, 0x68, 0xbe, 0x36, 0x11, 0x07, 0xd2, 0x81, 0x33, 0xa5, 0x46, 0xc3, 0x61, 0x6d, 0xb0, - 0x9b, 0x9b, 0x3c, 0x40, 0x05, 0xb2, 0x9e, 0x48, 0x67, 0x7d, 0x55, 0xbe, 0x5d, 0xda, 0x21, 0x95, - 0x25, 0xe3, 0x5a, 0xc4, 0xaa, 0x49, 0x67, 0x6c, 0xd4, 0x60, 0x4a, 0x6f, 0xbc, 0x1e, 0x9e, 0x61, - 0x02, 0xf2, 0x66, 0xad, 0x64, 0xd5, 0x56, 0x4a, 0x37, 0x0a, 0x19, 0x52, 0x80, 0x09, 0xf1, 0x6b, - 0xd1, 0x5a, 0x7c, 0xeb, 0x56, 0x21, 0xab, 0x41, 0xde, 0xba, 0xb1, 0x58, 0xc8, 0x2d, 0x64, 0xe7, - 0x33, 0x31, 0xcf, 0xc8, 0xd1, 0x42, 0x9e, 0x2b, 0x71, 0x8d, 0x5f, 0xcb, 0x40, 0x5e, 0x7e, 0x3b, - 0xb9, 0x05, 0xb9, 0x5a, 0x6d, 0x25, 0xe6, 0xcb, 0x18, 0x9d, 0x32, 0x7c, 0x3f, 0xf5, 0x7d, 0xd5, - 0x60, 0x9d, 0x11, 0x30, 0xba, 0xcd, 0xd5, 0x9a, 0x90, 0x3c, 0x24, 0x5d, 0xb4, 0x79, 0x73, 0xba, - 0x14, 0x07, 0xaf, 0x5b, 0x90, 0xbb, 0xbb, 0xbd, 0x29, 0xae, 0x56, 0x92, 0x2e, 0xda, 0x4f, 0x39, - 0xdd, 0x47, 0x8f, 0xd4, 0x5d, 0x9e, 0x11, 0x18, 0x26, 0x8c, 0x2b, 0x13, 0x99, 0x1f, 0xba, 0x2d, - 0x37, 0x8c, 0x49, 0x20, 0x0e, 0x5d, 0x06, 0x31, 0x45, 0x09, 0x13, 0x40, 0x56, 0xdd, 0xba, 0xdd, - 0x14, 0xa7, 0x37, 0x0a, 0x20, 0x4d, 0x06, 0x30, 0x39, 0xdc, 0xf8, 0x9d, 0x0c, 0x14, 0x50, 0x4c, - 0x43, 0x83, 0x73, 0xf7, 0x80, 0xb6, 0x1f, 0xdc, 0x20, 0x6f, 0xca, 0x25, 0x97, 0x09, 0x55, 0x53, - 0xc3, 0xb8, 0xe4, 0x62, 0xaf, 0x77, 0x62, 0xd9, 0x29, 0x61, 0x1f, 0xb2, 0x83, 0xbb, 0x8b, 0x9f, - 0x10, 0xf6, 0xa1, 0x08, 0xc3, 0xf8, 0x39, 0x62, 0x73, 0xc4, 0x2f, 0x0f, 0x18, 0xc0, 0xe4, 0x70, - 0x65, 0x6f, 0xfa, 0x99, 0x6c, 0xa2, 0x0d, 0x8b, 0x9f, 0x2a, 0x97, 0x6b, 0xbd, 0x71, 0x03, 0xed, - 0xd7, 0x1f, 0xc2, 0x5c, 0xbc, 0x4b, 0x50, 0x6d, 0x58, 0x82, 0x69, 0x1d, 0x2e, 0x35, 0x88, 0xe7, - 0x52, 0xeb, 0x7a, 0xb0, 0x68, 0xc6, 0xf1, 0x8d, 0xff, 0x23, 0x03, 0x63, 0xf8, 0xa7, 0xd9, 0x6d, - 0xa2, 0xe1, 0x5f, 0x69, 0xbb, 0x26, 0x14, 0x22, 0xaa, 0x30, 0x67, 0x3f, 0xf2, 0x2d, 0xa1, 0x3d, - 0xd1, 0xf6, 0x98, 0x10, 0x59, 0x90, 0xf2, 0x17, 0x09, 0xa9, 0x46, 0x0b, 0x49, 0xf9, 0xd3, 0x85, - 0x1f, 0x23, 0x15, 0xc8, 0x68, 0x2e, 0xbc, 0x5d, 0x63, 0xd3, 0x4f, 0xb5, 0xc4, 0x41, 0x3a, 0xb7, - 0xa9, 0x9b, 0x0b, 0x73, 0x34, 0x34, 0xc4, 0xd9, 0xae, 0x95, 0xcc, 0x75, 0xcd, 0x10, 0x87, 0x7d, - 0xa3, 0xa6, 0x4a, 0x12, 0x48, 0xc6, 0x2f, 0x8c, 0xc7, 0x3b, 0x50, 0x1c, 0x78, 0xa7, 0x5c, 0x1b, - 0xef, 0xc0, 0x70, 0xa9, 0xd9, 0x74, 0x1f, 0x89, 0x5d, 0x42, 0xde, 0x57, 0xc3, 0xfe, 0xe3, 0xe7, - 0x19, 0x2a, 0xe2, 0x34, 0x37, 0x52, 0x06, 0x20, 0x65, 0x18, 0x2b, 0x6d, 0xd7, 0xaa, 0xd5, 0xca, - 0xe6, 0x26, 0x77, 0x99, 0xcb, 0x2d, 0xbd, 0x22, 0xfb, 0xc7, 0x71, 0x1a, 0x56, 0xdc, 0xc2, 0x20, - 0x92, 0xdf, 0x23, 0x3a, 0xf2, 0x1e, 0xc0, 0x5d, 0xd7, 0x69, 0x73, 0xc5, 0xa3, 0x68, 0x3c, 0xbb, - 0x77, 0x8f, 0x7f, 0xe4, 0x3a, 0x6d, 0xa1, 0xa9, 0x64, 0xdf, 0x1e, 0x21, 0x99, 0xca, 0xdf, 0xac, - 0xa7, 0x97, 0x5c, 0x6e, 0xcc, 0x37, 0x1c, 0xf5, 0xf4, 0x8e, 0x9b, 0xb0, 0xe3, 0x93, 0x68, 0xa4, - 0x05, 0xd3, 0xb5, 0xee, 0xde, 0x1e, 0x65, 0x3b, 0xbb, 0xd0, 0x22, 0x8d, 0x88, 0x0b, 0x74, 0x18, - 0xa8, 0x88, 0xdf, 0x47, 0xd8, 0x15, 0xc8, 0x5f, 0x7a, 0x83, 0x4d, 0xe4, 0xef, 0x1c, 0x15, 0x85, - 0xe5, 0x02, 0x13, 0xd5, 0x7c, 0x49, 0x9f, 0xd4, 0x21, 0xc5, 0x79, 0x93, 0xfb, 0x30, 0xc2, 0x5f, - 0x79, 0x84, 0x0b, 0xd8, 0x8b, 0x7d, 0x16, 0x0d, 0x47, 0xec, 0xf5, 0x8e, 0xc8, 0x4b, 0xc9, 0x36, - 0xe4, 0xcb, 0x8e, 0x57, 0x6f, 0xd2, 0x72, 0x55, 0x9c, 0xfd, 0x2f, 0xf5, 0x61, 0x29, 0x51, 0x79, - 0xbf, 0xd4, 0xf1, 0x57, 0xdd, 0x51, 0x65, 0x01, 0x89, 0x41, 0xfe, 0x56, 0x06, 0x9e, 0x0f, 0xbf, - 0xbe, 0xb4, 0x47, 0xdb, 0xc1, 0x9a, 0x1d, 0xd4, 0xf7, 0xa9, 0x27, 0x7a, 0x69, 0xac, 0x5f, 0x2f, - 0x7d, 0x21, 0xd1, 0x4b, 0x57, 0xa2, 0x5e, 0xb2, 0x19, 0x33, 0xab, 0xc5, 0xb9, 0x25, 0xfb, 0xac, - 0x5f, 0xad, 0xc4, 0x02, 0x88, 0xde, 0x2f, 0x85, 0x0b, 0xf1, 0x2b, 0x7d, 0x1a, 0x1c, 0x21, 0x0b, - 0xd7, 0x9f, 0xf0, 0xb7, 0x66, 0xbb, 0x1a, 0x42, 0xc9, 0x3d, 0xe9, 0x6f, 0xc9, 0xa5, 0x92, 0x4b, - 0x7d, 0x78, 0x73, 0x1f, 0xcc, 0xd9, 0x3e, 0x9e, 0xd5, 0x7c, 0xb4, 0x57, 0xed, 0x1d, 0x21, 0x88, - 0x9c, 0x30, 0xda, 0xab, 0x76, 0x34, 0xda, 0x4d, 0x3b, 0x3e, 0xda, 0xab, 0xf6, 0x0e, 0x29, 0x73, - 0x27, 0x71, 0xee, 0x51, 0x7c, 0xb1, 0x1f, 0xb7, 0xf2, 0x06, 0x3f, 0x99, 0x53, 0x9c, 0xc5, 0xbf, - 0x02, 0x63, 0xb5, 0x8e, 0x5d, 0xa7, 0x4d, 0x67, 0x37, 0x10, 0x8f, 0xe3, 0x2f, 0xf7, 0x61, 0x15, - 0xe2, 0x8a, 0xc7, 0x50, 0xf9, 0x53, 0xbd, 0x26, 0x85, 0x38, 0xec, 0x0b, 0x37, 0x37, 0xd6, 0xc4, - 0xfb, 0x78, 0xbf, 0x2f, 0xdc, 0xdc, 0x58, 0x13, 0x32, 0x47, 0xa7, 0xa5, 0xc9, 0x1c, 0x1b, 0x6b, - 0xa4, 0x03, 0x53, 0x9b, 0xd4, 0xf3, 0xec, 0x5d, 0xd7, 0x6b, 0x71, 0xad, 0x25, 0xf7, 0x52, 0xbb, - 0xda, 0x8f, 0x9f, 0x46, 0xc0, 0x95, 0x75, 0x81, 0x84, 0x59, 0x71, 0x55, 0x67, 0x8c, 0x3f, 0xeb, - 0x93, 0x25, 0x27, 0xd8, 0xe9, 0xd6, 0x0f, 0x68, 0x30, 0x3f, 0x73, 0x62, 0x9f, 0x84, 0xb8, 0xbc, - 0x4f, 0x76, 0xe4, 0x4f, 0xb5, 0x4f, 0x42, 0x1c, 0xe3, 0x37, 0x73, 0x70, 0xae, 0x47, 0x17, 0x90, - 0x75, 0xb9, 0xe5, 0x66, 0x34, 0xdd, 0x75, 0x0f, 0xf4, 0x6b, 0x27, 0xee, 0xc2, 0xab, 0x50, 0x58, - 0xbe, 0x87, 0xb2, 0x3a, 0x7f, 0x7a, 0x29, 0x97, 0xe4, 0x61, 0x85, 0xfa, 0x55, 0x7a, 0x80, 0x56, - 0xbd, 0xf2, 0xc9, 0xa6, 0xae, 0xb9, 0xaf, 0x27, 0x28, 0x17, 0x7e, 0x20, 0x0b, 0x43, 0x78, 0x70, - 0xc6, 0x82, 0x76, 0x65, 0x4e, 0x15, 0xb4, 0xeb, 0x8b, 0x30, 0xb1, 0x7c, 0x8f, 0xdf, 0xa4, 0x57, - 0x6c, 0x7f, 0x5f, 0x6c, 0xeb, 0x68, 0x7a, 0x41, 0x0f, 0x2c, 0x71, 0xf1, 0xde, 0xb7, 0x35, 0x99, - 0x55, 0xa3, 0x20, 0x5b, 0x30, 0xcb, 0xbf, 0xcd, 0xd9, 0x75, 0xea, 0x3c, 0xf6, 0x8f, 0x63, 0x37, - 0xc5, 0x1e, 0xff, 0xd2, 0xf1, 0x51, 0xb1, 0x48, 0x0f, 0xd0, 0x5e, 0x59, 0x94, 0x5b, 0x3e, 0x22, - 0xa8, 0x86, 0xcb, 0x29, 0xf4, 0x6a, 0x40, 0x12, 0x73, 0x0c, 0x2b, 0x64, 0xb5, 0xb1, 0xba, 0x19, - 0x2e, 0x47, 0x32, 0xfe, 0x74, 0x18, 0x16, 0x7a, 0x6f, 0xcf, 0xe4, 0x4b, 0xfa, 0x00, 0x5e, 0x3e, - 0x71, 0x43, 0x3f, 0x79, 0x0c, 0xbf, 0x0c, 0x73, 0xcb, 0xed, 0x80, 0x7a, 0x1d, 0xcf, 0x91, 0x21, - 0x68, 0x56, 0x5c, 0x5f, 0xda, 0x87, 0xa3, 0xa1, 0x36, 0x0d, 0xcb, 0x85, 0x46, 0x15, 0xad, 0xd5, - 0x15, 0x56, 0xa9, 0x1c, 0xc8, 0x32, 0x4c, 0x29, 0xf0, 0x66, 0x77, 0x4f, 0x08, 0x24, 0xfc, 0x05, - 0x4c, 0xe1, 0xd9, 0xec, 0xaa, 0xc6, 0xb3, 0x31, 0x22, 0xb4, 0x41, 0x67, 0x57, 0xc6, 0xfa, 0xdd, - 0xed, 0x7b, 0x35, 0x31, 0x9c, 0xdc, 0x06, 0x1d, 0xa1, 0xd6, 0x47, 0x8f, 0x0e, 0xb4, 0xfd, 0x35, - 0x42, 0x5e, 0xf8, 0xe5, 0x9c, 0x98, 0x51, 0x2f, 0x41, 0xae, 0xd6, 0xdd, 0x51, 0x9f, 0xc9, 0x7c, - 0xed, 0x80, 0x63, 0xa5, 0xe4, 0xf3, 0x00, 0x26, 0xed, 0xb8, 0xbe, 0x13, 0xb8, 0xde, 0xa1, 0xea, - 0x04, 0xe9, 0x85, 0x50, 0xdd, 0x4f, 0x43, 0x42, 0xc9, 0x0a, 0x4c, 0x47, 0xbf, 0xee, 0x3f, 0x6a, - 0x0b, 0x0d, 0xf2, 0x18, 0xd7, 0xae, 0x44, 0xe4, 0x96, 0xcb, 0xca, 0xd4, 0x23, 0x3b, 0x46, 0x46, - 0x16, 0x21, 0xbf, 0xed, 0x7a, 0x07, 0xbb, 0x6c, 0x8c, 0x87, 0x22, 0xa1, 0xe2, 0x91, 0x80, 0xa9, - 0x87, 0xa7, 0xc4, 0x63, 0xcb, 0x65, 0xb9, 0xfd, 0xd0, 0xf1, 0xdc, 0x36, 0xda, 0xed, 0x2a, 0x56, - 0x28, 0x34, 0x02, 0x6b, 0xee, 0xe7, 0x11, 0x98, 0x5c, 0x85, 0xe1, 0x52, 0x3d, 0x70, 0x3d, 0x61, - 0x82, 0xc2, 0x67, 0x0a, 0x03, 0x68, 0x33, 0x85, 0x01, 0x58, 0x27, 0x9a, 0x74, 0x57, 0xbc, 0xe9, - 0x60, 0x27, 0x7a, 0x74, 0x57, 0xf3, 0xad, 0xa7, 0xbb, 0x4c, 0x28, 0x32, 0xe9, 0x2e, 0x2a, 0x3e, - 0xb4, 0x90, 0x74, 0xbb, 0x09, 0x95, 0x99, 0x40, 0x33, 0x7e, 0x6f, 0xac, 0xe7, 0x94, 0x67, 0xa7, - 0xd0, 0xe9, 0xa6, 0xfc, 0xaa, 0x3d, 0xc0, 0x94, 0x7f, 0x23, 0xf4, 0xfe, 0x50, 0x03, 0x4a, 0x20, - 0x44, 0x3d, 0x06, 0x39, 0xce, 0xc2, 0xaf, 0xe4, 0x4f, 0x33, 0x89, 0x44, 0x27, 0x65, 0x07, 0xed, - 0xa4, 0xdc, 0x40, 0x9d, 0x44, 0x96, 0x60, 0x32, 0x0c, 0x6a, 0xb8, 0x61, 0x07, 0xda, 0xb6, 0x16, - 0x46, 0xa2, 0xb4, 0x3a, 0x76, 0xa0, 0x6e, 0x6b, 0x3a, 0x09, 0x79, 0x17, 0xc6, 0x85, 0x0b, 0x14, - 0x72, 0x18, 0x8e, 0x6c, 0x7b, 0xa4, 0xbf, 0x54, 0x8c, 0x5e, 0x45, 0x67, 0xab, 0x79, 0xc3, 0xe9, - 0xd0, 0xa6, 0xd3, 0xa6, 0x35, 0x7c, 0xa2, 0x10, 0x33, 0x86, 0x3f, 0xd5, 0x8a, 0x12, 0x8b, 0xbf, - 0x5e, 0x68, 0xfa, 0x43, 0x8d, 0x28, 0x3e, 0x59, 0x47, 0x4f, 0x35, 0x59, 0xb9, 0x65, 0xa1, 0xb7, - 0xea, 0xee, 0x39, 0xd2, 0xea, 0x5d, 0x5a, 0x16, 0x7a, 0x56, 0x93, 0x41, 0x63, 0x96, 0x85, 0x1c, - 0x95, 0xdd, 0x70, 0xd8, 0x8f, 0x6a, 0x45, 0xbc, 0x1f, 0xe2, 0x0d, 0x07, 0x89, 0x74, 0x57, 0x03, - 0x8e, 0x24, 0xab, 0x59, 0x6e, 0xd9, 0x4e, 0x53, 0xc4, 0x0d, 0x88, 0xaa, 0xa1, 0x0c, 0x1a, 0xaf, - 0x06, 0x51, 0x49, 0x1d, 0x26, 0x4c, 0xba, 0xbb, 0xe1, 0xb9, 0x01, 0xad, 0x07, 0xb4, 0x21, 0xa4, - 0x3a, 0x79, 0xb1, 0x59, 0x72, 0x5d, 0x2e, 0xb1, 0xa2, 0x35, 0x7b, 0xe6, 0x3b, 0x47, 0x45, 0x60, - 0x20, 0xee, 0xc7, 0x72, 0x7c, 0x54, 0x3c, 0xc7, 0xc6, 0xbf, 0x23, 0x89, 0xd5, 0xd3, 0x49, 0x65, - 0x4a, 0xbe, 0xc5, 0xf6, 0xeb, 0xb0, 0x4b, 0xa2, 0xca, 0x26, 0x7a, 0x54, 0xf6, 0x56, 0x6a, 0x65, - 0x45, 0xa5, 0xb7, 0x53, 0x2b, 0x4d, 0xad, 0x84, 0xbc, 0x07, 0xe3, 0xe5, 0x6a, 0xd9, 0x6d, 0xef, - 0x3a, 0x7b, 0xb5, 0x95, 0x12, 0x8a, 0x86, 0xc2, 0x87, 0xa9, 0xee, 0x58, 0x75, 0x84, 0x5b, 0xfe, - 0xbe, 0xad, 0xb9, 0xb2, 0x46, 0xf8, 0xe4, 0x0e, 0x4c, 0xc9, 0x9f, 0x26, 0xdd, 0xdd, 0x32, 0xab, - 0x28, 0x11, 0x4a, 0xc7, 0xb1, 0x90, 0x03, 0xeb, 0x88, 0xae, 0xa7, 0xde, 0x14, 0x62, 0x64, 0x6c, - 0x32, 0x56, 0x68, 0xa7, 0xe9, 0x1e, 0xb2, 0xcf, 0xdb, 0x74, 0xa8, 0x87, 0x32, 0xa0, 0x98, 0x8c, - 0x8d, 0xb0, 0xc4, 0x0a, 0x1c, 0xfd, 0xd5, 0x54, 0x27, 0x22, 0xeb, 0x30, 0x23, 0xa6, 0xf8, 0x03, - 0xc7, 0x77, 0x76, 0x9c, 0xa6, 0x13, 0x1c, 0xa2, 0xf4, 0x27, 0x04, 0x18, 0xb9, 0x2e, 0x1e, 0x86, - 0xa5, 0x0a, 0xb3, 0x24, 0xa9, 0xf1, 0x6b, 0x59, 0x78, 0xa1, 0xdf, 0x4d, 0x88, 0xd4, 0xf4, 0xcd, - 0xec, 0xca, 0x00, 0xb7, 0xa7, 0x93, 0xb7, 0xb3, 0x65, 0x98, 0xba, 0xaf, 0x18, 0xe1, 0x85, 0x46, - 0x91, 0xd8, 0x19, 0xaa, 0x79, 0x9e, 0x3e, 0xdb, 0x63, 0x44, 0x0b, 0x0f, 0xc5, 0x36, 0xf7, 0x71, - 0x9d, 0x2a, 0x6f, 0xc1, 0x58, 0xd9, 0x6d, 0x07, 0xf4, 0x71, 0x10, 0x0b, 0x21, 0xc0, 0x81, 0x71, - 0x87, 0x52, 0x89, 0x6a, 0xfc, 0xeb, 0x2c, 0x5c, 0xe8, 0x7b, 0x15, 0x20, 0x9b, 0x7a, 0xaf, 0x5d, - 0x1d, 0xe4, 0xfe, 0x70, 0x72, 0xb7, 0x2d, 0x26, 0x2c, 0xe5, 0x4e, 0xf4, 0x59, 0x5a, 0xf8, 0x1f, - 0x33, 0xa2, 0x93, 0x3e, 0x03, 0xa3, 0x58, 0x55, 0xd8, 0x45, 0x5c, 0x4b, 0x86, 0xbb, 0xb0, 0xa3, - 0x6b, 0xc9, 0x38, 0x1a, 0xb9, 0x09, 0xf9, 0xb2, 0xdd, 0x6c, 0x2a, 0x01, 0x16, 0x50, 0x9a, 0xaf, - 0x23, 0x2c, 0x66, 0xee, 0x29, 0x11, 0x99, 0xec, 0xc3, 0xff, 0x56, 0xce, 0x0a, 0xdc, 0x2c, 0x05, - 0x59, 0xec, 0xb8, 0x50, 0x90, 0x31, 0x2c, 0x6b, 0xdd, 0x0d, 0x5d, 0xb8, 0x79, 0x58, 0x56, 0x06, - 0xd0, 0xc2, 0xb2, 0x32, 0x80, 0xf1, 0xeb, 0x39, 0xb8, 0xd8, 0xff, 0x3e, 0x4b, 0xb6, 0xf4, 0x21, - 0x78, 0x6d, 0xa0, 0x5b, 0xf0, 0xc9, 0x63, 0x20, 0x83, 0x1c, 0xf3, 0x0e, 0xb9, 0x92, 0x74, 0x58, - 0xf9, 0xee, 0x51, 0x51, 0xb1, 0x21, 0xbe, 0xeb, 0x3a, 0x6d, 0xe5, 0xcd, 0xe4, 0x9b, 0x9a, 0x64, - 0xc8, 0xdf, 0xec, 0x6f, 0x0d, 0xf6, 0x65, 0x11, 0x1d, 0xdf, 0x57, 0x06, 0x95, 0x28, 0xbf, 0x00, - 0x85, 0x38, 0x29, 0xb9, 0x0c, 0x43, 0xf8, 0x01, 0x8a, 0xd7, 0x4d, 0x8c, 0x03, 0x96, 0x2f, 0xac, - 0x89, 0xb9, 0x83, 0x31, 0x27, 0xd0, 0x0a, 0x40, 0xd7, 0x0d, 0x8a, 0x98, 0x13, 0xdc, 0x88, 0x20, - 0xa9, 0x1f, 0x8c, 0x11, 0x19, 0x7f, 0x9e, 0x81, 0xf3, 0x3d, 0x35, 0x05, 0x64, 0x43, 0x1f, 0xb0, - 0x57, 0x4e, 0x52, 0x2d, 0x9c, 0x38, 0x56, 0x0b, 0x3f, 0x21, 0xe7, 0xfe, 0xfb, 0x30, 0x51, 0xeb, - 0xee, 0xc4, 0xef, 0x67, 0x3c, 0x22, 0x8c, 0x02, 0x57, 0x4f, 0x30, 0x15, 0x9f, 0xb5, 0x5f, 0x9a, - 0x39, 0x08, 0xb3, 0x1f, 0xc5, 0x4e, 0x30, 0x74, 0x8a, 0x4e, 0xc6, 0xdc, 0xd0, 0x89, 0x8c, 0x5f, - 0xcd, 0xa6, 0x5f, 0x74, 0xef, 0x94, 0x37, 0x4e, 0x73, 0xd1, 0xbd, 0x53, 0xde, 0x38, 0xb9, 0xed, - 0xff, 0x58, 0xb6, 0x1d, 0x1f, 0x66, 0xc5, 0x8e, 0x27, 0x15, 0x9d, 0xe2, 0x61, 0x56, 0xee, 0x8e, - 0xbe, 0xfe, 0x30, 0x2b, 0x91, 0xc9, 0x5b, 0x30, 0xb6, 0xea, 0xf2, 0x70, 0x18, 0xb2, 0xc5, 0xdc, - 0x6b, 0x58, 0x02, 0xd5, 0xed, 0x31, 0xc4, 0x64, 0x77, 0x0b, 0x7d, 0xe0, 0xa5, 0x39, 0x24, 0xde, - 0x2d, 0x62, 0xd3, 0x45, 0x57, 0x07, 0xea, 0x64, 0xc6, 0x7f, 0x32, 0x0c, 0xc6, 0xc9, 0xca, 0x0c, - 0xf2, 0xa1, 0xde, 0x77, 0xd7, 0x06, 0x56, 0x83, 0x0c, 0xb4, 0xe5, 0x96, 0xba, 0x0d, 0x87, 0xb6, - 0xeb, 0x7a, 0x2c, 0x0b, 0x01, 0x53, 0xb7, 0x40, 0x89, 0xf7, 0x71, 0x5c, 0x4b, 0x17, 0xfe, 0xdb, - 0x5c, 0xb4, 0xd4, 0x62, 0x47, 0x63, 0xe6, 0x63, 0x1c, 0x8d, 0xe4, 0x1e, 0x14, 0x54, 0x88, 0xf2, - 0x42, 0x8b, 0x92, 0x8b, 0xc6, 0x28, 0xf6, 0x51, 0x09, 0x42, 0xfd, 0x7c, 0xcd, 0x0d, 0x7e, 0xbe, - 0x46, 0xe2, 0x3b, 0xd6, 0x3f, 0x94, 0x14, 0xdf, 0xe3, 0xee, 0xe3, 0x0a, 0xba, 0x8c, 0x7d, 0xe1, - 0x8b, 0x43, 0x6b, 0x58, 0x8f, 0x7d, 0x91, 0x72, 0x70, 0xa9, 0xe8, 0x32, 0x7c, 0x07, 0xfe, 0x54, - 0xbc, 0xd7, 0xc3, 0xf0, 0x1d, 0x9c, 0x3e, 0x2d, 0x7c, 0x47, 0x48, 0xc2, 0x0e, 0x40, 0xb3, 0xdb, - 0xe6, 0xf1, 0xbf, 0x47, 0xa3, 0x03, 0xd0, 0xeb, 0xb6, 0xad, 0x78, 0x0c, 0xf0, 0x10, 0xd1, 0xf8, - 0x47, 0x43, 0xe9, 0xc2, 0x41, 0xa8, 0xef, 0x3a, 0x8d, 0x70, 0x10, 0x12, 0x7d, 0x32, 0x33, 0x75, - 0x0b, 0x66, 0xa5, 0x55, 0x9e, 0x34, 0xef, 0xda, 0x32, 0x57, 0xc5, 0x10, 0xa3, 0xde, 0x28, 0xb4, - 0xe7, 0x93, 0x26, 0x62, 0x56, 0xd7, 0xd3, 0xf4, 0x46, 0x29, 0xf4, 0x0b, 0xbf, 0x21, 0xd5, 0x62, - 0xea, 0x20, 0x6c, 0x6d, 0x85, 0x73, 0x39, 0x36, 0x08, 0xdd, 0xae, 0x36, 0x8c, 0x3a, 0x09, 0xdf, - 0x7b, 0xa5, 0xca, 0x01, 0x99, 0x28, 0xb2, 0xa2, 0xa2, 0xa8, 0x88, 0x71, 0x89, 0x11, 0x91, 0x3d, - 0x38, 0x1f, 0x89, 0xd2, 0xca, 0x4d, 0x01, 0x39, 0xf2, 0x06, 0x5f, 0x3d, 0x3e, 0x2a, 0xbe, 0xa2, - 0x88, 0xe2, 0xea, 0x85, 0x23, 0xc6, 0xbd, 0x37, 0x2f, 0xb6, 0xdf, 0x2e, 0x79, 0x76, 0xbb, 0xbe, - 0xaf, 0xcc, 0x79, 0xdc, 0x6f, 0x77, 0x10, 0x9a, 0x08, 0x40, 0x10, 0x21, 0x1b, 0x3f, 0x91, 0x85, - 0x29, 0x7e, 0x56, 0xf3, 0xd7, 0xb9, 0x67, 0xf6, 0xe5, 0xf3, 0x1d, 0xed, 0xe5, 0x53, 0xc6, 0xca, - 0x53, 0x9b, 0x36, 0xd0, 0xbb, 0xe7, 0x3e, 0x90, 0x24, 0x0d, 0x31, 0x61, 0x42, 0x85, 0xf6, 0x7f, - 0xf2, 0xbc, 0x11, 0x85, 0x55, 0x14, 0xa2, 0x12, 0xbe, 0x3b, 0xfb, 0xa6, 0xc6, 0xc3, 0xf8, 0xf1, - 0x2c, 0x4c, 0x2a, 0x76, 0x2a, 0xcf, 0x6c, 0xc7, 0x7f, 0x41, 0xeb, 0xf8, 0xf9, 0xd0, 0xa7, 0x2f, - 0x6c, 0xd9, 0x40, 0xfd, 0xde, 0x85, 0x99, 0x04, 0x49, 0xdc, 0xdc, 0x27, 0x33, 0x88, 0xb9, 0xcf, - 0x1b, 0xc9, 0x18, 0x6d, 0x3c, 0xd5, 0x41, 0x18, 0xb1, 0x47, 0x0d, 0x0a, 0xf7, 0x53, 0x59, 0x98, - 0x13, 0xbf, 0x30, 0xa8, 0x29, 0x17, 0x56, 0x9f, 0xd9, 0xb1, 0x28, 0x69, 0x63, 0x51, 0xd4, 0xc7, - 0x42, 0x69, 0x60, 0xef, 0x21, 0x31, 0x7e, 0x18, 0x60, 0xbe, 0x17, 0xc1, 0xc0, 0xae, 0xf3, 0x91, - 0x33, 0x61, 0x76, 0x00, 0x67, 0xc2, 0x55, 0x28, 0x60, 0x55, 0x22, 0x6c, 0xa1, 0xbf, 0x65, 0x56, - 0x45, 0x27, 0xa1, 0x7e, 0x81, 0x47, 0x9e, 0x15, 0x61, 0x14, 0xfd, 0x98, 0xce, 0x23, 0x41, 0x49, - 0x7e, 0x39, 0x03, 0x53, 0x08, 0x5c, 0x7e, 0x48, 0xdb, 0x01, 0x32, 0x1b, 0x12, 0x5e, 0x66, 0xe1, - 0xc3, 0x68, 0x2d, 0xf0, 0x9c, 0xf6, 0x9e, 0x78, 0x19, 0xdd, 0x11, 0x2f, 0xa3, 0xef, 0xf2, 0x17, - 0xdd, 0x6b, 0x75, 0xb7, 0x75, 0x7d, 0xcf, 0xb3, 0x1f, 0x3a, 0xdc, 0x04, 0xcb, 0x6e, 0x5e, 0x8f, - 0x32, 0xf4, 0x74, 0x9c, 0x58, 0xee, 0x1c, 0xc1, 0x0a, 0x5f, 0x9d, 0xf9, 0x87, 0x52, 0xac, 0x36, - 0xae, 0x9a, 0xd1, 0xbf, 0x88, 0x7c, 0x0f, 0x9c, 0xe3, 0xc1, 0xc4, 0xd8, 0x0d, 0xdf, 0x69, 0x77, - 0xdd, 0xae, 0xbf, 0x64, 0xd7, 0x0f, 0x98, 0x98, 0xcf, 0x7d, 0x81, 0xb1, 0xe5, 0xf5, 0xb0, 0xd0, - 0xda, 0xe1, 0xa5, 0x5a, 0x94, 0x8a, 0x74, 0x06, 0x64, 0x05, 0x66, 0x78, 0x51, 0xa9, 0x1b, 0xb8, - 0xb5, 0xba, 0xdd, 0x74, 0xda, 0x7b, 0x28, 0x4b, 0xe4, 0xb9, 0x28, 0x63, 0x77, 0x03, 0xd7, 0xf2, - 0x39, 0x5c, 0xd5, 0xd4, 0x24, 0x88, 0x48, 0x15, 0xa6, 0x4d, 0x6a, 0x37, 0xd6, 0xec, 0xc7, 0x65, - 0xbb, 0x63, 0xd7, 0x9d, 0x80, 0x47, 0x37, 0xcd, 0x71, 0x81, 0xce, 0xa3, 0x76, 0xc3, 0x6a, 0xd9, - 0x8f, 0xad, 0xba, 0x28, 0xd4, 0x55, 0xf6, 0x1a, 0x5d, 0xc8, 0xca, 0x69, 0x87, 0xac, 0xc6, 0xe2, - 0xac, 0x9c, 0x76, 0x6f, 0x56, 0x11, 0x9d, 0x64, 0xb5, 0x69, 0x7b, 0x7b, 0x34, 0xe0, 0xe6, 0xd1, - 0x70, 0x29, 0x73, 0x25, 0xa3, 0xb0, 0x0a, 0xb0, 0xcc, 0x42, 0x53, 0xe9, 0x38, 0x2b, 0x85, 0x8e, - 0xcd, 0xbc, 0x6d, 0xcf, 0x09, 0xa8, 0xda, 0xc2, 0x71, 0xfc, 0x2c, 0xec, 0x7f, 0x34, 0x2c, 0xef, - 0xd5, 0xc4, 0x04, 0x65, 0xc4, 0x4d, 0x69, 0xe4, 0x44, 0x82, 0x5b, 0x7a, 0x2b, 0x13, 0x94, 0x21, - 0x37, 0xb5, 0x9d, 0x93, 0xd8, 0x4e, 0x85, 0x5b, 0x8f, 0x86, 0x26, 0x28, 0xc9, 0x3a, 0xeb, 0xb4, - 0x80, 0xc9, 0x4d, 0x6e, 0x5b, 0x58, 0x70, 0x4f, 0xe1, 0xa7, 0xbd, 0x2c, 0xcc, 0x10, 0x0b, 0x9e, - 0x2c, 0xb6, 0x52, 0xec, 0xb9, 0xe3, 0xc4, 0xe4, 0xaf, 0xc1, 0xf4, 0x96, 0x4f, 0x6f, 0x57, 0x37, - 0x6a, 0x32, 0xf6, 0x18, 0x2a, 0x17, 0xa7, 0x16, 0x6f, 0x9c, 0xb0, 0xe9, 0x5c, 0x53, 0x69, 0x30, - 0xe1, 0x0d, 0x1f, 0xb7, 0xae, 0x4f, 0xad, 0x5d, 0xa7, 0xe3, 0x87, 0x81, 0x1c, 0xd5, 0x71, 0x8b, - 0x55, 0x65, 0xac, 0xc0, 0x4c, 0x82, 0x0d, 0x99, 0x02, 0x60, 0x40, 0x6b, 0x6b, 0xbd, 0xb6, 0xbc, - 0x59, 0x78, 0x8e, 0x14, 0x60, 0x02, 0x7f, 0x2f, 0xaf, 0x97, 0x96, 0x56, 0x97, 0x2b, 0x85, 0x0c, - 0x99, 0x81, 0x49, 0x84, 0x54, 0xaa, 0x35, 0x0e, 0xca, 0xf2, 0x74, 0x07, 0x66, 0x81, 0x2f, 0xdd, - 0x80, 0x2d, 0x00, 0x3c, 0x53, 0x8c, 0xbf, 0x93, 0x85, 0xf3, 0xf2, 0x58, 0xa1, 0x01, 0x13, 0x1c, - 0x9d, 0xf6, 0xde, 0x33, 0x7e, 0x3a, 0xdc, 0xd6, 0x4e, 0x87, 0x97, 0x63, 0x27, 0x75, 0xac, 0x95, - 0x7d, 0x8e, 0x88, 0xdf, 0x1e, 0x83, 0x0b, 0x7d, 0xa9, 0xc8, 0x97, 0xd8, 0x69, 0xee, 0xd0, 0x76, - 0x50, 0x6d, 0x34, 0xe9, 0xa6, 0xd3, 0xa2, 0x6e, 0x37, 0x10, 0x1e, 0x03, 0x2f, 0xa1, 0x3e, 0x0f, - 0x0b, 0x2d, 0xa7, 0xd1, 0xa4, 0x56, 0xc0, 0x8b, 0xb5, 0xe9, 0x96, 0xa4, 0x66, 0x2c, 0xc3, 0xe4, - 0x5b, 0xd5, 0x76, 0x40, 0xbd, 0x87, 0x68, 0x95, 0x18, 0xb2, 0x3c, 0xa0, 0xb4, 0x63, 0xd9, 0xac, - 0xd4, 0x72, 0x44, 0xb1, 0xce, 0x32, 0x41, 0x4d, 0x6e, 0x2b, 0x2c, 0xcb, 0xec, 0xf6, 0xbf, 0x66, - 0x3f, 0x16, 0x66, 0x52, 0x22, 0x96, 0x6d, 0xc8, 0x92, 0x3b, 0xf1, 0xb5, 0xec, 0xc7, 0x66, 0x92, - 0x84, 0x7c, 0x0d, 0xce, 0x88, 0x03, 0x48, 0x84, 0x5b, 0x91, 0x2d, 0xe6, 0xc1, 0x5c, 0x5e, 0x3d, - 0x3e, 0x2a, 0x9e, 0x93, 0x51, 0x80, 0x65, 0x28, 0xa4, 0xb4, 0x56, 0xa7, 0x73, 0x21, 0x9b, 0xec, - 0x40, 0x8e, 0x75, 0xc7, 0x1a, 0xf5, 0x7d, 0xe9, 0x65, 0x29, 0x6e, 0xc6, 0x6a, 0x67, 0x5a, 0x2d, - 0x5e, 0x6e, 0xf6, 0xa4, 0x24, 0x2b, 0x30, 0xb5, 0x4d, 0x77, 0xd4, 0xf1, 0x19, 0x09, 0xb7, 0xaa, - 0xc2, 0x23, 0xba, 0xd3, 0x7b, 0x70, 0x62, 0x74, 0xc4, 0xc1, 0xf7, 0x81, 0xc7, 0x87, 0xab, 0x8e, - 0x1f, 0xd0, 0x36, 0xf5, 0x30, 0xe0, 0xda, 0x28, 0x6e, 0x06, 0xf3, 0x91, 0x84, 0xac, 0x97, 0x2f, - 0xbd, 0x78, 0x7c, 0x54, 0xbc, 0xc0, 0xdd, 0x95, 0x9b, 0x02, 0x6e, 0xc5, 0x52, 0x57, 0x25, 0xb9, - 0x92, 0x6f, 0xc0, 0xb4, 0xe9, 0x76, 0x03, 0xa7, 0xbd, 0x57, 0x0b, 0x3c, 0x3b, 0xa0, 0x7b, 0xfc, - 0x40, 0x8a, 0x22, 0xbb, 0xc5, 0x4a, 0xc5, 0xd3, 0x32, 0x07, 0x5a, 0xbe, 0x80, 0x6a, 0x27, 0x82, - 0x4e, 0x40, 0xbe, 0x0e, 0x53, 0x3c, 0xd0, 0x46, 0x58, 0xc1, 0x98, 0x96, 0x76, 0x43, 0x2f, 0x7c, - 0x70, 0x43, 0x58, 0xb5, 0x20, 0x34, 0xad, 0x82, 0x18, 0x37, 0xf2, 0x15, 0xd1, 0x59, 0x1b, 0x4e, - 0x7b, 0x2f, 0x9c, 0xc6, 0x80, 0x3d, 0xff, 0x66, 0xd4, 0x25, 0x1d, 0xf6, 0xb9, 0x72, 0x1a, 0xf7, - 0x30, 0xd1, 0x4b, 0xf2, 0x21, 0x01, 0x5c, 0x28, 0xf9, 0xbe, 0xe3, 0x07, 0xc2, 0xaf, 0x66, 0xf9, - 0x31, 0xad, 0x77, 0x19, 0x32, 0xbb, 0xde, 0x52, 0x8f, 0xdb, 0x75, 0x0f, 0x2f, 0x5d, 0x3b, 0x3e, - 0x2a, 0xbe, 0x66, 0x23, 0xa2, 0x25, 0x5c, 0x71, 0x2c, 0x2a, 0x51, 0xad, 0x47, 0x1c, 0x57, 0x69, - 0x43, 0x7f, 0xa6, 0xe4, 0xeb, 0x70, 0xb6, 0x6c, 0xfb, 0xb4, 0xda, 0xf6, 0x69, 0xdb, 0x77, 0x02, - 0xe7, 0x21, 0x15, 0x9d, 0x8a, 0x87, 0x5f, 0x1e, 0x93, 0x7c, 0x19, 0x75, 0xdb, 0x67, 0x0b, 0x33, - 0x44, 0xb1, 0xc4, 0xa0, 0x28, 0xd5, 0xf4, 0xe0, 0x42, 0x4c, 0x98, 0xaa, 0xd5, 0x56, 0x2a, 0x8e, - 0x1d, 0xae, 0xab, 0x49, 0xec, 0xaf, 0xd7, 0x50, 0xb5, 0xe7, 0xef, 0x5b, 0x0d, 0xc7, 0x0e, 0x17, - 0x54, 0x8f, 0xce, 0x8a, 0x71, 0x30, 0x8e, 0x32, 0x50, 0x88, 0x0f, 0x25, 0xf9, 0x32, 0x8c, 0x71, - 0xfb, 0x36, 0xea, 0xef, 0x8b, 0x58, 0x11, 0xd2, 0x5c, 0x2a, 0x84, 0xeb, 0x44, 0xc2, 0x89, 0x8e, - 0x5b, 0xcf, 0x51, 0xd5, 0x5a, 0x06, 0x9d, 0xe8, 0x24, 0x11, 0x69, 0xc0, 0x04, 0x1f, 0x2d, 0x8a, - 0x61, 0x1d, 0x85, 0x99, 0xf3, 0x8b, 0xea, 0xea, 0x10, 0x45, 0x31, 0xfe, 0xf8, 0x6a, 0x28, 0xe6, - 0x04, 0x47, 0xd0, 0xaa, 0xd0, 0xb8, 0x2e, 0x01, 0xe4, 0x25, 0xa1, 0x71, 0x1e, 0xce, 0xf5, 0xf8, - 0x66, 0xe3, 0x21, 0x5a, 0x12, 0xf4, 0xa8, 0x91, 0x7c, 0x19, 0xe6, 0x90, 0xb0, 0xec, 0xb6, 0xdb, - 0xb4, 0x1e, 0xe0, 0x76, 0x24, 0xb5, 0xef, 0x39, 0x6e, 0xe9, 0xc2, 0xdb, 0x5b, 0x0f, 0x11, 0xac, - 0xb8, 0x12, 0x3e, 0x95, 0x83, 0xf1, 0xf3, 0x59, 0x98, 0x17, 0x3b, 0x9c, 0x49, 0xeb, 0xae, 0xd7, - 0x78, 0xf6, 0x4f, 0xd4, 0x65, 0xed, 0x44, 0x7d, 0x29, 0x0c, 0x34, 0x94, 0xd6, 0xc8, 0x3e, 0x07, - 0xea, 0xaf, 0x66, 0xe0, 0x85, 0x7e, 0x44, 0xac, 0x77, 0xc2, 0x30, 0x96, 0x63, 0x89, 0x70, 0x95, - 0x1d, 0x98, 0xc5, 0x01, 0x2d, 0xef, 0xd3, 0xfa, 0x81, 0xbf, 0xe2, 0xfa, 0x01, 0x7a, 0x5a, 0x64, - 0x7b, 0xbc, 0x75, 0xbf, 0x91, 0xfa, 0xd6, 0x7d, 0x96, 0xcf, 0xb2, 0x3a, 0xf2, 0xe0, 0x81, 0x36, - 0x0f, 0xe8, 0xa1, 0x6f, 0xa6, 0xb1, 0x46, 0x8b, 0xf9, 0x52, 0x37, 0xd8, 0xdf, 0xf0, 0xe8, 0x2e, - 0xf5, 0x68, 0xbb, 0x4e, 0x3f, 0x65, 0x16, 0xf3, 0x7a, 0xe3, 0x06, 0xd2, 0x60, 0xfc, 0xe3, 0x49, - 0x98, 0x4b, 0x23, 0x63, 0xfd, 0xa2, 0x5c, 0x9a, 0xe3, 0x39, 0x48, 0x7f, 0x28, 0x03, 0x13, 0x35, - 0x5a, 0x77, 0xdb, 0x8d, 0xdb, 0x68, 0x51, 0x24, 0x7a, 0xc7, 0xe2, 0x42, 0x03, 0x83, 0x5b, 0xbb, - 0x31, 0x53, 0xa3, 0xef, 0x1e, 0x15, 0xbf, 0x38, 0xd8, 0x5d, 0xb5, 0xee, 0x62, 0x80, 0x9f, 0x00, - 0x73, 0x64, 0x84, 0x55, 0xe0, 0xe3, 0xa0, 0x56, 0x29, 0x59, 0x82, 0x49, 0xb1, 0x5c, 0x5d, 0x35, - 0x8a, 0x29, 0x8f, 0xc5, 0x24, 0x0b, 0x12, 0xaa, 0x6b, 0x8d, 0x84, 0xdc, 0x84, 0xdc, 0xd6, 0xe2, - 0x6d, 0x31, 0x06, 0x32, 0xcb, 0xc8, 0xd6, 0xe2, 0x6d, 0x54, 0x87, 0xb1, 0x2b, 0xc6, 0x64, 0x77, - 0x51, 0x33, 0xf2, 0xd9, 0x5a, 0xbc, 0x4d, 0xbe, 0x0f, 0xce, 0x54, 0x1c, 0x5f, 0x54, 0xc1, 0x7d, - 0x37, 0x1a, 0xe8, 0xb1, 0x38, 0xd2, 0x63, 0xf6, 0x7e, 0x2e, 0x75, 0xf6, 0xbe, 0xd8, 0x08, 0x99, - 0x58, 0xdc, 0x31, 0xa4, 0x11, 0x8f, 0xd6, 0x9a, 0x5e, 0x0f, 0xf9, 0x08, 0xa6, 0x50, 0x99, 0x8d, - 0xee, 0x2c, 0x18, 0x67, 0x7f, 0xb4, 0x47, 0xcd, 0x9f, 0x49, 0xad, 0x79, 0x81, 0x47, 0xc8, 0x40, - 0xa7, 0x18, 0x8c, 0xc9, 0xaf, 0xdd, 0xfa, 0x35, 0xce, 0xe4, 0x2e, 0x4c, 0x0b, 0xf1, 0xeb, 0xfe, - 0xee, 0xe6, 0x3e, 0xad, 0xd8, 0x87, 0xc2, 0x3e, 0x07, 0x6f, 0x74, 0x42, 0x66, 0xb3, 0xdc, 0x5d, - 0x2b, 0xd8, 0xa7, 0x56, 0xc3, 0xd6, 0x04, 0x95, 0x18, 0x21, 0xf9, 0x16, 0x8c, 0xaf, 0xba, 0x75, - 0x26, 0x79, 0xe3, 0xce, 0xc0, 0x4d, 0x76, 0x3e, 0xc4, 0x2c, 0x97, 0x1c, 0x1c, 0x13, 0xa7, 0xbe, - 0x7b, 0x54, 0x7c, 0xe7, 0xb4, 0x93, 0x46, 0xa9, 0xc0, 0x54, 0x6b, 0x23, 0x65, 0xc8, 0x6f, 0xd3, - 0x1d, 0xd6, 0xda, 0x78, 0x06, 0x3c, 0x09, 0x16, 0x16, 0x79, 0xe2, 0x97, 0x66, 0x91, 0x27, 0x60, - 0xc4, 0x83, 0x19, 0xec, 0x9f, 0x0d, 0xdb, 0xf7, 0x1f, 0xb9, 0x5e, 0x03, 0x53, 0x9d, 0xf4, 0xb2, - 0x06, 0x5a, 0x4c, 0xed, 0xfc, 0x17, 0x78, 0xe7, 0x77, 0x14, 0x0e, 0xaa, 0x00, 0x99, 0x60, 0x4f, - 0xbe, 0x01, 0x53, 0x22, 0x62, 0xc1, 0xda, 0xed, 0x12, 0xae, 0xca, 0x09, 0xcd, 0xef, 0x53, 0x2f, - 0xe4, 0x52, 0xaa, 0x08, 0x80, 0x20, 0x35, 0x50, 0x56, 0x6b, 0xd7, 0xd6, 0x95, 0xfe, 0x2a, 0x09, - 0xd9, 0x80, 0xf1, 0x0a, 0xe6, 0x61, 0x46, 0xdf, 0x34, 0x61, 0x17, 0x1e, 0xa6, 0xf0, 0x8a, 0x4a, - 0xb8, 0x2e, 0x46, 0xa4, 0x6c, 0x46, 0x4f, 0x37, 0xdd, 0x56, 0x37, 0x44, 0x24, 0xb7, 0x20, 0x57, - 0xad, 0x6c, 0x08, 0xb3, 0xf0, 0x99, 0x30, 0x2e, 0xc8, 0x86, 0x4c, 0x78, 0x84, 0xf6, 0x73, 0x4e, - 0x43, 0x33, 0x2a, 0xaf, 0x56, 0x36, 0xc8, 0x2e, 0x4c, 0x62, 0x07, 0xac, 0x50, 0x9b, 0xf7, 0xed, - 0x74, 0x8f, 0xbe, 0xbd, 0x96, 0xda, 0xb7, 0xf3, 0xbc, 0x6f, 0xf7, 0x05, 0xb5, 0x96, 0xc1, 0x45, - 0x65, 0xcb, 0x44, 0x5a, 0x91, 0x55, 0x4a, 0xe6, 0x1d, 0xd9, 0x5c, 0x45, 0xfb, 0x20, 0x21, 0xd2, - 0xca, 0x24, 0x54, 0x61, 0x22, 0x94, 0x9e, 0x5e, 0x27, 0x49, 0x3e, 0xe4, 0x0b, 0x30, 0x74, 0xff, - 0x20, 0xb0, 0x85, 0x01, 0xb8, 0xec, 0x47, 0x06, 0x92, 0xcd, 0x47, 0x2d, 0xa4, 0x7b, 0xa0, 0x45, - 0x89, 0x43, 0x1a, 0x36, 0x14, 0x2b, 0xb6, 0xd7, 0x78, 0x64, 0x7b, 0xe8, 0x20, 0x3c, 0xab, 0xb1, - 0x50, 0x4a, 0xf8, 0x50, 0xec, 0x0b, 0x40, 0xcc, 0x6b, 0x58, 0x65, 0x41, 0xbe, 0x07, 0xce, 0xfb, - 0xce, 0x5e, 0xdb, 0x0e, 0xba, 0x1e, 0xb5, 0xec, 0xe6, 0x9e, 0xeb, 0x39, 0xc1, 0x7e, 0xcb, 0xf2, - 0xbb, 0x4e, 0x40, 0xe7, 0xe7, 0xb4, 0x1c, 0xd4, 0x35, 0x89, 0x57, 0x92, 0x68, 0x35, 0x86, 0x65, - 0x9e, 0xf3, 0xd3, 0x0b, 0xc8, 0x57, 0x60, 0x52, 0xdd, 0x92, 0xfd, 0xf9, 0x33, 0x97, 0x72, 0x57, - 0xa6, 0xc2, 0x8b, 0x47, 0x7c, 0x03, 0x97, 0xb1, 0x9b, 0x95, 0x13, 0xc2, 0xd7, 0x63, 0x37, 0x2b, - 0xbc, 0xc2, 0xac, 0x8e, 0xa4, 0x30, 0x6b, 0xce, 0x88, 0x19, 0x2b, 0x7a, 0x79, 0xed, 0x76, 0xc9, - 0x1c, 0xdd, 0xa8, 0x3e, 0xa8, 0x35, 0xdd, 0xc0, 0xf8, 0x2f, 0x32, 0xb8, 0x89, 0x93, 0xd7, 0x30, - 0xf4, 0x53, 0xf8, 0x7a, 0x86, 0xfa, 0x5b, 0xbb, 0x13, 0x0b, 0xfc, 0xcf, 0x51, 0xc8, 0x1b, 0x30, - 0x72, 0xdb, 0xae, 0xcb, 0xd0, 0x35, 0x02, 0x79, 0x17, 0x21, 0xaa, 0xb2, 0x97, 0xe3, 0x30, 0xf9, - 0x92, 0x4f, 0xee, 0x52, 0x94, 0xde, 0xbc, 0x5c, 0x92, 0xcf, 0xf5, 0x28, 0x5f, 0x8a, 0x45, 0xa1, - 0xe4, 0x3f, 0x8f, 0x59, 0xc5, 0xa7, 0x72, 0x30, 0xfe, 0x34, 0x13, 0xed, 0x4a, 0xe4, 0x55, 0x18, - 0x32, 0x37, 0xc2, 0xef, 0xe7, 0x4e, 0xbf, 0xb1, 0xcf, 0x47, 0x04, 0xf2, 0x15, 0x38, 0xa3, 0xf0, - 0x49, 0x98, 0xe8, 0xbf, 0x82, 0x3e, 0xa9, 0xca, 0x97, 0xa4, 0xdb, 0xe9, 0xa7, 0xf3, 0x40, 0x61, - 0x3a, 0x2a, 0xa8, 0xd0, 0xb6, 0xc3, 0x79, 0x2b, 0x8d, 0x55, 0x79, 0x37, 0x10, 0x21, 0xde, 0xd8, - 0x34, 0x0e, 0xdc, 0x25, 0xd5, 0xf8, 0xad, 0x8c, 0xb6, 0xdb, 0x84, 0xf9, 0xa0, 0x33, 0x27, 0xe4, - 0x83, 0x7e, 0x1b, 0xa0, 0xd4, 0x0d, 0xdc, 0xe5, 0xb6, 0xe7, 0x36, 0xb9, 0x16, 0x45, 0xe4, 0xbe, - 0x40, 0xdd, 0x30, 0x45, 0xb0, 0xe6, 0x39, 0x17, 0x22, 0xa7, 0x7a, 0x33, 0xe4, 0x3e, 0xae, 0x37, - 0x83, 0xf1, 0xfb, 0x19, 0x6d, 0x8d, 0x32, 0x29, 0x51, 0x4c, 0x45, 0xd5, 0x62, 0xac, 0xe3, 0x3c, - 0xb4, 0xfc, 0xa6, 0xab, 0x05, 0xa9, 0x10, 0x68, 0xe4, 0xdf, 0xce, 0xc0, 0x59, 0xee, 0x16, 0xb0, - 0xde, 0x6d, 0xed, 0x50, 0xef, 0x81, 0xdd, 0x74, 0x1a, 0x51, 0x60, 0xbd, 0xc8, 0x7c, 0x50, 0xa9, - 0x26, 0x1d, 0x9f, 0x5f, 0x54, 0xb9, 0x9b, 0x82, 0xd5, 0xc6, 0x42, 0xeb, 0x61, 0x58, 0xaa, 0x5e, - 0x54, 0xd3, 0xe9, 0x8d, 0x5f, 0xcb, 0xc0, 0x8b, 0x27, 0xd6, 0x42, 0xae, 0xc3, 0xa8, 0x4c, 0x3a, - 0x92, 0xc1, 0x8e, 0x47, 0x3b, 0xdb, 0x64, 0xc2, 0x11, 0x89, 0x45, 0xbe, 0x0a, 0x67, 0x54, 0x56, - 0x9b, 0x9e, 0xed, 0xa8, 0xa9, 0x3d, 0x52, 0xbe, 0x3a, 0x60, 0x28, 0x71, 0x69, 0x2d, 0x9d, 0x89, - 0xf1, 0xff, 0x65, 0x94, 0x0c, 0xf1, 0xcf, 0xa8, 0x0c, 0x7f, 0x4b, 0x93, 0xe1, 0x65, 0x58, 0xd1, - 0xb0, 0x55, 0xac, 0x2c, 0xf5, 0xde, 0x35, 0xad, 0xd8, 0x8b, 0x23, 0xe0, 0x47, 0xb3, 0x30, 0xbe, - 0xe5, 0x53, 0x8f, 0x3f, 0xe4, 0x7e, 0xba, 0x82, 0x2b, 0x86, 0xed, 0x1a, 0x28, 0xfc, 0xdd, 0x1f, - 0x67, 0x50, 0xc1, 0xaf, 0x52, 0xb0, 0xde, 0x50, 0xb2, 0x42, 0x62, 0x6f, 0x60, 0x3e, 0x48, 0x84, - 0xf2, 0x80, 0x62, 0xab, 0x7a, 0x82, 0x58, 0xcc, 0x12, 0xbc, 0x4a, 0xbe, 0x08, 0xc3, 0x5b, 0xa8, - 0xae, 0xd4, 0x83, 0x6c, 0x84, 0xfc, 0xb1, 0x90, 0x6f, 0xd2, 0x5d, 0x5f, 0x8f, 0x14, 0xc7, 0x09, - 0x49, 0x0d, 0x46, 0xcb, 0x1e, 0xc5, 0x7c, 0xef, 0x43, 0x83, 0xbb, 0x88, 0xd7, 0x39, 0x49, 0xdc, - 0x45, 0x5c, 0x70, 0x32, 0x7e, 0x2e, 0x0b, 0x24, 0x6a, 0x23, 0x26, 0x37, 0xf3, 0x9f, 0xd9, 0x41, - 0xff, 0x40, 0x1b, 0xf4, 0x0b, 0x89, 0x41, 0xe7, 0xcd, 0x1b, 0x68, 0xec, 0x7f, 0x27, 0x03, 0x67, - 0xd3, 0x09, 0xc9, 0x4b, 0x30, 0x72, 0x7f, 0x73, 0x43, 0xc6, 0x69, 0x11, 0x4d, 0x71, 0x3b, 0xa8, - 0x2b, 0x30, 0x45, 0x11, 0x79, 0x13, 0x46, 0xbe, 0x64, 0x96, 0xd9, 0x39, 0xa4, 0xa4, 0xcf, 0xf8, - 0xa6, 0x67, 0xd5, 0xf5, 0xa3, 0x48, 0x20, 0xa9, 0x63, 0x9b, 0x7b, 0x6a, 0x63, 0xfb, 0x53, 0x59, - 0x98, 0x2e, 0xd5, 0xeb, 0xd4, 0xf7, 0x45, 0x68, 0xf8, 0x67, 0x76, 0x60, 0xd3, 0x23, 0xb0, 0x68, - 0x6d, 0x1b, 0x68, 0x54, 0x7f, 0x37, 0x03, 0x67, 0x24, 0xd5, 0x43, 0x87, 0x3e, 0xda, 0xdc, 0xf7, - 0xa8, 0xbf, 0xef, 0x36, 0x1b, 0x03, 0xe7, 0xe8, 0x61, 0x82, 0x1e, 0x86, 0x73, 0x57, 0x5f, 0xf5, - 0x77, 0x11, 0xa2, 0x09, 0x7a, 0x3c, 0xe4, 0xfb, 0x75, 0x18, 0x2d, 0x75, 0x3a, 0x9e, 0xfb, 0x90, - 0x2f, 0x7b, 0x11, 0x0b, 0xd2, 0xe6, 0x20, 0xcd, 0xc3, 0x9e, 0x83, 0xd8, 0x67, 0x54, 0x68, 0x9b, - 0x07, 0xf0, 0x9b, 0xe4, 0x9f, 0xd1, 0xa0, 0x6d, 0x55, 0x16, 0xc7, 0x72, 0xa3, 0x06, 0x64, 0xc3, - 0x73, 0x5b, 0x6e, 0x40, 0x1b, 0xbc, 0x3d, 0x18, 0x98, 0xe0, 0xc4, 0x40, 0x5a, 0x9b, 0x4e, 0xd0, - 0xd4, 0x02, 0x69, 0x05, 0x0c, 0x60, 0x72, 0xb8, 0xf1, 0xff, 0x0c, 0xc3, 0x84, 0xda, 0x3b, 0xc4, - 0xe0, 0x89, 0x37, 0x5c, 0x4f, 0x8d, 0x8e, 0x61, 0x23, 0xc4, 0x14, 0x25, 0x51, 0x68, 0x99, 0xec, - 0x89, 0xa1, 0x65, 0xb6, 0x61, 0x72, 0xc3, 0x73, 0x31, 0x68, 0x25, 0xbe, 0x56, 0x8a, 0xad, 0x70, - 0x56, 0xb9, 0x77, 0xb2, 0x81, 0xc4, 0xf7, 0x50, 0x94, 0xec, 0x3b, 0x02, 0x1b, 0xd3, 0x51, 0x6a, - 0x5a, 0x17, 0x8d, 0x0f, 0x37, 0xb5, 0xb0, 0x7d, 0x11, 0x79, 0x36, 0x34, 0xb5, 0x60, 0x10, 0xdd, - 0xd4, 0x82, 0x41, 0xd4, 0xb5, 0x36, 0xfc, 0xb4, 0xd6, 0x1a, 0xf9, 0xb9, 0x0c, 0x8c, 0x97, 0xda, - 0x6d, 0x11, 0xb2, 0xe6, 0x04, 0x6f, 0xfd, 0xaf, 0x0a, 0x6b, 0x8b, 0x77, 0x3e, 0x96, 0xb5, 0x05, - 0xca, 0x2d, 0x3e, 0x4a, 0xaa, 0x51, 0x85, 0xea, 0x6d, 0x4d, 0xf9, 0x0e, 0xf2, 0x0e, 0x14, 0xc2, - 0x49, 0x5e, 0x6d, 0x37, 0xe8, 0x63, 0xca, 0x13, 0x17, 0x4e, 0x8a, 0x48, 0xd8, 0xaa, 0x64, 0x1a, - 0x47, 0x24, 0x9b, 0x00, 0x76, 0x38, 0xbb, 0x62, 0x19, 0x58, 0x93, 0xd3, 0x4f, 0x48, 0xcf, 0xf8, - 0x1b, 0x1f, 0xb4, 0x54, 0xe9, 0x39, 0xe2, 0x43, 0x5a, 0x30, 0xcd, 0xd3, 0x9f, 0xd6, 0x02, 0xdb, - 0x0b, 0x30, 0x79, 0x04, 0x9c, 0x38, 0x0e, 0xaf, 0x0a, 0xfd, 0xd9, 0xf3, 0x22, 0xa9, 0xaa, 0xcf, - 0x68, 0xad, 0x94, 0x4c, 0x12, 0x71, 0xde, 0x3c, 0xee, 0xb8, 0x79, 0x2e, 0xf9, 0xbd, 0x7c, 0xd2, - 0xff, 0x54, 0x06, 0xce, 0xaa, 0x93, 0xbe, 0xd6, 0xdd, 0x11, 0x01, 0x43, 0xc9, 0x35, 0x18, 0x13, - 0x73, 0x32, 0xbc, 0x44, 0x25, 0x73, 0x60, 0x44, 0x28, 0x64, 0x99, 0x4d, 0x43, 0xc6, 0x43, 0x48, - 0xdd, 0xb3, 0xb1, 0x7d, 0x8a, 0x15, 0x45, 0xa9, 0xb5, 0x3d, 0xfc, 0xad, 0xcf, 0x4f, 0x06, 0x31, - 0xde, 0x87, 0x19, 0x7d, 0x24, 0x6a, 0x34, 0x20, 0x57, 0x61, 0x54, 0x0e, 0x5f, 0x26, 0x7d, 0xf8, - 0x64, 0xb9, 0xb1, 0x0d, 0x24, 0x41, 0xef, 0xa3, 0x59, 0x14, 0xbb, 0x9f, 0x72, 0xb3, 0x3d, 0xf9, - 0x28, 0x99, 0x40, 0x5c, 0x9a, 0x15, 0xdf, 0x37, 0xae, 0xb9, 0x25, 0x60, 0xf0, 0xd4, 0x3f, 0x9d, - 0x82, 0xd9, 0x94, 0x3d, 0xf7, 0x04, 0x99, 0xa8, 0xa8, 0x6f, 0x10, 0x63, 0x61, 0xb0, 0x0f, 0xb9, - 0x2d, 0xbc, 0x0f, 0xc3, 0x27, 0x6e, 0x07, 0xdc, 0x29, 0x25, 0xb6, 0x0b, 0x70, 0xb2, 0x4f, 0x44, - 0x2e, 0x52, 0xe3, 0xf1, 0x0c, 0x3f, 0xb5, 0x78, 0x3c, 0x4b, 0x30, 0x29, 0x5a, 0x25, 0xb6, 0x2b, - 0xc5, 0x38, 0x5a, 0xe6, 0x74, 0x49, 0x6c, 0x5b, 0x3a, 0x09, 0xe7, 0xe1, 0xbb, 0xcd, 0x87, 0x54, - 0xf0, 0x18, 0x55, 0x79, 0x60, 0x41, 0x2a, 0x0f, 0x85, 0x84, 0xfc, 0x47, 0x98, 0x7a, 0x11, 0x21, - 0xea, 0x9e, 0x95, 0xef, 0xb7, 0x67, 0x35, 0x9e, 0xce, 0x9e, 0x75, 0x41, 0x7e, 0x63, 0xfa, 0xde, - 0x95, 0xf2, 0x59, 0xe4, 0x57, 0x32, 0x30, 0xc3, 0x83, 0xc2, 0xa8, 0x1f, 0xdb, 0x37, 0xd0, 0x47, - 0xfd, 0xe9, 0x7c, 0xec, 0x0b, 0x22, 0x9b, 0x4f, 0xfa, 0xb7, 0x26, 0x3f, 0x8a, 0x7c, 0x0f, 0x40, - 0xb8, 0xa2, 0x78, 0x00, 0xd9, 0xf1, 0xc5, 0x17, 0x52, 0x76, 0x81, 0x10, 0x29, 0x4a, 0xba, 0x11, - 0x84, 0x74, 0x5a, 0xc2, 0xcd, 0x10, 0x4a, 0xbe, 0x0f, 0xe6, 0xd8, 0x7a, 0x09, 0x21, 0x22, 0x84, - 0xd5, 0xfc, 0x38, 0xd6, 0xf2, 0xd9, 0xde, 0x32, 0xd1, 0xb5, 0x34, 0x32, 0x1e, 0x6e, 0x38, 0xca, - 0x7d, 0x1e, 0xa8, 0xd1, 0x2e, 0x52, 0x2b, 0xc2, 0xc8, 0x70, 0xf8, 0xf5, 0x3c, 0x31, 0x46, 0x8f, - 0xfd, 0xed, 0xbc, 0x5c, 0x0b, 0x7c, 0x7f, 0xf3, 0x75, 0x1f, 0x65, 0x04, 0x91, 0x2f, 0x01, 0x09, - 0xa3, 0xa9, 0x70, 0x18, 0x95, 0x49, 0x33, 0xb8, 0xba, 0x39, 0x8a, 0xca, 0xe2, 0xc9, 0x62, 0x75, - 0x92, 0x24, 0x89, 0x09, 0x85, 0x39, 0xd1, 0x68, 0x06, 0x95, 0x79, 0x11, 0xfd, 0xf9, 0x29, 0x2d, - 0x40, 0x58, 0x54, 0x12, 0x25, 0x49, 0x57, 0x92, 0x2b, 0x6a, 0x2a, 0xa7, 0x34, 0x76, 0xe4, 0x16, - 0x8c, 0xa1, 0xa3, 0xf0, 0x8a, 0x34, 0xf6, 0x12, 0x86, 0x27, 0xe8, 0x52, 0x6c, 0xed, 0xeb, 0x26, - 0x5b, 0x11, 0x2a, 0xbb, 0x0e, 0x54, 0xbc, 0x43, 0xb3, 0xdb, 0x46, 0xa5, 0xb0, 0xd0, 0x77, 0x34, - 0xbc, 0x43, 0xcb, 0xeb, 0xea, 0x9e, 0xe4, 0x88, 0x44, 0xbe, 0x01, 0xe3, 0x6b, 0xf6, 0xe3, 0x30, - 0x33, 0xd4, 0xcc, 0xe0, 0xf9, 0xa7, 0x5a, 0xf6, 0xe3, 0x30, 0x2d, 0x54, 0x3c, 0xff, 0x94, 0xc2, - 0x92, 0x7c, 0x0d, 0x40, 0xd1, 0x54, 0x93, 0x13, 0x2b, 0x78, 0x51, 0x86, 0xbd, 0x4b, 0xd5, 0x60, - 0x23, 0x7f, 0x85, 0x61, 0x4c, 0x72, 0x98, 0xfb, 0xe4, 0x24, 0x87, 0x33, 0x9f, 0x9c, 0xe4, 0xb0, - 0xb0, 0x03, 0xe7, 0x7b, 0x2e, 0x9d, 0x94, 0x50, 0xc7, 0xd7, 0xf5, 0x50, 0xc7, 0xe7, 0x7b, 0x1d, - 0xb1, 0xbe, 0x9e, 0x1b, 0x65, 0xb6, 0x30, 0xd7, 0x5b, 0x3a, 0xf9, 0x4e, 0x36, 0x76, 0xe4, 0x8a, - 0x8b, 0x05, 0xcf, 0xcb, 0xd5, 0x4b, 0x26, 0xc9, 0x62, 0xd2, 0x6c, 0x7e, 0x28, 0x2b, 0xa1, 0xdc, - 0xd9, 0xa1, 0xac, 0x1e, 0xea, 0x78, 0x3c, 0x3f, 0xe9, 0xe9, 0xfb, 0x2e, 0x4c, 0xf1, 0x3c, 0xb7, - 0xf7, 0xe8, 0xe1, 0x23, 0xd7, 0x6b, 0xf0, 0x8c, 0x43, 0x42, 0x06, 0x4f, 0x24, 0xa9, 0x8f, 0xe1, - 0x92, 0x8a, 0xf4, 0x3d, 0x1d, 0xc6, 0xda, 0xcf, 0xa7, 0xee, 0x62, 0x0c, 0xa1, 0x9f, 0x5b, 0x2a, - 0x79, 0x2b, 0x14, 0xd4, 0xa8, 0xa7, 0x66, 0x48, 0xf1, 0x24, 0x30, 0x45, 0x5e, 0xa3, 0x9e, 0xf1, - 0xcf, 0x73, 0x40, 0x78, 0x4d, 0x65, 0xbb, 0x63, 0xa3, 0x67, 0xb6, 0x83, 0xb1, 0x96, 0x0a, 0x02, - 0xc7, 0xde, 0x69, 0x52, 0x35, 0x50, 0x99, 0x30, 0xae, 0x0d, 0xcb, 0xac, 0xf8, 0x45, 0x27, 0x41, - 0xd8, 0x63, 0xab, 0xcb, 0x3e, 0xc9, 0x56, 0xf7, 0x0d, 0x78, 0xbe, 0xd4, 0xc1, 0x84, 0xd9, 0xb2, - 0x96, 0xdb, 0xae, 0x27, 0x37, 0x29, 0xcd, 0xe7, 0xcf, 0x0e, 0xd1, 0x12, 0x5f, 0xda, 0x8f, 0x85, - 0x22, 0xa7, 0xb0, 0x79, 0xd9, 0x09, 0xd4, 0x18, 0x12, 0x52, 0x4e, 0xe9, 0x60, 0x49, 0x8a, 0x9c, - 0xc2, 0x49, 0x24, 0x0f, 0xc7, 0x93, 0x72, 0x0a, 0xe6, 0x17, 0x8b, 0x78, 0x38, 0x1e, 0xed, 0x21, - 0xeb, 0x84, 0x24, 0xe4, 0x5d, 0x18, 0x2f, 0x75, 0x03, 0x57, 0x30, 0x16, 0x56, 0xe1, 0x91, 0xfd, - 0xb6, 0xf8, 0x14, 0xed, 0xea, 0x13, 0xa1, 0x1b, 0x7f, 0x92, 0x83, 0xf3, 0xc9, 0xe1, 0x15, 0xa5, - 0xe1, 0xfa, 0xc8, 0x9c, 0xb0, 0x3e, 0xd2, 0x66, 0x43, 0x36, 0xca, 0x0d, 0xf1, 0x34, 0x66, 0x03, - 0xcf, 0xbb, 0xfd, 0x31, 0x67, 0x43, 0x0d, 0xc6, 0xd5, 0xf3, 0x6e, 0xe8, 0xe3, 0x9e, 0x77, 0x2a, - 0x17, 0x76, 0xa9, 0xe7, 0xa1, 0x33, 0x86, 0xa3, 0xa7, 0xa3, 0x78, 0xd4, 0x0c, 0x8e, 0x41, 0xfe, - 0x2d, 0xb8, 0xc4, 0xf7, 0xa4, 0x78, 0x63, 0x97, 0x0e, 0x25, 0x47, 0x31, 0x70, 0x8b, 0xc7, 0x47, - 0xc5, 0x6b, 0x5c, 0x55, 0x62, 0x25, 0xba, 0xcd, 0xda, 0x39, 0xb4, 0xe4, 0x97, 0x29, 0x95, 0x9c, - 0xc8, 0xdb, 0x28, 0xc3, 0x79, 0x51, 0x1a, 0x39, 0x6d, 0xcb, 0x42, 0x36, 0xc8, 0x07, 0x91, 0xb6, - 0x0b, 0x07, 0x39, 0xa6, 0xc8, 0xc2, 0x72, 0xcc, 0xd8, 0xad, 0x64, 0x53, 0x7e, 0x33, 0xcd, 0xe7, - 0x86, 0x47, 0xed, 0xe6, 0x60, 0xdd, 0xdd, 0x46, 0xea, 0xd4, 0xb2, 0xa9, 0x3a, 0x35, 0xa9, 0x94, - 0xc9, 0xa5, 0x2a, 0x65, 0x2a, 0x30, 0x5d, 0xeb, 0xee, 0xc8, 0xba, 0xe3, 0xfe, 0x9a, 0x7e, 0x77, - 0x27, 0xad, 0x57, 0xe2, 0x24, 0xc6, 0x8f, 0x65, 0x61, 0x62, 0xa3, 0xd9, 0xdd, 0x73, 0xda, 0x15, - 0x3b, 0xb0, 0x9f, 0x59, 0x35, 0xdf, 0xdb, 0x9a, 0x9a, 0x2f, 0x74, 0x2d, 0x0b, 0x1b, 0x36, 0x90, - 0x8e, 0xef, 0x67, 0x33, 0x30, 0x1d, 0x91, 0xf0, 0xc3, 0x7a, 0x05, 0x86, 0xd8, 0x0f, 0x71, 0xf9, - 0xbd, 0x94, 0x60, 0xcc, 0x13, 0x43, 0x86, 0x7f, 0x09, 0xc5, 0x9b, 0x9e, 0x75, 0x0d, 0x39, 0x2c, - 0x7c, 0x0e, 0xc6, 0x22, 0xb6, 0xa7, 0x49, 0x08, 0xf9, 0xeb, 0x19, 0x28, 0xc4, 0x5b, 0x42, 0xee, - 0xc1, 0x28, 0xe3, 0xe4, 0x50, 0x79, 0x2f, 0x7f, 0xb9, 0x47, 0x9b, 0xaf, 0x09, 0x34, 0xfe, 0x79, - 0xd8, 0xf9, 0x94, 0x43, 0x4c, 0xc9, 0x61, 0xc1, 0x84, 0x09, 0x15, 0x2b, 0xe5, 0xeb, 0xde, 0xd0, - 0x25, 0x94, 0xb3, 0xe9, 0xfd, 0xa0, 0xa5, 0xb1, 0xd4, 0xbe, 0x5a, 0x08, 0x1f, 0x97, 0xb5, 0xc9, - 0x95, 0xba, 0xaa, 0x70, 0xd2, 0x2c, 0x46, 0x59, 0x0a, 0xd4, 0x79, 0x96, 0x32, 0xa1, 0x43, 0x3c, - 0xf2, 0x06, 0x8c, 0xf0, 0xfa, 0xd4, 0x14, 0x6c, 0x1d, 0x84, 0xa8, 0x72, 0x32, 0xc7, 0x31, 0xfe, - 0x6e, 0x0e, 0xce, 0x46, 0x9f, 0xb7, 0xd5, 0x69, 0xd8, 0x01, 0xdd, 0xb0, 0x3d, 0xbb, 0xe5, 0x9f, - 0xb0, 0x02, 0xae, 0x24, 0x3e, 0x0d, 0x93, 0x5f, 0xc9, 0x4f, 0x53, 0x3e, 0xc8, 0x88, 0x7d, 0x10, - 0xea, 0x40, 0xf9, 0x07, 0xc9, 0xcf, 0x20, 0xf7, 0x20, 0x57, 0xa3, 0x81, 0xd8, 0x7b, 0x2f, 0x27, - 0x7a, 0x55, 0xfd, 0xae, 0x6b, 0x35, 0x1a, 0xf0, 0x41, 0xe4, 0x71, 0xa1, 0xb4, 0xe0, 0x7c, 0x8c, - 0x0b, 0xd9, 0x86, 0x91, 0xe5, 0xc7, 0x1d, 0x5a, 0x0f, 0x44, 0x3a, 0xd3, 0xab, 0xfd, 0xf9, 0x71, - 0x5c, 0x25, 0x9b, 0x29, 0x45, 0x80, 0xda, 0x59, 0x1c, 0x65, 0xe1, 0x16, 0xe4, 0x65, 0xe5, 0xa7, - 0x99, 0xb9, 0x0b, 0x6f, 0xc3, 0xb8, 0x52, 0xc9, 0xa9, 0x26, 0xfd, 0x2f, 0xb2, 0x7d, 0xd5, 0x6d, - 0xca, 0x0c, 0xa8, 0xcb, 0x09, 0x59, 0x51, 0xc9, 0x1f, 0xc5, 0x65, 0x45, 0xeb, 0x40, 0x14, 0xf5, - 0x11, 0x1a, 0xab, 0x30, 0x5d, 0x3b, 0x70, 0x3a, 0x51, 0xa0, 0x58, 0xed, 0x44, 0xc6, 0x3c, 0x37, - 0xe2, 0xe2, 0x1e, 0x3f, 0x91, 0xe3, 0x74, 0xc6, 0x9f, 0x67, 0x60, 0x84, 0xfd, 0xf5, 0xe0, 0xd6, - 0x33, 0xba, 0x65, 0xde, 0xd4, 0xb6, 0xcc, 0x19, 0x25, 0x56, 0x3b, 0x6e, 0x1c, 0xb7, 0x4e, 0xd8, - 0x2c, 0x8f, 0xc4, 0x00, 0x71, 0x64, 0x72, 0x07, 0x46, 0x85, 0x49, 0x91, 0xb0, 0xfd, 0x56, 0x83, - 0xbf, 0x4b, 0x63, 0xa3, 0xf0, 0x86, 0xef, 0x76, 0xe2, 0x2a, 0x11, 0x49, 0xcd, 0xe4, 0x7a, 0x19, - 0xb2, 0x57, 0xcb, 0x70, 0xee, 0xa2, 0xb3, 0x1e, 0x0f, 0x5d, 0xee, 0x2f, 0x9d, 0x13, 0x9c, 0x7a, - 0xf9, 0xd6, 0x97, 0xc4, 0x6b, 0x48, 0xae, 0x1f, 0x93, 0xb3, 0x32, 0xad, 0x70, 0xea, 0x43, 0x49, - 0x0b, 0xce, 0xd6, 0x6a, 0x2b, 0x68, 0x7e, 0xb8, 0xe1, 0x7a, 0xc1, 0x6d, 0xd7, 0x7b, 0x64, 0xa3, - 0x6d, 0x31, 0x6a, 0xf8, 0x14, 0x1b, 0x84, 0x34, 0xa3, 0xb0, 0x57, 0x53, 0x8d, 0xc2, 0xfa, 0xd8, - 0x29, 0x18, 0x6d, 0x38, 0x57, 0xab, 0xad, 0xf0, 0xc0, 0xe1, 0x7f, 0x11, 0xf5, 0xfd, 0x7a, 0x06, - 0x66, 0x6a, 0xb5, 0x95, 0x58, 0x55, 0xab, 0x32, 0x62, 0x79, 0x46, 0xcf, 0xcc, 0x9d, 0xda, 0x11, - 0x38, 0x0a, 0x19, 0x2e, 0xe1, 0xd5, 0xb5, 0xe0, 0x94, 0x9c, 0x09, 0xd9, 0x08, 0x63, 0xa4, 0x67, - 0x35, 0x7f, 0x80, 0x1e, 0x0d, 0x45, 0x0d, 0xb7, 0xf0, 0xa6, 0x63, 0xa5, 0xba, 0x86, 0x9b, 0x41, - 0x8c, 0xff, 0xe6, 0x2c, 0x8f, 0xc2, 0x2e, 0x67, 0xcb, 0x7b, 0x30, 0x21, 0xe8, 0xd1, 0x68, 0x5e, - 0xd8, 0x84, 0x9c, 0x67, 0x1b, 0xe4, 0x2e, 0x87, 0xf3, 0xe8, 0xbc, 0xdf, 0x3d, 0x2a, 0x0e, 0xb1, - 0xae, 0x31, 0x35, 0x74, 0x72, 0x1f, 0x26, 0xd7, 0xec, 0xc7, 0x8a, 0x3a, 0x83, 0xbb, 0x44, 0x5d, - 0x65, 0xbb, 0x4a, 0xcb, 0x7e, 0x3c, 0x80, 0xd1, 0x9d, 0x4e, 0x4f, 0x0e, 0x60, 0x4a, 0x6f, 0x93, - 0x98, 0x81, 0xc9, 0x11, 0xbb, 0x91, 0x3a, 0x62, 0xe7, 0x3b, 0xae, 0x17, 0x58, 0xbb, 0x21, 0xb9, - 0x96, 0x71, 0x20, 0xc6, 0x9a, 0xbc, 0x07, 0x33, 0x4a, 0x08, 0xd0, 0xdb, 0xae, 0xd7, 0xb2, 0xe5, - 0x85, 0x0b, 0x75, 0xfc, 0x68, 0x4b, 0xb4, 0x8b, 0x60, 0x33, 0x89, 0x49, 0xbe, 0x92, 0xe6, 0x66, - 0x36, 0x1c, 0x59, 0x1e, 0xa6, 0xb8, 0x99, 0xf5, 0xb2, 0x3c, 0x4c, 0x3a, 0x9c, 0xed, 0xf5, 0xb3, - 0x4c, 0xce, 0xf3, 0xd6, 0x0f, 0x64, 0x79, 0x1c, 0x8e, 0x5c, 0x0f, 0x0b, 0xe4, 0x45, 0xc8, 0x2d, - 0x6d, 0xdc, 0xc6, 0x97, 0x29, 0x69, 0x44, 0xd5, 0xde, 0xb7, 0xdb, 0x75, 0xbc, 0x08, 0x09, 0x6f, - 0x00, 0xf5, 0xa0, 0x5c, 0xda, 0xb8, 0x4d, 0x6c, 0x98, 0xc5, 0xec, 0x6e, 0xc1, 0x97, 0x6f, 0xdc, - 0x50, 0x86, 0x2a, 0x8f, 0x9f, 0x76, 0x5d, 0x7c, 0x5a, 0x11, 0x73, 0xc3, 0x05, 0xd6, 0xe3, 0x1b, - 0x37, 0x52, 0x07, 0x24, 0xfc, 0xb0, 0x34, 0x5e, 0xec, 0xc0, 0x5a, 0xb3, 0x1f, 0x47, 0x4e, 0x1c, - 0xbe, 0x70, 0xd8, 0xbd, 0x20, 0xa7, 0x56, 0xe4, 0x00, 0xa2, 0x1d, 0x58, 0x3a, 0x11, 0xbb, 0xc7, - 0x46, 0x13, 0xcc, 0x17, 0xae, 0x4e, 0x0b, 0x52, 0x5d, 0x27, 0xbd, 0xba, 0xd5, 0xcb, 0x98, 0x82, - 0x4e, 0xb6, 0xc2, 0xdb, 0x38, 0xbf, 0xcd, 0x8a, 0x5c, 0xc6, 0xd7, 0xd5, 0xdb, 0x38, 0x57, 0x92, - 0x69, 0xcd, 0x9a, 0x0e, 0x55, 0x38, 0xdc, 0xab, 0xc5, 0xd4, 0xb9, 0x24, 0x2f, 0xf9, 0x13, 0xa7, - 0xbf, 0xe4, 0x53, 0x18, 0x5a, 0x75, 0xeb, 0x07, 0x22, 0x38, 0xdf, 0x97, 0xd8, 0x2e, 0xac, 0x27, - 0xbe, 0x7f, 0x52, 0x8b, 0x6b, 0x64, 0x4f, 0xd6, 0xd9, 0xa7, 0xb2, 0x59, 0x20, 0xfa, 0x44, 0x58, - 0xf1, 0xce, 0x85, 0xb7, 0x5c, 0xa5, 0x8c, 0xcb, 0xa3, 0x7c, 0xd2, 0xc8, 0xae, 0x35, 0x75, 0x72, - 0x42, 0xa1, 0x50, 0xa1, 0xfe, 0x41, 0xe0, 0x76, 0xca, 0x4d, 0xa7, 0xb3, 0xe3, 0xda, 0x9e, 0x0c, - 0xe5, 0x3c, 0xf0, 0x9e, 0xdc, 0xe0, 0xf4, 0x56, 0x5d, 0x32, 0x30, 0x13, 0x2c, 0xc9, 0x57, 0x60, - 0x8a, 0x4d, 0xee, 0xe5, 0xc7, 0x01, 0x6d, 0xf3, 0x91, 0x9f, 0x41, 0x89, 0x6e, 0x4e, 0xc9, 0x5d, - 0x12, 0x16, 0xf2, 0x39, 0x85, 0x8b, 0x9d, 0x86, 0x04, 0x5a, 0x60, 0x43, 0x8d, 0x15, 0x69, 0xc0, - 0xfc, 0x9a, 0xfd, 0x58, 0xc9, 0x9a, 0xac, 0x4c, 0x52, 0x82, 0x13, 0xec, 0xca, 0xf1, 0x51, 0xf1, - 0x65, 0x36, 0xc1, 0xa2, 0xe8, 0xe2, 0x3d, 0xe6, 0x6b, 0x4f, 0x4e, 0xe4, 0x5b, 0x70, 0x4e, 0x34, - 0xab, 0x82, 0xd9, 0xc2, 0x5c, 0xef, 0xb0, 0xb6, 0x6f, 0xa3, 0xff, 0xd6, 0x6c, 0x8f, 0x0e, 0xbb, - 0x9e, 0xbe, 0x25, 0xca, 0x0e, 0x6b, 0x48, 0x3e, 0x96, 0xcf, 0x19, 0x99, 0xbd, 0x6a, 0x20, 0x1f, - 0xc1, 0x14, 0x7f, 0x8e, 0x5b, 0x71, 0xfd, 0x00, 0x95, 0x35, 0x73, 0xa7, 0x73, 0x4b, 0xe0, 0x6f, - 0x7c, 0xdc, 0x91, 0x27, 0xa6, 0xdc, 0x89, 0x71, 0x26, 0xef, 0xc0, 0xf8, 0x86, 0xd3, 0xe6, 0xa1, - 0x47, 0xab, 0x1b, 0xa8, 0x56, 0x16, 0x27, 0x50, 0xc7, 0x69, 0x5b, 0x52, 0x63, 0xd2, 0x09, 0xb7, - 0x0b, 0x15, 0x9b, 0x6c, 0xc3, 0x78, 0xad, 0xb6, 0x72, 0xdb, 0x61, 0x72, 0x49, 0xe7, 0x70, 0xfe, - 0x6c, 0x8f, 0xaf, 0x7c, 0x29, 0xf5, 0x2b, 0x27, 0x7d, 0x7f, 0xdf, 0xda, 0x75, 0x9a, 0xd4, 0xaa, - 0xbb, 0x9d, 0x43, 0x53, 0xe5, 0x94, 0x62, 0xaa, 0x7f, 0xee, 0x29, 0x9b, 0xea, 0x57, 0x61, 0x5a, - 0x31, 0x9e, 0x45, 0xc3, 0xd9, 0xf9, 0x28, 0x5e, 0x95, 0x6a, 0x9a, 0x1f, 0x77, 0x4d, 0x8d, 0xd3, - 0x49, 0x1b, 0xfd, 0xf3, 0xa7, 0xb5, 0xd1, 0x77, 0x60, 0x86, 0x0f, 0x86, 0x98, 0x07, 0x38, 0xd2, - 0x0b, 0x3d, 0xfa, 0xf0, 0x6a, 0x6a, 0x1f, 0xce, 0x8a, 0x91, 0x96, 0x93, 0x0c, 0x9f, 0x9f, 0x93, - 0x5c, 0xc9, 0x2e, 0x10, 0x01, 0xb4, 0x03, 0x7b, 0xc7, 0xf6, 0x29, 0xd6, 0xf5, 0x7c, 0x8f, 0xba, - 0x5e, 0x4e, 0xad, 0x6b, 0x4a, 0xd6, 0xb5, 0xc3, 0xab, 0x49, 0xe1, 0x48, 0xda, 0xb2, 0x1e, 0x39, - 0xbf, 0xb0, 0x63, 0x5f, 0xd0, 0x74, 0xdc, 0x49, 0x04, 0x1e, 0xfa, 0x29, 0x3e, 0x69, 0xe3, 0xfd, - 0x9e, 0xc2, 0x99, 0x3c, 0x86, 0xb3, 0xc9, 0xaf, 0xc0, 0x3a, 0x2f, 0x60, 0x9d, 0x17, 0xb4, 0x3a, - 0xe3, 0x48, 0x7c, 0xde, 0xe8, 0xcd, 0x8a, 0xd7, 0xda, 0x83, 0x3f, 0xf9, 0xe1, 0x0c, 0x9c, 0x5b, - 0xbb, 0x5d, 0xc2, 0x1c, 0xa2, 0x0e, 0x8f, 0x44, 0x17, 0xba, 0xf4, 0x5e, 0x14, 0xef, 0x20, 0xf1, - 0xb7, 0x19, 0x29, 0x71, 0xe0, 0x56, 0xc1, 0x44, 0xf7, 0x97, 0x5a, 0xbb, 0x36, 0x4f, 0x4d, 0x2a, - 0x58, 0xa4, 0xf8, 0xfd, 0x7e, 0xfb, 0x8f, 0x8a, 0x19, 0xb3, 0x57, 0x55, 0xa4, 0x09, 0x0b, 0x7a, - 0xb7, 0x48, 0x2f, 0x8a, 0x7d, 0xda, 0x6c, 0xce, 0x17, 0x71, 0x46, 0xbf, 0x71, 0x7c, 0x54, 0xbc, - 0x92, 0xe8, 0xdd, 0xd0, 0x33, 0x83, 0x61, 0x2a, 0x0d, 0xee, 0xc3, 0x8f, 0xb4, 0x52, 0x84, 0xee, - 0xf9, 0x4b, 0x5a, 0xec, 0x9f, 0x44, 0xf9, 0xd2, 0x2b, 0x42, 0x22, 0xb9, 0xc0, 0xd6, 0x7b, 0x4f, - 0x01, 0xd1, 0x4c, 0x72, 0xbe, 0x3b, 0x94, 0x9f, 0x2c, 0x4c, 0xa5, 0xb8, 0x2c, 0x18, 0xbf, 0x9d, - 0x8d, 0x1d, 0x8c, 0xa4, 0x0a, 0xa3, 0x62, 0xbe, 0xf7, 0xbc, 0x64, 0x5c, 0x48, 0x9d, 0xd5, 0xa3, - 0x62, 0xe9, 0x98, 0x92, 0x9e, 0x3c, 0x62, 0xac, 0xb0, 0xd1, 0xe2, 0xc6, 0xfb, 0x35, 0x7e, 0xee, - 0x21, 0x48, 0x3b, 0xe1, 0x2b, 0xa7, 0x77, 0xc4, 0xd3, 0xfd, 0x3c, 0xf1, 0xa8, 0x97, 0xb5, 0x91, - 0x03, 0x9e, 0x4a, 0x2a, 0x17, 0x7a, 0x73, 0xe9, 0x79, 0xa3, 0x9e, 0x5a, 0x85, 0xac, 0x16, 0xe3, - 0xb7, 0x32, 0x30, 0xa9, 0x9d, 0xac, 0xe4, 0x96, 0xe2, 0xaa, 0x18, 0x79, 0xef, 0x6b, 0x38, 0xb8, - 0xd9, 0xc6, 0x9d, 0x18, 0x6f, 0x09, 0xbf, 0x83, 0x6c, 0x6f, 0x3a, 0x5c, 0x6c, 0x71, 0xcf, 0xd5, - 0xfe, 0xfa, 0xe1, 0x30, 0xfb, 0xe5, 0x50, 0x8f, 0xec, 0x97, 0xbf, 0x7c, 0x01, 0xa6, 0xf4, 0x1b, - 0x31, 0x79, 0x03, 0x46, 0x50, 0x37, 0x2f, 0xd5, 0x2b, 0xa8, 0x16, 0x42, 0xf5, 0xbd, 0xe6, 0x8c, - 0xc2, 0x71, 0xc8, 0x2b, 0x00, 0xa1, 0x01, 0xb8, 0x7c, 0x99, 0x1a, 0x3e, 0x3e, 0x2a, 0x66, 0xde, - 0x34, 0x95, 0x02, 0xf2, 0x75, 0x80, 0x75, 0xb7, 0x41, 0xc3, 0x94, 0xc6, 0x7d, 0xac, 0x2f, 0x5e, - 0x4d, 0xa4, 0x59, 0x39, 0xd3, 0x76, 0x1b, 0x34, 0x99, 0x53, 0x45, 0xe1, 0x48, 0xbe, 0x00, 0xc3, - 0x66, 0xb7, 0x49, 0xe5, 0x0b, 0xc6, 0xb8, 0x3c, 0xe1, 0xba, 0x4d, 0x1a, 0xe9, 0x09, 0xbc, 0x6e, - 0xdc, 0xb0, 0x90, 0x01, 0xc8, 0x07, 0x3c, 0xfd, 0x8a, 0x88, 0x11, 0x3a, 0x1c, 0xbd, 0xd5, 0x29, - 0x92, 0x4f, 0x22, 0x4a, 0xa8, 0x42, 0x42, 0xee, 0xc3, 0xa8, 0xfa, 0xc8, 0xa4, 0xf8, 0xbc, 0xab, - 0x0f, 0x91, 0x8a, 0xd2, 0x41, 0xe4, 0x42, 0x8e, 0xbf, 0x3f, 0x49, 0x2e, 0xe4, 0x5d, 0x18, 0x63, - 0xec, 0xd9, 0xce, 0xe1, 0x8b, 0x5b, 0x0d, 0xbe, 0xc8, 0x29, 0x1f, 0xc4, 0x76, 0x1f, 0x2d, 0x92, - 0x67, 0x48, 0x40, 0xbe, 0x82, 0xd9, 0x6b, 0x45, 0x57, 0xf7, 0xb5, 0xca, 0xb9, 0x9c, 0xe8, 0x6a, - 0x4c, 0x67, 0x9b, 0xe8, 0xe9, 0x88, 0x1f, 0xd9, 0x0b, 0x43, 0xae, 0x0d, 0x92, 0x32, 0xe7, 0xb5, - 0x44, 0x05, 0xf3, 0x32, 0x8a, 0x58, 0x32, 0x35, 0xb5, 0xc6, 0x97, 0x74, 0xa0, 0x10, 0x09, 0x95, - 0xa2, 0x2e, 0xe8, 0x57, 0xd7, 0x9b, 0x89, 0xba, 0xd4, 0x01, 0x4c, 0x54, 0x97, 0xe0, 0x4e, 0x1a, - 0x30, 0x25, 0x0f, 0x28, 0x51, 0xdf, 0x78, 0xbf, 0xfa, 0x5e, 0x49, 0xd4, 0x37, 0xdb, 0xd8, 0x49, - 0xd6, 0x13, 0xe3, 0x49, 0xde, 0x85, 0x49, 0x09, 0xe1, 0x89, 0xa2, 0x27, 0xa2, 0x4c, 0xbb, 0x8d, - 0x9d, 0x44, 0x7a, 0x68, 0x1d, 0x59, 0xa5, 0xe6, 0xb3, 0x63, 0x52, 0xa3, 0x8e, 0xcf, 0x0a, 0x1d, - 0x99, 0x7c, 0x08, 0xe3, 0xd5, 0x16, 0x6b, 0x88, 0xdb, 0xb6, 0x03, 0x2a, 0xfc, 0x21, 0xa5, 0x85, - 0x91, 0x52, 0xa2, 0x4c, 0x55, 0x9e, 0x02, 0x3b, 0x2a, 0xd2, 0x52, 0x60, 0x47, 0x60, 0xd6, 0x79, - 0xfc, 0x55, 0x51, 0xcc, 0x61, 0xe9, 0x2b, 0x79, 0x21, 0xc5, 0xca, 0x47, 0x61, 0x2f, 0xe2, 0x41, - 0x32, 0xa8, 0x7c, 0xd5, 0x8b, 0xc5, 0xe2, 0x55, 0x79, 0x92, 0xf7, 0x60, 0x5c, 0x64, 0x13, 0x2b, - 0x99, 0xeb, 0xfe, 0x7c, 0x01, 0x1b, 0x8f, 0x11, 0x1e, 0x64, 0xe2, 0x31, 0xcb, 0xf6, 0x62, 0xe6, - 0xac, 0x11, 0x3e, 0xf9, 0x32, 0xcc, 0x6d, 0x3b, 0xed, 0x86, 0xfb, 0xc8, 0x17, 0xc7, 0x94, 0xd8, - 0xe8, 0x66, 0x22, 0x67, 0xb2, 0x47, 0xbc, 0x3c, 0x94, 0x05, 0x13, 0x1b, 0x5f, 0x2a, 0x07, 0xf2, - 0xd7, 0x13, 0x9c, 0xf9, 0x0c, 0x22, 0xfd, 0x66, 0xd0, 0x62, 0x62, 0x06, 0x25, 0xab, 0x8f, 0x4f, - 0xa7, 0xd4, 0x6a, 0x88, 0x0b, 0x44, 0x3f, 0xdf, 0xef, 0xba, 0x4e, 0x7b, 0x7e, 0x16, 0xf7, 0xc2, - 0xe7, 0xe3, 0x31, 0x15, 0x10, 0x4f, 0xa4, 0x12, 0x37, 0x8e, 0x8f, 0x8a, 0x17, 0xe3, 0x32, 0xff, - 0x47, 0xae, 0xf6, 0x5c, 0x92, 0xc2, 0x9a, 0x7c, 0x08, 0x13, 0xec, 0xff, 0x50, 0x29, 0x31, 0xa7, - 0xd9, 0x85, 0x2a, 0x98, 0xa2, 0x1e, 0x1c, 0x23, 0x4c, 0x77, 0x96, 0xa2, 0xaf, 0xd0, 0x58, 0x91, - 0xb7, 0x01, 0x98, 0xd8, 0x24, 0xb6, 0xe3, 0x33, 0x51, 0xe8, 0x63, 0x94, 0xba, 0x92, 0x1b, 0x71, - 0x84, 0x4c, 0xde, 0x85, 0x71, 0xf6, 0xab, 0xd6, 0x6d, 0xb8, 0x6c, 0x6d, 0x9c, 0x45, 0x5a, 0xee, - 0x9a, 0xca, 0x68, 0x7d, 0x0e, 0xd7, 0x5c, 0x53, 0x23, 0x74, 0xb2, 0x02, 0xd3, 0x18, 0xa2, 0x5a, - 0x04, 0x47, 0x75, 0xa8, 0x3f, 0x7f, 0x4e, 0xb1, 0x86, 0x60, 0x45, 0x96, 0x13, 0x96, 0xa9, 0x77, - 0x99, 0x18, 0x19, 0xf1, 0x61, 0x36, 0xf9, 0x9c, 0xec, 0xcf, 0xcf, 0x63, 0x27, 0x49, 0x09, 0x3e, - 0x89, 0xc1, 0xf7, 0x63, 0x36, 0x22, 0xca, 0xc6, 0x25, 0x1f, 0x95, 0xd4, 0x0a, 0xd3, 0xb8, 0x13, - 0x13, 0xc8, 0x9d, 0xf2, 0x46, 0x3c, 0x86, 0xf3, 0x79, 0x6c, 0x01, 0x0e, 0xf3, 0x5e, 0x3d, 0xca, - 0x1d, 0x9e, 0x12, 0xc7, 0x39, 0x85, 0x9a, 0x7c, 0x2f, 0x9c, 0x91, 0x3b, 0x88, 0x28, 0x12, 0xf3, - 0x7a, 0xe1, 0x94, 0x3b, 0x71, 0x63, 0x27, 0xac, 0x3a, 0x31, 0xa5, 0xd3, 0xab, 0x20, 0x36, 0x8c, - 0xe3, 0xb0, 0x8a, 0x1a, 0x9f, 0xef, 0x57, 0xe3, 0x95, 0x44, 0x8d, 0x67, 0x71, 0xa2, 0x24, 0x2b, - 0x53, 0x79, 0x92, 0x25, 0x98, 0x14, 0xeb, 0x48, 0xcc, 0xb6, 0x17, 0xb0, 0xb7, 0x50, 0x89, 0x25, - 0x57, 0x60, 0x62, 0xc2, 0xe9, 0x24, 0xea, 0x8e, 0xcc, 0x1f, 0x93, 0x2e, 0x68, 0x3b, 0x72, 0xfc, - 0x0d, 0x49, 0x47, 0x66, 0x3b, 0x52, 0x24, 0xc5, 0x2c, 0x3f, 0xee, 0x78, 0x42, 0x45, 0x75, 0x31, - 0xca, 0x8a, 0xa4, 0x08, 0x3f, 0x16, 0x0d, 0x31, 0xd4, 0x2d, 0x21, 0x8d, 0x03, 0xd9, 0x82, 0xd9, - 0xf0, 0xd4, 0x56, 0x18, 0x17, 0xa3, 0x28, 0xc1, 0xd1, 0x51, 0x9f, 0xce, 0x37, 0x8d, 0x9e, 0xd8, - 0x70, 0x4e, 0x3b, 0xa7, 0x15, 0xd6, 0x97, 0x90, 0x35, 0xe6, 0xaa, 0xd7, 0x0f, 0xf9, 0x74, 0xf6, - 0xbd, 0xf8, 0x90, 0x8f, 0x60, 0x21, 0x7e, 0x36, 0x2b, 0xb5, 0xbc, 0x88, 0xb5, 0xbc, 0x76, 0x7c, - 0x54, 0xbc, 0x9c, 0x38, 0xde, 0xd3, 0x2b, 0xea, 0xc3, 0x8d, 0x7c, 0x1d, 0xe6, 0xf5, 0xf3, 0x59, - 0xa9, 0xc9, 0xc0, 0x9a, 0x70, 0xe9, 0x84, 0x07, 0x7b, 0x7a, 0x0d, 0x3d, 0x79, 0x90, 0x00, 0x8a, - 0xa9, 0xb3, 0x5b, 0xa9, 0xe6, 0xa5, 0xa8, 0x41, 0x89, 0x55, 0x92, 0x5e, 0xdd, 0x49, 0x2c, 0xc9, - 0x23, 0xb8, 0x98, 0x76, 0x4c, 0x28, 0x95, 0xbe, 0x1c, 0x2a, 0x81, 0x5f, 0x4f, 0x3f, 0x72, 0xd2, - 0x6b, 0x3e, 0x81, 0x2d, 0xf9, 0x0a, 0x9c, 0x51, 0xd6, 0x97, 0x52, 0xdf, 0x2b, 0x58, 0x1f, 0xba, - 0x82, 0xab, 0x0b, 0x33, 0xbd, 0x96, 0x74, 0x1e, 0xa4, 0x05, 0xb3, 0xb2, 0xe1, 0xa8, 0x6d, 0x17, - 0x47, 0xcf, 0x65, 0x6d, 0x57, 0x4d, 0x62, 0x2c, 0x5d, 0x12, 0xbb, 0xea, 0x7c, 0x63, 0xc7, 0xea, - 0x44, 0x84, 0xea, 0x4c, 0x4f, 0xe1, 0x4b, 0x56, 0x60, 0xa4, 0xb6, 0x51, 0xbd, 0x7d, 0x7b, 0x79, - 0xfe, 0x55, 0xac, 0x41, 0xfa, 0x8d, 0x71, 0xa0, 0x76, 0x69, 0x12, 0xe6, 0x8a, 0x1d, 0x67, 0x77, - 0x57, 0x7b, 0xb0, 0xe2, 0xa8, 0xe4, 0xaf, 0xa3, 0xa1, 0x20, 0xdb, 0x51, 0x4b, 0xbe, 0xef, 0xec, - 0x61, 0xd4, 0x69, 0x7f, 0xfe, 0x35, 0xed, 0xbd, 0x5f, 0x46, 0xe4, 0x2e, 0x63, 0xc2, 0xb2, 0x04, - 0x3a, 0x97, 0x36, 0xd9, 0xfd, 0x5f, 0xec, 0xdc, 0x96, 0x1d, 0xb1, 0x52, 0x37, 0xf1, 0x64, 0x45, - 0xac, 0xdf, 0xf6, 0x9c, 0xc0, 0xda, 0xef, 0x6a, 0xcd, 0x9f, 0x7f, 0x5d, 0x8b, 0xc0, 0xcc, 0xd3, - 0xb8, 0x29, 0xbd, 0xf6, 0xb2, 0xa8, 0xf0, 0x05, 0x7e, 0x5b, 0xee, 0xd1, 0x73, 0x33, 0x7b, 0x31, - 0x3a, 0xff, 0xee, 0x50, 0xfe, 0x4a, 0xe1, 0xea, 0xdd, 0xa1, 0xfc, 0xd5, 0xc2, 0x6b, 0xe6, 0x0b, - 0xb5, 0xd2, 0xda, 0x6a, 0xb5, 0x21, 0xcf, 0x15, 0x19, 0x6e, 0x9c, 0x0f, 0xad, 0x79, 0xb9, 0x5f, - 0x69, 0x34, 0xf0, 0xc6, 0xdf, 0xce, 0x40, 0xf1, 0x84, 0xfe, 0x61, 0x5b, 0x79, 0xf4, 0x11, 0x35, - 0x1a, 0xa8, 0x41, 0xcb, 0xa3, 0x4f, 0xb7, 0x74, 0x8b, 0x09, 0x9d, 0x04, 0xfd, 0xed, 0x44, 0xa6, - 0x0c, 0xc5, 0xed, 0x32, 0x99, 0x21, 0x43, 0x62, 0x19, 0xab, 0x50, 0x88, 0xf7, 0x1b, 0xf9, 0x3c, - 0x4c, 0xaa, 0x71, 0xfa, 0xe5, 0x2d, 0x9a, 0xc7, 0xd8, 0xf0, 0xf6, 0xb4, 0xb3, 0x40, 0x43, 0x34, - 0x7e, 0x31, 0x03, 0xb3, 0x29, 0x93, 0x8b, 0x5c, 0x86, 0x21, 0x4c, 0xa4, 0xa5, 0x18, 0xcc, 0xc4, - 0x12, 0x68, 0x61, 0x39, 0xf9, 0x0c, 0x8c, 0x56, 0xd6, 0x6b, 0xb5, 0xd2, 0xba, 0xbc, 0x87, 0xf3, - 0x33, 0xa8, 0xed, 0x5b, 0xbe, 0xad, 0xbf, 0xb3, 0x0b, 0x34, 0xf2, 0x26, 0x8c, 0x54, 0x37, 0x90, - 0x80, 0x9b, 0x7d, 0x62, 0x7b, 0x9d, 0x4e, 0x1c, 0x5f, 0x20, 0x19, 0x3f, 0x91, 0x01, 0x92, 0x5c, - 0x29, 0xe4, 0x06, 0x8c, 0xab, 0xeb, 0x91, 0xb7, 0x17, 0x1f, 0x1f, 0x95, 0x39, 0x63, 0xaa, 0x38, - 0xa4, 0x02, 0xc3, 0x98, 0x02, 0x35, 0x7c, 0xe0, 0x4f, 0x3d, 0xd5, 0xcf, 0x25, 0x4e, 0xf5, 0x61, - 0x4c, 0xb0, 0x6a, 0x72, 0x62, 0xe3, 0x77, 0x33, 0x40, 0xd2, 0xcd, 0xf6, 0x06, 0x32, 0x30, 0x7a, - 0x4b, 0x71, 0xdb, 0x57, 0x53, 0xe5, 0x84, 0x79, 0xce, 0xd4, 0x1b, 0x70, 0xe4, 0xe0, 0x7f, 0x59, - 0xd3, 0xb8, 0xf4, 0xf6, 0xf5, 0xbc, 0x0a, 0xc3, 0x0f, 0xa8, 0xb7, 0x23, 0x2d, 0x9a, 0xd1, 0x0a, - 0xf2, 0x21, 0x03, 0xa8, 0x1a, 0x08, 0xc4, 0x30, 0xfe, 0x24, 0x03, 0x73, 0x69, 0xe2, 0xf9, 0x09, - 0x2e, 0x99, 0x46, 0xcc, 0x9b, 0x14, 0x8d, 0x8b, 0xb8, 0x89, 0x64, 0xe8, 0x43, 0x5a, 0x84, 0x61, - 0xd6, 0x58, 0x39, 0xc2, 0xa8, 0x01, 0x62, 0xbd, 0xe1, 0x9b, 0x1c, 0xce, 0x10, 0x78, 0x78, 0xba, - 0x21, 0x8c, 0x6c, 0x88, 0x08, 0x38, 0xbb, 0x4d, 0x0e, 0x67, 0x08, 0x6b, 0x6e, 0x23, 0xcc, 0xfe, - 0x8f, 0x08, 0x2d, 0x06, 0x30, 0x39, 0x9c, 0x5c, 0x86, 0xd1, 0xfb, 0xed, 0x55, 0x6a, 0x3f, 0x94, - 0xe9, 0x1a, 0xd0, 0x18, 0xca, 0x6d, 0x5b, 0x4d, 0x06, 0x33, 0x65, 0xa1, 0xf1, 0xb3, 0x19, 0x98, - 0x49, 0xdc, 0x0c, 0x4e, 0xf6, 0x3a, 0xed, 0xef, 0xfe, 0x35, 0x48, 0xfb, 0xf8, 0xe7, 0x0f, 0xa5, - 0x7f, 0xbe, 0xf1, 0xdf, 0x8d, 0xc0, 0xb9, 0x1e, 0x8a, 0x9a, 0xc8, 0x3d, 0x35, 0x73, 0xa2, 0x7b, - 0xea, 0x57, 0x61, 0xb2, 0xdc, 0xb4, 0x9d, 0x96, 0xbf, 0xe9, 0x46, 0x5f, 0x1c, 0x79, 0xb9, 0x60, - 0x99, 0x70, 0x01, 0x08, 0xdd, 0x21, 0xce, 0xd7, 0x91, 0xc2, 0x0a, 0xdc, 0xa4, 0x9c, 0xa8, 0x31, - 0x4b, 0x38, 0x88, 0xe6, 0xfe, 0x92, 0x38, 0x88, 0xea, 0x2e, 0x4b, 0x43, 0x4f, 0xd5, 0x65, 0x29, - 0xdd, 0xdc, 0x79, 0xf8, 0x49, 0x8c, 0xdf, 0xcb, 0x30, 0xc9, 0xad, 0xc1, 0x4a, 0x3e, 0x1f, 0xa4, - 0x91, 0x84, 0x05, 0x99, 0xed, 0x27, 0xc7, 0x42, 0xa3, 0x21, 0x2b, 0xba, 0x7b, 0xcd, 0x28, 0x3e, - 0x97, 0x5e, 0xee, 0xed, 0x3e, 0xa3, 0x99, 0x49, 0x68, 0x6e, 0x34, 0xdf, 0x82, 0xb9, 0xb4, 0x9b, - 0xde, 0x7c, 0x5e, 0x33, 0x34, 0xed, 0x69, 0xa0, 0x3c, 0xf8, 0x7d, 0xf1, 0x20, 0xf5, 0xbe, 0x28, - 0xdd, 0x9e, 0xc7, 0xb4, 0x68, 0xc6, 0x3d, 0xd6, 0x02, 0xc7, 0xed, 0xef, 0x1c, 0x6d, 0x7c, 0x15, - 0x2e, 0xf4, 0x25, 0x27, 0xef, 0x68, 0xe1, 0x75, 0x5e, 0x4d, 0x86, 0xd7, 0xf9, 0xee, 0x51, 0x71, - 0x46, 0x73, 0x59, 0x5c, 0x0b, 0x75, 0xdd, 0xc6, 0xcf, 0x66, 0x75, 0x67, 0xdb, 0xbf, 0x8c, 0x0b, - 0xf5, 0x2a, 0x0c, 0x6f, 0xef, 0x53, 0x4f, 0x1e, 0x0f, 0xf8, 0x21, 0x8f, 0x18, 0x40, 0xfd, 0x10, - 0xc4, 0x20, 0xb7, 0x61, 0x6a, 0x83, 0x4f, 0x5c, 0x39, 0x1b, 0x87, 0x22, 0x75, 0x43, 0x47, 0x28, - 0xc5, 0x52, 0xa6, 0x63, 0x8c, 0xca, 0xb8, 0x13, 0xeb, 0x74, 0x11, 0x1c, 0x88, 0x3b, 0x05, 0x71, - 0x01, 0x62, 0x2a, 0x72, 0x83, 0x8a, 0x36, 0x5b, 0x33, 0x06, 0x35, 0x76, 0xe1, 0x62, 0x5f, 0x46, - 0xec, 0xdc, 0x86, 0x4e, 0xf8, 0x2b, 0x66, 0x74, 0xdc, 0x97, 0xd4, 0x54, 0xe8, 0x8c, 0x6f, 0xc1, - 0x84, 0xda, 0xcb, 0x78, 0x04, 0xb1, 0xdf, 0x62, 0x56, 0xf0, 0x23, 0x88, 0x01, 0x4c, 0x0e, 0x8f, - 0x9e, 0x31, 0xb2, 0xe9, 0xcf, 0x18, 0xd1, 0xf0, 0xe7, 0x4e, 0x1a, 0x7e, 0x56, 0x39, 0xee, 0x70, - 0x4a, 0xe5, 0xf8, 0x5b, 0xad, 0x1c, 0xa3, 0xff, 0x98, 0x1c, 0xfe, 0x54, 0x2b, 0xff, 0x27, 0x32, - 0xbf, 0x17, 0xfa, 0x1c, 0xc9, 0xe5, 0x9e, 0x89, 0x92, 0x74, 0xa5, 0xad, 0xde, 0x08, 0x33, 0x92, - 0x29, 0xb2, 0x27, 0xc9, 0x14, 0xa7, 0x99, 0x88, 0x28, 0xf7, 0xf2, 0x21, 0x1d, 0x8a, 0xe4, 0x40, - 0x3b, 0x61, 0xe8, 0x21, 0xb1, 0x8c, 0x6f, 0x67, 0xe0, 0x4c, 0xaa, 0xba, 0x98, 0xd5, 0xca, 0xf5, - 0xd2, 0xca, 0x3a, 0x8c, 0x2b, 0xa5, 0x39, 0xc6, 0x69, 0x42, 0x3f, 0x0c, 0xde, 0x16, 0xe3, 0x45, - 0x18, 0x0b, 0x1f, 0x2b, 0xc9, 0x9c, 0x1c, 0x3a, 0x34, 0x09, 0x94, 0x6f, 0x5e, 0x35, 0x00, 0xf6, - 0x05, 0x4f, 0xd5, 0xaa, 0xd8, 0xf8, 0x27, 0x59, 0x9e, 0xfb, 0xf5, 0x99, 0x8d, 0xe2, 0x9a, 0x6e, - 0x0a, 0xcc, 0x9a, 0xd4, 0x3b, 0x76, 0x2b, 0x59, 0x86, 0x91, 0x5a, 0x60, 0x07, 0x5d, 0x19, 0xb1, - 0x62, 0x56, 0x25, 0xc3, 0x82, 0x07, 0x8b, 0x51, 0xcc, 0x02, 0x1f, 0x21, 0xda, 0x05, 0x19, 0x21, - 0x8a, 0x45, 0xf1, 0x1f, 0x64, 0x60, 0x42, 0x25, 0x26, 0x1f, 0xc2, 0x94, 0x8c, 0x4d, 0xc9, 0xe3, - 0x78, 0x88, 0x97, 0x55, 0x69, 0x05, 0x25, 0x63, 0x53, 0xaa, 0x71, 0x3f, 0x34, 0x7c, 0x75, 0xab, - 0xee, 0xa8, 0xc8, 0xa4, 0x01, 0xa4, 0xb5, 0x6b, 0x5b, 0x8f, 0xa8, 0x7d, 0x40, 0xfd, 0xc0, 0xe2, - 0xd6, 0x2a, 0xe2, 0x01, 0x56, 0xb2, 0x5f, 0xbb, 0x5d, 0xe2, 0x86, 0x2a, 0x6c, 0x24, 0x44, 0x90, - 0xd1, 0x04, 0x8d, 0xfa, 0xaa, 0xd4, 0xda, 0xb5, 0xb7, 0x79, 0x21, 0xa7, 0x33, 0xfe, 0x74, 0x84, - 0x4f, 0x37, 0x11, 0xca, 0x76, 0x07, 0xa6, 0xee, 0x57, 0x2b, 0x65, 0x45, 0xc7, 0xac, 0x67, 0x42, - 0x5a, 0x7e, 0x1c, 0x50, 0xaf, 0x6d, 0x37, 0xe5, 0x7d, 0x37, 0x3a, 0x82, 0x5c, 0xa7, 0x51, 0x4f, - 0xd7, 0x3f, 0xc7, 0x38, 0xb2, 0x3a, 0xf8, 0xcd, 0x3a, 0xac, 0x23, 0x3b, 0x60, 0x1d, 0xbe, 0xdd, - 0x6a, 0xf6, 0xa8, 0x43, 0xe7, 0x48, 0xf6, 0xf1, 0xea, 0xbb, 0xdf, 0xdd, 0x51, 0x6a, 0xc9, 0xf5, - 0xaf, 0xe5, 0x25, 0x51, 0xcb, 0xf3, 0x42, 0xa3, 0x90, 0x5a, 0x4f, 0x82, 0x6b, 0xb4, 0x4f, 0x0c, - 0x9d, 0xb8, 0x4f, 0xfc, 0x8d, 0x0c, 0x8c, 0x70, 0xf1, 0x55, 0x4c, 0xe3, 0x1e, 0x02, 0xf2, 0xf6, - 0xd3, 0x11, 0x90, 0x0b, 0x78, 0x4e, 0x68, 0x13, 0x9a, 0x97, 0x91, 0x4a, 0x6c, 0x5d, 0x48, 0x43, - 0x78, 0x7c, 0x2d, 0xe2, 0x25, 0x27, 0x2f, 0x0b, 0x52, 0x8d, 0xa2, 0x48, 0x8c, 0x9e, 0xe8, 0xa8, - 0x2c, 0x23, 0x6f, 0x8c, 0x8a, 0x28, 0x12, 0x7a, 0xec, 0x88, 0x55, 0x18, 0x13, 0xb1, 0x29, 0x96, - 0x0e, 0xc5, 0x9b, 0x70, 0x41, 0xb3, 0xea, 0x69, 0x2c, 0x1d, 0x46, 0xa2, 0xb9, 0x88, 0x6e, 0x61, - 0xed, 0x1c, 0x6a, 0xa9, 0x74, 0x25, 0x22, 0xb9, 0xcf, 0x53, 0x4c, 0xf2, 0x60, 0xbf, 0x7a, 0x74, - 0xff, 0x10, 0x2e, 0xa2, 0x5e, 0x49, 0x07, 0xf7, 0x94, 0xd8, 0xbe, 0x11, 0x0f, 0xb2, 0x0a, 0x05, - 0xb4, 0x04, 0xa3, 0x0d, 0xbe, 0x6a, 0xaa, 0x15, 0x1e, 0xff, 0x40, 0x58, 0xf3, 0x06, 0xbc, 0x4c, - 0x2c, 0xb7, 0x98, 0xeb, 0x61, 0x82, 0x92, 0x5d, 0xa7, 0x0b, 0xf1, 0xd9, 0x47, 0xde, 0x85, 0xf1, - 0x30, 0xd8, 0x72, 0xe8, 0xfc, 0x8c, 0x6f, 0x43, 0x51, 0x74, 0x66, 0x3d, 0x31, 0xa1, 0x82, 0x4e, - 0x16, 0x21, 0xcf, 0x16, 0x71, 0x3c, 0x89, 0x6f, 0x57, 0xc0, 0x54, 0x67, 0x24, 0x89, 0x47, 0x6a, - 0x30, 0xcb, 0x16, 0x4d, 0xcd, 0x69, 0xef, 0x35, 0xe9, 0xaa, 0xbb, 0xe7, 0x76, 0x83, 0x28, 0x4f, - 0x1f, 0xbf, 0xc0, 0xd8, 0xad, 0xa6, 0x56, 0xac, 0x67, 0xe9, 0x4b, 0xa1, 0x56, 0xb6, 0xca, 0x3f, - 0xca, 0xc2, 0xb8, 0x32, 0x9f, 0xc8, 0x55, 0xc8, 0x57, 0xfd, 0x55, 0xb7, 0x7e, 0x10, 0x86, 0x45, - 0x9c, 0x3c, 0x3e, 0x2a, 0x8e, 0x39, 0xbe, 0xd5, 0x44, 0xa0, 0x19, 0x16, 0x93, 0x25, 0x98, 0xe4, - 0x7f, 0xc9, 0x24, 0x18, 0xd9, 0x48, 0x59, 0xc6, 0x91, 0x65, 0xfa, 0x0b, 0x75, 0xf7, 0xd4, 0x48, - 0xc8, 0xd7, 0x00, 0x38, 0x00, 0x1d, 0xe9, 0x73, 0x83, 0x87, 0x00, 0x10, 0x15, 0xa4, 0xb8, 0xd0, - 0x2b, 0x0c, 0xc9, 0x37, 0x78, 0x70, 0x66, 0x39, 0xff, 0x87, 0x06, 0x8f, 0x61, 0xc0, 0xf8, 0x5b, - 0xe9, 0xa1, 0x54, 0x54, 0x96, 0x22, 0x6f, 0xcd, 0x82, 0x49, 0xeb, 0xee, 0x43, 0xea, 0x1d, 0x96, - 0x02, 0x44, 0x54, 0x30, 0x8c, 0xff, 0x35, 0xa3, 0xac, 0x1a, 0xb2, 0x8e, 0x79, 0xa7, 0xf9, 0x8c, - 0x10, 0xe6, 0x51, 0xe1, 0x9d, 0x41, 0xc2, 0x4d, 0xba, 0xbb, 0xf4, 0xbc, 0xb0, 0xd4, 0x9a, 0x0d, - 0xe7, 0x55, 0x2c, 0x1f, 0x35, 0x07, 0x92, 0x2f, 0xc2, 0x10, 0x76, 0x5d, 0xf6, 0xc4, 0xa6, 0xc9, - 0x63, 0x7b, 0x88, 0xf5, 0x19, 0x36, 0x04, 0x29, 0xc9, 0x67, 0x84, 0x13, 0x32, 0xef, 0xfc, 0x29, - 0xe5, 0xec, 0x65, 0xdf, 0x11, 0x9e, 0xd7, 0x51, 0x34, 0x1d, 0x65, 0xf6, 0xfc, 0xed, 0x2c, 0x14, - 0xe2, 0x6b, 0x95, 0x7c, 0x00, 0x13, 0xf2, 0x3c, 0x5d, 0xb1, 0x45, 0x06, 0x87, 0x09, 0x91, 0x41, - 0x41, 0x1e, 0xaa, 0xfb, 0xb6, 0x6a, 0x4e, 0x65, 0x6a, 0x04, 0x4c, 0xb8, 0xd9, 0x14, 0xd1, 0xed, - 0x94, 0x55, 0x12, 0xb8, 0x41, 0x27, 0x16, 0x13, 0x58, 0xa2, 0x91, 0xb7, 0x20, 0xb7, 0x76, 0xbb, - 0x24, 0x9c, 0xd5, 0x0a, 0xf1, 0x53, 0x97, 0x5b, 0x7d, 0xea, 0x36, 0xa8, 0x0c, 0x9f, 0xac, 0x2a, - 0xe1, 0xb3, 0x47, 0x34, 0xd3, 0x39, 0x09, 0x0e, 0x1b, 0x77, 0x72, 0x1c, 0xed, 0xbb, 0x43, 0xf9, - 0x5c, 0x61, 0x48, 0x04, 0x84, 0xfd, 0x1f, 0x72, 0x30, 0x16, 0xd6, 0x4f, 0x88, 0xea, 0x02, 0xcc, - 0xdd, 0x7d, 0xc9, 0x79, 0xc8, 0x4b, 0x71, 0x4d, 0xf8, 0xac, 0x8d, 0xfa, 0x42, 0x54, 0x9b, 0x07, - 0x29, 0x97, 0xf1, 0x65, 0x6e, 0xca, 0x9f, 0xe4, 0x06, 0x84, 0x42, 0x57, 0x2f, 0xe9, 0x6c, 0x88, - 0x0d, 0x98, 0x19, 0xa2, 0x91, 0x29, 0xc8, 0x3a, 0x3c, 0xc8, 0xd8, 0x98, 0x99, 0x75, 0x1a, 0xe4, - 0x03, 0xc8, 0xdb, 0x8d, 0x06, 0x6d, 0x58, 0xb6, 0xb4, 0x33, 0xea, 0x37, 0x69, 0xf2, 0x8c, 0x1b, - 0x3f, 0x04, 0x90, 0xaa, 0x14, 0x90, 0x12, 0x8c, 0x35, 0x6d, 0x6e, 0xb9, 0xd8, 0x18, 0xe0, 0x44, - 0x89, 0x38, 0xe4, 0x19, 0xd9, 0x96, 0x4f, 0x1b, 0xe4, 0x55, 0x18, 0x62, 0xa3, 0x29, 0x8e, 0x10, - 0x29, 0x25, 0xb2, 0xc1, 0xe4, 0x1d, 0xb6, 0xf2, 0x9c, 0x89, 0x08, 0xe4, 0x65, 0xc8, 0x75, 0x17, - 0x77, 0xc5, 0xe1, 0x50, 0x88, 0x42, 0xd9, 0x87, 0x68, 0xac, 0x98, 0xdc, 0x84, 0xfc, 0x23, 0x3d, - 0x0a, 0xfa, 0x99, 0xd8, 0x30, 0x86, 0xf8, 0x21, 0x22, 0x79, 0x15, 0x72, 0xbe, 0xef, 0x0a, 0xe3, - 0x9c, 0xd9, 0xd0, 0x62, 0xf2, 0x7e, 0x38, 0x6a, 0x8c, 0xbb, 0xef, 0xbb, 0x4b, 0x79, 0x18, 0xe1, - 0x27, 0x86, 0x71, 0x11, 0x20, 0xfa, 0xc6, 0xa4, 0x0f, 0xa2, 0xf1, 0x35, 0x18, 0x0b, 0xbf, 0x8d, - 0x5c, 0x00, 0x38, 0xa0, 0x87, 0xd6, 0xbe, 0xdd, 0x6e, 0x34, 0xb9, 0xb8, 0x39, 0x61, 0x8e, 0x1d, - 0xd0, 0xc3, 0x15, 0x04, 0x90, 0x73, 0x30, 0xda, 0x61, 0xc3, 0x2f, 0xe6, 0xf8, 0x84, 0x39, 0xd2, - 0xe9, 0xee, 0xb0, 0xa9, 0x3c, 0x0f, 0xa3, 0xa8, 0x38, 0x15, 0x2b, 0x72, 0xd2, 0x94, 0x3f, 0x8d, - 0x3f, 0xcb, 0x61, 0xaa, 0x20, 0xa5, 0x41, 0xe4, 0x25, 0x98, 0xac, 0x7b, 0x14, 0x0f, 0x27, 0x9b, - 0x89, 0x5c, 0xa2, 0x9e, 0x89, 0x08, 0x58, 0x6d, 0x90, 0xcb, 0x30, 0xdd, 0xe9, 0xee, 0x34, 0x9d, - 0x3a, 0xab, 0xcd, 0xaa, 0xef, 0x88, 0xdc, 0x06, 0x13, 0xe6, 0x24, 0x07, 0xdf, 0xa3, 0x87, 0xe5, - 0x1d, 0x8c, 0xa2, 0x57, 0x50, 0x83, 0x20, 0x07, 0x61, 0x12, 0x77, 0x73, 0x5a, 0x81, 0xa3, 0x9d, - 0xe1, 0x59, 0x18, 0xb1, 0xed, 0xbd, 0xae, 0xc3, 0xa3, 0x5d, 0x4d, 0x98, 0xe2, 0x17, 0x79, 0x1d, - 0x66, 0xa2, 0xb8, 0xdc, 0xb2, 0x19, 0xc3, 0xd8, 0x8c, 0x42, 0x58, 0x50, 0xe6, 0x70, 0xf2, 0x26, - 0x10, 0xb5, 0x3e, 0x77, 0xe7, 0x23, 0x5a, 0xe7, 0x73, 0x72, 0xc2, 0x9c, 0x51, 0x4a, 0xee, 0x63, - 0x01, 0x79, 0x11, 0x26, 0x3c, 0xea, 0xa3, 0xb8, 0x87, 0xdd, 0x86, 0x99, 0xf4, 0xcc, 0x71, 0x09, - 0x63, 0x7d, 0x77, 0x05, 0x0a, 0x4a, 0x77, 0x60, 0x9c, 0x69, 0x1e, 0xd8, 0xdf, 0x9c, 0x8a, 0xe0, - 0x66, 0xa7, 0xda, 0x20, 0x5f, 0x86, 0x05, 0x05, 0x93, 0x27, 0xf5, 0xb3, 0x68, 0xd3, 0xd9, 0x73, - 0x76, 0x9a, 0x54, 0xcc, 0xb7, 0xe4, 0xac, 0x0e, 0xef, 0x84, 0xe6, 0x7c, 0x44, 0xcd, 0xd3, 0xfd, - 0x2d, 0x0b, 0x5a, 0xb2, 0x0a, 0x73, 0x31, 0xce, 0xb4, 0x61, 0x75, 0x3b, 0x3d, 0xc3, 0xcb, 0x45, - 0x3c, 0x89, 0xce, 0x93, 0x36, 0xb6, 0x3a, 0xc6, 0xb7, 0x60, 0x42, 0x9d, 0x93, 0xac, 0x13, 0x54, - 0x41, 0x43, 0xcc, 0xbe, 0xf1, 0x10, 0x56, 0x65, 0x17, 0xbd, 0xa9, 0x08, 0x25, 0x08, 0xf3, 0xd5, - 0x9b, 0x93, 0x21, 0x14, 0x87, 0xf0, 0x45, 0x98, 0x68, 0x38, 0x7e, 0xa7, 0x69, 0x1f, 0x5a, 0x51, - 0xb6, 0x6a, 0x73, 0x5c, 0xc0, 0x50, 0x93, 0xb3, 0x04, 0x33, 0x89, 0x7d, 0x90, 0xbc, 0xc9, 0x6f, - 0xa8, 0x42, 0xf8, 0x99, 0xe0, 0xb7, 0x7c, 0xb4, 0x62, 0xd6, 0xe4, 0x1e, 0x81, 0x64, 0xb4, 0x61, - 0x42, 0x3d, 0xd7, 0x4e, 0x48, 0xc2, 0x71, 0x16, 0x43, 0xca, 0xf0, 0x4d, 0x7f, 0xe4, 0xf8, 0xa8, - 0x98, 0x75, 0x1a, 0x18, 0x48, 0xe6, 0x0a, 0xe4, 0xa5, 0x08, 0x26, 0x24, 0x1f, 0x7c, 0x1d, 0x90, - 0x19, 0x8a, 0xcd, 0xb0, 0xd4, 0x78, 0x15, 0x46, 0xc5, 0xd1, 0xd5, 0xff, 0x4d, 0xc0, 0xf8, 0x91, - 0x2c, 0x4c, 0x9b, 0x94, 0x6d, 0xac, 0x94, 0x67, 0xde, 0x79, 0x66, 0xef, 0xdc, 0xe9, 0x81, 0x49, - 0xb5, 0xb6, 0xf5, 0xc9, 0x79, 0xf3, 0x0f, 0x33, 0x30, 0x9b, 0x82, 0xfb, 0xb1, 0x72, 0xbe, 0xde, - 0x82, 0xb1, 0x8a, 0x63, 0x37, 0x4b, 0x8d, 0x46, 0x18, 0x5f, 0x06, 0x05, 0x77, 0x4c, 0x0c, 0x65, - 0x33, 0xa8, 0x2a, 0xc4, 0x84, 0xa8, 0xe4, 0x35, 0x31, 0x29, 0xa2, 0x8c, 0xe9, 0x38, 0x29, 0xbe, - 0x7b, 0x54, 0x04, 0xfe, 0x4d, 0x9b, 0xe1, 0x14, 0xc1, 0x60, 0xc1, 0x1c, 0x18, 0xf9, 0x08, 0x3d, - 0xb3, 0x43, 0x97, 0x1e, 0x2c, 0x38, 0xde, 0xbc, 0x81, 0xd2, 0xde, 0xfc, 0x64, 0x16, 0xce, 0xa6, - 0x13, 0x7e, 0xdc, 0xf4, 0xbd, 0x98, 0x70, 0x48, 0x09, 0x70, 0x8e, 0xe9, 0x7b, 0x79, 0x76, 0x22, - 0xc4, 0x8f, 0x10, 0xc8, 0x2e, 0x4c, 0xae, 0xda, 0x7e, 0xb0, 0x42, 0x6d, 0x2f, 0xd8, 0xa1, 0x76, - 0x30, 0x80, 0x24, 0x2f, 0x2d, 0x03, 0xe6, 0x51, 0x98, 0xd8, 0x97, 0x94, 0x31, 0x59, 0x5b, 0x67, - 0x1b, 0x4e, 0x94, 0xa1, 0x01, 0x26, 0xca, 0x37, 0x61, 0xba, 0x46, 0x5b, 0x76, 0x67, 0xdf, 0xf5, - 0xa4, 0xef, 0xff, 0x35, 0x98, 0x0c, 0x41, 0xa9, 0xb3, 0x45, 0x2f, 0xd6, 0xf0, 0x95, 0x8e, 0x88, - 0xb6, 0x12, 0xbd, 0xd8, 0xf8, 0x3b, 0x59, 0x38, 0x57, 0xaa, 0x0b, 0x33, 0x47, 0x51, 0x20, 0xad, - 0xb1, 0x3f, 0xe1, 0xba, 0xc9, 0x75, 0x18, 0x5b, 0xb3, 0x1f, 0xaf, 0x52, 0xdb, 0xa7, 0xbe, 0x48, - 0x9e, 0xc8, 0xc5, 0x5e, 0xfb, 0x71, 0xf4, 0x9a, 0x63, 0x46, 0x38, 0xaa, 0x5e, 0x60, 0xe8, 0x09, - 0xf5, 0x02, 0x06, 0x8c, 0xac, 0xb8, 0xcd, 0x86, 0x38, 0xeb, 0xc5, 0x13, 0xf2, 0x3e, 0x42, 0x4c, - 0x51, 0xc2, 0xae, 0xd3, 0x53, 0xe1, 0x17, 0xe3, 0x27, 0x7c, 0xe2, 0x5d, 0x72, 0x19, 0x46, 0xb1, - 0xa2, 0x30, 0xcb, 0x3b, 0x1e, 0x1a, 0x4d, 0x8a, 0x29, 0xf0, 0x1a, 0xa6, 0x2c, 0x54, 0x7b, 0x62, - 0xf8, 0xc9, 0x7a, 0xc2, 0xf8, 0x07, 0xf8, 0x3a, 0xad, 0xb6, 0x92, 0x9d, 0x44, 0xca, 0x87, 0x64, - 0x06, 0xfc, 0x90, 0xec, 0x53, 0x1b, 0x92, 0x5c, 0xcf, 0x21, 0xf9, 0xd1, 0x2c, 0x8c, 0x87, 0x1f, - 0xfb, 0x29, 0x8b, 0xb2, 0x1f, 0xb6, 0x6b, 0xa0, 0x78, 0x3d, 0x35, 0x65, 0xaf, 0x10, 0x61, 0x71, - 0xbe, 0x08, 0x23, 0x62, 0x31, 0x65, 0x62, 0x56, 0xc9, 0xb1, 0xd1, 0x5d, 0x9a, 0x12, 0xac, 0x47, - 0x70, 0x40, 0x7d, 0x53, 0xd0, 0x61, 0x40, 0xa4, 0x6d, 0xba, 0x23, 0x8c, 0x15, 0x9e, 0xd9, 0x33, - 0x2a, 0x3d, 0x20, 0x52, 0xd4, 0xb0, 0x81, 0x4e, 0xa7, 0x7f, 0x9a, 0x87, 0x42, 0x9c, 0xe4, 0xe4, - 0x3c, 0x06, 0x1b, 0xdd, 0x1d, 0x7e, 0x55, 0xe1, 0x79, 0x0c, 0x3a, 0xdd, 0x1d, 0x93, 0xc1, 0xd0, - 0x96, 0xc9, 0x73, 0x1e, 0x62, 0xab, 0x27, 0x84, 0x2d, 0x93, 0xe7, 0x3c, 0xd4, 0x6c, 0x99, 0x3c, - 0xe7, 0x21, 0x2a, 0x12, 0x56, 0x6b, 0x18, 0x2c, 0x00, 0xef, 0x29, 0x42, 0x91, 0xd0, 0xf4, 0xe3, - 0x39, 0xc9, 0x24, 0x1a, 0x3b, 0x2a, 0x97, 0xa8, 0xed, 0x89, 0x98, 0xfb, 0x62, 0x3b, 0xc3, 0xa3, - 0x72, 0x07, 0xc1, 0x56, 0xc0, 0xe0, 0xa6, 0x8a, 0x44, 0x9a, 0x40, 0x94, 0x9f, 0x72, 0x01, 0x9f, - 0x7c, 0xb7, 0x96, 0x16, 0x85, 0x73, 0x2a, 0x6b, 0x4b, 0x5d, 0xcd, 0x29, 0x7c, 0x9f, 0xa6, 0x3a, - 0x77, 0x43, 0x04, 0x12, 0x45, 0x05, 0x52, 0xfe, 0x44, 0x66, 0x32, 0xc8, 0x09, 0xf0, 0x40, 0xa3, - 0xa1, 0x1a, 0x29, 0x62, 0x42, 0xde, 0x87, 0x71, 0x35, 0x04, 0x04, 0x0f, 0x54, 0xf0, 0x02, 0x8f, - 0x0d, 0xd9, 0x23, 0x8b, 0xad, 0x4a, 0x40, 0x76, 0xe0, 0x5c, 0xd9, 0x6d, 0xfb, 0xdd, 0x96, 0x8c, - 0x42, 0x19, 0xc5, 0xbe, 0x06, 0x1c, 0x0a, 0xf4, 0x27, 0xaf, 0x0b, 0x14, 0x11, 0x71, 0x40, 0xba, - 0x7c, 0xe8, 0x17, 0x90, 0x5e, 0x8c, 0xc8, 0x26, 0x8c, 0xa3, 0x4a, 0x54, 0xd8, 0x94, 0x8e, 0xeb, - 0xdb, 0x46, 0x54, 0x52, 0x61, 0x0b, 0x83, 0x47, 0x40, 0xb3, 0x5b, 0x4d, 0xe9, 0x71, 0xa0, 0xaa, - 0x76, 0x15, 0x64, 0xf2, 0x35, 0x98, 0xe2, 0x57, 0xb4, 0x6d, 0xba, 0xc3, 0xe7, 0xce, 0x84, 0xa6, - 0x89, 0xd0, 0x0b, 0xf9, 0xeb, 0xbc, 0x50, 0x44, 0x3f, 0xa2, 0x3b, 0x7c, 0xec, 0x35, 0x7f, 0x1f, - 0x0d, 0x9f, 0x6c, 0xc1, 0xec, 0x8a, 0xed, 0x73, 0xa0, 0xe2, 0xcb, 0x3f, 0x89, 0x1a, 0x5a, 0xb4, - 0xc3, 0xde, 0xb7, 0x7d, 0xa9, 0xd9, 0x4e, 0xf5, 0xdd, 0x4f, 0xa3, 0x27, 0x3f, 0x92, 0x81, 0x79, - 0x4d, 0xf1, 0x2d, 0x0c, 0xc7, 0x5a, 0xb4, 0x1d, 0xa0, 0x63, 0xcf, 0xd4, 0x62, 0x51, 0x0a, 0xa5, - 0x3d, 0xd0, 0xf8, 0x90, 0xc4, 0x74, 0xeb, 0x5e, 0x54, 0xae, 0x1a, 0x38, 0xf7, 0xe2, 0x21, 0x16, - 0x2a, 0xae, 0xe9, 0x69, 0x7d, 0xa1, 0xc6, 0xd6, 0xb5, 0x44, 0x33, 0x6e, 0xc5, 0xfb, 0x5b, 0x28, - 0xba, 0x32, 0xa1, 0xa2, 0x6b, 0x0e, 0x86, 0xb1, 0x57, 0x65, 0x44, 0x28, 0xfc, 0x61, 0x7c, 0x46, - 0xdd, 0x87, 0x84, 0x58, 0xd8, 0x77, 0x1f, 0x32, 0xfe, 0xa7, 0x11, 0x98, 0x8e, 0x4d, 0x0b, 0x71, - 0x4f, 0xcd, 0x24, 0xee, 0xa9, 0x35, 0x00, 0xae, 0xea, 0x1d, 0x50, 0x27, 0x2b, 0x9d, 0x0a, 0xc7, - 0x85, 0x4b, 0x70, 0xb8, 0xa6, 0x14, 0x36, 0x8c, 0x29, 0x5f, 0xb1, 0x03, 0xea, 0xc8, 0x43, 0xa6, - 0x7c, 0xd1, 0x2b, 0x4c, 0x23, 0x36, 0xa4, 0x08, 0xc3, 0x18, 0x0b, 0x56, 0xf5, 0xe9, 0x74, 0x18, - 0xc0, 0xe4, 0x70, 0xf2, 0x12, 0x8c, 0x30, 0x21, 0xaa, 0x5a, 0x11, 0x9b, 0x20, 0x9e, 0x2d, 0x4c, - 0xca, 0x62, 0x12, 0x8b, 0x28, 0x22, 0xb7, 0x60, 0x82, 0xff, 0x25, 0x42, 0xc6, 0x8c, 0xe8, 0xd6, - 0x8c, 0x96, 0xd3, 0x90, 0x51, 0x63, 0x34, 0x3c, 0x76, 0xbb, 0xa8, 0x75, 0x51, 0xad, 0x53, 0xad, - 0x88, 0xe0, 0xe1, 0x78, 0xbb, 0xf0, 0x39, 0x90, 0x55, 0x11, 0x21, 0x30, 0x59, 0x46, 0x78, 0x56, - 0xe4, 0xf1, 0x4e, 0x89, 0xb2, 0x0c, 0xf7, 0xa8, 0x30, 0x45, 0x09, 0xb9, 0xca, 0x9f, 0x56, 0x50, - 0x2c, 0xe4, 0x39, 0x18, 0xf1, 0xdd, 0x02, 0x15, 0x13, 0x28, 0x1b, 0x86, 0xc5, 0xac, 0x72, 0xf6, - 0xf7, 0x72, 0xcb, 0x76, 0x9a, 0x62, 0x5b, 0xc1, 0xca, 0x11, 0x97, 0x32, 0xa8, 0x19, 0x21, 0x90, - 0x77, 0x61, 0x8a, 0xfd, 0x28, 0xbb, 0xad, 0x96, 0xdb, 0x46, 0xf6, 0xe3, 0x51, 0x50, 0x38, 0x24, - 0xa9, 0x63, 0x11, 0xaf, 0x25, 0x86, 0xcb, 0xce, 0x13, 0x7c, 0xb6, 0xed, 0xf2, 0x47, 0x9f, 0x89, - 0xe8, 0x3c, 0x41, 0x52, 0x9f, 0xc3, 0x4d, 0x15, 0x89, 0xbc, 0x0d, 0x93, 0xec, 0xe7, 0x1d, 0xe7, - 0x21, 0xe5, 0x15, 0x4e, 0x46, 0xf6, 0x0a, 0x48, 0xb5, 0xc7, 0x4a, 0x78, 0x7d, 0x3a, 0x26, 0xf9, - 0x12, 0x9c, 0x41, 0x4e, 0x75, 0xb7, 0x43, 0x1b, 0xa5, 0xdd, 0x5d, 0xa7, 0xe9, 0x70, 0xf3, 0x32, - 0x1e, 0x1c, 0x05, 0x75, 0xf0, 0xbc, 0x62, 0xc4, 0xb0, 0xec, 0x08, 0xc5, 0x4c, 0xa7, 0x24, 0xdb, - 0x50, 0x28, 0x77, 0xfd, 0xc0, 0x6d, 0x95, 0x82, 0xc0, 0x73, 0x76, 0xba, 0x01, 0xf5, 0xe7, 0xa7, - 0xb5, 0x10, 0x22, 0x6c, 0x71, 0x84, 0x85, 0x5c, 0x1f, 0x54, 0x47, 0x0a, 0xcb, 0x0e, 0x49, 0xcc, - 0x04, 0x13, 0xe3, 0x9f, 0x65, 0x60, 0x52, 0x23, 0x25, 0x6f, 0xc1, 0xc4, 0x6d, 0xcf, 0xa1, 0xed, - 0x46, 0xf3, 0x50, 0xb9, 0xa8, 0xe2, 0x2d, 0x66, 0x57, 0xc0, 0x79, 0xab, 0x35, 0xb4, 0x50, 0xcf, - 0x93, 0x4d, 0xb5, 0xfd, 0xbc, 0xce, 0x5d, 0x8b, 0xc5, 0x04, 0xcd, 0x45, 0x31, 0x8d, 0x70, 0x82, - 0x8a, 0xd9, 0xa9, 0xa0, 0x90, 0xf7, 0x60, 0x84, 0x3f, 0xf0, 0x0a, 0x43, 0xc4, 0xf3, 0x69, 0xcd, - 0xe4, 0x6e, 0xec, 0x38, 0x11, 0xd1, 0x8a, 0xc7, 0x37, 0x05, 0x91, 0xf1, 0x73, 0x19, 0x20, 0x49, - 0xd4, 0x13, 0xf4, 0x5e, 0x27, 0x5a, 0x07, 0x7d, 0x31, 0x5c, 0x8d, 0x39, 0x4d, 0x67, 0xce, 0x6a, - 0xe2, 0x05, 0xbc, 0xe3, 0xc5, 0xaa, 0x53, 0x15, 0x71, 0xbc, 0xd8, 0xf8, 0xe1, 0x2c, 0x40, 0x84, - 0x4d, 0x3e, 0xcf, 0x53, 0x6e, 0x7d, 0xa9, 0x6b, 0x37, 0x9d, 0x5d, 0x47, 0x8f, 0x41, 0x8b, 0x4c, - 0xbe, 0x29, 0x4b, 0x4c, 0x1d, 0x91, 0x7c, 0x00, 0xd3, 0xb5, 0x0d, 0x9d, 0x56, 0xb1, 0x73, 0xf7, - 0x3b, 0x56, 0x8c, 0x3c, 0x8e, 0x8d, 0x06, 0xc7, 0xea, 0x68, 0x70, 0x83, 0x63, 0x3e, 0x10, 0xa2, - 0x84, 0x6d, 0x2c, 0xb5, 0x0d, 0x61, 0xca, 0xdf, 0xa8, 0x56, 0xc4, 0x2e, 0x85, 0x5f, 0xe7, 0x77, - 0xac, 0x8e, 0xb0, 0xf1, 0x67, 0xfb, 0x84, 0x86, 0x17, 0x75, 0xe4, 0x70, 0x0f, 0x57, 0xf5, 0x9f, - 0x47, 0xb5, 0x5f, 0xcb, 0x0d, 0xa8, 0xd0, 0x76, 0x3c, 0xb3, 0xf7, 0x9e, 0xc8, 0x3a, 0x60, 0x58, - 0xf3, 0xc0, 0xd5, 0x5a, 0x27, 0x2c, 0x60, 0x6e, 0x46, 0x97, 0x14, 0x6e, 0x27, 0x90, 0x62, 0x34, - 0xf3, 0xf7, 0x33, 0x70, 0x26, 0x95, 0x96, 0x5c, 0x03, 0x88, 0x74, 0x4a, 0xa2, 0x97, 0x70, 0xc7, - 0x8c, 0x22, 0xf9, 0x98, 0x0a, 0x06, 0xf9, 0x6a, 0x5c, 0x1b, 0x74, 0xf2, 0x41, 0xb8, 0x20, 0x03, - 0xe8, 0xe9, 0xda, 0xa0, 0x14, 0x1d, 0x90, 0xf1, 0x0f, 0x73, 0x30, 0xa3, 0x04, 0x0a, 0xe2, 0xdf, - 0x7a, 0x82, 0x01, 0xf8, 0x01, 0x4c, 0xb0, 0xd6, 0x38, 0x75, 0xe1, 0x06, 0xc8, 0x2d, 0x59, 0x5e, - 0x4b, 0xf8, 0x50, 0x0a, 0x6e, 0xd7, 0x54, 0x64, 0x1e, 0xd6, 0x12, 0xb7, 0x4e, 0x7c, 0x90, 0xa8, - 0x27, 0xdd, 0x01, 0x35, 0xe6, 0xc4, 0x87, 0xc9, 0xca, 0x61, 0xdb, 0x6e, 0x85, 0xb5, 0x71, 0x8b, - 0x96, 0xd7, 0x7b, 0xd6, 0xa6, 0x61, 0xf3, 0xea, 0x22, 0x6f, 0x23, 0x5e, 0x96, 0xe2, 0xe8, 0xae, - 0x51, 0x2d, 0x7c, 0x00, 0x33, 0x89, 0x8f, 0x3e, 0x55, 0x84, 0xcd, 0x6d, 0x20, 0xc9, 0xef, 0x48, - 0xe1, 0xf0, 0xba, 0x1e, 0xbf, 0xf5, 0x4c, 0xf8, 0x78, 0xdd, 0x6a, 0xd9, 0xed, 0x06, 0xb7, 0x8f, - 0x59, 0x54, 0xe3, 0x6f, 0xfe, 0x7c, 0x56, 0xf5, 0x63, 0x7d, 0xd6, 0x57, 0xdd, 0x17, 0xb5, 0xdb, - 0xf0, 0xc5, 0x5e, 0x63, 0x3a, 0x90, 0xd6, 0xe1, 0x3b, 0x39, 0x38, 0xd7, 0x83, 0x92, 0x1c, 0xc6, - 0x27, 0x11, 0xd7, 0x42, 0xdc, 0xe8, 0x5f, 0xe1, 0xd3, 0x98, 0x4a, 0xe4, 0xf3, 0x3c, 0x92, 0x45, - 0x1d, 0x13, 0xdf, 0x8b, 0xfb, 0x37, 0xaa, 0xf1, 0x0f, 0x42, 0x68, 0x3c, 0x84, 0x05, 0x87, 0x92, - 0x0f, 0x60, 0x18, 0x9d, 0x98, 0x63, 0xa1, 0x0a, 0x19, 0x06, 0xc2, 0x95, 0x60, 0x9b, 0xec, 0xa7, - 0x16, 0x6c, 0x93, 0x01, 0xc8, 0xe7, 0x20, 0x57, 0xda, 0xae, 0x89, 0x71, 0x99, 0x52, 0xc9, 0xb7, - 0x6b, 0x51, 0xa2, 0x10, 0x5b, 0xcb, 0xe8, 0xc1, 0x28, 0x18, 0xe1, 0x9d, 0xf2, 0x86, 0x18, 0x15, - 0x95, 0xf0, 0x4e, 0x79, 0x23, 0x22, 0xdc, 0xab, 0x6b, 0x81, 0x9f, 0xee, 0x94, 0x37, 0x3e, 0xb9, - 0x69, 0xff, 0xef, 0x64, 0x79, 0xf8, 0x0d, 0xde, 0xb0, 0x0f, 0x60, 0x42, 0x8b, 0xaf, 0x9d, 0x89, - 0xe4, 0xb1, 0x30, 0x16, 0x7a, 0xcc, 0x04, 0x48, 0x23, 0x90, 0x29, 0x77, 0xd8, 0x6f, 0x94, 0x78, - 0x55, 0x63, 0x9b, 0x90, 0x03, 0xca, 0xc4, 0xf1, 0x94, 0x3b, 0x21, 0x09, 0xb9, 0x09, 0xf9, 0x4d, - 0xda, 0xb6, 0xdb, 0x41, 0xa8, 0x10, 0x45, 0x6b, 0xe1, 0x00, 0x61, 0xba, 0xd4, 0x10, 0x22, 0xa2, - 0x65, 0x6b, 0x77, 0xc7, 0xaf, 0x7b, 0x0e, 0x86, 0xe9, 0x09, 0xcf, 0x62, 0x6e, 0xd9, 0xaa, 0x94, - 0xe8, 0x0c, 0x62, 0x44, 0xc6, 0xcf, 0x67, 0x60, 0x54, 0x0c, 0x24, 0x4f, 0x95, 0xb6, 0x17, 0x9d, - 0x25, 0xc2, 0x1b, 0x60, 0xcf, 0x89, 0x7b, 0x03, 0xec, 0xf1, 0x58, 0x38, 0x63, 0xc2, 0x53, 0x2e, - 0x7c, 0x1a, 0xc4, 0xd9, 0x28, 0x5d, 0x18, 0xf5, 0x4c, 0x58, 0x21, 0xea, 0xa0, 0x1e, 0x56, 0xc6, - 0xdf, 0x15, 0x5f, 0x76, 0xa7, 0xbc, 0x41, 0x16, 0x21, 0xbf, 0xea, 0xf2, 0xb0, 0x4e, 0x6a, 0xde, - 0xdb, 0xa6, 0x80, 0xa9, 0x1d, 0x24, 0xf1, 0xd8, 0xf7, 0x6d, 0x78, 0xae, 0xb8, 0xcb, 0x28, 0xdf, - 0xd7, 0xe1, 0xc0, 0xd8, 0xf7, 0x85, 0xa8, 0x03, 0x7f, 0x1f, 0x4d, 0xd9, 0x24, 0x1e, 0xdc, 0xc4, - 0x5c, 0x24, 0x77, 0x55, 0xcf, 0x35, 0x51, 0x24, 0x77, 0x8a, 0x85, 0x5e, 0x3b, 0xc5, 0x83, 0x9b, - 0x66, 0x0a, 0x15, 0xbe, 0xab, 0x45, 0xe0, 0x1a, 0xf5, 0x1e, 0x3e, 0xc3, 0xbb, 0x74, 0xfa, 0xbb, - 0x5a, 0xbc, 0x79, 0x03, 0x6d, 0xd2, 0x7f, 0x90, 0x85, 0xb3, 0xe9, 0x84, 0x6a, 0x5b, 0x32, 0x7d, - 0xda, 0x72, 0x05, 0xf2, 0x2b, 0xae, 0x1f, 0x28, 0x56, 0x7f, 0xa8, 0xfe, 0xdf, 0x17, 0x30, 0x33, - 0x2c, 0x65, 0x77, 0x6e, 0xf6, 0x77, 0xb8, 0x3c, 0x91, 0x1f, 0x06, 0x9d, 0x60, 0x77, 0x6e, 0x5e, - 0x44, 0xee, 0x40, 0xde, 0x14, 0x9e, 0x53, 0xb1, 0xae, 0x91, 0xe0, 0x50, 0x9a, 0x22, 0x9e, 0x80, - 0x68, 0x61, 0xce, 0x05, 0x8c, 0x94, 0x60, 0x54, 0x8c, 0x7e, 0xec, 0xe9, 0x38, 0x65, 0xca, 0xe8, - 0x99, 0x07, 0x24, 0x1d, 0xdb, 0x51, 0xf0, 0x11, 0xb0, 0x5a, 0x91, 0x4e, 0x50, 0xb8, 0xa3, 0xf0, - 0x47, 0x42, 0xdd, 0xc0, 0x32, 0x44, 0x34, 0x7e, 0x24, 0x0b, 0x20, 0xb5, 0x36, 0xcf, 0xec, 0x0c, - 0xfb, 0x9c, 0x36, 0xc3, 0x14, 0x7b, 0xa3, 0xc1, 0x53, 0xfb, 0xde, 0x47, 0x73, 0x9e, 0xc1, 0x13, - 0xfb, 0x16, 0x61, 0x78, 0x33, 0x52, 0x68, 0x09, 0x1f, 0x13, 0x54, 0x47, 0x73, 0xb8, 0xb1, 0x03, - 0x73, 0x77, 0x68, 0x10, 0xa9, 0xb7, 0xe4, 0xd3, 0x63, 0x7f, 0xb6, 0x6f, 0xc0, 0x98, 0xc0, 0x0f, - 0xf7, 0x2f, 0xae, 0x8b, 0x11, 0x71, 0x5c, 0x50, 0x17, 0x23, 0x11, 0xd8, 0x6e, 0x54, 0xa1, 0x4d, - 0x1a, 0xd0, 0x4f, 0xb6, 0x9a, 0x1a, 0x10, 0xde, 0x14, 0x6c, 0xd9, 0x60, 0x35, 0x9c, 0xd8, 0x3f, - 0x0f, 0xe0, 0x4c, 0xf8, 0xed, 0x4f, 0x93, 0xef, 0x75, 0x76, 0xa5, 0x14, 0x41, 0xfb, 0x23, 0x8e, - 0x7d, 0x6c, 0x4f, 0x1e, 0xc3, 0x82, 0x24, 0xd8, 0x76, 0x42, 0xc3, 0xc9, 0x81, 0x68, 0xc9, 0xbb, - 0x30, 0xae, 0xd0, 0x88, 0xa0, 0xf3, 0xa8, 0xa6, 0x7e, 0xe4, 0x04, 0xfb, 0x96, 0xcf, 0xe1, 0xaa, - 0x9a, 0x5a, 0x41, 0x37, 0xbe, 0x02, 0xcf, 0x87, 0x7e, 0x40, 0x29, 0x55, 0xc7, 0x98, 0x67, 0x4e, - 0xc7, 0x7c, 0x3d, 0x6a, 0x56, 0xb5, 0x1d, 0xba, 0x3a, 0x4b, 0xde, 0x44, 0x6d, 0x96, 0x68, 0xcc, - 0x0b, 0x09, 0xe7, 0x69, 0xc5, 0x47, 0xda, 0x78, 0x47, 0xf9, 0xd8, 0x14, 0x86, 0x1a, 0x71, 0x26, - 0x4e, 0xfc, 0x23, 0x59, 0x98, 0xbe, 0x5f, 0xad, 0x94, 0x43, 0xeb, 0xa3, 0x4f, 0x59, 0xe2, 0x61, - 0xad, 0x6d, 0xbd, 0xf7, 0x1b, 0x63, 0x0b, 0x66, 0x63, 0xdd, 0x80, 0xa2, 0xc3, 0xfb, 0xdc, 0x83, - 0x24, 0x04, 0x4b, 0xb1, 0xe1, 0x6c, 0x1a, 0xfb, 0x07, 0x37, 0xcd, 0x18, 0xb6, 0xf1, 0x5f, 0x42, - 0x8c, 0xaf, 0xd8, 0xc2, 0xde, 0x80, 0xb1, 0xaa, 0xef, 0x77, 0xa9, 0xb7, 0x65, 0xae, 0xaa, 0xaa, - 0x02, 0x07, 0x81, 0x56, 0xd7, 0x6b, 0x9a, 0x11, 0x02, 0xb9, 0x0a, 0x79, 0x11, 0xf0, 0x5b, 0xee, - 0x09, 0xa8, 0xb5, 0x0d, 0xe3, 0x85, 0x9b, 0x61, 0x31, 0x79, 0x0b, 0x26, 0xf8, 0xdf, 0x7c, 0xb6, - 0x89, 0x0e, 0x47, 0xe5, 0xa0, 0x40, 0xe7, 0xb3, 0xd3, 0xd4, 0xd0, 0xc8, 0x6b, 0x90, 0x2b, 0x95, - 0x4d, 0xa1, 0x0e, 0x12, 0x72, 0xa3, 0x67, 0x71, 0x9d, 0x9d, 0x76, 0x89, 0x28, 0x9b, 0x4c, 0xfa, - 0x93, 0xd1, 0x23, 0x84, 0x26, 0x1b, 0x67, 0x80, 0xd4, 0x36, 0xc5, 0x0e, 0x33, 0x84, 0x91, 0xeb, - 0x30, 0x5a, 0xe1, 0x26, 0x73, 0x42, 0x8f, 0xcd, 0xb3, 0xea, 0x71, 0x90, 0x16, 0x2d, 0x81, 0x83, - 0xc8, 0x55, 0x99, 0x6d, 0x2c, 0x1f, 0x39, 0xa2, 0xf4, 0x48, 0x29, 0xf6, 0x06, 0x8c, 0x88, 0xb0, - 0xd8, 0x63, 0x4a, 0x1e, 0x92, 0x78, 0x38, 0x6c, 0x81, 0x93, 0xf4, 0x48, 0x85, 0xa7, 0xe9, 0x91, - 0xba, 0x03, 0xe7, 0xee, 0xa0, 0xf6, 0x46, 0x0f, 0xee, 0xb4, 0x65, 0x56, 0x85, 0x3e, 0x1c, 0x9f, - 0x81, 0xb8, 0x82, 0x27, 0x1e, 0x1f, 0xca, 0xea, 0x7a, 0x6a, 0x92, 0xd8, 0x5e, 0x8c, 0xc8, 0x97, - 0x61, 0x2e, 0xad, 0x48, 0x68, 0xcd, 0x31, 0x8c, 0x51, 0x7a, 0x05, 0x6a, 0x18, 0xa3, 0x34, 0x0e, - 0x64, 0x15, 0x0a, 0x1c, 0x5e, 0x6a, 0xb4, 0x9c, 0x36, 0xd7, 0xfc, 0x73, 0xad, 0x3a, 0x7a, 0x86, - 0x08, 0xae, 0x36, 0x2b, 0xe4, 0x2f, 0x00, 0x9a, 0x2f, 0x51, 0x8c, 0x92, 0xfc, 0x74, 0x86, 0xdd, - 0xe6, 0x78, 0x10, 0xe9, 0x2d, 0x73, 0xd5, 0x17, 0x21, 0xf0, 0xce, 0x46, 0x6e, 0x42, 0xb5, 0xc0, - 0x73, 0xda, 0x7b, 0xc2, 0x4f, 0x68, 0x53, 0xf8, 0x09, 0xbd, 0xfb, 0xb1, 0xfc, 0x84, 0x38, 0x2b, - 0xff, 0xf8, 0xa8, 0x38, 0xe1, 0x89, 0x3a, 0x71, 0x15, 0x69, 0x5f, 0xc0, 0xba, 0x0e, 0x9d, 0x65, - 0xb7, 0xda, 0x3c, 0x84, 0x2d, 0x6d, 0xf0, 0x46, 0x4e, 0xe3, 0x0e, 0x8e, 0x5d, 0x87, 0xf9, 0x2d, - 0xac, 0x6e, 0x88, 0x90, 0x68, 0x68, 0x2a, 0x07, 0x76, 0xf1, 0x94, 0xbe, 0x28, 0xdc, 0xbd, 0xb6, - 0x10, 0x5d, 0x3c, 0xa5, 0xe3, 0x8a, 0x85, 0xd3, 0x48, 0x9d, 0x3c, 0x1a, 0x09, 0xb9, 0x0e, 0x23, - 0x6b, 0xf6, 0xe3, 0xd2, 0x1e, 0x15, 0x59, 0x24, 0x27, 0xe5, 0xf6, 0x87, 0xc0, 0xa5, 0xfc, 0x1f, - 0x72, 0x5f, 0x87, 0xe7, 0x4c, 0x81, 0x46, 0xbe, 0x3f, 0x03, 0x67, 0xf9, 0x32, 0x96, 0xad, 0xac, - 0xd1, 0x20, 0x60, 0xfd, 0x20, 0x62, 0xe1, 0x5d, 0x8a, 0x0c, 0xb6, 0xd3, 0xf1, 0xd0, 0x95, 0xde, - 0x10, 0x3b, 0x43, 0xd8, 0x71, 0xbe, 0x28, 0xd5, 0x82, 0x0a, 0xa7, 0xd2, 0x93, 0x4d, 0x18, 0x5f, - 0xbb, 0x5d, 0x0a, 0xab, 0xe5, 0x91, 0xc6, 0x8b, 0x69, 0xbb, 0xa3, 0x82, 0x96, 0xe6, 0x69, 0xa0, - 0xb2, 0x11, 0xde, 0x01, 0x9f, 0x93, 0xfd, 0x41, 0xde, 0x54, 0x7d, 0x4b, 0x73, 0x28, 0x3d, 0x8f, - 0xb6, 0xec, 0xc7, 0x96, 0xbd, 0x47, 0xb5, 0x57, 0x72, 0xa1, 0xbd, 0xfe, 0xd9, 0x0c, 0x9c, 0xef, - 0xd9, 0x64, 0x72, 0x0b, 0xce, 0xd9, 0xdc, 0x63, 0xda, 0xda, 0x0f, 0x82, 0x8e, 0x6f, 0xc9, 0x2b, - 0x86, 0xf0, 0x46, 0x35, 0xcf, 0x88, 0xe2, 0x15, 0x56, 0x2a, 0x6f, 0x1d, 0x3e, 0xf9, 0x00, 0x5e, - 0x70, 0xda, 0x3e, 0xad, 0x77, 0x3d, 0x6a, 0x49, 0x06, 0x75, 0xa7, 0xe1, 0x59, 0x9e, 0xdd, 0xde, - 0x93, 0xae, 0xb5, 0xe6, 0x79, 0x89, 0x23, 0xbc, 0xb2, 0xcb, 0x4e, 0xc3, 0x33, 0x11, 0xc1, 0xf8, - 0x67, 0x19, 0x98, 0xef, 0xd5, 0x25, 0x64, 0x1e, 0x46, 0xa9, 0x92, 0x73, 0x24, 0x6f, 0xca, 0x9f, - 0xe4, 0x79, 0x88, 0x76, 0x7a, 0x71, 0xfa, 0xe7, 0xeb, 0x22, 0xff, 0x03, 0x9a, 0xb6, 0xab, 0xfb, - 0xba, 0x30, 0x50, 0x9e, 0xa8, 0xab, 0xbb, 0xfb, 0x05, 0x80, 0x68, 0x3b, 0xe7, 0x8a, 0x09, 0x73, - 0xcc, 0xae, 0x7b, 0x7c, 0xe5, 0x91, 0xb3, 0x30, 0xc2, 0xb7, 0x4b, 0xe1, 0xff, 0x20, 0x7e, 0xb1, - 0x73, 0x5b, 0x74, 0x32, 0xee, 0xf3, 0xb9, 0xa5, 0x09, 0xad, 0xb3, 0x47, 0x5a, 0x38, 0x38, 0xc6, - 0xcf, 0x4c, 0x72, 0x11, 0xa2, 0xd4, 0x0d, 0xf6, 0xa5, 0xd0, 0xb1, 0x98, 0xe6, 0x00, 0xc6, 0x6d, - 0x29, 0x15, 0xbb, 0x6c, 0xdd, 0xed, 0x4b, 0xbe, 0xfd, 0x64, 0x53, 0xdf, 0x7e, 0xde, 0x80, 0xb1, - 0xf2, 0x3e, 0xad, 0x1f, 0x84, 0x4e, 0x38, 0x79, 0xa1, 0x5c, 0x67, 0x40, 0x1e, 0xde, 0x3b, 0x42, - 0x20, 0xd7, 0x01, 0xd0, 0xef, 0x94, 0x4b, 0xa4, 0x4a, 0x8a, 0x0e, 0x74, 0x53, 0x15, 0xe6, 0x29, - 0x0a, 0x0a, 0xb2, 0xaf, 0x99, 0xb7, 0x55, 0x7b, 0x16, 0xce, 0xde, 0xf7, 0x76, 0x05, 0x7a, 0x84, - 0xc0, 0x9a, 0xa7, 0xec, 0x2b, 0xe2, 0x14, 0x2c, 0x24, 0x36, 0x1f, 0x15, 0x89, 0x5c, 0x83, 0xb1, - 0x0d, 0xe9, 0x48, 0x80, 0x87, 0xe0, 0x04, 0x52, 0x40, 0xe4, 0x74, 0x30, 0x9f, 0x31, 0x23, 0x14, - 0xf2, 0x39, 0x18, 0x2d, 0x53, 0x2f, 0xd8, 0xdc, 0x5c, 0x45, 0xa3, 0x13, 0x9e, 0xc9, 0x22, 0x8f, - 0x59, 0x07, 0x82, 0xa0, 0xf9, 0xdd, 0xa3, 0xe2, 0x64, 0xe0, 0xb4, 0x68, 0x18, 0xa1, 0xdb, 0x94, - 0xd8, 0x64, 0x09, 0x0a, 0xfc, 0x59, 0x3c, 0xba, 0x7b, 0xe0, 0xc9, 0x98, 0xe7, 0xe7, 0xb4, 0x78, - 0x43, 0x7f, 0x44, 0x77, 0xc2, 0x9c, 0x0b, 0x09, 0x7c, 0xb2, 0x2c, 0x53, 0x95, 0xa8, 0xcd, 0x84, - 0x48, 0x19, 0x16, 0xdf, 0x31, 0x58, 0x6b, 0x93, 0x14, 0xa4, 0x04, 0x93, 0x65, 0xb7, 0xd5, 0xb1, - 0x03, 0x07, 0x73, 0x3a, 0x1e, 0x8a, 0x43, 0x10, 0x15, 0x7a, 0x75, 0xb5, 0x40, 0x3b, 0x51, 0xd5, - 0x02, 0x72, 0x1b, 0xa6, 0x4c, 0xb7, 0xcb, 0x86, 0x49, 0xde, 0xc2, 0xf9, 0x39, 0x87, 0xa6, 0x21, - 0x1e, 0x2b, 0x61, 0xc7, 0xb2, 0xb8, 0x72, 0x6b, 0xd1, 0x4c, 0x35, 0x2a, 0xb2, 0x9e, 0xf2, 0x1c, - 0xa2, 0x1e, 0x6e, 0x6a, 0xe6, 0x85, 0x04, 0xb3, 0x94, 0x97, 0x94, 0x9b, 0x30, 0x5e, 0xab, 0xdd, - 0xdf, 0xa4, 0x7e, 0x70, 0xbb, 0xe9, 0x3e, 0xc2, 0xb3, 0x2d, 0x2f, 0x12, 0x85, 0xf9, 0xae, 0x15, - 0x50, 0x3f, 0xb0, 0x76, 0x9b, 0xee, 0x23, 0x53, 0xc5, 0x22, 0x5f, 0x67, 0xfd, 0xa1, 0x48, 0x82, - 0x22, 0x6e, 0x6b, 0x3f, 0x61, 0x15, 0x4f, 0x90, 0x68, 0xd1, 0x30, 0x91, 0x55, 0xef, 0x2c, 0x05, - 0x1d, 0x7d, 0xca, 0x3c, 0xf7, 0xf1, 0x61, 0xa9, 0xd1, 0xf0, 0xa8, 0xef, 0x8b, 0x43, 0x88, 0xfb, - 0x94, 0xa1, 0xb2, 0xc1, 0xe6, 0x05, 0x9a, 0x4f, 0x99, 0x42, 0x40, 0x7e, 0x2c, 0x03, 0x67, 0x54, - 0x6f, 0x13, 0x5c, 0x2e, 0x68, 0xe6, 0xc2, 0x8f, 0xa4, 0x37, 0xaf, 0xc9, 0x43, 0xf8, 0x9a, 0x82, - 0x76, 0xed, 0xe1, 0x8d, 0x6b, 0xa5, 0xe8, 0x67, 0x4d, 0x12, 0x61, 0x0c, 0xba, 0x62, 0x2a, 0x3f, - 0x2d, 0xcf, 0xce, 0x9c, 0x9d, 0x42, 0x4c, 0xca, 0x4c, 0x52, 0x63, 0x33, 0x0a, 0x0d, 0xa7, 0xaa, - 0x1b, 0x78, 0xa6, 0x09, 0x8d, 0xaa, 0x98, 0x7f, 0xdc, 0xc4, 0xca, 0xe9, 0xe8, 0x02, 0x99, 0x42, - 0x43, 0xaa, 0x30, 0xcd, 0x01, 0x6c, 0x5b, 0xe0, 0x29, 0x8b, 0x66, 0xa3, 0xa4, 0x09, 0x82, 0x0d, - 0xbe, 0xf5, 0x63, 0xda, 0x22, 0x35, 0xd0, 0x68, 0x8c, 0x8e, 0x7c, 0x00, 0x53, 0x18, 0x0f, 0x3e, - 0x5a, 0xaf, 0x73, 0xb8, 0x8a, 0x31, 0x5e, 0xaa, 0x28, 0x89, 0x79, 0xde, 0x4d, 0xf8, 0xfe, 0x7e, - 0xb4, 0xa2, 0x3f, 0x80, 0x29, 0xb4, 0xd5, 0x89, 0x18, 0x9c, 0x89, 0x18, 0x88, 0x92, 0x38, 0x83, - 0xa0, 0xe9, 0x47, 0x0c, 0xfe, 0x66, 0x06, 0xce, 0xb3, 0x8a, 0xd2, 0x47, 0xe8, 0xec, 0xc7, 0x19, - 0x21, 0x8c, 0x20, 0xd9, 0x93, 0xa7, 0x2a, 0x8e, 0xfa, 0xfe, 0x7e, 0x1a, 0x07, 0xfc, 0x28, 0xf6, - 0xf1, 0xe9, 0x1f, 0x75, 0xee, 0x63, 0x7f, 0x54, 0x4f, 0x9e, 0xea, 0x47, 0x05, 0x4d, 0x3f, 0x8d, - 0x03, 0x5e, 0x6b, 0x6b, 0xa5, 0xb5, 0xd5, 0xe8, 0x6e, 0xf6, 0xe9, 0x72, 0x5b, 0xd1, 0xda, 0xd6, - 0xc7, 0x6d, 0x65, 0x8b, 0xbb, 0x45, 0x2b, 0xdd, 0x20, 0xaf, 0xb5, 0x1a, 0x38, 0x7e, 0xad, 0x8d, - 0xd1, 0x98, 0x31, 0x6c, 0xe3, 0x97, 0x21, 0xc6, 0x57, 0x98, 0xaa, 0x1a, 0x30, 0xc2, 0x6f, 0xad, - 0xa2, 0x93, 0xd1, 0x66, 0x81, 0xdf, 0x69, 0x4d, 0x51, 0x42, 0xce, 0x43, 0xae, 0x56, 0xbb, 0x2f, - 0x3a, 0x19, 0x0d, 0x56, 0x7d, 0xdf, 0x35, 0x19, 0x8c, 0x8d, 0x10, 0x5a, 0xa1, 0x2a, 0xf1, 0xf5, - 0xd9, 0x79, 0x67, 0x22, 0x94, 0xf5, 0xb7, 0xbc, 0x43, 0x0e, 0x45, 0xfd, 0x2d, 0xee, 0x90, 0xd1, - 0xcd, 0xb1, 0x0c, 0xf3, 0x25, 0xdf, 0xa7, 0x1e, 0x9b, 0x10, 0xc2, 0xb8, 0xd1, 0x13, 0xf7, 0x1c, - 0x71, 0xb0, 0x63, 0xa5, 0x76, 0xdd, 0x37, 0x7b, 0x22, 0x92, 0x2b, 0x90, 0x2f, 0x75, 0x1b, 0x0e, - 0x6d, 0xd7, 0xb5, 0x38, 0x6b, 0xb6, 0x80, 0x99, 0x61, 0x29, 0xf9, 0x12, 0x9c, 0x89, 0x85, 0x54, - 0x14, 0x3d, 0x30, 0x1a, 0xed, 0xbd, 0xf2, 0x1e, 0x16, 0x19, 0x64, 0xf0, 0x2e, 0x49, 0xa7, 0x24, - 0x25, 0x28, 0x2c, 0xa3, 0x9b, 0x56, 0x85, 0xf2, 0xb7, 0x21, 0xd7, 0xe3, 0xfe, 0x79, 0xfc, 0xd6, - 0xcc, 0x5d, 0xb8, 0xac, 0x46, 0x58, 0x68, 0x26, 0xd0, 0xc9, 0x3d, 0x98, 0x8d, 0xc3, 0xd8, 0x09, - 0xce, 0x2f, 0xc8, 0xb8, 0xdf, 0x24, 0xb8, 0xe0, 0x19, 0x9e, 0x46, 0x45, 0x76, 0x60, 0x26, 0x32, - 0x48, 0xd2, 0xaf, 0xcd, 0xd2, 0xce, 0x39, 0x2c, 0x97, 0x57, 0xe7, 0xe7, 0xc5, 0x64, 0x9c, 0x8d, - 0x8c, 0x9b, 0xc2, 0xeb, 0xb3, 0x99, 0x64, 0x47, 0x1a, 0x30, 0x55, 0x73, 0xf6, 0xda, 0x4e, 0x7b, - 0xef, 0x1e, 0x3d, 0xdc, 0xb0, 0x1d, 0x4f, 0x58, 0x9c, 0x4a, 0x7b, 0xf2, 0x92, 0x7f, 0xd8, 0x6a, - 0xd1, 0xc0, 0xc3, 0x8d, 0x90, 0x95, 0xa3, 0x0f, 0x3a, 0xbb, 0x0e, 0x2d, 0xf8, 0x9c, 0x0e, 0xdd, - 0x36, 0x3b, 0xb6, 0xa3, 0x09, 0x01, 0x3a, 0x4f, 0x4d, 0x75, 0x31, 0x31, 0xa0, 0xea, 0xa2, 0x09, - 0x33, 0xcb, 0xed, 0xba, 0x77, 0x88, 0x4f, 0x74, 0xf2, 0xe3, 0x26, 0x4f, 0xf8, 0xb8, 0x97, 0xc5, - 0xc7, 0xbd, 0x60, 0xcb, 0x19, 0x96, 0xf6, 0x79, 0x49, 0xc6, 0xa4, 0x06, 0x33, 0x78, 0x71, 0xa8, - 0x56, 0x36, 0xaa, 0x6d, 0x27, 0x70, 0xec, 0x80, 0x36, 0x84, 0x70, 0x11, 0x66, 0x25, 0xe1, 0x57, - 0x54, 0xa7, 0xd1, 0xb1, 0x1c, 0x89, 0xa2, 0x32, 0x4d, 0xd0, 0xf7, 0xbb, 0x27, 0x4e, 0xff, 0x05, - 0xdd, 0x13, 0xab, 0x30, 0x1d, 0x8f, 0xcd, 0x50, 0x88, 0xce, 0x61, 0x1f, 0x8b, 0xd8, 0x71, 0xee, - 0x76, 0x51, 0x98, 0xd4, 0x12, 0x81, 0xea, 0x74, 0xf1, 0x2b, 0xe7, 0x8c, 0x76, 0xe5, 0xd4, 0x76, - 0xa5, 0x53, 0x5c, 0x39, 0xc9, 0x06, 0xc0, 0x6d, 0xd7, 0xab, 0xd3, 0x12, 0xfa, 0x47, 0x13, 0x2d, - 0x77, 0x13, 0x63, 0x1a, 0x15, 0xf2, 0xf5, 0xb3, 0xcb, 0x7e, 0x5b, 0x71, 0x37, 0x77, 0x85, 0x87, - 0xf1, 0xe3, 0x59, 0x98, 0xef, 0xf5, 0x39, 0x7d, 0xae, 0x7b, 0xaf, 0x43, 0x72, 0x85, 0x8b, 0x6b, - 0x5f, 0x81, 0xc6, 0xd7, 0xf9, 0x22, 0xa4, 0x2f, 0x64, 0x71, 0x0d, 0x9c, 0x8d, 0x13, 0x6c, 0x79, - 0x4d, 0x72, 0x0b, 0xc6, 0x95, 0x8f, 0xc7, 0xbd, 0xb4, 0x57, 0x53, 0x4d, 0xd8, 0x0d, 0xff, 0x66, - 0xd7, 0x44, 0xbe, 0x6f, 0xc9, 0x6b, 0x22, 0xff, 0x45, 0x0a, 0xdc, 0x45, 0x7c, 0x84, 0x5b, 0x01, - 0xf8, 0xbe, 0x4b, 0x08, 0xe0, 0xbe, 0xcd, 0xb7, 0x40, 0x13, 0xff, 0x36, 0x7e, 0x63, 0x82, 0x9f, - 0xc8, 0xea, 0x2d, 0xb1, 0x97, 0x7d, 0x70, 0xec, 0xf6, 0x98, 0x3d, 0xcd, 0xed, 0x31, 0x77, 0xf2, - 0xed, 0x71, 0xe8, 0xa4, 0xdb, 0x63, 0xec, 0x7a, 0x37, 0x7c, 0xea, 0xeb, 0xdd, 0xc8, 0xa9, 0xae, - 0x77, 0xa3, 0xa7, 0xba, 0xde, 0x69, 0x37, 0xd5, 0xfc, 0x49, 0x37, 0xd5, 0xbf, 0xba, 0x0c, 0x3e, - 0xab, 0x97, 0xc1, 0x34, 0x11, 0xef, 0x54, 0x97, 0xc1, 0x1f, 0xed, 0x79, 0x97, 0x2b, 0x7c, 0x1c, - 0xa1, 0xfc, 0xa5, 0x01, 0xee, 0x72, 0x83, 0xde, 0xe4, 0x66, 0x9e, 0xce, 0x4d, 0x8e, 0x3c, 0xb5, - 0x9b, 0xdc, 0xec, 0x93, 0xde, 0xe4, 0xe6, 0x9e, 0xe6, 0x4d, 0xee, 0xcc, 0x5f, 0xc6, 0x9b, 0xdc, - 0xd9, 0x7f, 0x33, 0x37, 0xb9, 0xbf, 0x06, 0x85, 0xb8, 0x70, 0x79, 0x72, 0x18, 0xe3, 0xa7, 0x16, - 0x43, 0x92, 0x89, 0xbe, 0x71, 0xe1, 0x8e, 0x5c, 0x07, 0xd8, 0xf0, 0x9c, 0x87, 0x76, 0x40, 0xef, - 0x49, 0xeb, 0x37, 0x11, 0x82, 0x9b, 0x43, 0xd9, 0xc8, 0x9b, 0x0a, 0x4a, 0x78, 0xaf, 0xc9, 0xa6, - 0xdd, 0x6b, 0x8c, 0x1f, 0xcb, 0xc2, 0x0c, 0x0f, 0xc4, 0xf6, 0xec, 0x3f, 0xc2, 0xbe, 0xaf, 0xdd, - 0x56, 0x5f, 0x88, 0xe2, 0xdd, 0xab, 0xad, 0xeb, 0xf3, 0x0c, 0xfb, 0x35, 0x38, 0x93, 0xe8, 0x0a, - 0xbc, 0xb1, 0x56, 0x64, 0x08, 0xbc, 0xc4, 0x9d, 0x75, 0x3e, 0xbd, 0x92, 0x07, 0x37, 0xcd, 0x04, - 0x85, 0xf1, 0x67, 0x43, 0x09, 0xfe, 0xe2, 0x41, 0x56, 0x7d, 0x62, 0xcd, 0x9c, 0xee, 0x89, 0x35, - 0x3b, 0xd8, 0x13, 0x6b, 0x4c, 0xa8, 0xc8, 0x0d, 0x22, 0x54, 0x7c, 0x09, 0x26, 0x37, 0xa9, 0xdd, - 0xf2, 0x37, 0x5d, 0x91, 0x3c, 0x89, 0xfb, 0x5a, 0xc8, 0x08, 0x77, 0xac, 0x4c, 0x5e, 0xb8, 0x42, - 0x9b, 0xd1, 0x80, 0x11, 0xb0, 0x63, 0x90, 0x67, 0x53, 0x32, 0x75, 0x0e, 0xea, 0x2d, 0x7a, 0xb8, - 0xcf, 0x2d, 0xba, 0x06, 0x13, 0x82, 0x2e, 0x8a, 0xdd, 0x1c, 0x5d, 0xf7, 0x58, 0x11, 0xc2, 0x65, - 0xed, 0x61, 0x66, 0xf7, 0xb0, 0x76, 0x7e, 0xd3, 0xd3, 0x98, 0xb0, 0x2e, 0x58, 0x6e, 0x37, 0x3a, - 0xae, 0xd3, 0xc6, 0x2e, 0x18, 0x8d, 0xba, 0x80, 0x0a, 0x30, 0xef, 0x02, 0x05, 0x89, 0xbc, 0x0b, - 0x53, 0xa5, 0x8d, 0xaa, 0x4a, 0x96, 0x8f, 0x5e, 0x79, 0xed, 0x8e, 0x63, 0x69, 0xa4, 0x31, 0xdc, - 0x7e, 0x37, 0x9f, 0xb1, 0xbf, 0x98, 0x9b, 0x8f, 0xf1, 0x2f, 0x27, 0xe4, 0xf2, 0xfe, 0x64, 0x1f, - 0x48, 0xf4, 0x27, 0x8f, 0xdc, 0x29, 0x9f, 0x3c, 0x86, 0x4e, 0x12, 0x24, 0x35, 0xf9, 0x76, 0xf8, - 0x54, 0xf2, 0xed, 0xc8, 0x13, 0x3f, 0x5f, 0x8c, 0x9e, 0x52, 0x62, 0x8d, 0xad, 0xb5, 0xfc, 0x20, - 0x6b, 0x2d, 0x55, 0xca, 0x1d, 0x7b, 0x72, 0x29, 0x17, 0x4e, 0x2d, 0xe5, 0xd6, 0x22, 0xdf, 0xe5, - 0xf1, 0x13, 0x5d, 0x42, 0x2e, 0x08, 0xad, 0xc0, 0x4c, 0x7a, 0x14, 0xbe, 0xd0, 0x8b, 0xf9, 0x53, - 0x25, 0x3a, 0x7f, 0x23, 0x5d, 0x74, 0xee, 0x7f, 0xde, 0x9c, 0x4a, 0x78, 0xfe, 0xb1, 0xa7, 0x2b, - 0x3c, 0x3f, 0xdd, 0x87, 0x90, 0xbf, 0x12, 0x9f, 0xff, 0x4a, 0x7c, 0x1e, 0x50, 0x7c, 0xf6, 0x70, - 0x79, 0x6d, 0xdb, 0x5e, 0x1b, 0xd5, 0x4e, 0xd7, 0x61, 0x54, 0x86, 0x21, 0xcd, 0x44, 0x1a, 0xe5, - 0x64, 0xfc, 0x51, 0x89, 0x45, 0x16, 0x21, 0x2f, 0x89, 0xd5, 0x44, 0x37, 0x8f, 0x04, 0x4c, 0x8b, - 0xf0, 0x28, 0x60, 0xc6, 0x7f, 0x30, 0x24, 0xb7, 0x70, 0x36, 0x67, 0x36, 0x6c, 0xcf, 0x6e, 0x61, - 0xfa, 0xb7, 0x70, 0x85, 0x29, 0xc2, 0x7b, 0x6c, 0x51, 0xc6, 0x4c, 0xfb, 0x75, 0x92, 0x8f, 0x15, - 0x18, 0x36, 0xca, 0xb0, 0x9b, 0x1b, 0x20, 0xc3, 0xee, 0xdb, 0x5a, 0x7a, 0xda, 0xa1, 0x28, 0x1f, - 0x22, 0xdb, 0xd6, 0xfa, 0x27, 0xa6, 0xbd, 0xa5, 0xe6, 0x91, 0x1d, 0x8e, 0xa2, 0x7a, 0x21, 0x65, - 0x9f, 0x0c, 0xb2, 0xe1, 0x6d, 0x64, 0xe4, 0x34, 0x21, 0x97, 0x47, 0xff, 0x8d, 0x86, 0x5c, 0x5e, - 0x06, 0x10, 0x47, 0x6d, 0x64, 0x9e, 0xf0, 0x0a, 0xae, 0x7e, 0x61, 0xa6, 0x1c, 0x04, 0xcd, 0x1e, - 0x39, 0x39, 0x14, 0x42, 0xe3, 0xf7, 0x09, 0xcc, 0xd4, 0x6a, 0xf7, 0x2b, 0x8e, 0xbd, 0xd7, 0x76, - 0xfd, 0xc0, 0xa9, 0x57, 0xdb, 0xbb, 0x2e, 0x13, 0xc5, 0xc3, 0xe3, 0x40, 0x89, 0xad, 0x1b, 0x1d, - 0x05, 0x61, 0x31, 0xbb, 0xea, 0x2d, 0x7b, 0x9e, 0xd4, 0x8f, 0xf2, 0xab, 0x1e, 0x65, 0x00, 0x93, - 0xc3, 0x99, 0xb4, 0x5b, 0xeb, 0x62, 0x64, 0x0b, 0x61, 0x33, 0x82, 0xd2, 0xae, 0xcf, 0x41, 0xa6, - 0x2c, 0x23, 0x34, 0x39, 0x61, 0xc5, 0xed, 0xe7, 0x9c, 0x16, 0xb8, 0x39, 0x2a, 0xe6, 0x87, 0x9d, - 0x10, 0x46, 0x70, 0xdb, 0xec, 0x20, 0x5c, 0xb5, 0x88, 0x4b, 0xac, 0x81, 0x43, 0x38, 0xa3, 0xf9, - 0x3c, 0x0f, 0xfa, 0x98, 0xf2, 0x9a, 0x90, 0xae, 0x0d, 0x0c, 0xb1, 0x91, 0xf2, 0xa2, 0xa2, 0xe6, - 0x73, 0x4b, 0xad, 0x81, 0x9d, 0x67, 0x17, 0x52, 0x4b, 0xc2, 0xd5, 0x3d, 0xae, 0x05, 0xcf, 0x56, - 0x36, 0x0d, 0x9e, 0xb9, 0xae, 0x57, 0xd5, 0x56, 0xca, 0x56, 0xd0, 0xbf, 0x26, 0xf2, 0x9b, 0x19, - 0x38, 0xa7, 0x61, 0x84, 0xdb, 0x95, 0x1f, 0x86, 0x03, 0x49, 0x9d, 0xd7, 0x1f, 0x3d, 0x9d, 0x79, - 0xfd, 0x92, 0xde, 0x96, 0x68, 0x43, 0x55, 0xdb, 0xd0, 0xeb, 0x0b, 0xc9, 0x43, 0x98, 0xc1, 0x22, - 0xf9, 0xb0, 0xc3, 0xe6, 0xac, 0x78, 0x0f, 0x9a, 0x8b, 0x3e, 0x9b, 0xfb, 0xf1, 0x63, 0xf6, 0xf1, - 0xc5, 0xef, 0x1c, 0x15, 0x27, 0x35, 0x74, 0x19, 0x8e, 0xda, 0x8a, 0x5e, 0x87, 0x9c, 0xf6, 0xae, - 0xab, 0xa5, 0x96, 0x8f, 0x57, 0x41, 0xfe, 0xeb, 0x0c, 0x7f, 0x4e, 0xe0, 0xcd, 0xb8, 0xed, 0xb9, - 0xad, 0xb0, 0x5c, 0x9a, 0x56, 0xf6, 0xe8, 0xb6, 0xe6, 0xd3, 0xe9, 0xb6, 0x57, 0xf0, 0x93, 0xf9, - 0x9e, 0x60, 0xed, 0x7a, 0x6e, 0x2b, 0xfa, 0x7c, 0xb5, 0xe3, 0x7a, 0x7e, 0x24, 0xf9, 0x81, 0x0c, - 0x9c, 0xd7, 0xb4, 0x9a, 0x6a, 0x6e, 0x10, 0x11, 0x2d, 0x61, 0x36, 0x8c, 0xa3, 0x12, 0x15, 0x2d, - 0x5d, 0x13, 0xf3, 0xff, 0x32, 0x7e, 0x81, 0x12, 0xb6, 0x93, 0x21, 0x59, 0x2d, 0x8e, 0xa5, 0x7c, - 0x42, 0xef, 0x5a, 0x88, 0x03, 0x33, 0x68, 0x65, 0xa3, 0x99, 0x00, 0xcf, 0xf5, 0x36, 0x01, 0x0e, - 0xb3, 0xfe, 0x60, 0x46, 0x80, 0xde, 0x76, 0xc0, 0x49, 0xae, 0xe4, 0xaf, 0xc3, 0xf9, 0x04, 0x30, - 0x5c, 0x6d, 0x67, 0x7a, 0xae, 0xb6, 0xd7, 0x8f, 0x8f, 0x8a, 0xaf, 0xa6, 0xd5, 0x96, 0xb6, 0xd2, - 0x7a, 0xd7, 0x40, 0x6c, 0x80, 0xa8, 0x50, 0x88, 0x1f, 0xe9, 0x13, 0xf4, 0x75, 0x31, 0x3f, 0x14, - 0x7c, 0xb6, 0x97, 0x2b, 0xdf, 0xa0, 0x1e, 0x79, 0x11, 0x12, 0xa1, 0x30, 0xa1, 0x64, 0x43, 0x38, - 0x14, 0xc6, 0x1e, 0x3d, 0x2a, 0xf9, 0xce, 0x51, 0x51, 0xc3, 0x66, 0x17, 0x22, 0x35, 0xcd, 0x82, - 0x26, 0xed, 0xa9, 0x88, 0xe4, 0xd7, 0x33, 0x30, 0xc7, 0x00, 0xd1, 0xa4, 0x12, 0x8d, 0x9a, 0xef, - 0x37, 0xeb, 0xf7, 0x9f, 0xce, 0xac, 0x7f, 0x11, 0xbf, 0x51, 0x9d, 0xf5, 0x89, 0x2e, 0x49, 0xfd, - 0x38, 0x9c, 0xed, 0x9a, 0x41, 0x97, 0x36, 0xdb, 0xcf, 0x0f, 0x30, 0xdb, 0xf9, 0x00, 0x9c, 0x3c, - 0xdb, 0x7b, 0xd6, 0x42, 0x36, 0x61, 0x42, 0xdc, 0x85, 0x78, 0x87, 0x5d, 0xd4, 0xc2, 0x38, 0xab, - 0x45, 0xfc, 0x82, 0x2a, 0x92, 0x45, 0x24, 0x5a, 0xa8, 0x71, 0x21, 0x6d, 0x98, 0xe5, 0xbf, 0x75, - 0xdd, 0x54, 0xb1, 0xa7, 0x6e, 0xea, 0x8a, 0x68, 0xd1, 0x25, 0xc1, 0x3f, 0xa6, 0xa2, 0x52, 0xc3, - 0x2f, 0xa5, 0x30, 0x26, 0x1d, 0x20, 0x1a, 0x98, 0x2f, 0xda, 0x4b, 0xfd, 0x35, 0x52, 0xaf, 0x8a, - 0x3a, 0x8b, 0xf1, 0x3a, 0xe3, 0x2b, 0x37, 0x85, 0x37, 0xb1, 0x61, 0x5a, 0x40, 0xdd, 0x03, 0xca, - 0x77, 0xf8, 0x17, 0xb5, 0x00, 0x58, 0xb1, 0x52, 0x7e, 0x89, 0x92, 0x35, 0x61, 0x80, 0xb2, 0xd8, - 0x86, 0x1e, 0xe7, 0x47, 0xee, 0xc3, 0x4c, 0xa9, 0xd3, 0x69, 0x3a, 0xb4, 0x81, 0xad, 0x34, 0xbb, - 0xac, 0x4d, 0x46, 0x94, 0x6f, 0xcd, 0xe6, 0x85, 0xe2, 0x66, 0xe7, 0x75, 0x63, 0xdb, 0x4d, 0x82, - 0xd6, 0xf8, 0xd1, 0x4c, 0xe2, 0xa3, 0xc9, 0x1b, 0x30, 0x86, 0x3f, 0x94, 0x98, 0x2a, 0xa8, 0xe2, - 0xe1, 0x9f, 0x88, 0xca, 0xa3, 0x08, 0x81, 0x09, 0x4b, 0x6a, 0x5c, 0xc5, 0x1c, 0x17, 0x96, 0x84, - 0x5e, 0x21, 0xd2, 0x24, 0x14, 0xa5, 0x6b, 0x46, 0x2e, 0x12, 0xba, 0xd0, 0x35, 0x43, 0x38, 0x64, - 0x18, 0x3f, 0x90, 0xd5, 0xa7, 0x1d, 0xb9, 0xa2, 0xc8, 0xed, 0x4a, 0x64, 0x47, 0x29, 0xb7, 0x2b, - 0xd2, 0xfa, 0xdf, 0xcf, 0xc0, 0xec, 0x7d, 0x25, 0x51, 0xe7, 0xa6, 0x8b, 0xe3, 0xd2, 0x3f, 0x75, - 0xe5, 0xd3, 0x4a, 0xc1, 0xa7, 0x66, 0x08, 0x65, 0x33, 0x05, 0xa7, 0x8c, 0x99, 0xf6, 0x3d, 0xe8, - 0xec, 0x86, 0x1f, 0xa6, 0x64, 0x42, 0xe4, 0xe8, 0x1c, 0x6e, 0xfc, 0x64, 0x16, 0xc6, 0x95, 0x25, - 0x40, 0x3e, 0x0b, 0x13, 0x2a, 0x1f, 0x55, 0xe1, 0xa7, 0x56, 0x6b, 0x6a, 0x58, 0xa8, 0xf1, 0xa3, - 0x76, 0x4b, 0xd3, 0xf8, 0xb1, 0x89, 0x8e, 0xd0, 0x53, 0x5e, 0x6d, 0x3e, 0x48, 0xb9, 0xda, 0xe0, - 0xb4, 0x55, 0x34, 0x36, 0x7d, 0x2f, 0x38, 0xef, 0x26, 0x2f, 0x38, 0xa8, 0x3c, 0x52, 0xe8, 0x7b, - 0x5f, 0x73, 0x8c, 0x9f, 0xc9, 0x40, 0x21, 0xbe, 0x48, 0x3f, 0x91, 0x5e, 0x39, 0xc5, 0xeb, 0xce, - 0x4f, 0x64, 0xc3, 0x54, 0x28, 0xd2, 0x85, 0xf7, 0x59, 0x35, 0x13, 0x7c, 0x4f, 0x7b, 0x78, 0x79, - 0x5e, 0x8f, 0x46, 0xa7, 0x06, 0xbf, 0x48, 0x0f, 0x41, 0x39, 0xf4, 0xed, 0x5f, 0x2a, 0x3e, 0x67, - 0x7c, 0x08, 0x73, 0xf1, 0xee, 0xc0, 0xc7, 0x97, 0x12, 0x4c, 0xeb, 0xf0, 0x78, 0x22, 0xa5, 0x38, - 0x95, 0x19, 0xc7, 0x37, 0xfe, 0x30, 0x1b, 0xe7, 0x2d, 0x4c, 0x06, 0xd9, 0xa6, 0xa3, 0x1a, 0xc2, - 0x88, 0x4d, 0x87, 0x83, 0x4c, 0x59, 0x76, 0x9a, 0x04, 0x66, 0xa1, 0x23, 0x6a, 0x2e, 0xdd, 0x11, - 0x95, 0xdc, 0x8a, 0x59, 0x49, 0x2b, 0x51, 0x93, 0x1e, 0xd1, 0x1d, 0x2b, 0xb2, 0x94, 0x8e, 0x19, - 0x47, 0x97, 0x61, 0x4e, 0x0b, 0x01, 0x2e, 0xe9, 0x87, 0x23, 0x5d, 0x7b, 0x80, 0x05, 0x9c, 0x38, - 0x15, 0x99, 0xac, 0xc0, 0x28, 0xfb, 0xcc, 0x35, 0xbb, 0x23, 0xde, 0x54, 0x48, 0xe8, 0x96, 0xde, - 0x0c, 0x2f, 0x7c, 0x8a, 0x67, 0x7a, 0x93, 0xb2, 0x23, 0x5f, 0x9d, 0x58, 0x02, 0xd1, 0xf8, 0x17, - 0x19, 0xb6, 0xfe, 0xeb, 0x07, 0x9f, 0xb2, 0x2c, 0x68, 0xac, 0x49, 0x7d, 0x2c, 0x5a, 0xff, 0x38, - 0xcb, 0x73, 0xe1, 0x88, 0xe9, 0xf3, 0x36, 0x8c, 0x6c, 0xda, 0xde, 0x9e, 0xc8, 0x41, 0xad, 0x73, - 0xe1, 0x05, 0x51, 0x4c, 0xa7, 0x00, 0x7f, 0x9b, 0x82, 0x40, 0xd5, 0x85, 0x65, 0x07, 0xd2, 0x85, - 0x29, 0x7a, 0xf9, 0xdc, 0x53, 0xd3, 0xcb, 0x7f, 0x4f, 0x98, 0xf6, 0xa6, 0x14, 0x0c, 0x10, 0x61, - 0xfa, 0x52, 0x3c, 0x6d, 0x54, 0x22, 0x16, 0x78, 0xc4, 0x8e, 0xdc, 0x52, 0x13, 0x51, 0x29, 0xbe, - 0x9d, 0x27, 0xa4, 0x9c, 0x32, 0xfe, 0x38, 0xc7, 0xfb, 0x58, 0x74, 0xd4, 0x65, 0xcd, 0xef, 0x1b, - 0xd7, 0x09, 0xdb, 0xe8, 0xd5, 0x10, 0x1c, 0x68, 0x36, 0x75, 0x19, 0x86, 0xd8, 0xdc, 0x14, 0xbd, - 0x89, 0x78, 0x6c, 0xfe, 0xaa, 0x78, 0xac, 0x9c, 0xad, 0x65, 0x3c, 0x93, 0xd4, 0x0c, 0x83, 0x78, - 0x6c, 0xa9, 0x6b, 0x19, 0x31, 0xc8, 0x15, 0x18, 0x5a, 0x77, 0x1b, 0x32, 0x92, 0xf9, 0x1c, 0x46, - 0xff, 0xd0, 0x52, 0x98, 0xce, 0x67, 0x4c, 0xc4, 0x60, 0x6d, 0x0d, 0xf3, 0x3f, 0xa8, 0x6d, 0x6d, - 0xed, 0xda, 0xc9, 0xcc, 0x71, 0x4a, 0xd2, 0x99, 0x65, 0x98, 0xd2, 0xf3, 0xec, 0x0b, 0x7b, 0x5f, - 0xd4, 0xae, 0xc7, 0xd2, 0xf5, 0xab, 0xcf, 0x22, 0x3a, 0x11, 0x59, 0x82, 0x49, 0x2d, 0x82, 0xaa, - 0x78, 0xdc, 0x44, 0xf5, 0xa6, 0x1e, 0x7f, 0x55, 0x55, 0x6f, 0x6a, 0x24, 0xec, 0x3c, 0x17, 0xdf, - 0xaf, 0x3c, 0x71, 0x26, 0xbe, 0x5d, 0xe0, 0x90, 0x9b, 0x90, 0xe7, 0x61, 0x36, 0xaa, 0x15, 0xf5, - 0x99, 0xca, 0x47, 0x58, 0x2c, 0x4c, 0x8d, 0x44, 0x54, 0xc2, 0x2a, 0x7c, 0x06, 0x0a, 0x62, 0x4b, - 0x8a, 0x92, 0x9f, 0xbf, 0x00, 0x43, 0xe5, 0x6a, 0xc5, 0x54, 0xb7, 0x91, 0xba, 0xd3, 0xf0, 0x4c, - 0x84, 0xa2, 0x57, 0xdd, 0x3a, 0x0d, 0x1e, 0xb9, 0xde, 0x81, 0x49, 0xfd, 0xc0, 0x73, 0x78, 0x82, - 0x4a, 0x5c, 0x88, 0x9f, 0x25, 0xef, 0xc2, 0x30, 0x1a, 0x9e, 0xc6, 0x4e, 0x86, 0x78, 0x1d, 0x4b, - 0x93, 0x62, 0x02, 0x0f, 0xa3, 0x15, 0xab, 0xc9, 0x89, 0xc8, 0xdb, 0x30, 0x54, 0xa1, 0xed, 0xc3, - 0x58, 0xee, 0xbc, 0x04, 0x71, 0xb8, 0x21, 0x34, 0x68, 0xfb, 0xd0, 0x44, 0x12, 0xe3, 0x67, 0xb2, - 0x70, 0x26, 0xe5, 0xb3, 0x1e, 0x7c, 0xf6, 0x19, 0xdd, 0x15, 0x97, 0xb4, 0x5d, 0x51, 0xbe, 0x4f, - 0xf7, 0xec, 0xf8, 0xd4, 0x4d, 0xf2, 0x17, 0x32, 0x70, 0x4e, 0x9f, 0xa0, 0xc2, 0xd2, 0xfc, 0xc1, - 0x4d, 0xf2, 0x0e, 0x8c, 0xac, 0x50, 0xbb, 0x41, 0x65, 0x5e, 0xad, 0x33, 0x61, 0x40, 0x3c, 0x1e, - 0x43, 0x80, 0x17, 0x72, 0xb6, 0x91, 0xc7, 0x29, 0x87, 0x92, 0x8a, 0xf8, 0x38, 0x2e, 0x8f, 0x1b, - 0x32, 0x9e, 0x47, 0x5a, 0x55, 0x7d, 0xac, 0x3c, 0xbe, 0x93, 0x81, 0xe7, 0xfb, 0xd0, 0xb0, 0x81, - 0x63, 0x43, 0xaf, 0x0e, 0x1c, 0x9e, 0xa8, 0x08, 0x25, 0xef, 0xc3, 0xf4, 0xa6, 0x90, 0xe7, 0xe5, - 0x70, 0x64, 0xa3, 0xf5, 0x22, 0x45, 0x7d, 0x4b, 0x8e, 0x4b, 0x1c, 0x59, 0x0b, 0x34, 0x93, 0xeb, - 0x1b, 0x68, 0x46, 0x8d, 0xdb, 0x32, 0x34, 0x68, 0xdc, 0x96, 0x0f, 0x61, 0x4e, 0x6f, 0x9b, 0x08, - 0x9f, 0x1b, 0x45, 0xad, 0xc9, 0xf4, 0x8e, 0x5a, 0xd3, 0x37, 0x48, 0xa7, 0xf1, 0x93, 0x19, 0x28, - 0xe8, 0xbc, 0x9f, 0x74, 0x3c, 0xdf, 0xd3, 0xc6, 0xf3, 0xf9, 0xf4, 0xf1, 0xec, 0x3d, 0x90, 0xff, - 0x77, 0x26, 0xde, 0xd8, 0x81, 0x46, 0xd0, 0x80, 0x91, 0x8a, 0xdb, 0xb2, 0x9d, 0xb6, 0x9a, 0x4b, - 0xbf, 0x81, 0x10, 0x53, 0x94, 0x0c, 0x16, 0xe4, 0xe7, 0x12, 0x0c, 0xaf, 0xbb, 0xed, 0x52, 0x45, - 0x98, 0xf4, 0x22, 0x9f, 0xb6, 0xdb, 0xb6, 0xec, 0x86, 0xc9, 0x0b, 0xc8, 0x2a, 0x40, 0xad, 0xee, - 0x51, 0xda, 0xae, 0x39, 0xdf, 0x4b, 0x63, 0x92, 0x06, 0xeb, 0xa1, 0x66, 0x17, 0x37, 0x16, 0xfe, - 0x74, 0x89, 0x88, 0x96, 0xef, 0x7c, 0xaf, 0xba, 0xdf, 0x2a, 0xf4, 0xb8, 0xae, 0x44, 0x1c, 0xb4, - 0xd8, 0x38, 0xdc, 0xf8, 0x24, 0xd6, 0x55, 0x6a, 0x55, 0xd8, 0xc3, 0x37, 0x52, 0x87, 0xe3, 0x0f, - 0x32, 0xf0, 0x7c, 0x1f, 0x9a, 0xa7, 0x30, 0x2a, 0x7f, 0xd1, 0x1d, 0x4e, 0x01, 0x22, 0x22, 0x4c, - 0x4d, 0xec, 0x34, 0x02, 0x9e, 0x2b, 0x6f, 0x52, 0xa4, 0x26, 0x66, 0x00, 0x2d, 0x35, 0x31, 0x03, - 0xb0, 0xb3, 0x74, 0x85, 0x3a, 0x7b, 0xfb, 0xdc, 0x3c, 0x6b, 0x92, 0xef, 0x0d, 0xfb, 0x08, 0x51, - 0xcf, 0x52, 0x8e, 0x63, 0xfc, 0xab, 0x61, 0x38, 0x6f, 0xd2, 0x3d, 0x87, 0xdd, 0x4b, 0xb6, 0x7c, - 0xa7, 0xbd, 0xa7, 0xc5, 0xbd, 0x31, 0x62, 0x2b, 0x57, 0x24, 0x89, 0x60, 0x90, 0x70, 0x26, 0x5e, - 0x85, 0x3c, 0x13, 0x43, 0x94, 0xc5, 0x8b, 0x8f, 0x56, 0x4c, 0x58, 0x11, 0x81, 0x95, 0x65, 0x31, - 0x79, 0x4d, 0x88, 0x49, 0x4a, 0x1a, 0x1f, 0x26, 0x26, 0x7d, 0xf7, 0xa8, 0x08, 0xb5, 0x43, 0x3f, - 0xa0, 0x78, 0x45, 0x16, 0xa2, 0x52, 0x78, 0x97, 0x19, 0xea, 0x71, 0x97, 0x59, 0x83, 0xb9, 0x52, - 0x83, 0x9f, 0x8e, 0x76, 0x73, 0xc3, 0x73, 0xda, 0x75, 0xa7, 0x63, 0x37, 0xe5, 0xfd, 0x1c, 0x7b, - 0xd9, 0x0e, 0xcb, 0xad, 0x4e, 0x88, 0x60, 0xa6, 0x92, 0xb1, 0x66, 0x54, 0xd6, 0x6b, 0x18, 0x1e, - 0x46, 0xbc, 0x47, 0x62, 0x33, 0x1a, 0x6d, 0x1f, 0x5b, 0xe1, 0x9b, 0x61, 0x31, 0xde, 0xa2, 0xf0, - 0x41, 0x7e, 0x73, 0xb5, 0x16, 0xb9, 0x34, 0xf3, 0x2c, 0x03, 0xfc, 0x61, 0x3f, 0x68, 0xfa, 0x68, - 0x0a, 0xa9, 0xe1, 0x45, 0x74, 0xb5, 0xda, 0x0a, 0xa3, 0xcb, 0x27, 0xe8, 0x7c, 0x7f, 0x5f, 0xa5, - 0xe3, 0x78, 0xe4, 0x3a, 0x9b, 0x0a, 0x2d, 0x37, 0xa0, 0x38, 0x85, 0xc7, 0xa2, 0x3b, 0x97, 0x87, - 0x50, 0x7e, 0xe7, 0x52, 0x50, 0xc8, 0xbb, 0x30, 0xbb, 0x5c, 0x5e, 0x94, 0x5a, 0xe4, 0x8a, 0x5b, - 0xef, 0xe2, 0x43, 0x3c, 0x60, 0x7d, 0x38, 0x86, 0xb4, 0xbe, 0xc8, 0x76, 0x93, 0x34, 0x34, 0x72, - 0x19, 0x46, 0xab, 0x15, 0xde, 0xf7, 0xe3, 0x6a, 0x2a, 0x2d, 0x61, 0x19, 0x25, 0x0b, 0xc9, 0xfd, - 0xe8, 0x52, 0x30, 0x71, 0xa2, 0xf4, 0x7e, 0x7e, 0x80, 0x0b, 0xc1, 0xdb, 0x30, 0xb9, 0xe4, 0x06, - 0xd5, 0xb6, 0x1f, 0xd8, 0xed, 0x3a, 0xad, 0x56, 0xd4, 0xb8, 0xd6, 0x3b, 0x6e, 0x60, 0x39, 0xa2, - 0x84, 0x7d, 0xb9, 0x8e, 0x49, 0x3e, 0x8f, 0xa4, 0x77, 0x68, 0x9b, 0x7a, 0x51, 0x3c, 0xeb, 0x61, - 0xde, 0xb7, 0x8c, 0x74, 0x2f, 0x2c, 0x31, 0x75, 0x44, 0x91, 0xe6, 0x8b, 0x27, 0xe7, 0x2c, 0xbb, - 0x0d, 0xea, 0xf3, 0xdd, 0xe2, 0x53, 0x94, 0xe6, 0x4b, 0x69, 0x5b, 0x9f, 0x1d, 0xf4, 0xdf, 0xc5, - 0x34, 0x5f, 0x09, 0x5c, 0xf2, 0x79, 0x18, 0xc6, 0x9f, 0x42, 0xba, 0x9d, 0x4d, 0x61, 0x1b, 0x49, - 0xb6, 0x75, 0x86, 0x69, 0x72, 0x02, 0x52, 0x85, 0x51, 0x71, 0xb1, 0x3a, 0x4d, 0xb2, 0x1a, 0x71, - 0x43, 0xe3, 0x33, 0x43, 0xd0, 0x1b, 0x0d, 0x98, 0x50, 0x2b, 0x64, 0x2b, 0x62, 0xc5, 0xf6, 0xf7, - 0x69, 0x83, 0xfd, 0x12, 0x79, 0xe6, 0x70, 0x45, 0xec, 0x23, 0xd4, 0x62, 0xdf, 0x61, 0x2a, 0x28, - 0xec, 0x4c, 0xad, 0xfa, 0x5b, 0xbe, 0xf8, 0x14, 0xa1, 0x6a, 0x71, 0x50, 0x6d, 0xd7, 0x30, 0x45, - 0x91, 0xf1, 0x3d, 0x30, 0xb7, 0xde, 0x6d, 0x36, 0xed, 0x9d, 0x26, 0x95, 0x79, 0x48, 0x30, 0x83, - 0xf7, 0x12, 0x0c, 0xd7, 0x94, 0x9c, 0xe0, 0x61, 0x2e, 0x48, 0x05, 0x07, 0x8d, 0x50, 0x33, 0x18, - 0xaa, 0x27, 0x96, 0x0d, 0x9c, 0x93, 0x1a, 0xbf, 0x97, 0x81, 0x39, 0xf9, 0xfe, 0xef, 0xd9, 0xf5, - 0x83, 0x30, 0x31, 0xfc, 0x65, 0x6d, 0xae, 0xe1, 0x84, 0x8d, 0x4d, 0x23, 0x3e, 0xeb, 0xee, 0xca, - 0x8f, 0xd0, 0x05, 0x96, 0xb4, 0x0f, 0x3e, 0xe9, 0x63, 0xc8, 0xbb, 0x30, 0x2e, 0x8e, 0x47, 0x25, - 0xc0, 0x24, 0x46, 0xf1, 0x12, 0xd7, 0xbd, 0xb8, 0x35, 0x8a, 0x8a, 0x8e, 0xb2, 0x98, 0xde, 0x94, - 0x27, 0x95, 0x01, 0xd2, 0x65, 0x31, 0xbd, 0x8e, 0x3e, 0x53, 0xf7, 0xb7, 0xc7, 0xe3, 0x7d, 0x2b, - 0xe6, 0xee, 0x2d, 0x35, 0xa4, 0x5c, 0x26, 0xba, 0x19, 0x47, 0x21, 0xe5, 0xd4, 0x9b, 0x71, 0x88, - 0x1a, 0x8e, 0x49, 0xf6, 0x84, 0x31, 0x79, 0x5f, 0x8e, 0x49, 0xae, 0xf7, 0xc4, 0x98, 0xed, 0x33, - 0x0e, 0xb5, 0x68, 0x85, 0x0c, 0x0d, 0xa4, 0x56, 0x79, 0x0e, 0x63, 0xe7, 0x73, 0x92, 0xf8, 0x2e, - 0x2a, 0x38, 0xa9, 0xba, 0x9a, 0xe1, 0xc1, 0x99, 0x9e, 0xb0, 0x35, 0x7f, 0x01, 0x26, 0x4a, 0x41, - 0x60, 0xd7, 0xf7, 0x69, 0xa3, 0xc2, 0xb6, 0x27, 0x25, 0xfa, 0x95, 0x2d, 0xe0, 0xea, 0xa3, 0x99, - 0x8a, 0xcb, 0xa3, 0xb9, 0xda, 0xbe, 0x30, 0x66, 0x0d, 0xa3, 0xb9, 0x32, 0x88, 0x1e, 0xcd, 0x95, - 0x41, 0xc8, 0x75, 0x18, 0xad, 0xb6, 0x1f, 0x3a, 0xac, 0x4f, 0x78, 0x00, 0x2c, 0xd4, 0x4d, 0x39, - 0x1c, 0xa4, 0x6e, 0xae, 0x02, 0x8b, 0xbc, 0xad, 0x5c, 0x6a, 0xc6, 0x22, 0x05, 0x06, 0x57, 0x79, - 0x85, 0x11, 0x6e, 0xd4, 0x0b, 0x4b, 0x78, 0xcb, 0xb9, 0x05, 0xa3, 0x52, 0x93, 0x09, 0x91, 0xd2, - 0x42, 0x50, 0x26, 0x03, 0x46, 0x48, 0x64, 0x4c, 0xf2, 0xad, 0xe4, 0xcb, 0x1b, 0x57, 0x92, 0x7c, - 0x2b, 0xf9, 0xf2, 0xb4, 0x24, 0xdf, 0x4a, 0xe6, 0xbc, 0x50, 0x09, 0x34, 0x71, 0xa2, 0x12, 0xe8, - 0x01, 0x4c, 0x6c, 0xd8, 0x5e, 0xe0, 0x30, 0x19, 0xa5, 0x1d, 0xf8, 0xf3, 0x93, 0x9a, 0xde, 0x54, - 0x29, 0x5a, 0xba, 0x28, 0xf3, 0x52, 0x77, 0x14, 0x7c, 0x3d, 0x81, 0x72, 0x04, 0x4f, 0x37, 0x65, - 0x9d, 0x7a, 0x12, 0x53, 0x56, 0xec, 0x54, 0xd4, 0x95, 0x4d, 0x47, 0x1a, 0x19, 0xbc, 0xb4, 0xc4, - 0x14, 0x66, 0x21, 0x22, 0xf9, 0x2a, 0x4c, 0xb0, 0xbf, 0x37, 0xdc, 0xa6, 0x53, 0x77, 0xa8, 0x3f, - 0x5f, 0xc0, 0xc6, 0x5d, 0x4c, 0x5d, 0xfd, 0x88, 0x74, 0x58, 0xa3, 0x01, 0x5f, 0xc0, 0xc8, 0x38, - 0xae, 0x04, 0xd7, 0xb8, 0x91, 0x0f, 0x60, 0x82, 0xcd, 0xbe, 0x1d, 0xdb, 0xe7, 0xa2, 0xe9, 0x4c, - 0x64, 0x8c, 0xdc, 0x10, 0xf0, 0x44, 0x40, 0x65, 0x95, 0x80, 0x1d, 0xf3, 0xa5, 0x0e, 0xdf, 0x20, - 0x89, 0x32, 0xdb, 0x3b, 0x89, 0xcd, 0x51, 0xa2, 0x91, 0x2f, 0xc2, 0x44, 0xa9, 0xd3, 0x89, 0x76, - 0x9c, 0x59, 0x45, 0x11, 0xd6, 0xe9, 0x58, 0xa9, 0xbb, 0x8e, 0x46, 0x11, 0xdf, 0x98, 0xe7, 0x4e, - 0xb5, 0x31, 0x93, 0x37, 0x43, 0x69, 0xfd, 0x4c, 0xa4, 0xd5, 0x15, 0x17, 0x47, 0x4d, 0xf4, 0xe7, - 0x82, 0x7b, 0x19, 0x26, 0xb9, 0x9a, 0x53, 0x4a, 0x33, 0x67, 0x13, 0xab, 0x27, 0x45, 0xa8, 0xd1, - 0x69, 0xc8, 0x32, 0x4c, 0x71, 0x6f, 0xeb, 0xa6, 0x88, 0x74, 0x3d, 0x7f, 0x0e, 0x57, 0x2d, 0x72, - 0xe1, 0x4e, 0xda, 0x4d, 0x4c, 0x80, 0x62, 0x6b, 0x5c, 0x62, 0x44, 0xc6, 0x9f, 0x64, 0xe0, 0x5c, - 0x8f, 0x11, 0x0f, 0xe3, 0x20, 0x67, 0xfa, 0xc7, 0x41, 0x66, 0x3b, 0x87, 0xae, 0x15, 0xc1, 0xf6, - 0x0b, 0x29, 0x4b, 0x1d, 0x2f, 0x29, 0x6f, 0xb9, 0x40, 0x44, 0x8e, 0x21, 0x51, 0xf5, 0x5d, 0x17, - 0x55, 0xb3, 0xb9, 0xe4, 0x21, 0x24, 0xf0, 0xf8, 0x47, 0x2d, 0x19, 0xc7, 0x47, 0xc5, 0x8b, 0x22, - 0x85, 0x51, 0x38, 0xac, 0x1f, 0xb9, 0xda, 0x0a, 0x4e, 0x61, 0x6d, 0x1c, 0x65, 0x60, 0x5c, 0x59, - 0x87, 0xe4, 0x92, 0xe2, 0x05, 0x5c, 0xe0, 0x49, 0xb0, 0x14, 0x0e, 0x59, 0x7e, 0x12, 0xe1, 0xa2, - 0xca, 0x9e, 0xac, 0x80, 0x5e, 0x63, 0xa2, 0x90, 0x12, 0x2b, 0xba, 0xa5, 0x69, 0x8b, 0x4d, 0x2c, - 0xc7, 0x74, 0xfa, 0xb6, 0x1f, 0x94, 0xea, 0x81, 0xf3, 0x90, 0x0e, 0x70, 0xe8, 0x44, 0xe9, 0xf4, - 0x6d, 0x3f, 0xb0, 0x6c, 0x24, 0x4b, 0xa4, 0xd3, 0x0f, 0x19, 0x1a, 0x3f, 0x98, 0x01, 0xd8, 0xaa, - 0x96, 0x31, 0xd8, 0xfb, 0x93, 0x0a, 0x05, 0xe9, 0x01, 0x74, 0x25, 0xf7, 0x3e, 0xe2, 0xc0, 0xff, - 0x9c, 0x81, 0x29, 0x1d, 0x8d, 0xbc, 0x0f, 0xd3, 0xb5, 0xba, 0xe7, 0x36, 0x9b, 0x3b, 0x76, 0xfd, - 0x60, 0xd5, 0x69, 0x53, 0x1e, 0xba, 0x74, 0x98, 0x9f, 0x45, 0x7e, 0x58, 0x64, 0x35, 0x59, 0x99, - 0x19, 0x47, 0x26, 0x3f, 0x94, 0x81, 0xc9, 0xda, 0xbe, 0xfb, 0x28, 0x8c, 0x36, 0x2a, 0x06, 0xe4, - 0x6b, 0x6c, 0x6d, 0xfb, 0xfb, 0xee, 0xa3, 0x28, 0x83, 0xa6, 0x66, 0xfc, 0xf9, 0xde, 0x60, 0xef, - 0xf2, 0x75, 0x17, 0x6f, 0x32, 0x81, 0x7f, 0x4d, 0xab, 0xc4, 0xd4, 0xeb, 0x34, 0xfe, 0x3c, 0x03, - 0xe3, 0x78, 0xe7, 0x69, 0x36, 0x51, 0xe6, 0xfa, 0x34, 0xa5, 0x63, 0x0c, 0xdb, 0xd5, 0x67, 0x60, - 0xdf, 0x82, 0xe9, 0x18, 0x1a, 0x31, 0x60, 0xa4, 0x86, 0x0e, 0xfe, 0xaa, 0x82, 0x82, 0xbb, 0xfc, - 0x9b, 0xa2, 0xc4, 0x58, 0x56, 0xc8, 0x1e, 0xdc, 0xc0, 0x67, 0xdd, 0x45, 0x00, 0x47, 0x82, 0xe4, - 0xcd, 0x86, 0xc4, 0xbf, 0xe4, 0xc1, 0x0d, 0x53, 0xc1, 0x32, 0xd6, 0x61, 0xa4, 0xe6, 0x7a, 0xc1, - 0xd2, 0x21, 0xbf, 0x4c, 0x54, 0xa8, 0x5f, 0x57, 0xdf, 0x6d, 0x1d, 0x7c, 0x2b, 0xa9, 0x9b, 0xa2, - 0x88, 0x14, 0x61, 0xf8, 0xb6, 0x43, 0x9b, 0x0d, 0xd5, 0x40, 0x77, 0x97, 0x01, 0x4c, 0x0e, 0x67, - 0x17, 0xae, 0xb3, 0x51, 0x4e, 0x94, 0xc8, 0x12, 0xf8, 0x49, 0xd7, 0x4d, 0x59, 0xeb, 0xdf, 0x17, - 0xc3, 0x3c, 0x04, 0xc9, 0x9a, 0xfa, 0x74, 0xf5, 0x7f, 0x9c, 0x81, 0x85, 0xde, 0x24, 0xaa, 0x71, - 0x71, 0xa6, 0x8f, 0x71, 0xf1, 0x2b, 0xf1, 0x77, 0x46, 0x44, 0x13, 0xef, 0x8c, 0xd1, 0xeb, 0x62, - 0x05, 0x6d, 0xbb, 0xeb, 0x54, 0x26, 0x42, 0xb9, 0xd4, 0xe7, 0x9b, 0x11, 0x91, 0x0f, 0x73, 0x80, - 0x34, 0xa6, 0xa0, 0x35, 0x7e, 0x6b, 0x08, 0xce, 0xf7, 0xa4, 0x20, 0x2b, 0x4a, 0x7a, 0xa5, 0xa9, - 0x30, 0xb1, 0x4b, 0x4f, 0xfc, 0x6b, 0xf8, 0x2f, 0x9a, 0xef, 0xc5, 0xbd, 0xcd, 0xee, 0x87, 0x69, - 0x75, 0xb2, 0xc8, 0xeb, 0xf5, 0x13, 0x79, 0x71, 0x74, 0x64, 0x06, 0xc9, 0x0c, 0x3b, 0xe8, 0x97, - 0x48, 0x03, 0xdb, 0x69, 0xfa, 0xea, 0xb2, 0x6b, 0x70, 0x90, 0x29, 0xcb, 0x22, 0x8b, 0xef, 0xa1, - 0x74, 0x8b, 0x6f, 0xe3, 0x5f, 0x65, 0x60, 0x2c, 0xfc, 0x6c, 0xb2, 0x00, 0x67, 0x37, 0xcd, 0x52, - 0x79, 0xd9, 0xda, 0xfc, 0x70, 0x63, 0xd9, 0xda, 0x5a, 0xaf, 0x6d, 0x2c, 0x97, 0xab, 0xb7, 0xab, - 0xcb, 0x95, 0xc2, 0x73, 0x64, 0x06, 0x26, 0xb7, 0xd6, 0xef, 0xad, 0xdf, 0xdf, 0x5e, 0xb7, 0x96, - 0x4d, 0xf3, 0xbe, 0x59, 0xc8, 0x90, 0x49, 0x18, 0x33, 0x97, 0x4a, 0x65, 0x6b, 0xfd, 0x7e, 0x65, - 0xb9, 0x90, 0x25, 0x05, 0x98, 0x28, 0xdf, 0x5f, 0x5f, 0x5f, 0x2e, 0x6f, 0x56, 0x1f, 0x54, 0x37, - 0x3f, 0x2c, 0xe4, 0x08, 0x81, 0x29, 0x44, 0xd8, 0x30, 0xab, 0xeb, 0xe5, 0xea, 0x46, 0x69, 0xb5, - 0x30, 0xc4, 0x60, 0x0c, 0x5f, 0x81, 0x0d, 0x87, 0x8c, 0xee, 0x6d, 0x2d, 0x2d, 0x17, 0x46, 0x18, - 0x0a, 0xfb, 0x4b, 0x41, 0x19, 0x65, 0xd5, 0x23, 0x4a, 0xa5, 0xb4, 0x59, 0x5a, 0x2a, 0xd5, 0x96, - 0x0b, 0x79, 0x72, 0x0e, 0x66, 0x35, 0x90, 0xb5, 0x7a, 0xff, 0x4e, 0x75, 0xbd, 0x30, 0x46, 0xe6, - 0xa0, 0x10, 0xc2, 0x2a, 0x4b, 0xd6, 0x56, 0x6d, 0xd9, 0x2c, 0x40, 0x1c, 0xba, 0x5e, 0x5a, 0x5b, - 0x2e, 0x8c, 0x1b, 0xef, 0x71, 0x3f, 0x40, 0xde, 0xd5, 0xe4, 0x2c, 0x90, 0xda, 0x66, 0x69, 0x73, - 0xab, 0x16, 0x6b, 0xfc, 0x38, 0x8c, 0xd6, 0xb6, 0xca, 0xe5, 0xe5, 0x5a, 0xad, 0x90, 0x21, 0x00, - 0x23, 0xb7, 0x4b, 0xd5, 0xd5, 0xe5, 0x4a, 0x21, 0x6b, 0xfc, 0x74, 0x06, 0x66, 0xa4, 0x04, 0x28, - 0x1f, 0x8d, 0x9e, 0x70, 0x2d, 0xbe, 0xaf, 0x5d, 0x6c, 0xa5, 0x93, 0x56, 0xac, 0x92, 0x3e, 0xcb, - 0xf0, 0x17, 0x32, 0x70, 0x26, 0x15, 0x9b, 0x7c, 0x08, 0x05, 0xf9, 0x05, 0x6b, 0x76, 0x50, 0xdf, - 0x8f, 0xf6, 0xb1, 0x8b, 0xb1, 0x5a, 0x62, 0x68, 0x5c, 0xad, 0x19, 0x25, 0x7c, 0x4e, 0xb0, 0x19, - 0x3c, 0x1d, 0x81, 0xf1, 0xed, 0x0c, 0x9c, 0xeb, 0x51, 0x0d, 0x29, 0xc3, 0x48, 0x98, 0x98, 0xa6, - 0x8f, 0x05, 0xdb, 0xdc, 0x77, 0x8e, 0x8a, 0x02, 0x11, 0x33, 0xe4, 0xe2, 0x5f, 0xe6, 0x48, 0x98, - 0x69, 0x06, 0xd3, 0xbd, 0xf0, 0xee, 0x3b, 0x1f, 0xeb, 0x79, 0x51, 0x53, 0x69, 0xbb, 0xb6, 0x34, - 0x2e, 0xfa, 0x2e, 0x67, 0x3f, 0xf2, 0x31, 0xdf, 0x8b, 0xf1, 0xb3, 0x19, 0x26, 0xdc, 0xc5, 0x11, - 0x99, 0xcc, 0x5b, 0xf2, 0xfd, 0x6e, 0x8b, 0x9a, 0x6e, 0x93, 0x96, 0xcc, 0x75, 0x71, 0x6c, 0xa0, - 0xb4, 0x6a, 0x63, 0x01, 0x5e, 0x2b, 0x2c, 0xdb, 0x6b, 0x6b, 0xaf, 0xd5, 0x2a, 0x0d, 0x79, 0x1b, - 0x60, 0xf9, 0x71, 0x40, 0xbd, 0xb6, 0xdd, 0x0c, 0x63, 0xb4, 0xf0, 0xc8, 0x52, 0x02, 0xaa, 0xcb, - 0xdb, 0x0a, 0xb2, 0xf1, 0x37, 0x32, 0x30, 0x21, 0x2e, 0x4d, 0xa5, 0x26, 0xf5, 0x82, 0x27, 0x9b, - 0x5e, 0x6f, 0x6b, 0xd3, 0x2b, 0x74, 0xd8, 0x50, 0xf8, 0xb3, 0xe2, 0xd4, 0x99, 0xf5, 0x4f, 0x33, - 0x50, 0x88, 0x23, 0x92, 0xf7, 0x21, 0x5f, 0xa3, 0x0f, 0xa9, 0xe7, 0x04, 0x87, 0x62, 0xa3, 0x94, - 0x29, 0xfc, 0x38, 0x8e, 0x28, 0xe3, 0xf3, 0xc1, 0x17, 0xbf, 0xcc, 0x90, 0x66, 0xd0, 0xfd, 0x5e, - 0x51, 0x7b, 0xe4, 0x9e, 0x96, 0xda, 0xc3, 0xf8, 0xdf, 0xb3, 0x70, 0xee, 0x0e, 0x0d, 0xd4, 0x36, - 0x85, 0xe6, 0x05, 0x9f, 0x19, 0xac, 0x5d, 0x4a, 0x4b, 0xe6, 0x61, 0x14, 0x8b, 0xe4, 0xf8, 0x9a, - 0xf2, 0x27, 0x59, 0x0a, 0xe7, 0x75, 0x4e, 0xcb, 0x11, 0xd6, 0xa3, 0xee, 0x6b, 0x4a, 0xd6, 0xa0, - 0x70, 0x5a, 0x5f, 0x86, 0x29, 0x0c, 0x8b, 0xdf, 0x65, 0xcb, 0x81, 0x36, 0x84, 0xfa, 0x27, 0x6f, - 0xc6, 0xa0, 0xe4, 0x35, 0x28, 0x30, 0x48, 0xa9, 0x7e, 0xd0, 0x76, 0x1f, 0x35, 0x69, 0x63, 0x8f, - 0x36, 0xf0, 0x58, 0xcf, 0x9b, 0x09, 0xb8, 0xe4, 0xb9, 0xd5, 0xe6, 0x57, 0x37, 0xda, 0x40, 0x1d, - 0x8d, 0xe0, 0x19, 0x41, 0x17, 0xde, 0x86, 0xf1, 0x8f, 0x99, 0x01, 0xcc, 0xf8, 0xdf, 0x32, 0x30, - 0x87, 0x8d, 0x53, 0x2a, 0x96, 0xd9, 0x59, 0x65, 0x6f, 0x29, 0x49, 0x71, 0x6c, 0x06, 0xd2, 0x97, - 0x42, 0xd8, 0x8b, 0x91, 0x4e, 0x28, 0x3b, 0x80, 0x4e, 0xa8, 0x76, 0x9a, 0x4c, 0xf4, 0x03, 0xaa, - 0xb4, 0xee, 0x0e, 0xe5, 0x73, 0x85, 0xa1, 0x68, 0xc8, 0x8d, 0x1f, 0xca, 0xc2, 0xa8, 0x49, 0x31, - 0x45, 0x37, 0xb9, 0x0c, 0xa3, 0xeb, 0x6e, 0x40, 0xfd, 0x35, 0x2d, 0x1f, 0x7b, 0x9b, 0x81, 0xac, - 0x56, 0xc3, 0x94, 0x85, 0x6c, 0xc2, 0x6f, 0x78, 0x6e, 0xa3, 0x5b, 0x0f, 0xd4, 0x09, 0xdf, 0xe1, - 0x20, 0x53, 0x96, 0x91, 0x37, 0x60, 0x4c, 0x70, 0x0e, 0x1f, 0x75, 0xd1, 0x18, 0xd9, 0xa3, 0x61, - 0x8a, 0xf7, 0x08, 0x01, 0x65, 0x5a, 0x2e, 0x60, 0x0c, 0x29, 0x32, 0x6d, 0x42, 0x66, 0x90, 0xa2, - 0xfa, 0x70, 0x1f, 0x51, 0xfd, 0x33, 0x30, 0x52, 0xf2, 0x7d, 0x1a, 0xc8, 0x28, 0x06, 0x13, 0x61, - 0xd8, 0x36, 0x9f, 0x06, 0x9c, 0xb1, 0x8d, 0xe5, 0xa6, 0xc0, 0x33, 0xfe, 0x45, 0x16, 0x86, 0xf1, - 0x4f, 0x7c, 0x32, 0xf5, 0xea, 0xfb, 0xda, 0x93, 0xa9, 0x57, 0xdf, 0x37, 0x11, 0x4a, 0x6e, 0xa0, - 0xa6, 0x42, 0xe6, 0x6f, 0x12, 0xad, 0x47, 0x15, 0x7c, 0x23, 0x02, 0x9b, 0x2a, 0x4e, 0xf8, 0xc2, - 0x9f, 0x4b, 0x8d, 0x5d, 0x72, 0x16, 0xb2, 0xf7, 0x6b, 0xa2, 0xc5, 0x18, 0x11, 0xcb, 0xf5, 0xcd, - 0xec, 0xfd, 0x1a, 0xf6, 0xc6, 0x4a, 0x69, 0xf1, 0xad, 0x5b, 0xa2, 0xa1, 0xbc, 0x37, 0xf6, 0xed, - 0xc5, 0xb7, 0x6e, 0x99, 0xa2, 0x84, 0xf5, 0x2f, 0x7e, 0x33, 0x3e, 0xbc, 0x72, 0x9f, 0x7b, 0xec, - 0x5f, 0x6c, 0x1b, 0x3e, 0xb2, 0x9a, 0x11, 0x02, 0x59, 0x84, 0x71, 0x11, 0xeb, 0x01, 0xf1, 0x95, - 0x58, 0x0c, 0x22, 0x16, 0x04, 0xa7, 0x50, 0x91, 0xf8, 0x13, 0x9c, 0x18, 0x20, 0x99, 0x65, 0x56, - 0x3c, 0xc1, 0xc9, 0x21, 0xf4, 0x4d, 0x05, 0x85, 0x7d, 0x12, 0x7f, 0xc3, 0x8b, 0x7c, 0xe9, 0xa7, - 0x94, 0xa0, 0x01, 0x98, 0xe6, 0x20, 0x44, 0x30, 0x7e, 0x25, 0x0b, 0xf9, 0x8d, 0x66, 0x77, 0xcf, - 0x69, 0x3f, 0xb8, 0x41, 0x08, 0xe0, 0x35, 0x4e, 0xe6, 0xc1, 0x60, 0x7f, 0x93, 0xf3, 0x90, 0x97, - 0x37, 0x37, 0xb9, 0x21, 0xf9, 0xe2, 0xd6, 0x36, 0x0f, 0x72, 0xdc, 0x45, 0xe8, 0x33, 0xf9, 0x93, - 0xdc, 0x80, 0xf0, 0xfe, 0xd5, 0xeb, 0xa2, 0x36, 0xc4, 0x16, 0x8b, 0x19, 0xa2, 0x91, 0x37, 0x01, - 0x0f, 0x09, 0x71, 0x79, 0x90, 0x0a, 0x6d, 0xfe, 0x69, 0x42, 0x4e, 0xe1, 0x24, 0x88, 0x46, 0x6e, - 0x82, 0x98, 0x98, 0x22, 0x9b, 0xf9, 0x19, 0x9d, 0x80, 0xe7, 0x87, 0x94, 0x24, 0x02, 0x95, 0xbc, - 0x0b, 0xe3, 0x75, 0x8f, 0xe2, 0xab, 0xa3, 0xdd, 0x8c, 0x92, 0x94, 0xab, 0x94, 0xe5, 0xa8, 0xfc, - 0xc1, 0x0d, 0x53, 0x45, 0x37, 0x7e, 0x25, 0x0f, 0x13, 0xea, 0xf7, 0x10, 0x13, 0x66, 0xfd, 0x26, - 0xbb, 0xbb, 0x0b, 0x63, 0xb3, 0x0e, 0x16, 0x8a, 0xe3, 0xf4, 0x92, 0xfe, 0x41, 0x0c, 0x8f, 0x5b, - 0x9e, 0xc9, 0x20, 0x15, 0x2b, 0xcf, 0x99, 0x33, 0x7e, 0x04, 0xe6, 0x78, 0xa4, 0x04, 0x79, 0xb7, - 0xe3, 0xef, 0xd1, 0xb6, 0x23, 0xdf, 0x5b, 0x5e, 0xd2, 0x18, 0xdd, 0x17, 0x85, 0x09, 0x5e, 0x21, - 0x19, 0x79, 0x0b, 0x46, 0xdc, 0x0e, 0x6d, 0xdb, 0x8e, 0x38, 0xe3, 0x9e, 0x8f, 0x31, 0xa0, 0xed, - 0x52, 0x55, 0x21, 0x14, 0xc8, 0xe4, 0x3a, 0x0c, 0xb9, 0x07, 0xe1, 0x78, 0x9d, 0xd7, 0x89, 0x0e, - 0x02, 0x5b, 0x21, 0x41, 0x44, 0x46, 0xf0, 0x91, 0xdd, 0xda, 0x15, 0x23, 0xa6, 0x13, 0xdc, 0xb5, - 0x5b, 0xbb, 0x2a, 0x01, 0x43, 0x24, 0x1f, 0x00, 0x74, 0xec, 0x3d, 0xea, 0x59, 0x8d, 0x6e, 0x70, - 0x28, 0xc6, 0xed, 0xa2, 0x46, 0xb6, 0xc1, 0x8a, 0x2b, 0xdd, 0xe0, 0x50, 0xa1, 0x1d, 0xeb, 0x48, - 0x20, 0x29, 0x01, 0xb4, 0xec, 0x20, 0xa0, 0x5e, 0xcb, 0x15, 0xd6, 0x7e, 0x51, 0x10, 0x42, 0xce, - 0x60, 0x2d, 0x2c, 0x56, 0x38, 0x28, 0x44, 0xf8, 0xd1, 0x8e, 0x67, 0x8b, 0x9c, 0xf2, 0xb1, 0x8f, - 0x76, 0x3c, 0xad, 0x95, 0x0c, 0x91, 0x7c, 0x1e, 0x46, 0x1b, 0x8e, 0x5f, 0x77, 0xbd, 0x86, 0x88, - 0x5e, 0xf2, 0x82, 0x46, 0x53, 0xe1, 0x65, 0x0a, 0x99, 0x44, 0x67, 0x5f, 0x2b, 0x82, 0x90, 0xae, - 0xbb, 0x8f, 0x50, 0xcd, 0x1f, 0xff, 0xda, 0x5a, 0x58, 0xac, 0x7e, 0x6d, 0x44, 0xc4, 0x86, 0x72, - 0xcf, 0x09, 0x9a, 0xf6, 0x8e, 0x78, 0xe7, 0xd6, 0x87, 0xf2, 0x0e, 0x16, 0xa9, 0x43, 0xc9, 0x91, - 0xc9, 0xdb, 0x90, 0xa7, 0xed, 0xc0, 0xb3, 0x2d, 0xa7, 0x21, 0xbc, 0x24, 0xf5, 0x8f, 0x66, 0x07, - 0xb0, 0x5d, 0xad, 0xa8, 0x1f, 0x8d, 0xf8, 0xd5, 0x06, 0xeb, 0x1f, 0xbf, 0xee, 0xb4, 0x84, 0x73, - 0xa3, 0xde, 0x3f, 0xb5, 0x72, 0x75, 0x4d, 0xed, 0x1f, 0x86, 0x48, 0xde, 0x87, 0x51, 0xb6, 0x7e, - 0x1b, 0xee, 0x9e, 0x08, 0x08, 0x61, 0xe8, 0xfd, 0xc3, 0xcb, 0x12, 0xd3, 0x55, 0x12, 0xb1, 0x85, - 0x6c, 0x3f, 0xf2, 0x2d, 0xa7, 0x2e, 0x82, 0x3c, 0xe8, 0xcb, 0xb1, 0xb4, 0x5d, 0xab, 0x96, 0x15, - 0xb2, 0x61, 0xfb, 0x91, 0x5f, 0xad, 0x93, 0x45, 0x18, 0xc6, 0x14, 0x11, 0x22, 0x10, 0xa5, 0x4e, - 0x83, 0xc9, 0x21, 0x54, 0x1a, 0x44, 0x65, 0x03, 0xd9, 0xf2, 0xd1, 0x5f, 0x44, 0x24, 0x6a, 0xd0, - 0xfb, 0x64, 0xad, 0x86, 0x4e, 0x24, 0xea, 0x27, 0x0a, 0x74, 0x72, 0x11, 0x20, 0x7a, 0xc5, 0xe7, - 0x6f, 0x2e, 0xa6, 0x02, 0xf9, 0xc2, 0xd0, 0xff, 0xf5, 0x4b, 0xc5, 0xcc, 0x12, 0x40, 0x5e, 0x46, - 0xa8, 0x31, 0x56, 0xe1, 0x7c, 0xcf, 0x75, 0x4f, 0xae, 0x42, 0x61, 0xd7, 0x16, 0x5a, 0xbf, 0xfa, - 0xbe, 0xdd, 0x6e, 0xd3, 0xa6, 0xd8, 0x71, 0xa7, 0x25, 0xbc, 0xcc, 0xc1, 0x9c, 0xb3, 0xf1, 0x01, - 0xcc, 0xa5, 0x0d, 0x38, 0x79, 0x11, 0x26, 0xd4, 0x60, 0x3c, 0x82, 0xc9, 0xb8, 0xdd, 0x71, 0x64, - 0x38, 0x1e, 0xc1, 0xe0, 0x37, 0x33, 0xf0, 0x42, 0xbf, 0xed, 0x83, 0x2c, 0x40, 0xbe, 0xe3, 0x39, - 0x2e, 0x8a, 0xa9, 0x22, 0xdb, 0x81, 0xfc, 0x8d, 0x89, 0x0c, 0x50, 0x9e, 0x0a, 0xec, 0x3d, 0xe1, - 0xe0, 0x61, 0x8e, 0x21, 0x64, 0xd3, 0xde, 0xf3, 0xc9, 0xeb, 0x30, 0xd3, 0xa0, 0xbb, 0x76, 0xb7, - 0x19, 0x58, 0x7e, 0x7d, 0x9f, 0x36, 0xd0, 0xa7, 0x0a, 0x0d, 0xf7, 0xcc, 0x82, 0x28, 0xa8, 0x49, - 0x78, 0xe2, 0x8b, 0x87, 0x7b, 0x7c, 0xf1, 0xdd, 0xa1, 0x7c, 0xa6, 0x90, 0x35, 0xd1, 0x52, 0xca, - 0xf8, 0xfe, 0x2c, 0xcc, 0xf7, 0x5a, 0x2f, 0xe4, 0xbd, 0xb4, 0x3e, 0xe0, 0x0f, 0x17, 0x2a, 0x5c, - 0x7d, 0xb8, 0xf8, 0xff, 0xd9, 0xfb, 0x96, 0x18, 0x37, 0x92, 0xf3, 0x60, 0x35, 0xc9, 0x99, 0xe1, - 0x7c, 0x9c, 0x47, 0x4f, 0xe9, 0x31, 0xb3, 0x92, 0x56, 0x5a, 0xf5, 0x6a, 0x65, 0x89, 0xeb, 0x5d, - 0x5b, 0xda, 0x7f, 0xbd, 0xbb, 0x7e, 0xf7, 0x90, 0x3d, 0x43, 0x4a, 0x7c, 0xb9, 0x9b, 0x1c, 0x59, - 0x5e, 0xdb, 0xed, 0x16, 0xd9, 0x33, 0xd3, 0x36, 0x87, 0x4d, 0xb3, 0xc9, 0x95, 0x65, 0xfc, 0x40, - 0x62, 0x04, 0xb0, 0x81, 0xbc, 0x9c, 0x38, 0x09, 0xb2, 0xc8, 0xc5, 0x87, 0x18, 0x41, 0x0e, 0xb9, - 0x06, 0x09, 0x92, 0x5c, 0x7c, 0x33, 0x60, 0x18, 0x30, 0x90, 0x9b, 0x13, 0x2c, 0x92, 0x05, 0x12, - 0x20, 0x8f, 0x5b, 0x90, 0x1c, 0x7c, 0x0a, 0xea, 0xab, 0xaa, 0xee, 0xea, 0x07, 0xa9, 0x91, 0x77, - 0x9d, 0xc4, 0x80, 0x4f, 0x33, 0xfc, 0xea, 0xfb, 0xbe, 0xae, 0x77, 0x7d, 0xf5, 0xd5, 0xf7, 0x90, - 0xbe, 0x46, 0xee, 0x40, 0xe8, 0x11, 0xf5, 0xa4, 0xe8, 0x06, 0x02, 0x46, 0x69, 0xc6, 0x4e, 0x10, - 0x3c, 0xa2, 0x5b, 0x42, 0x5e, 0x0a, 0x68, 0xcb, 0x61, 0x32, 0x8d, 0x80, 0x91, 0xd7, 0x00, 0xfa, - 0x43, 0x3f, 0x70, 0xd1, 0x3e, 0x80, 0xcb, 0x1a, 0xcc, 0x2c, 0x3c, 0x84, 0xca, 0x0f, 0xc2, 0x08, - 0xad, 0xf8, 0x03, 0x97, 0x0f, 0xa0, 0x03, 0xdb, 0x73, 0x36, 0x48, 0x3a, 0x3c, 0x51, 0x76, 0x78, - 0x91, 0x6b, 0x6a, 0x16, 0xe6, 0x88, 0x4f, 0xf6, 0x78, 0x6e, 0xde, 0x1c, 0x79, 0x0c, 0x24, 0xbd, - 0x0b, 0x52, 0xee, 0xdc, 0xb8, 0x79, 0x36, 0x09, 0xb9, 0x33, 0x48, 0x6f, 0x32, 0x24, 0x57, 0xa1, - 0x24, 0x72, 0x49, 0x52, 0x59, 0x9e, 0x31, 0x07, 0x0e, 0xba, 0xe7, 0xe2, 0xe4, 0xc1, 0x88, 0xa5, - 0xe8, 0xf7, 0xc6, 0xa5, 0x84, 0x55, 0x84, 0x74, 0x1f, 0x8f, 0x45, 0xeb, 0x2e, 0x8b, 0xf9, 0x1d, - 0x3f, 0x9b, 0x78, 0xe9, 0x1f, 0x28, 0x62, 0xf8, 0xd3, 0x9b, 0xfb, 0x93, 0xea, 0x47, 0x00, 0xbd, - 0x94, 0x78, 0xc5, 0xf0, 0x7f, 0x2a, 0xb5, 0x88, 0x55, 0xc7, 0xa5, 0x16, 0xfe, 0x93, 0xdc, 0x80, - 0xcd, 0x09, 0xb3, 0x63, 0x9d, 0xfa, 0xbc, 0x3f, 0x59, 0xde, 0x8e, 0x75, 0x06, 0xee, 0xfa, 0xd8, - 0xa7, 0xbc, 0x5e, 0x77, 0xc3, 0x0e, 0x93, 0xce, 0x3a, 0xf2, 0x32, 0xac, 0xd2, 0xb3, 0x0e, 0x23, - 0xdd, 0x24, 0xdc, 0x23, 0x10, 0x0f, 0x25, 0x07, 0xb3, 0xf8, 0x65, 0xfe, 0x3f, 0xe7, 0xf5, 0x76, - 0x4e, 0x30, 0x93, 0x4f, 0x5a, 0xb2, 0x0d, 0x2b, 0xfe, 0xe4, 0x48, 0x6a, 0xda, 0xb2, 0x3f, 0x39, - 0xa2, 0xed, 0xba, 0x09, 0x2a, 0xf3, 0xd6, 0x61, 0x61, 0x10, 0x82, 0xc7, 0x23, 0x76, 0x15, 0x2f, - 0x9a, 0x1b, 0x0c, 0x8e, 0x09, 0xf3, 0x1f, 0x8f, 0xfa, 0x14, 0x33, 0x08, 0x7c, 0x5b, 0x0e, 0x70, - 0xc5, 0x9b, 0xbd, 0x11, 0x04, 0x7e, 0x14, 0xe9, 0x6a, 0x40, 0x76, 0x61, 0x9d, 0xf2, 0x09, 0xc3, - 0x6c, 0x71, 0x41, 0xe0, 0xd9, 0xb4, 0x20, 0xf0, 0x78, 0xd4, 0x17, 0x55, 0x34, 0xd7, 0x02, 0xe9, - 0x17, 0xb9, 0x07, 0xaa, 0x24, 0x31, 0xa1, 0x3f, 0x66, 0xc2, 0xa6, 0x3a, 0x62, 0x23, 0x49, 0x5a, - 0xf5, 0xd1, 0xa1, 0x6f, 0x6e, 0xf6, 0xe3, 0x00, 0xde, 0x35, 0xdf, 0x55, 0xc4, 0x5e, 0x9a, 0x41, - 0x44, 0x34, 0x58, 0x3f, 0x76, 0x02, 0x3b, 0x08, 0x4e, 0x98, 0x8d, 0x18, 0x0f, 0xec, 0x5b, 0x3a, - 0x76, 0x02, 0x2b, 0x38, 0x11, 0x89, 0x43, 0xce, 0x53, 0x1c, 0xdf, 0x99, 0x4d, 0x8f, 0x6d, 0x59, - 0xfe, 0x63, 0x3d, 0x76, 0xf6, 0xd8, 0x09, 0xda, 0xb4, 0x4c, 0xe2, 0x4d, 0xae, 0xc3, 0x06, 0xf2, - 0xed, 0x7b, 0x82, 0x31, 0x86, 0xb2, 0x30, 0xd7, 0x28, 0xe3, 0xbe, 0xc7, 0x38, 0xf3, 0x1a, 0xfe, - 0x4b, 0x0e, 0x2e, 0x64, 0xf7, 0x0e, 0x4e, 0x4f, 0xda, 0xa7, 0xe8, 0xa3, 0xc7, 0xeb, 0xb6, 0x4a, - 0x21, 0x2c, 0x0c, 0x49, 0xd6, 0xe0, 0xe4, 0x32, 0x07, 0xa7, 0x0c, 0x5b, 0xc8, 0x88, 0x4b, 0x9a, - 0x43, 0x2f, 0x98, 0xf2, 0xe8, 0x1a, 0xe6, 0x26, 0x2d, 0x60, 0xfb, 0x79, 0x83, 0x82, 0xc9, 0x0b, - 0xb0, 0x21, 0x76, 0x64, 0xff, 0xd1, 0x88, 0x7e, 0x98, 0x6d, 0xc7, 0xeb, 0x1c, 0xda, 0x46, 0x20, - 0x39, 0x0f, 0xcb, 0xce, 0x78, 0x4c, 0x3f, 0xc9, 0x76, 0xe1, 0x25, 0x67, 0x3c, 0x66, 0xc9, 0x6d, - 0xd0, 0x23, 0xd1, 0x3e, 0x44, 0x2b, 0x21, 0x6e, 0x92, 0x68, 0xae, 0x21, 0x90, 0x59, 0x0e, 0x05, - 0x74, 0xdd, 0x53, 0x5a, 0x81, 0xb2, 0x82, 0x28, 0xe0, 0x8c, 0x43, 0x84, 0x67, 0xa0, 0x28, 0xde, - 0xab, 0x99, 0x63, 0x85, 0xb9, 0xe2, 0xf0, 0xb7, 0xea, 0x57, 0x61, 0x7b, 0xe0, 0x05, 0x38, 0x79, - 0x59, 0x93, 0xc6, 0x63, 0xee, 0x03, 0xc9, 0x82, 0xe4, 0x9a, 0xe7, 0x78, 0x31, 0xed, 0x49, 0x7d, - 0x3c, 0x66, 0x9e, 0x90, 0xbc, 0xaf, 0x5f, 0x87, 0x4d, 0x2e, 0x71, 0xf1, 0x23, 0x12, 0xeb, 0xc2, - 0x17, 0x30, 0xbd, 0x0a, 0xf1, 0x74, 0x42, 0xc0, 0x41, 0xf5, 0x81, 0xa0, 0xfc, 0x7b, 0x05, 0xce, - 0x67, 0x8a, 0x6c, 0xe4, 0x4b, 0xc0, 0x5c, 0xbe, 0xa6, 0xbe, 0x3d, 0x71, 0xfb, 0xde, 0xd8, 0xc3, - 0xa0, 0x18, 0x4c, 0xa5, 0x79, 0x67, 0x91, 0xb0, 0x87, 0xee, 0x63, 0x5d, 0xdf, 0x0c, 0x89, 0x98, - 0xae, 0x45, 0x9d, 0x24, 0xc0, 0x17, 0xdf, 0x84, 0xf3, 0x99, 0xa8, 0x19, 0x3a, 0x90, 0x0f, 0xc6, - 0x93, 0x39, 0x8b, 0x47, 0xaa, 0x44, 0xa3, 0x25, 0xdd, 0x08, 0x6f, 0xde, 0xf7, 0xc3, 0xe6, 0x25, - 0x84, 0x3b, 0x62, 0x24, 0xd7, 0x75, 0xd6, 0xfd, 0x44, 0x10, 0xcd, 0x5f, 0xda, 0x6f, 0xc2, 0x79, - 0x3e, 0xf9, 0x8e, 0x26, 0xce, 0xf8, 0x38, 0x62, 0xc7, 0x2a, 0xfa, 0x81, 0x2c, 0x76, 0x6c, 0x56, - 0xee, 0x53, 0xfc, 0x90, 0xeb, 0x59, 0x27, 0x0d, 0xe4, 0x6d, 0xf8, 0x46, 0x4e, 0x2c, 0xf5, 0x8c, - 0xea, 0x64, 0x4c, 0x6b, 0x25, 0x6b, 0x5a, 0x9f, 0x7e, 0x4d, 0xb5, 0x80, 0xc8, 0x9b, 0x15, 0xd3, - 0x7a, 0x72, 0x83, 0x2a, 0x21, 0xa7, 0xf3, 0x8a, 0x48, 0x5b, 0x83, 0xc5, 0x92, 0x69, 0x6e, 0xf5, - 0x93, 0x20, 0x72, 0x09, 0x56, 0xc3, 0x7c, 0xd5, 0xfc, 0xe0, 0x28, 0x32, 0x40, 0x7d, 0x40, 0x9e, - 0x83, 0x35, 0x26, 0x92, 0xc7, 0xd6, 0x1c, 0x20, 0x4c, 0xa7, 0x0b, 0x4f, 0xf4, 0x81, 0x02, 0xcf, - 0x3d, 0xa9, 0x0f, 0xc9, 0x7d, 0xb8, 0x80, 0x66, 0x1d, 0x81, 0x1f, 0x0e, 0x83, 0xdd, 0x77, 0xfa, - 0xc7, 0x2e, 0x9f, 0xb5, 0x5a, 0xe6, 0x60, 0x8c, 0xc7, 0x96, 0xd5, 0x96, 0xc6, 0x61, 0x3c, 0xb6, - 0x02, 0x5f, 0xfc, 0xae, 0x50, 0x72, 0x5e, 0x87, 0x01, 0x5c, 0x5a, 0x40, 0x29, 0x6d, 0x1c, 0x8a, - 0xbc, 0x71, 0xdc, 0x04, 0xf5, 0xd0, 0x1d, 0x50, 0x99, 0xd8, 0x1d, 0x60, 0xd5, 0xde, 0xba, 0xc3, - 0x32, 0xb4, 0x9b, 0x1b, 0x21, 0xdc, 0x0a, 0xfc, 0x83, 0x3b, 0xfc, 0x2b, 0x27, 0xe2, 0xc8, 0x93, - 0xaf, 0x15, 0xe4, 0x65, 0x38, 0x9b, 0x08, 0x38, 0x12, 0x79, 0xb0, 0x9b, 0x5b, 0xb4, 0x28, 0x1e, - 0x9e, 0xea, 0x1a, 0xac, 0x89, 0x59, 0x31, 0x09, 0xfd, 0xe0, 0xcc, 0x12, 0x87, 0xd1, 0x55, 0xc7, - 0x3f, 0x37, 0x13, 0x8d, 0xca, 0xbc, 0x91, 0x9c, 0x42, 0x96, 0x26, 0x2f, 0x01, 0x09, 0xe5, 0xf6, - 0x70, 0xa3, 0xe0, 0x1f, 0xdc, 0x12, 0x25, 0xe1, 0x0a, 0xe7, 0x9f, 0xfd, 0x9b, 0x1c, 0x9c, 0xcd, - 0xb8, 0xca, 0xd0, 0x4b, 0x80, 0x37, 0x9a, 0xba, 0x47, 0xec, 0x0a, 0x21, 0x37, 0x72, 0x53, 0x82, - 0x73, 0xfd, 0xd4, 0x32, 0xcb, 0x40, 0xce, 0xbf, 0xc5, 0x7f, 0xd1, 0xcd, 0xc3, 0x99, 0x08, 0xd5, - 0x0b, 0xfd, 0x97, 0xd4, 0x61, 0x0b, 0xd3, 0x2a, 0x04, 0x9e, 0x8f, 0xd9, 0x19, 0x50, 0x08, 0x29, - 0xc4, 0x2e, 0x3b, 0x58, 0x8b, 0x8e, 0x84, 0x44, 0xa5, 0x10, 0x53, 0x1d, 0x27, 0x20, 0xe4, 0x63, - 0x70, 0x51, 0x3a, 0x6b, 0xec, 0xc4, 0xca, 0x43, 0x4b, 0x77, 0x73, 0xdb, 0x09, 0x4f, 0x9d, 0x6a, - 0x6c, 0x0d, 0xee, 0xc2, 0x15, 0x1c, 0x44, 0x6f, 0x30, 0xb6, 0x53, 0x79, 0x38, 0xb0, 0xa9, 0x2c, - 0x70, 0xfd, 0x45, 0x8a, 0x55, 0x1f, 0x8c, 0x13, 0x29, 0x39, 0x68, 0xab, 0x79, 0xf7, 0xbd, 0x09, - 0xe7, 0x33, 0x6b, 0x4c, 0x0f, 0x18, 0x34, 0xa4, 0x8a, 0x64, 0xa3, 0x15, 0xfa, 0x9b, 0x0a, 0x47, - 0xd7, 0x60, 0xed, 0xa1, 0xeb, 0x4c, 0xdc, 0x09, 0x3f, 0xb9, 0xf9, 0x94, 0x60, 0x30, 0xf9, 0xe0, - 0x1e, 0xc4, 0x87, 0x86, 0xeb, 0x8c, 0x48, 0x13, 0xce, 0xb2, 0x13, 0xd0, 0x3b, 0x41, 0x61, 0x90, - 0xeb, 0x99, 0x94, 0x98, 0x38, 0x84, 0x24, 0x78, 0x34, 0xd5, 0x11, 0x8b, 0x51, 0x9b, 0x5b, 0x47, - 0x49, 0x10, 0x5d, 0xd1, 0x17, 0xb2, 0xb1, 0xc9, 0x2e, 0x94, 0x18, 0x73, 0x76, 0x2d, 0x60, 0x0f, - 0x04, 0xd7, 0x16, 0x7e, 0xa1, 0x82, 0xf6, 0xc5, 0x41, 0xf8, 0x3f, 0x3d, 0xaf, 0xf1, 0x2d, 0xd6, - 0x3e, 0x91, 0xdf, 0x3f, 0xcc, 0x35, 0x04, 0xf2, 0x77, 0x0f, 0xed, 0x6f, 0x15, 0xd1, 0xd4, 0xd8, - 0xe5, 0x98, 0x4e, 0xad, 0xc0, 0x1d, 0x89, 0x37, 0xa0, 0x55, 0x93, 0xff, 0x7a, 0xca, 0xa9, 0x4e, - 0x5e, 0x83, 0x35, 0xca, 0xf6, 0x68, 0x36, 0x62, 0x53, 0x2e, 0x1f, 0x0b, 0xb4, 0xd3, 0x64, 0x45, - 0x74, 0xd8, 0x6a, 0x67, 0xcc, 0xd2, 0x49, 0xf4, 0x93, 0x4a, 0xcb, 0xc1, 0xc9, 0x74, 0x2c, 0x4f, - 0x54, 0xa1, 0x28, 0xb4, 0x9a, 0xdd, 0x0e, 0x27, 0x29, 0x52, 0x9c, 0x48, 0x5a, 0xde, 0x5d, 0x66, - 0xaa, 0x42, 0xed, 0x45, 0x28, 0x49, 0xbc, 0x69, 0x63, 0x98, 0xe7, 0x8c, 0x68, 0x0c, 0xfb, 0xc5, - 0x07, 0xfb, 0x21, 0x14, 0x05, 0x4b, 0x7a, 0x2d, 0x38, 0xf6, 0x03, 0xb1, 0xc8, 0xf1, 0x7f, 0x0a, - 0xa3, 0xbd, 0x8c, 0x8d, 0x5c, 0x32, 0xf1, 0x7f, 0x3c, 0x4b, 0xa6, 0x0e, 0xbd, 0x0f, 0x0c, 0x03, - 0x7b, 0x8c, 0x16, 0x58, 0xa1, 0xf0, 0x4c, 0xe1, 0xdd, 0x61, 0xc0, 0xec, 0xb2, 0xf8, 0x37, 0xfe, - 0x32, 0x3c, 0x84, 0x13, 0xda, 0x84, 0x79, 0x7b, 0x66, 0xec, 0xc8, 0xc8, 0xa5, 0x8f, 0x0c, 0x16, - 0x40, 0x85, 0x53, 0xb2, 0x2f, 0x03, 0xc2, 0xf0, 0xc8, 0x90, 0x76, 0x86, 0x42, 0x6c, 0x67, 0x90, - 0xee, 0xe4, 0xd1, 0xe8, 0xb1, 0x13, 0x47, 0xdc, 0xc9, 0x93, 0xfb, 0xd4, 0x9f, 0xe4, 0x84, 0x8a, - 0x60, 0xd7, 0xf7, 0xa7, 0xc1, 0x74, 0xe2, 0x8c, 0x63, 0xaa, 0x50, 0x72, 0x02, 0xcf, 0xa0, 0x04, - 0x7d, 0x07, 0x53, 0x58, 0xf8, 0x13, 0x11, 0xb3, 0x23, 0x9c, 0xb9, 0xa5, 0x3b, 0x1f, 0x8a, 0xcb, - 0xf8, 0x3a, 0xc5, 0xd6, 0x65, 0x64, 0x3a, 0x61, 0x25, 0xae, 0xb5, 0x33, 0xe6, 0x36, 0xe3, 0x99, - 0xc2, 0x22, 0xb5, 0x8c, 0x45, 0x9c, 0xd4, 0x85, 0xee, 0x46, 0x2b, 0x3a, 0xce, 0x55, 0x5e, 0xeb, - 0xe4, 0x93, 0xb0, 0xea, 0x0d, 0xe4, 0x4c, 0x8d, 0x49, 0x2d, 0x5c, 0x7d, 0xc0, 0xa2, 0x45, 0x47, - 0x3c, 0xe8, 0x9c, 0xf3, 0x38, 0x74, 0x77, 0x3d, 0xa6, 0x34, 0xd6, 0x76, 0xc5, 0x6d, 0x34, 0x4d, - 0x46, 0x36, 0x20, 0x17, 0x8e, 0x70, 0xce, 0x1b, 0xb0, 0xe5, 0x15, 0xc5, 0xab, 0x36, 0xf9, 0x2f, - 0xed, 0xff, 0xc3, 0xcd, 0xd3, 0xf6, 0x11, 0x5d, 0x8a, 0x73, 0x3a, 0x7c, 0xd5, 0xdc, 0x72, 0x52, - 0xfd, 0x76, 0x0d, 0xe4, 0x70, 0xbb, 0x9e, 0xd8, 0xfc, 0x04, 0xac, 0x37, 0xf1, 0xb4, 0xbf, 0xc8, - 0xc3, 0x46, 0x5c, 0x4d, 0x4e, 0x5e, 0x84, 0x82, 0xb4, 0x03, 0x6d, 0x67, 0xe8, 0xd2, 0x71, 0xdf, - 0x41, 0xa4, 0x53, 0xed, 0x38, 0xe4, 0x2e, 0x6c, 0xa0, 0xe1, 0x1e, 0x8a, 0x9e, 0x53, 0x8f, 0x3f, - 0xbe, 0x2c, 0x7e, 0x3f, 0x2b, 0xfe, 0xe0, 0x9d, 0xab, 0x67, 0xf0, 0xa9, 0x6c, 0x8d, 0xd2, 0x52, - 0xe9, 0x8f, 0x16, 0x4a, 0x5a, 0xd0, 0xc2, 0x7c, 0x2d, 0x28, 0x6f, 0xca, 0x1c, 0x2d, 0xe8, 0xd2, - 0x02, 0x2d, 0x68, 0x44, 0x29, 0x6b, 0x41, 0x51, 0x17, 0xbe, 0x32, 0x4f, 0x17, 0x1e, 0xd1, 0x30, - 0x5d, 0x78, 0xa4, 0xc5, 0x2c, 0xce, 0xd5, 0x62, 0x46, 0x34, 0x5c, 0x8b, 0x79, 0x9d, 0xf7, 0xd1, - 0xc4, 0x79, 0x64, 0x63, 0xe7, 0xf1, 0x63, 0x11, 0x5b, 0x6f, 0x3a, 0x8f, 0xd0, 0xb8, 0x66, 0x77, - 0x15, 0x84, 0x45, 0x8e, 0xf6, 0x7b, 0x4a, 0x42, 0x13, 0x28, 0xc6, 0xef, 0x05, 0xd8, 0x60, 0x87, - 0x95, 0x3b, 0x90, 0xee, 0x9a, 0xeb, 0xe6, 0xba, 0x80, 0xb2, 0xfb, 0xe6, 0x07, 0x60, 0x33, 0x44, - 0xe3, 0x57, 0x2e, 0xf4, 0xd4, 0x33, 0x43, 0x6a, 0x1e, 0x76, 0xe6, 0x45, 0xd8, 0x0a, 0x11, 0xb9, - 0x36, 0x87, 0x5d, 0x37, 0xd7, 0x4d, 0x55, 0x14, 0x74, 0x38, 0x5c, 0x3b, 0x4a, 0xde, 0x3c, 0x7e, - 0x4e, 0xb5, 0xd2, 0xbe, 0x9f, 0x8f, 0x69, 0x49, 0xc4, 0x67, 0xe8, 0x29, 0x1a, 0xf8, 0x36, 0xef, - 0x24, 0xbe, 0x17, 0x5d, 0x9b, 0x33, 0x66, 0xdc, 0xa6, 0xc9, 0xb2, 0xda, 0x26, 0x04, 0x81, 0x2f, - 0x4c, 0x9c, 0x6c, 0x26, 0x51, 0xb3, 0x73, 0x1f, 0xe7, 0xac, 0x60, 0xc7, 0x36, 0x9e, 0xf2, 0x62, - 0x76, 0xe2, 0x9a, 0x4a, 0xa7, 0x2c, 0x4a, 0xd6, 0xe1, 0x2f, 0xf1, 0x81, 0x1e, 0xa0, 0x52, 0x31, - 0x88, 0x33, 0xcf, 0x67, 0xdc, 0x9d, 0x52, 0xcc, 0xb1, 0x97, 0x90, 0xb3, 0x3a, 0x13, 0xff, 0x0a, - 0xb6, 0x06, 0xac, 0xa1, 0x8e, 0x42, 0x30, 0x2c, 0x64, 0xa8, 0xe0, 0xd3, 0x8d, 0xaf, 0xd4, 0x9b, - 0x66, 0x89, 0xd2, 0x09, 0x36, 0xc7, 0xf0, 0x8c, 0xac, 0x59, 0x88, 0x57, 0x72, 0x49, 0x44, 0xd1, - 0x5d, 0xd8, 0x03, 0x91, 0x02, 0x02, 0xab, 0x7a, 0xc1, 0x89, 0x03, 0x38, 0x9a, 0x76, 0x0c, 0x17, - 0xe7, 0x0f, 0xc9, 0x82, 0x0c, 0x4d, 0xd1, 0x01, 0x9a, 0x93, 0x0f, 0x50, 0x59, 0xcf, 0x90, 0x8f, - 0xe9, 0x19, 0xb4, 0x3f, 0xce, 0xc3, 0xf3, 0xa7, 0x18, 0xae, 0x05, 0xdf, 0xfc, 0x74, 0x5c, 0x3c, - 0xcb, 0xc5, 0x6e, 0x86, 0x94, 0x29, 0xdf, 0x20, 0xe9, 0x2d, 0x35, 0x5b, 0x38, 0xfb, 0x12, 0x6c, - 0xb2, 0x5d, 0x90, 0x99, 0x25, 0x1e, 0xce, 0x86, 0xa7, 0xd8, 0x06, 0x2f, 0x09, 0x1f, 0xaa, 0x04, - 0x29, 0xee, 0x8c, 0xb8, 0x63, 0x58, 0x21, 0x8c, 0x74, 0xa1, 0x84, 0x68, 0x87, 0x8e, 0x37, 0x3c, - 0x95, 0x33, 0x8f, 0xf0, 0xd0, 0x92, 0xc9, 0x98, 0x35, 0x35, 0x05, 0xec, 0xe1, 0x6f, 0x72, 0x03, - 0x36, 0x47, 0xb3, 0x13, 0x2a, 0x78, 0xb0, 0xb9, 0xc0, 0xad, 0x3f, 0x96, 0xcc, 0xf5, 0xd1, 0xec, - 0x44, 0x1f, 0x8f, 0x71, 0x48, 0xd1, 0x4c, 0x64, 0x8b, 0xe2, 0xb1, 0x55, 0x2b, 0x30, 0x97, 0x11, - 0x93, 0x32, 0x60, 0xeb, 0x96, 0xe3, 0x9e, 0x03, 0x66, 0x34, 0xc8, 0x33, 0x54, 0xb1, 0x1f, 0xda, - 0x7f, 0xe5, 0xc4, 0x7d, 0x77, 0xfe, 0xbc, 0xff, 0xe5, 0x10, 0x65, 0x0c, 0xd1, 0x4d, 0x50, 0x69, - 0xd7, 0x47, 0x9b, 0x4a, 0x38, 0x46, 0x1b, 0xa3, 0xd9, 0x49, 0xd8, 0x77, 0x72, 0xc7, 0x2f, 0xcb, - 0x1d, 0xff, 0x9a, 0xb8, 0x0f, 0x67, 0x6e, 0x0f, 0xf3, 0xbb, 0x5c, 0xfb, 0xf7, 0x3c, 0xdc, 0x38, - 0xdd, 0x26, 0xf0, 0xcb, 0x71, 0xcb, 0x18, 0xb7, 0x84, 0xea, 0x74, 0x29, 0xa5, 0x3a, 0xcd, 0x58, - 0x7b, 0xcb, 0x59, 0x6b, 0x2f, 0xa5, 0xa8, 0x5d, 0xc9, 0x50, 0xd4, 0x66, 0x2e, 0xd0, 0xe2, 0x13, - 0x16, 0xe8, 0xaa, 0x3c, 0x4f, 0xfe, 0x39, 0x54, 0x60, 0xc4, 0xef, 0x03, 0x6f, 0xc2, 0x59, 0x71, - 0x1f, 0x60, 0x27, 0x47, 0xa4, 0x7f, 0x2f, 0xdd, 0xb9, 0x95, 0x75, 0x13, 0x40, 0xb4, 0x0c, 0x69, - 0x7d, 0x8b, 0xdf, 0x01, 0xa2, 0xf2, 0xff, 0x3b, 0xd2, 0x3f, 0x79, 0x00, 0x17, 0x30, 0xbe, 0x7b, - 0x5f, 0x7e, 0x39, 0xb0, 0x27, 0xee, 0x21, 0x9f, 0x0f, 0xd7, 0x52, 0xb2, 0xb2, 0xd7, 0x97, 0xaa, - 0x63, 0xba, 0x87, 0xb5, 0x33, 0xe6, 0xb9, 0x20, 0x03, 0x9e, 0xbc, 0x58, 0xfc, 0x99, 0x02, 0xda, - 0x93, 0xfb, 0x0b, 0x15, 0x55, 0xc9, 0x0e, 0x5f, 0x35, 0x4b, 0x8e, 0xd4, 0x7b, 0xcf, 0xc3, 0xfa, - 0xc4, 0x3d, 0x9c, 0xb8, 0xc1, 0x71, 0x4c, 0x03, 0xb2, 0xc6, 0x81, 0xa2, 0x63, 0x44, 0x94, 0xc9, - 0xa7, 0x92, 0xcc, 0x05, 0x91, 0xb6, 0x17, 0xde, 0x17, 0x33, 0xc7, 0x81, 0xce, 0x26, 0xb9, 0x82, - 0xec, 0xc7, 0xdd, 0x42, 0x31, 0xa7, 0xe6, 0x4d, 0x1e, 0x0b, 0xf3, 0xd0, 0x1b, 0xba, 0xda, 0x5f, - 0x29, 0x42, 0x22, 0xc8, 0xea, 0x3c, 0xf2, 0xa6, 0x64, 0xcc, 0x9b, 0x4f, 0x89, 0x21, 0x59, 0x24, - 0xb2, 0xdd, 0x23, 0x0f, 0xcf, 0x88, 0x80, 0x58, 0x78, 0x46, 0x84, 0xbc, 0x07, 0x8b, 0x44, 0x7e, - 0x6b, 0x7e, 0x43, 0x58, 0x04, 0xd1, 0x3d, 0xef, 0xe0, 0x36, 0xb9, 0x05, 0x2b, 0xcc, 0x08, 0x48, - 0x54, 0x77, 0x33, 0x56, 0xdd, 0x83, 0xdb, 0xa6, 0x28, 0xd7, 0xde, 0x0e, 0xdf, 0xb5, 0x52, 0x8d, - 0x38, 0xb8, 0x4d, 0x5e, 0x3b, 0x9d, 0x71, 0x6e, 0x51, 0x18, 0xe7, 0x86, 0x86, 0xb9, 0xaf, 0xc7, - 0x0c, 0x73, 0xaf, 0x2f, 0xee, 0x2d, 0xfe, 0x1a, 0xc9, 0xc2, 0x11, 0x46, 0x61, 0xaa, 0x7e, 0x92, - 0x83, 0x67, 0x17, 0x52, 0x90, 0xcb, 0x50, 0xd4, 0x3b, 0xf5, 0x6e, 0x34, 0xbe, 0x74, 0xcd, 0x08, - 0x08, 0xd9, 0x87, 0xd5, 0x5d, 0x27, 0xf0, 0xfa, 0x74, 0x1a, 0x67, 0x3e, 0x0f, 0xa4, 0xd8, 0x86, - 0xe8, 0xb5, 0x33, 0x66, 0x44, 0x4b, 0x6c, 0xd8, 0xc2, 0xb5, 0x10, 0x4b, 0xfd, 0x94, 0xcf, 0xd0, - 0x35, 0xa4, 0x18, 0xa6, 0xc8, 0xe8, 0x3e, 0x93, 0x02, 0x92, 0x87, 0x40, 0x2c, 0xab, 0x56, 0x71, - 0x27, 0x53, 0x7e, 0x07, 0x9f, 0x7a, 0xa1, 0xa5, 0xe7, 0x87, 0x9f, 0xd0, 0x77, 0x29, 0xba, 0xda, - 0x19, 0x33, 0x83, 0x5b, 0x72, 0x99, 0xbf, 0x25, 0xe4, 0x9d, 0xf9, 0x9d, 0xf0, 0x14, 0xb1, 0x5b, - 0x6f, 0x42, 0xb1, 0x23, 0x6c, 0x11, 0x24, 0x8b, 0x79, 0x61, 0x77, 0x60, 0x86, 0xa5, 0xda, 0x6f, - 0x2a, 0x42, 0xe9, 0xf0, 0xe4, 0xce, 0x92, 0x32, 0x73, 0x0d, 0x16, 0x67, 0xe6, 0x1a, 0xfc, 0x8c, - 0x99, 0xb9, 0x34, 0x0f, 0x6e, 0x9d, 0xba, 0x63, 0xc9, 0xc7, 0x41, 0xc5, 0x24, 0x46, 0x8e, 0x34, - 0x48, 0x6c, 0x7d, 0x6d, 0x85, 0xc1, 0xbc, 0x6b, 0x3c, 0x53, 0x9c, 0xb9, 0xd9, 0x8f, 0x53, 0x6b, - 0x7f, 0xca, 0x83, 0xb8, 0xd7, 0x07, 0x9d, 0x84, 0xa2, 0xf9, 0xbd, 0x3a, 0x59, 0x18, 0xb1, 0xc5, - 0xf6, 0xbc, 0x94, 0x44, 0x32, 0xfd, 0xad, 0xf9, 0xbe, 0x16, 0xd2, 0xca, 0xfb, 0xc3, 0x3c, 0x5c, - 0x5e, 0x44, 0x9e, 0x99, 0xa6, 0x5a, 0x79, 0xba, 0x34, 0xd5, 0xb7, 0xa0, 0xc8, 0x60, 0xa1, 0x07, - 0x01, 0x8e, 0x2d, 0x27, 0xa5, 0x63, 0x2b, 0x8a, 0xc9, 0xf3, 0xb0, 0xac, 0x57, 0xac, 0x28, 0x73, - 0x1a, 0x9a, 0xfa, 0x3a, 0xfd, 0x00, 0x8d, 0x48, 0x79, 0x11, 0xf9, 0x62, 0x3a, 0x59, 0x20, 0x4f, - 0x99, 0x76, 0x49, 0xea, 0x90, 0x54, 0x7e, 0x05, 0xac, 0x6f, 0x94, 0x0f, 0x80, 0x87, 0xd8, 0x36, - 0xd3, 0x89, 0x07, 0x35, 0x58, 0xee, 0x4c, 0xdc, 0xc0, 0x9d, 0xca, 0x66, 0xb8, 0x63, 0x84, 0x98, - 0xbc, 0x84, 0x1b, 0xc9, 0x3a, 0x8f, 0x59, 0x4c, 0x84, 0x65, 0x39, 0x4e, 0x0d, 0x5a, 0xd5, 0x52, - 0xb0, 0x29, 0xa1, 0x50, 0x82, 0x86, 0x33, 0x1b, 0xf5, 0x8f, 0x7b, 0x66, 0x83, 0x4b, 0x4e, 0x8c, - 0x60, 0x88, 0x50, 0xda, 0xc0, 0xc0, 0x94, 0x50, 0xb4, 0x6f, 0x29, 0x70, 0x2e, 0xab, 0x1d, 0xe4, - 0x32, 0x14, 0x46, 0x99, 0x79, 0x11, 0x47, 0xcc, 0x95, 0xbb, 0x44, 0xff, 0xda, 0x87, 0xfe, 0xe4, - 0xc4, 0x99, 0xca, 0xc6, 0xca, 0x12, 0xd8, 0x04, 0xfa, 0x63, 0x0f, 0xff, 0x27, 0x57, 0xc5, 0x91, - 0x93, 0x4f, 0x65, 0x52, 0xc4, 0x3f, 0x9a, 0x0e, 0x50, 0x1f, 0x74, 0xda, 0x63, 0x16, 0xdf, 0xff, - 0x15, 0x28, 0xd0, 0x6a, 0x25, 0x66, 0x2f, 0x9d, 0x3f, 0x7a, 0xb3, 0xc1, 0x91, 0x58, 0xad, 0x02, - 0xe7, 0x64, 0x68, 0x22, 0xb2, 0x76, 0x1f, 0x36, 0xe2, 0x18, 0xc4, 0x88, 0x47, 0x84, 0x2d, 0xdd, - 0x51, 0x39, 0xa7, 0x5d, 0xdf, 0x67, 0x0e, 0x33, 0xbb, 0xcf, 0xfc, 0xe4, 0x9d, 0xab, 0x40, 0x7f, - 0x32, 0x9a, 0xac, 0x88, 0xb1, 0xda, 0xb7, 0x73, 0x70, 0x2e, 0xf2, 0xd1, 0x17, 0x6b, 0xe8, 0x17, - 0xd6, 0x61, 0x54, 0x8f, 0x39, 0x34, 0x0a, 0xb9, 0x31, 0xdd, 0xc0, 0x05, 0x7e, 0x54, 0xfb, 0xb0, - 0x33, 0x0f, 0x9f, 0xbc, 0x08, 0xab, 0x18, 0xd6, 0x69, 0xec, 0xf4, 0x5d, 0x79, 0x9b, 0x1d, 0x09, - 0xa0, 0x19, 0x95, 0x6b, 0x3f, 0x52, 0xe0, 0x22, 0x77, 0xf3, 0x68, 0x3a, 0xde, 0x08, 0x5f, 0x09, - 0xfa, 0xee, 0xfb, 0xe3, 0xf0, 0xbc, 0x1f, 0xdb, 0xc7, 0x5e, 0x88, 0x7b, 0xf3, 0xa4, 0xbe, 0x36, - 0xbf, 0xb5, 0xe4, 0x16, 0x86, 0x2a, 0xe3, 0xaf, 0xe8, 0x05, 0x16, 0x60, 0x62, 0x44, 0x01, 0x72, - 0x80, 0x09, 0xc4, 0xd0, 0x7e, 0x05, 0xae, 0x2c, 0xfe, 0x00, 0xf9, 0x02, 0xac, 0x63, 0xee, 0xab, - 0xde, 0xf8, 0x68, 0xe2, 0x0c, 0x5c, 0xa1, 0xd9, 0x13, 0xda, 0x58, 0xb9, 0x8c, 0x45, 0x5e, 0xe3, - 0x01, 0x0f, 0x8e, 0x30, 0xab, 0x16, 0x27, 0x8a, 0xf9, 0x52, 0xc9, 0xdc, 0xb4, 0x5f, 0x55, 0x80, - 0xa4, 0x79, 0x90, 0x8f, 0xc0, 0x5a, 0xaf, 0x5b, 0xb1, 0xa6, 0xce, 0x64, 0x5a, 0xf3, 0x67, 0x13, - 0x1e, 0xf6, 0x8c, 0xf9, 0xbf, 0x4f, 0xfb, 0x36, 0x7b, 0x0f, 0x3a, 0xf6, 0x67, 0x13, 0x33, 0x86, - 0x87, 0x49, 0x9b, 0x5c, 0xf7, 0x2b, 0x03, 0xe7, 0x71, 0x3c, 0x69, 0x13, 0x87, 0xc5, 0x92, 0x36, - 0x71, 0x98, 0xf6, 0x3d, 0x05, 0x2e, 0x09, 0xe3, 0xc8, 0x41, 0x46, 0x5d, 0x2a, 0x18, 0xe5, 0x65, - 0x22, 0xe2, 0xec, 0x2e, 0x92, 0xd0, 0xb7, 0x44, 0x20, 0x24, 0xac, 0x20, 0x8a, 0xea, 0x8c, 0x96, - 0x7c, 0x1a, 0x0a, 0xd6, 0xd4, 0x1f, 0x9f, 0x22, 0x12, 0x92, 0x1a, 0x8e, 0xe8, 0xd4, 0x1f, 0x23, - 0x0b, 0xa4, 0xd4, 0x5c, 0x38, 0x27, 0x57, 0x4e, 0xd4, 0x98, 0x34, 0x61, 0x85, 0x87, 0xbc, 0x4b, - 0xd8, 0x1d, 0x2c, 0x68, 0xd3, 0xee, 0xa6, 0x08, 0xb7, 0xc4, 0xe3, 0xbc, 0x9a, 0x82, 0x87, 0xf6, - 0xdb, 0x0a, 0x94, 0xa8, 0x60, 0x83, 0x97, 0xd2, 0xf7, 0x3a, 0xa5, 0xe3, 0x72, 0xb0, 0x30, 0xa3, - 0x09, 0xd9, 0x9f, 0xea, 0x34, 0x7e, 0x15, 0x36, 0x13, 0x04, 0x44, 0xc3, 0x40, 0x1b, 0x43, 0xaf, - 0xef, 0xb0, 0x1c, 0x30, 0xcc, 0x04, 0x25, 0x06, 0xd3, 0x7e, 0x5d, 0x81, 0x73, 0xed, 0xaf, 0x4c, - 0x1d, 0xf6, 0x6c, 0x6b, 0xce, 0x86, 0x62, 0xbd, 0x53, 0x61, 0x4d, 0x58, 0xd9, 0xb2, 0x20, 0x00, - 0x4c, 0x58, 0xe3, 0x30, 0x33, 0x2c, 0x25, 0x35, 0x28, 0xf2, 0xf3, 0x25, 0xe0, 0xe1, 0x59, 0xaf, - 0x48, 0xba, 0x91, 0x88, 0x31, 0x47, 0xa2, 0x2d, 0xc1, 0x2d, 0x8c, 0xd3, 0x98, 0x21, 0xb5, 0xf6, - 0x1f, 0x0a, 0x6c, 0xcf, 0xa1, 0x21, 0x9f, 0x80, 0x25, 0x74, 0x50, 0xe4, 0xa3, 0x77, 0x79, 0xce, - 0x27, 0xa6, 0xfd, 0xe3, 0x83, 0xdb, 0xec, 0x20, 0x3a, 0xa1, 0x3f, 0x4c, 0x46, 0x45, 0xde, 0x84, - 0x55, 0x7d, 0x30, 0xe0, 0xb7, 0xb3, 0x5c, 0xec, 0x76, 0x36, 0xe7, 0x8b, 0x2f, 0x87, 0xf8, 0xec, - 0x76, 0xc6, 0x5c, 0x65, 0x06, 0x03, 0x9b, 0x3b, 0x5f, 0x46, 0xfc, 0x2e, 0x7e, 0x1c, 0x36, 0xe2, - 0xc8, 0x4f, 0xe5, 0x2f, 0xf6, 0xb6, 0x02, 0x6a, 0xbc, 0x0e, 0x3f, 0x9f, 0x40, 0x51, 0x59, 0xc3, - 0xfc, 0x84, 0x49, 0xf5, 0xbb, 0x39, 0x38, 0x9f, 0xd9, 0xc3, 0xe4, 0x25, 0x58, 0xd6, 0xc7, 0xe3, - 0x7a, 0x95, 0xcf, 0x2a, 0x2e, 0x21, 0xa1, 0xd2, 0x3b, 0x76, 0x79, 0x65, 0x48, 0xe4, 0x15, 0x28, - 0x32, 0xeb, 0x80, 0xaa, 0xd8, 0x70, 0x30, 0xf2, 0x0d, 0x37, 0x5d, 0x88, 0x07, 0x4a, 0x15, 0x88, - 0x64, 0x0f, 0x36, 0x78, 0xcc, 0x18, 0xd3, 0x3d, 0x72, 0xbf, 0x16, 0x46, 0xec, 0xc7, 0xa4, 0x02, - 0x42, 0x93, 0x6e, 0x4f, 0x58, 0x99, 0x1c, 0x35, 0x25, 0x4e, 0x45, 0x1a, 0xa0, 0x22, 0x4f, 0x99, - 0x13, 0x8b, 0xd6, 0x8a, 0x51, 0x7c, 0x58, 0x25, 0xe6, 0xf0, 0x4a, 0x51, 0x86, 0xc3, 0xa5, 0x07, - 0x81, 0x77, 0x34, 0x3a, 0x71, 0x47, 0xd3, 0x9f, 0xdf, 0x70, 0x45, 0xdf, 0x38, 0xd5, 0x70, 0xfd, - 0x7e, 0x81, 0x2d, 0xe6, 0x24, 0x19, 0x95, 0x68, 0xa4, 0x00, 0xdd, 0x28, 0xd1, 0xd0, 0xfb, 0x19, - 0x8f, 0x8a, 0x52, 0x85, 0x15, 0x16, 0xad, 0x46, 0xac, 0x8c, 0x67, 0x33, 0xab, 0xc0, 0x70, 0x0e, - 0x6e, 0x33, 0xf1, 0x85, 0x79, 0x4a, 0x06, 0xa6, 0x20, 0x25, 0x07, 0x50, 0xaa, 0x0c, 0x5d, 0x67, - 0x34, 0x1b, 0x77, 0x4f, 0xf7, 0x82, 0xba, 0xc3, 0xdb, 0xb2, 0xd6, 0x67, 0x64, 0xf8, 0xf2, 0x8a, - 0x3b, 0xb9, 0xcc, 0x88, 0x74, 0x43, 0xe7, 0xa9, 0x02, 0x2a, 0x5e, 0x3f, 0xbc, 0xa0, 0x7f, 0x92, - 0x40, 0xa4, 0x8b, 0x7b, 0x06, 0x72, 0xef, 0x2a, 0x1b, 0x36, 0x1a, 0x4e, 0x30, 0xed, 0x4e, 0x9c, - 0x51, 0x80, 0x51, 0x2e, 0x4f, 0x11, 0x05, 0xec, 0x92, 0xc8, 0xa0, 0x8c, 0x2a, 0xd3, 0x69, 0x48, - 0xca, 0x14, 0xb2, 0x71, 0x76, 0x54, 0x5e, 0xda, 0xf3, 0x46, 0xce, 0xd0, 0xfb, 0xba, 0xf0, 0x31, - 0x65, 0xf2, 0xd2, 0xa1, 0x00, 0x9a, 0x51, 0xb9, 0xf6, 0xf9, 0xd4, 0xb8, 0xb1, 0x5a, 0x96, 0x60, - 0x85, 0x47, 0x20, 0x60, 0x1e, 0xf9, 0x1d, 0xa3, 0x55, 0xad, 0xb7, 0xf6, 0x55, 0x85, 0x6c, 0x00, - 0x74, 0xcc, 0x76, 0xc5, 0xb0, 0x2c, 0xfa, 0x3b, 0x47, 0x7f, 0x73, 0x77, 0xfd, 0xbd, 0x5e, 0x43, - 0xcd, 0x4b, 0x1e, 0xfb, 0x05, 0xed, 0x87, 0x0a, 0x5c, 0xc8, 0x1e, 0x4a, 0xd2, 0x05, 0x8c, 0xd9, - 0xc0, 0xdf, 0xd2, 0x3f, 0xb2, 0x70, 0xdc, 0x33, 0xc1, 0xc9, 0xd8, 0x0f, 0x53, 0x16, 0x53, 0x20, - 0x27, 0xde, 0xbe, 0x98, 0x93, 0xa2, 0x37, 0x30, 0x73, 0xde, 0x40, 0xab, 0xc0, 0xce, 0x3c, 0x1e, - 0xf1, 0xa6, 0x6e, 0x42, 0x49, 0xef, 0x74, 0x1a, 0xf5, 0x8a, 0xde, 0xad, 0xb7, 0x5b, 0xaa, 0x42, - 0x56, 0x61, 0x69, 0xdf, 0x6c, 0xf7, 0x3a, 0x6a, 0x4e, 0xfb, 0x8e, 0x02, 0xeb, 0xf5, 0xc8, 0xea, - 0xec, 0xbd, 0x2e, 0xbe, 0x8f, 0xc6, 0x16, 0xdf, 0x4e, 0x18, 0xdd, 0x24, 0xfc, 0xc0, 0xa9, 0x56, - 0xde, 0xbb, 0x39, 0xd8, 0x4a, 0xd1, 0x10, 0x0b, 0x56, 0xf4, 0xfb, 0x56, 0xbb, 0x5e, 0xad, 0xf0, - 0x9a, 0x5d, 0x8d, 0xcc, 0xa5, 0x30, 0x81, 0x55, 0xea, 0x2b, 0xcc, 0x23, 0xf8, 0x51, 0x60, 0xfb, - 0xde, 0x40, 0x4a, 0x3e, 0x5b, 0x3b, 0x63, 0x0a, 0x4e, 0x78, 0x92, 0x7d, 0x7d, 0x36, 0x71, 0x91, - 0x6d, 0x2e, 0xa6, 0xd7, 0x0d, 0xe1, 0x69, 0xc6, 0xe8, 0xbf, 0xe1, 0xd0, 0xf2, 0x34, 0xeb, 0x88, - 0x1f, 0x69, 0xc1, 0xf2, 0xbe, 0x37, 0xad, 0xcd, 0x1e, 0xf2, 0xf5, 0x7b, 0x25, 0x4a, 0x67, 0x54, - 0x9b, 0x3d, 0x4c, 0xb3, 0x45, 0x95, 0x25, 0x8b, 0xde, 0x13, 0x63, 0xc9, 0xb9, 0x24, 0x9d, 0x18, - 0x0b, 0x4f, 0xe5, 0xc4, 0xb8, 0xbb, 0x0e, 0x25, 0x7e, 0x87, 0xc2, 0xeb, 0xc9, 0xf7, 0x15, 0xd8, - 0x99, 0xd7, 0x73, 0xf4, 0x5a, 0x16, 0x0f, 0x56, 0x70, 0x21, 0x4c, 0x8f, 0x11, 0x8f, 0x52, 0x20, - 0xd0, 0xc8, 0xa7, 0xa0, 0x54, 0x0f, 0x82, 0x99, 0x3b, 0xb1, 0x5e, 0xe9, 0x99, 0x75, 0x3e, 0x5d, - 0x9f, 0xfd, 0xd7, 0x77, 0xae, 0x6e, 0xa3, 0xcf, 0xc7, 0xc4, 0x0e, 0x5e, 0xb1, 0x67, 0x13, 0x2f, - 0x96, 0x4a, 0x40, 0xa6, 0xa0, 0x52, 0xb4, 0x33, 0x1b, 0x78, 0xae, 0xb8, 0x43, 0x08, 0x87, 0x6e, - 0x0e, 0x93, 0xcf, 0x34, 0x01, 0xd3, 0xbe, 0xa9, 0xc0, 0xc5, 0xf9, 0xc3, 0x44, 0xcf, 0xc9, 0x2e, - 0x33, 0xa9, 0x12, 0x2e, 0xd5, 0x78, 0x4e, 0x86, 0x76, 0x57, 0x32, 0x4f, 0x81, 0x48, 0x89, 0xc2, - 0xd4, 0xf4, 0xb9, 0x54, 0x3e, 0xea, 0x38, 0x91, 0x40, 0xd4, 0x1e, 0xc0, 0xf6, 0x9c, 0x41, 0x25, - 0x9f, 0xcc, 0x4c, 0xba, 0x83, 0x6e, 0x4a, 0x72, 0xd2, 0x9d, 0x58, 0x3a, 0x36, 0x09, 0xae, 0xfd, - 0x5b, 0x0e, 0x2e, 0xd0, 0xd5, 0x35, 0x74, 0x83, 0x40, 0x9f, 0x4d, 0x8f, 0xe9, 0x70, 0x32, 0x79, - 0x93, 0xbc, 0x06, 0xcb, 0xc7, 0x4f, 0xa7, 0x2a, 0x66, 0xe8, 0x84, 0x00, 0x9e, 0x58, 0xc2, 0x39, - 0x86, 0xfe, 0x4f, 0xae, 0x81, 0x9c, 0x5c, 0x3c, 0x8f, 0xe1, 0x4d, 0x73, 0x3b, 0x8a, 0xb9, 0x3a, - 0x0e, 0xf3, 0x00, 0xbf, 0x0e, 0x4b, 0xa8, 0x4f, 0xe1, 0x67, 0x87, 0x90, 0xf9, 0xb3, 0x6b, 0x87, - 0xda, 0x16, 0x93, 0x11, 0x90, 0x0f, 0x01, 0x44, 0x99, 0x21, 0xf8, 0xe1, 0x20, 0xf4, 0x0c, 0x61, - 0x72, 0x08, 0x73, 0xf5, 0xe4, 0xd0, 0xe1, 0xe9, 0x16, 0xca, 0xb0, 0x25, 0x7a, 0x7c, 0x2c, 0xa2, - 0x22, 0xf2, 0x57, 0xcc, 0x4d, 0x56, 0x50, 0x1f, 0x8b, 0xc8, 0x88, 0xd7, 0x53, 0x09, 0x92, 0x31, - 0x38, 0x72, 0x22, 0x0b, 0xf2, 0xf5, 0x54, 0x16, 0xe4, 0x22, 0xc3, 0x92, 0x53, 0x1d, 0x6b, 0xff, - 0x94, 0x83, 0xd5, 0xfb, 0x54, 0x2a, 0x43, 0x5d, 0xc3, 0x62, 0xdd, 0xc5, 0x1d, 0x28, 0x35, 0x7c, - 0x87, 0x3f, 0x17, 0x71, 0x9f, 0x12, 0xe6, 0xd3, 0x3d, 0xf4, 0x1d, 0xf1, 0xf2, 0x14, 0x98, 0x32, - 0xd2, 0x13, 0xfc, 0xd1, 0xef, 0xc2, 0x32, 0x7b, 0xbe, 0xe3, 0x6a, 0x34, 0x21, 0x97, 0x87, 0x35, - 0x7a, 0x99, 0x15, 0x4b, 0x2f, 0x1c, 0xec, 0x09, 0x50, 0x16, 0x12, 0x79, 0x8c, 0x57, 0x49, 0xb3, - 0xb2, 0x74, 0x3a, 0xcd, 0x8a, 0x14, 0xcb, 0x6e, 0xf9, 0x34, 0xb1, 0xec, 0x2e, 0xbe, 0x01, 0x25, - 0xa9, 0x3e, 0x4f, 0x25, 0xa6, 0x7f, 0x23, 0x07, 0xeb, 0xd8, 0xaa, 0xd0, 0x96, 0xe7, 0x17, 0x53, - 0x4f, 0xf4, 0xd1, 0x98, 0x9e, 0x68, 0x47, 0x1e, 0x2f, 0xd6, 0xb2, 0x05, 0x0a, 0xa2, 0xbb, 0xb0, - 0x95, 0x42, 0x24, 0xaf, 0xc2, 0x12, 0xad, 0xbe, 0xb8, 0x57, 0xab, 0xc9, 0x19, 0x10, 0xc5, 0x3d, - 0xa6, 0x0d, 0x0f, 0x4c, 0x86, 0xad, 0xfd, 0xa7, 0x02, 0x6b, 0x3c, 0xed, 0xc8, 0xe8, 0xd0, 0x7f, - 0x62, 0x77, 0xde, 0x48, 0x76, 0x27, 0x8b, 0xae, 0xc2, 0xbb, 0xf3, 0x7f, 0xba, 0x13, 0xdf, 0x88, - 0x75, 0xe2, 0x76, 0x18, 0x05, 0x51, 0x34, 0x67, 0x41, 0x1f, 0xfe, 0x35, 0xc6, 0x05, 0x8e, 0x23, - 0x92, 0x2f, 0xc2, 0x6a, 0xcb, 0x7d, 0x14, 0xbb, 0x9e, 0xde, 0x98, 0xc3, 0xf4, 0xe5, 0x10, 0x91, - 0xad, 0x29, 0x3c, 0xd9, 0x47, 0xee, 0x23, 0x3b, 0xf5, 0x72, 0x18, 0xb1, 0xa4, 0x37, 0xd4, 0x38, - 0xd9, 0xd3, 0x4c, 0x7d, 0xee, 0xe0, 0x8a, 0x01, 0x83, 0xbe, 0x95, 0x07, 0x88, 0x7c, 0x03, 0xe9, - 0x02, 0x8c, 0x19, 0x4d, 0x08, 0xcd, 0x3e, 0x82, 0xe4, 0x39, 0x2e, 0x6c, 0x29, 0x6e, 0x70, 0x0d, - 0x74, 0x6e, 0x7e, 0x94, 0x4a, 0xd4, 0x45, 0x57, 0xb8, 0x33, 0xda, 0xc0, 0x1d, 0x3a, 0x6c, 0x6f, - 0xcf, 0xef, 0x5e, 0xc7, 0xa0, 0xc4, 0x21, 0x74, 0x4e, 0xfe, 0x68, 0x74, 0x59, 0xab, 0x52, 0x84, - 0x94, 0xbf, 0x6d, 0xe1, 0xe9, 0xfc, 0x6d, 0x3b, 0xb0, 0xea, 0x8d, 0xde, 0x72, 0x47, 0x53, 0x7f, - 0xf2, 0x18, 0xd5, 0xee, 0x91, 0x3e, 0x8f, 0x76, 0x41, 0x5d, 0x94, 0xb1, 0x71, 0xc0, 0x33, 0x37, - 0xc4, 0x97, 0x87, 0x21, 0x04, 0x86, 0xfe, 0xc2, 0x4b, 0xea, 0xf2, 0xdd, 0x42, 0x71, 0x59, 0x5d, - 0xb9, 0x5b, 0x28, 0x16, 0xd5, 0xd5, 0xbb, 0x85, 0xe2, 0xaa, 0x0a, 0xa6, 0xf4, 0x66, 0x16, 0xbe, - 0x89, 0x49, 0xcf, 0x58, 0xf1, 0x27, 0x2a, 0xed, 0xa7, 0x39, 0x20, 0xe9, 0x6a, 0x90, 0x8f, 0x42, - 0x89, 0x6d, 0xb0, 0xf6, 0x24, 0xf8, 0x2a, 0x77, 0x37, 0x60, 0x61, 0x97, 0x24, 0xb0, 0x1c, 0x76, - 0x89, 0x81, 0xcd, 0xe0, 0xab, 0x43, 0xf2, 0x05, 0x38, 0x8b, 0xdd, 0x3b, 0x76, 0x27, 0x9e, 0x3f, - 0xb0, 0x31, 0x46, 0xae, 0x33, 0xe4, 0xb9, 0x1e, 0x5f, 0xc2, 0xa4, 0xc4, 0xe9, 0xe2, 0x39, 0xc3, - 0x80, 0x2e, 0x80, 0x1d, 0xc4, 0xec, 0x30, 0x44, 0xd2, 0x05, 0x55, 0xa6, 0x3f, 0x9c, 0x0d, 0x87, - 0x7c, 0x64, 0xcb, 0xf4, 0x46, 0x9f, 0x2c, 0x9b, 0xc3, 0x78, 0x23, 0x62, 0xbc, 0x37, 0x1b, 0x0e, - 0xc9, 0x6b, 0x00, 0xfe, 0xc8, 0x3e, 0xf1, 0x82, 0x80, 0x3d, 0xe6, 0x84, 0xde, 0xca, 0x11, 0x54, - 0x1e, 0x0c, 0x7f, 0xd4, 0x64, 0x40, 0xf2, 0xff, 0x00, 0xa3, 0x35, 0x60, 0x18, 0x13, 0x66, 0x8d, - 0xc4, 0xb3, 0xb7, 0x08, 0x60, 0xdc, 0x39, 0xfa, 0xc8, 0xb5, 0xbc, 0xaf, 0x0b, 0x57, 0x8f, 0xcf, - 0xc1, 0x16, 0x37, 0x1e, 0xbe, 0xef, 0x4d, 0x8f, 0xf9, 0x55, 0xe2, 0xbd, 0xdc, 0x43, 0xa4, 0xbb, - 0xc4, 0xdf, 0x15, 0x00, 0xf4, 0xfb, 0x96, 0x88, 0x10, 0x76, 0x0b, 0x96, 0xe8, 0x05, 0x49, 0x28, - 0x5a, 0x50, 0x4d, 0x8d, 0x7c, 0x65, 0x35, 0x35, 0x62, 0xd0, 0xd5, 0x68, 0xa2, 0x51, 0xbd, 0x50, - 0xb2, 0xe0, 0x6a, 0x64, 0x76, 0xf6, 0xb1, 0x08, 0xcd, 0x1c, 0x8b, 0x34, 0x00, 0xa2, 0x98, 0x5d, - 0x5c, 0xe4, 0xdf, 0x8a, 0x82, 0xdf, 0xf0, 0x02, 0x9e, 0x25, 0x22, 0x8a, 0xfb, 0x25, 0x4f, 0x9f, - 0x08, 0x8d, 0xdc, 0x83, 0x42, 0xd7, 0x09, 0x7d, 0x71, 0xe7, 0x44, 0x32, 0x7b, 0x8e, 0xe7, 0xe2, - 0x8c, 0xa2, 0x99, 0x6d, 0x4c, 0x9d, 0x58, 0xca, 0x62, 0x64, 0x42, 0x0c, 0x58, 0xe6, 0x79, 0xd6, - 0xe7, 0x44, 0xc0, 0xe4, 0x69, 0xd6, 0x79, 0xdc, 0x6b, 0x04, 0xca, 0x32, 0x05, 0xcf, 0xa8, 0x7e, - 0x07, 0xf2, 0x96, 0xd5, 0xe4, 0xf1, 0x3b, 0xd6, 0xa3, 0xeb, 0x97, 0x65, 0x35, 0xd9, 0xbb, 0x6f, - 0x10, 0x9c, 0x48, 0x64, 0x14, 0x99, 0x7c, 0x0c, 0x4a, 0x92, 0x50, 0xcc, 0x23, 0xdf, 0x60, 0x1f, - 0x48, 0xde, 0x4e, 0xf2, 0xa6, 0x21, 0x61, 0x93, 0x06, 0xa8, 0xf7, 0x66, 0x0f, 0x5d, 0x7d, 0x3c, - 0x46, 0x37, 0xc8, 0xb7, 0xdc, 0x09, 0x13, 0xdb, 0x8a, 0x51, 0xc8, 0x68, 0xf4, 0x91, 0x18, 0x88, - 0x52, 0x59, 0xd9, 0x94, 0xa4, 0x24, 0x1d, 0xd8, 0xb2, 0xdc, 0xe9, 0x6c, 0xcc, 0xec, 0x6b, 0xf6, - 0xfc, 0x09, 0xbd, 0xdf, 0xb0, 0x38, 0x39, 0x18, 0x5d, 0x37, 0xa0, 0x85, 0xc2, 0xa8, 0xe9, 0xd0, - 0x9f, 0x24, 0xee, 0x3a, 0x69, 0x62, 0xcd, 0x95, 0x87, 0x9c, 0x9e, 0xaa, 0xf1, 0x5b, 0x13, 0x9e, - 0xaa, 0xe2, 0xd6, 0x14, 0xdd, 0x95, 0x3e, 0x94, 0x11, 0xcb, 0x0d, 0x5f, 0x06, 0xa5, 0x58, 0x6e, - 0xb1, 0x08, 0x6e, 0xdf, 0x2b, 0x48, 0xe1, 0x44, 0xf9, 0x58, 0x7c, 0x02, 0xe0, 0xae, 0xef, 0x8d, - 0x9a, 0xee, 0xf4, 0xd8, 0x1f, 0x48, 0x21, 0xe5, 0x4a, 0x5f, 0xf6, 0xbd, 0x91, 0x7d, 0x82, 0xe0, - 0x9f, 0xbe, 0x73, 0x55, 0x42, 0x32, 0xa5, 0xff, 0xc9, 0x07, 0x61, 0x95, 0xfe, 0xea, 0x46, 0x56, - 0x42, 0x4c, 0x27, 0x8b, 0xd4, 0x2c, 0xe9, 0x46, 0x84, 0x40, 0xde, 0xc0, 0x34, 0x33, 0xde, 0x78, - 0x2a, 0x09, 0xaf, 0x22, 0xa7, 0x8c, 0x37, 0x9e, 0x26, 0x23, 0x44, 0x4b, 0xc8, 0xa4, 0x16, 0x56, - 0x5d, 0x64, 0x86, 0xe2, 0xd9, 0x6c, 0x50, 0xf1, 0xc8, 0xe7, 0x9a, 0x2d, 0x42, 0xd3, 0xca, 0x39, - 0x7c, 0x13, 0x64, 0x58, 0x09, 0xab, 0x56, 0x65, 0x2f, 0x45, 0x5c, 0xa8, 0x65, 0x95, 0x08, 0x8e, - 0x07, 0x76, 0x1f, 0xc1, 0xb1, 0x4a, 0x84, 0xc8, 0x64, 0x17, 0x36, 0x99, 0x8c, 0x1f, 0x66, 0x98, - 0xe4, 0x22, 0x2e, 0xee, 0x6d, 0x51, 0x0a, 0x4a, 0xf9, 0xf3, 0x09, 0x02, 0xb2, 0x07, 0x4b, 0x78, - 0xd7, 0xe4, 0xae, 0x01, 0x97, 0x64, 0x35, 0x41, 0x72, 0x1d, 0xe1, 0xbe, 0x82, 0x0a, 0x02, 0x79, - 0x5f, 0x41, 0x54, 0xf2, 0x59, 0x00, 0x63, 0x34, 0xf1, 0x87, 0x43, 0x0c, 0x9e, 0x5c, 0xc4, 0xab, - 0xd4, 0xb3, 0xf1, 0xf5, 0x88, 0x5c, 0x22, 0x24, 0x1e, 0xe8, 0x0f, 0x7f, 0xdb, 0x89, 0x10, 0xcb, - 0x12, 0x2f, 0xad, 0x0e, 0xcb, 0x6c, 0x31, 0x62, 0x20, 0x72, 0x9e, 0x5a, 0x45, 0x0a, 0x63, 0xcd, - 0x02, 0x91, 0x73, 0x78, 0x3a, 0x10, 0xb9, 0x44, 0xa0, 0xdd, 0x83, 0x73, 0x59, 0x0d, 0x8b, 0xdd, - 0x8e, 0x95, 0xd3, 0xde, 0x8e, 0xbf, 0x9b, 0x87, 0x35, 0xe4, 0x26, 0x76, 0x61, 0x1d, 0xd6, 0xad, - 0xd9, 0xc3, 0x30, 0x4a, 0x97, 0xd8, 0x8d, 0xb1, 0x7e, 0x81, 0x5c, 0x20, 0xbf, 0xe1, 0xc5, 0x28, - 0x88, 0x01, 0x1b, 0xe2, 0x24, 0xd8, 0x17, 0x9e, 0x03, 0x61, 0x0c, 0x70, 0x11, 0x69, 0x32, 0x9d, - 0x61, 0x37, 0x41, 0x14, 0x9d, 0x07, 0xf9, 0xa7, 0x39, 0x0f, 0x0a, 0xa7, 0x3a, 0x0f, 0xde, 0x84, - 0x35, 0xf1, 0x35, 0xdc, 0xc9, 0x97, 0xde, 0xdb, 0x4e, 0x1e, 0x63, 0x46, 0x1a, 0xe1, 0x8e, 0xbe, - 0xbc, 0x70, 0x47, 0xc7, 0x87, 0x51, 0xb1, 0xca, 0xc6, 0x08, 0x4b, 0x6f, 0xec, 0x98, 0x82, 0x72, - 0xbf, 0xd2, 0xf9, 0x19, 0x4e, 0xc9, 0x57, 0x61, 0xb5, 0xe1, 0x8b, 0x37, 0x31, 0xe9, 0x31, 0x62, - 0x28, 0x80, 0xb2, 0xb8, 0x10, 0x62, 0x86, 0xa7, 0x5b, 0xfe, 0xfd, 0x38, 0xdd, 0xde, 0x00, 0xe0, - 0x2e, 0x29, 0x51, 0xea, 0x38, 0x5c, 0x32, 0x22, 0x42, 0x49, 0xfc, 0x4d, 0x44, 0x42, 0xa6, 0xbb, - 0x13, 0x37, 0xb7, 0xd1, 0xfb, 0x7d, 0x7f, 0x36, 0x9a, 0xc6, 0x72, 0x2d, 0x0b, 0x0f, 0x56, 0x87, - 0x97, 0xc9, 0xdb, 0x43, 0x82, 0xec, 0xfd, 0x1d, 0x10, 0xf2, 0x99, 0xd0, 0xf8, 0x71, 0x65, 0x51, - 0x0f, 0x69, 0xa9, 0x1e, 0x9a, 0x6b, 0xf2, 0xa8, 0xfd, 0x50, 0x91, 0x13, 0x30, 0xfc, 0x0c, 0x43, - 0xfd, 0x3a, 0x40, 0x68, 0x94, 0x20, 0xc6, 0x9a, 0xdd, 0x97, 0x42, 0xa8, 0xdc, 0xcb, 0x11, 0xae, - 0xd4, 0x9a, 0xfc, 0xfb, 0xd5, 0x9a, 0x2e, 0x94, 0xda, 0x5f, 0x99, 0x3a, 0x91, 0x15, 0x0b, 0x58, - 0xa1, 0x24, 0x8b, 0x3b, 0x53, 0x7e, 0xf7, 0x05, 0x3c, 0x1b, 0x22, 0x39, 0x78, 0x8e, 0x08, 0x2c, - 0x11, 0x6a, 0x7f, 0xae, 0xc0, 0xa6, 0xec, 0x76, 0xff, 0x78, 0xd4, 0x27, 0x9f, 0x64, 0xf1, 0x60, - 0x95, 0xd8, 0x95, 0x45, 0x42, 0xa2, 0x5b, 0xee, 0xe3, 0x51, 0x9f, 0x09, 0x40, 0xce, 0x23, 0xb9, - 0xb2, 0x94, 0x90, 0x3c, 0x84, 0xb5, 0x8e, 0x3f, 0x1c, 0x52, 0xb1, 0x66, 0xf2, 0x16, 0xbf, 0x00, - 0x50, 0x46, 0xc9, 0xa7, 0x11, 0x51, 0xa1, 0xdd, 0xe7, 0xf9, 0x3d, 0x77, 0x7b, 0x4c, 0xf7, 0x7b, - 0x8f, 0xd3, 0x45, 0x6c, 0xdf, 0x46, 0x3f, 0x39, 0x99, 0xa7, 0xf6, 0x63, 0x05, 0x48, 0xba, 0x4a, - 0xf2, 0x96, 0xa5, 0xfc, 0x2f, 0x88, 0xb0, 0x09, 0xd1, 0xaf, 0xf0, 0x34, 0xa2, 0x5f, 0xf9, 0x77, - 0x14, 0xd8, 0xac, 0xeb, 0x4d, 0x9e, 0x92, 0x81, 0xbd, 0xe0, 0x5c, 0x83, 0x67, 0xeb, 0x7a, 0xd3, - 0xee, 0xb4, 0x1b, 0xf5, 0xca, 0x03, 0x3b, 0x33, 0xd2, 0xf2, 0xb3, 0xf0, 0x4c, 0x1a, 0x25, 0x7a, - 0xe9, 0xb9, 0x0c, 0x3b, 0xe9, 0x62, 0x11, 0x8d, 0x39, 0x9b, 0x58, 0x04, 0x6e, 0xce, 0x97, 0x3f, - 0x05, 0x9b, 0x22, 0xf2, 0x70, 0xb7, 0x61, 0x61, 0x6e, 0x83, 0x4d, 0x28, 0x1d, 0x18, 0x66, 0x7d, - 0xef, 0x81, 0xbd, 0xd7, 0x6b, 0x34, 0xd4, 0x33, 0x64, 0x1d, 0x56, 0x39, 0xa0, 0xa2, 0xab, 0x0a, - 0x59, 0x83, 0x62, 0xbd, 0x65, 0x19, 0x95, 0x9e, 0x69, 0xa8, 0xb9, 0xf2, 0xa7, 0x60, 0xa3, 0x33, - 0xf1, 0xde, 0x72, 0xa6, 0xee, 0x3d, 0xf7, 0x31, 0x3e, 0xd4, 0xac, 0x40, 0xde, 0xd4, 0xef, 0xab, - 0x67, 0x08, 0xc0, 0x72, 0xe7, 0x5e, 0xc5, 0xba, 0x7d, 0x5b, 0x55, 0x48, 0x09, 0x56, 0xf6, 0x2b, - 0x1d, 0xfb, 0x5e, 0xd3, 0x52, 0x73, 0xf4, 0x87, 0x7e, 0xdf, 0xc2, 0x1f, 0xf9, 0xf2, 0x87, 0x61, - 0x0b, 0x05, 0x92, 0x86, 0x17, 0x4c, 0xdd, 0x91, 0x3b, 0xc1, 0x3a, 0xac, 0x41, 0xd1, 0x72, 0xe9, - 0x4e, 0x32, 0x75, 0x59, 0x05, 0x9a, 0xb3, 0xe1, 0xd4, 0x1b, 0x0f, 0xdd, 0xaf, 0xa9, 0x4a, 0xf9, - 0x0d, 0xd8, 0x34, 0xfd, 0xd9, 0xd4, 0x1b, 0x1d, 0x59, 0x53, 0x8a, 0x71, 0xf4, 0x98, 0x9c, 0x87, - 0xad, 0x5e, 0x4b, 0x6f, 0xee, 0xd6, 0xf7, 0x7b, 0xed, 0x9e, 0x65, 0x37, 0xf5, 0x6e, 0xa5, 0xc6, - 0x9e, 0x89, 0x9a, 0x6d, 0xab, 0x6b, 0x9b, 0x46, 0xc5, 0x68, 0x75, 0x55, 0xa5, 0xfc, 0x6d, 0xd4, - 0xad, 0xf4, 0xfd, 0xd1, 0x60, 0xcf, 0xe9, 0x4f, 0xfd, 0x09, 0x56, 0x58, 0x83, 0x2b, 0x96, 0x51, - 0x69, 0xb7, 0xaa, 0xf6, 0x9e, 0x5e, 0xe9, 0xb6, 0xcd, 0xac, 0x50, 0xdf, 0x17, 0xe1, 0x42, 0x06, - 0x4e, 0xbb, 0xdb, 0x51, 0x15, 0x72, 0x15, 0x2e, 0x65, 0x94, 0xdd, 0x37, 0x76, 0xf5, 0x5e, 0xb7, - 0xd6, 0x52, 0x73, 0x73, 0x88, 0x2d, 0xab, 0xad, 0xe6, 0xcb, 0xbf, 0xa1, 0xc0, 0x46, 0x2f, 0xe0, - 0x26, 0xe7, 0x3d, 0xf4, 0x36, 0x7d, 0x0e, 0x2e, 0xf7, 0x2c, 0xc3, 0xb4, 0xbb, 0xed, 0x7b, 0x46, - 0xcb, 0xee, 0x59, 0xfa, 0x7e, 0xb2, 0x36, 0x57, 0xe1, 0x92, 0x84, 0x61, 0x1a, 0x95, 0xf6, 0x81, - 0x61, 0xda, 0x1d, 0xdd, 0xb2, 0xee, 0xb7, 0xcd, 0xaa, 0xaa, 0xd0, 0x2f, 0x66, 0x20, 0x34, 0xf7, - 0x74, 0x56, 0x9b, 0x58, 0x59, 0xcb, 0xb8, 0xaf, 0x37, 0xec, 0xdd, 0x76, 0x57, 0xcd, 0x97, 0x9b, - 0xf4, 0x7c, 0xc7, 0x80, 0xbb, 0xcc, 0xb2, 0xb0, 0x08, 0x85, 0x56, 0xbb, 0x65, 0x24, 0x1f, 0x17, - 0xd7, 0xa0, 0xa8, 0x77, 0x3a, 0x66, 0xfb, 0x00, 0xa7, 0x18, 0xc0, 0x72, 0xd5, 0x68, 0xd1, 0x9a, - 0xe5, 0x69, 0x49, 0xc7, 0x6c, 0x37, 0xdb, 0x5d, 0xa3, 0xaa, 0x16, 0xca, 0xa6, 0x58, 0xc2, 0x82, - 0x69, 0xdf, 0x67, 0x2f, 0x79, 0x55, 0x63, 0x4f, 0xef, 0x35, 0xba, 0x7c, 0x88, 0x1e, 0xd8, 0xa6, - 0xf1, 0x99, 0x9e, 0x61, 0x75, 0x2d, 0x55, 0x21, 0x2a, 0xac, 0xb5, 0x0c, 0xa3, 0x6a, 0xd9, 0xa6, - 0x71, 0x50, 0x37, 0xee, 0xab, 0x39, 0xca, 0x93, 0xfd, 0x4f, 0xbf, 0x50, 0xfe, 0x9e, 0x02, 0x84, - 0x05, 0x2b, 0x16, 0x19, 0x70, 0x70, 0xc6, 0x5c, 0x81, 0x8b, 0x35, 0x3a, 0xd4, 0xd8, 0xb4, 0x66, - 0xbb, 0x9a, 0xec, 0xb2, 0x0b, 0x40, 0x12, 0xe5, 0xed, 0xbd, 0x3d, 0x55, 0x21, 0x97, 0xe0, 0x6c, - 0x02, 0x5e, 0x35, 0xdb, 0x1d, 0x35, 0x77, 0x31, 0x57, 0x54, 0xc8, 0x76, 0xaa, 0xf0, 0x9e, 0x61, - 0x74, 0xd4, 0x3c, 0x1d, 0xa2, 0x44, 0x81, 0x58, 0x12, 0x8c, 0xbc, 0x50, 0xfe, 0xa6, 0x02, 0x17, - 0x58, 0x35, 0xc5, 0xfa, 0x0a, 0xab, 0x7a, 0x19, 0x76, 0x78, 0x08, 0xf6, 0xac, 0x8a, 0x9e, 0x03, - 0x35, 0x56, 0xca, 0xaa, 0x79, 0x1e, 0xb6, 0x62, 0x50, 0xac, 0x47, 0x8e, 0xee, 0x1e, 0x31, 0xf0, - 0xae, 0x61, 0x75, 0x6d, 0x63, 0x6f, 0xaf, 0x6d, 0x76, 0x59, 0x45, 0xf2, 0x65, 0x0d, 0xb6, 0x2a, - 0xee, 0x64, 0x4a, 0xaf, 0x5e, 0xa3, 0xc0, 0xf3, 0x47, 0x58, 0x85, 0x75, 0x58, 0x35, 0x3e, 0xdb, - 0x35, 0x5a, 0x56, 0xbd, 0xdd, 0x52, 0xcf, 0x94, 0x2f, 0x27, 0x70, 0xc4, 0x3a, 0xb6, 0xac, 0x9a, - 0x7a, 0xa6, 0xec, 0xc0, 0xba, 0x30, 0xbc, 0x66, 0xb3, 0xe2, 0x0a, 0x5c, 0x14, 0x73, 0x0d, 0x77, - 0x94, 0x64, 0x13, 0x76, 0xe0, 0x5c, 0xba, 0xdc, 0xe8, 0xaa, 0x0a, 0x1d, 0x85, 0x44, 0x09, 0x85, - 0xe7, 0xca, 0xbf, 0xa6, 0xc0, 0x7a, 0xf8, 0x68, 0x82, 0x6a, 0xda, 0xab, 0x70, 0xa9, 0xb9, 0xa7, - 0xdb, 0x55, 0xe3, 0xa0, 0x5e, 0x31, 0xec, 0x7b, 0xf5, 0x56, 0x35, 0xf1, 0x91, 0x67, 0xe0, 0x7c, - 0x06, 0x02, 0x7e, 0x65, 0x07, 0xce, 0x25, 0x8b, 0xba, 0x74, 0xa9, 0xe6, 0x68, 0xd7, 0x27, 0x4b, - 0xc2, 0x75, 0x9a, 0x2f, 0x1f, 0xc0, 0x86, 0xa5, 0x37, 0x1b, 0x7b, 0xfe, 0xa4, 0xef, 0xea, 0xb3, - 0xe9, 0xf1, 0x88, 0x5c, 0x82, 0xed, 0xbd, 0xb6, 0x59, 0x31, 0x6c, 0x44, 0x49, 0xd4, 0xe0, 0x2c, - 0x6c, 0xca, 0x85, 0x0f, 0x0c, 0x3a, 0x7d, 0x09, 0x6c, 0xc8, 0xc0, 0x56, 0x5b, 0xcd, 0x95, 0x3f, - 0x0f, 0x6b, 0xb1, 0x44, 0x78, 0xdb, 0x70, 0x56, 0xfe, 0xdd, 0x71, 0x47, 0x03, 0x6f, 0x74, 0xa4, - 0x9e, 0x49, 0x16, 0x98, 0xb3, 0xd1, 0x88, 0x16, 0xe0, 0x7a, 0x96, 0x0b, 0xba, 0xee, 0xe4, 0xc4, - 0x1b, 0x39, 0x53, 0x77, 0xa0, 0xe6, 0xca, 0x2f, 0xc3, 0x7a, 0x2c, 0xfc, 0x36, 0x1d, 0xb8, 0x46, - 0x9b, 0x6f, 0xc0, 0x4d, 0xa3, 0x5a, 0xef, 0x35, 0xd5, 0x25, 0xba, 0x92, 0x6b, 0xf5, 0xfd, 0x9a, - 0x0a, 0xe5, 0xef, 0x28, 0xf4, 0x9e, 0x81, 0x49, 0x75, 0x9a, 0x7b, 0xba, 0x18, 0x6a, 0x3a, 0xcd, - 0x58, 0x50, 0x7f, 0xc3, 0xb2, 0xd8, 0x9b, 0xfa, 0x65, 0xd8, 0xe1, 0x3f, 0x6c, 0xbd, 0x55, 0xb5, - 0x6b, 0xba, 0x59, 0xbd, 0xaf, 0x9b, 0x74, 0xee, 0x3d, 0x50, 0x73, 0xb8, 0xa0, 0x24, 0x88, 0xdd, - 0x6d, 0xf7, 0x2a, 0x35, 0x35, 0x4f, 0xe7, 0x6f, 0x0c, 0xde, 0xa9, 0xb7, 0xd4, 0x02, 0x2e, 0xcf, - 0x14, 0x36, 0xb2, 0xa5, 0xe5, 0x4b, 0xe5, 0x77, 0x15, 0xd8, 0xb6, 0xbc, 0xa3, 0x91, 0x33, 0x9d, - 0x4d, 0x5c, 0x7d, 0x78, 0xe4, 0x4f, 0xbc, 0xe9, 0xf1, 0x89, 0x35, 0xf3, 0xa6, 0x2e, 0xb9, 0x05, - 0x2f, 0x58, 0xf5, 0xfd, 0x96, 0xde, 0xa5, 0xcb, 0x4b, 0x6f, 0xec, 0xb7, 0xcd, 0x7a, 0xb7, 0xd6, - 0xb4, 0xad, 0x5e, 0x3d, 0x35, 0xf3, 0xae, 0xc3, 0x73, 0xf3, 0x51, 0x1b, 0xc6, 0xbe, 0x5e, 0x79, - 0xa0, 0x2a, 0x8b, 0x19, 0xee, 0xea, 0x0d, 0xbd, 0x55, 0x31, 0xaa, 0xf6, 0xc1, 0x6d, 0x35, 0x47, - 0x5e, 0x80, 0x6b, 0xf3, 0x51, 0xf7, 0xea, 0x1d, 0x8b, 0xa2, 0xe5, 0x17, 0x7f, 0xb7, 0x66, 0x35, - 0x29, 0x56, 0xa1, 0xfc, 0x47, 0x0a, 0xec, 0xcc, 0x8b, 0xc1, 0x44, 0x6e, 0x80, 0x66, 0xb4, 0xba, - 0xa6, 0x5e, 0xaf, 0xda, 0x15, 0xd3, 0xa8, 0x1a, 0xad, 0x6e, 0x5d, 0x6f, 0x58, 0xb6, 0xd5, 0xee, - 0xd1, 0xd9, 0x14, 0x99, 0x3e, 0x3c, 0x0f, 0x57, 0x17, 0xe0, 0xb5, 0xeb, 0xd5, 0x8a, 0xaa, 0x90, - 0xdb, 0xf0, 0xd2, 0x02, 0x24, 0xeb, 0x81, 0xd5, 0x35, 0x9a, 0x72, 0x89, 0x9a, 0x2b, 0x57, 0xe0, - 0xe2, 0xfc, 0x20, 0x2d, 0x74, 0x9b, 0x8e, 0xf7, 0x74, 0x11, 0x0a, 0x55, 0x7a, 0x32, 0xc4, 0x72, - 0x3f, 0x94, 0x3d, 0x50, 0x93, 0x71, 0x16, 0x52, 0x36, 0x2a, 0x66, 0xaf, 0xd5, 0x62, 0xc7, 0xc8, - 0x26, 0x94, 0xda, 0xdd, 0x9a, 0x61, 0xf2, 0xec, 0x19, 0x98, 0x2e, 0xa3, 0xd7, 0xa2, 0x0b, 0xa7, - 0x6d, 0xd6, 0x3f, 0x87, 0xe7, 0xc9, 0x0e, 0x9c, 0xb3, 0x1a, 0x7a, 0xe5, 0x9e, 0xdd, 0x6a, 0x77, - 0xed, 0x7a, 0xcb, 0xae, 0xd4, 0xf4, 0x56, 0xcb, 0x68, 0xa8, 0x80, 0x9d, 0x39, 0xcf, 0xb7, 0x92, - 0x7c, 0x10, 0x6e, 0xb6, 0xef, 0x75, 0x75, 0xbb, 0xd3, 0xe8, 0xed, 0xd7, 0x5b, 0xb6, 0xf5, 0xa0, - 0x55, 0x11, 0xb2, 0x4f, 0x25, 0xbd, 0xe5, 0xde, 0x84, 0xeb, 0x0b, 0xb1, 0xa3, 0x3c, 0x17, 0x37, - 0x40, 0x5b, 0x88, 0xc9, 0x1b, 0x52, 0xfe, 0x91, 0x02, 0x97, 0x16, 0xbc, 0x21, 0x93, 0x97, 0xe0, - 0x56, 0xcd, 0xd0, 0xab, 0x0d, 0xc3, 0xb2, 0x70, 0xa3, 0xa0, 0xc3, 0xc0, 0x6c, 0x59, 0x32, 0x37, - 0xd4, 0x5b, 0xf0, 0xc2, 0x62, 0xf4, 0xe8, 0x68, 0xbe, 0x09, 0xd7, 0x17, 0xa3, 0xf2, 0xa3, 0x3a, - 0x47, 0xca, 0x70, 0x63, 0x31, 0x66, 0x78, 0xc4, 0xe7, 0xcb, 0xbf, 0xa5, 0xc0, 0x85, 0x6c, 0x45, - 0x0e, 0xad, 0x5b, 0xbd, 0x65, 0x75, 0xf5, 0x46, 0xc3, 0xee, 0xe8, 0xa6, 0xde, 0xb4, 0x8d, 0x96, - 0xd9, 0x6e, 0x34, 0xb2, 0x8e, 0xb6, 0xeb, 0xf0, 0xdc, 0x7c, 0x54, 0xab, 0x62, 0xd6, 0x3b, 0x74, - 0xf7, 0xd6, 0xe0, 0xca, 0x7c, 0x2c, 0xa3, 0x5e, 0x31, 0xd4, 0xdc, 0xee, 0x27, 0x7e, 0xf0, 0x8f, - 0x57, 0xce, 0xfc, 0xe0, 0xdd, 0x2b, 0xca, 0x8f, 0xdf, 0xbd, 0xa2, 0xfc, 0xc3, 0xbb, 0x57, 0x94, - 0xcf, 0xbd, 0x78, 0xba, 0x14, 0x51, 0x28, 0xf7, 0x3f, 0x5c, 0xc6, 0x1b, 0xca, 0x2b, 0xff, 0x1d, - 0x00, 0x00, 0xff, 0xff, 0x1c, 0x37, 0x39, 0x99, 0x2c, 0xbd, 0x01, 0x00, + 0xae, 0xde, 0xaa, 0x6a, 0x92, 0xd0, 0xde, 0xf9, 0xf4, 0x3c, 0x59, 0x21, 0xeb, 0x75, 0x27, 0x9d, + 0xf6, 0x1c, 0x3a, 0x59, 0x21, 0xdf, 0xd9, 0x8a, 0x73, 0x48, 0x61, 0x4b, 0x96, 0x7d, 0xb6, 0xc2, + 0xb2, 0x74, 0x71, 0x96, 0x65, 0x85, 0xe3, 0xa4, 0xb0, 0xcf, 0x76, 0x78, 0x7d, 0x01, 0x59, 0x96, + 0x7f, 0x38, 0x10, 0xe1, 0x08, 0xc9, 0x17, 0xe1, 0x08, 0xef, 0x85, 0xee, 0x1c, 0xf9, 0x65, 0x66, + 0x55, 0x66, 0x55, 0x75, 0xa3, 0x31, 0xe4, 0xe8, 0xc4, 0x09, 0xfd, 0x21, 0xd1, 0x5f, 0x7e, 0xdf, + 0x97, 0x95, 0xef, 0x2f, 0xbf, 0xfc, 0x1e, 0xf0, 0x62, 0x40, 0x9b, 0xb4, 0xe3, 0x7a, 0xc1, 0xf5, + 0x26, 0xdd, 0xb3, 0xeb, 0x87, 0xd7, 0x83, 0xc3, 0x0e, 0xf5, 0xf9, 0xbf, 0xd7, 0x3a, 0x9e, 0x1b, + 0xb8, 0x64, 0x18, 0x7f, 0x2c, 0xcc, 0xed, 0xb9, 0x7b, 0x2e, 0x42, 0xae, 0xb3, 0xbf, 0x78, 0xe1, + 0xc2, 0xc5, 0x3d, 0xd7, 0xdd, 0x6b, 0xd2, 0xeb, 0xf8, 0x6b, 0xa7, 0xbb, 0x7b, 0xbd, 0xd1, 0xf5, + 0xec, 0xc0, 0x71, 0xdb, 0xa2, 0xbc, 0x18, 0x2f, 0x0f, 0x9c, 0x16, 0xf5, 0x03, 0xbb, 0xd5, 0xe9, + 0xc5, 0xe0, 0x91, 0x67, 0x77, 0x3a, 0xd4, 0x13, 0xb5, 0x2f, 0x5c, 0x0d, 0x3f, 0xd0, 0x0e, 0x02, + 0x46, 0xc9, 0x98, 0x5f, 0x7f, 0x78, 0x43, 0xfd, 0x29, 0x50, 0x6f, 0xf5, 0x68, 0x8b, 0xd7, 0xf5, + 0x03, 0xda, 0xb0, 0x1a, 0xf4, 0xa1, 0x53, 0xa7, 0x96, 0x47, 0xbf, 0xd9, 0x75, 0x3c, 0xda, 0xa2, + 0xed, 0x40, 0xd0, 0xbd, 0x99, 0x4e, 0x27, 0x3f, 0x24, 0xf6, 0x45, 0xc6, 0x2f, 0xe4, 0x60, 0xec, + 0x1e, 0xa5, 0x9d, 0x52, 0xd3, 0x79, 0x48, 0xc9, 0x4b, 0x30, 0xb4, 0x6e, 0xb7, 0xe8, 0x7c, 0xe6, + 0x52, 0xe6, 0xca, 0xd8, 0xd2, 0xf4, 0xf1, 0x51, 0x71, 0xdc, 0xa7, 0xde, 0x43, 0xea, 0x59, 0x6d, + 0xbb, 0x45, 0x4d, 0x2c, 0x24, 0xaf, 0xc3, 0x18, 0xfb, 0xdf, 0xef, 0xd8, 0x75, 0x3a, 0x9f, 0x45, + 0xcc, 0xc9, 0xe3, 0xa3, 0xe2, 0x58, 0x5b, 0x02, 0xcd, 0xa8, 0x9c, 0x54, 0x61, 0x74, 0xf9, 0x71, + 0xc7, 0xf1, 0xa8, 0x3f, 0x3f, 0x74, 0x29, 0x73, 0x65, 0x7c, 0x71, 0xe1, 0x1a, 0xef, 0xa3, 0x6b, + 0xb2, 0x8f, 0xae, 0x6d, 0xca, 0x4e, 0x5c, 0x9a, 0xfd, 0xbd, 0xa3, 0xe2, 0x73, 0xc7, 0x47, 0xc5, + 0x51, 0xca, 0x49, 0x7e, 0xea, 0x8f, 0x8a, 0x19, 0x53, 0xd2, 0x93, 0x77, 0x61, 0x68, 0xf3, 0xb0, + 0x43, 0xe7, 0xc7, 0x2e, 0x65, 0xae, 0x4c, 0x2d, 0x5e, 0xbc, 0xc6, 0x87, 0x35, 0xfc, 0xf8, 0xe8, + 0x2f, 0x86, 0xb5, 0x94, 0x3f, 0x3e, 0x2a, 0x0e, 0x31, 0x14, 0x13, 0xa9, 0xc8, 0x9b, 0x30, 0xb2, + 0xe2, 0xfa, 0x41, 0xb5, 0x32, 0x0f, 0xf8, 0xc9, 0x67, 0x8e, 0x8f, 0x8a, 0x33, 0xfb, 0xae, 0x1f, + 0x58, 0x4e, 0xe3, 0x0d, 0xb7, 0xe5, 0x04, 0xb4, 0xd5, 0x09, 0x0e, 0x4d, 0x81, 0x64, 0x3c, 0x86, + 0x49, 0x8d, 0x1f, 0x19, 0x87, 0xd1, 0xad, 0xf5, 0x7b, 0xeb, 0xf7, 0xb7, 0xd7, 0x0b, 0xcf, 0x91, + 0x3c, 0x0c, 0xad, 0xdf, 0xaf, 0x2c, 0x17, 0x32, 0x64, 0x14, 0x72, 0xa5, 0x8d, 0x8d, 0x42, 0x96, + 0x4c, 0x40, 0xbe, 0x52, 0xda, 0x2c, 0x2d, 0x95, 0x6a, 0xcb, 0x85, 0x1c, 0x99, 0x85, 0xe9, 0xed, + 0xea, 0x7a, 0xe5, 0xfe, 0x76, 0xcd, 0xaa, 0x2c, 0xd7, 0xee, 0x6d, 0xde, 0xdf, 0x28, 0x0c, 0x91, + 0x29, 0x80, 0x7b, 0x5b, 0x4b, 0xcb, 0xe6, 0xfa, 0xf2, 0xe6, 0x72, 0xad, 0x30, 0x4c, 0xe6, 0xa0, + 0x20, 0x49, 0xac, 0xda, 0xb2, 0xf9, 0xa0, 0x5a, 0x5e, 0x2e, 0x8c, 0xdc, 0x1d, 0xca, 0xe7, 0x0a, + 0x43, 0xe6, 0xe8, 0x2a, 0xb5, 0x7d, 0x5a, 0xad, 0x18, 0xff, 0x7e, 0x0e, 0xf2, 0x6b, 0x34, 0xb0, + 0x1b, 0x76, 0x60, 0x93, 0x17, 0xb4, 0xf1, 0xc1, 0x26, 0x2a, 0x03, 0xf3, 0x52, 0x72, 0x60, 0x86, + 0x8f, 0x8f, 0x8a, 0x99, 0x37, 0xd5, 0x01, 0x79, 0x07, 0xc6, 0x2b, 0xd4, 0xaf, 0x7b, 0x4e, 0x87, + 0x4d, 0xb6, 0xf9, 0x1c, 0xa2, 0x9d, 0x3f, 0x3e, 0x2a, 0x9e, 0x69, 0x44, 0x60, 0xa5, 0x43, 0x54, + 0x6c, 0x52, 0x85, 0x91, 0x55, 0x7b, 0x87, 0x36, 0xfd, 0xf9, 0xe1, 0x4b, 0xb9, 0x2b, 0xe3, 0x8b, + 0xcf, 0x8b, 0x41, 0x90, 0x1f, 0x78, 0x8d, 0x97, 0x2e, 0xb7, 0x03, 0xef, 0x70, 0x69, 0xee, 0xf8, + 0xa8, 0x58, 0x68, 0x22, 0x40, 0xed, 0x60, 0x8e, 0x42, 0x6a, 0xd1, 0xc4, 0x18, 0x39, 0x71, 0x62, + 0x5c, 0xf8, 0xbd, 0xa3, 0x62, 0x86, 0x0d, 0x98, 0x98, 0x18, 0x11, 0x3f, 0x7d, 0x8a, 0x2c, 0x42, + 0xde, 0xa4, 0x0f, 0x1d, 0x9f, 0xb5, 0x2c, 0x8f, 0x2d, 0x3b, 0x7b, 0x7c, 0x54, 0x24, 0x9e, 0x80, + 0x29, 0x9f, 0x11, 0xe2, 0x2d, 0xbc, 0x0d, 0xe3, 0xca, 0x57, 0x93, 0x02, 0xe4, 0x0e, 0xe8, 0x21, + 0xef, 0x61, 0x93, 0xfd, 0x49, 0xe6, 0x60, 0xf8, 0xa1, 0xdd, 0xec, 0x8a, 0x2e, 0x35, 0xf9, 0x8f, + 0x2f, 0x64, 0x3f, 0x9f, 0xb9, 0x3b, 0x94, 0x1f, 0x2d, 0xe4, 0xcd, 0x6c, 0xb5, 0x62, 0xfc, 0xad, + 0x21, 0xc8, 0x9b, 0x2e, 0x5f, 0xc0, 0xe4, 0x2a, 0x0c, 0xd7, 0x02, 0x3b, 0x90, 0xc3, 0x34, 0x7b, + 0x7c, 0x54, 0x9c, 0x66, 0x8b, 0x9b, 0x2a, 0xf5, 0x73, 0x0c, 0x86, 0xba, 0xb1, 0x6f, 0xfb, 0x72, + 0xb8, 0x10, 0xb5, 0xc3, 0x00, 0x2a, 0x2a, 0x62, 0x90, 0xcb, 0x30, 0xb4, 0xe6, 0x36, 0xa8, 0x18, + 0x31, 0x72, 0x7c, 0x54, 0x9c, 0x6a, 0xb9, 0x0d, 0x15, 0x11, 0xcb, 0xc9, 0x1b, 0x30, 0x56, 0xee, + 0x7a, 0x1e, 0x6d, 0xb3, 0xb9, 0x3e, 0x84, 0xc8, 0x53, 0xc7, 0x47, 0x45, 0xa8, 0x73, 0xa0, 0xe5, + 0x34, 0xcc, 0x08, 0x81, 0x0d, 0x43, 0x2d, 0xb0, 0xbd, 0x80, 0x36, 0xe6, 0x87, 0x07, 0x1a, 0x06, + 0xb6, 0x3e, 0x67, 0x7c, 0x4e, 0x12, 0x1f, 0x06, 0xc1, 0x89, 0xac, 0xc0, 0xf8, 0x1d, 0xcf, 0xae, + 0xd3, 0x0d, 0xea, 0x39, 0x6e, 0x03, 0xc7, 0x37, 0xb7, 0x74, 0xf9, 0xf8, 0xa8, 0x78, 0x76, 0x8f, + 0x81, 0xad, 0x0e, 0xc2, 0x23, 0xea, 0xef, 0x1e, 0x15, 0xf3, 0x15, 0xb1, 0xd5, 0x9a, 0x2a, 0x29, + 0xf9, 0x06, 0x1b, 0x1c, 0x3f, 0xc0, 0xae, 0xa5, 0x8d, 0xf9, 0xd1, 0x13, 0x3f, 0xd1, 0x10, 0x9f, + 0x78, 0xb6, 0x69, 0xfb, 0x81, 0xe5, 0x71, 0xba, 0xd8, 0x77, 0xaa, 0x2c, 0xc9, 0x7d, 0xc8, 0xd7, + 0xea, 0xfb, 0xb4, 0xd1, 0x6d, 0x52, 0x9c, 0x32, 0xe3, 0x8b, 0xe7, 0xc4, 0xa4, 0x96, 0xe3, 0x29, + 0x8b, 0x97, 0x16, 0x04, 0x6f, 0xe2, 0x0b, 0x88, 0x3a, 0x9f, 0x24, 0xd6, 0x17, 0xf2, 0xdf, 0xfe, + 0xc5, 0xe2, 0x73, 0xdf, 0xf7, 0xcf, 0x2f, 0x3d, 0x67, 0xfc, 0xe7, 0x59, 0x28, 0xc4, 0x99, 0x90, + 0x5d, 0x98, 0xdc, 0xea, 0x34, 0xec, 0x80, 0x96, 0x9b, 0x0e, 0x6d, 0x07, 0x3e, 0x4e, 0x92, 0xfe, + 0x6d, 0x7a, 0x59, 0xd4, 0x3b, 0xdf, 0x45, 0x42, 0xab, 0xce, 0x29, 0x63, 0xad, 0xd2, 0xd9, 0x46, + 0xf5, 0xd4, 0x70, 0x03, 0xf7, 0x71, 0x86, 0x9d, 0xae, 0x1e, 0xbe, 0xf5, 0xf7, 0xa8, 0x47, 0xb0, + 0x15, 0x13, 0xa8, 0xdd, 0xd8, 0x39, 0xc4, 0x99, 0x39, 0xf8, 0x04, 0x62, 0x24, 0x29, 0x13, 0x88, + 0x81, 0x8d, 0xff, 0x33, 0x03, 0x53, 0x26, 0xf5, 0xdd, 0xae, 0x57, 0xa7, 0x2b, 0xd4, 0x6e, 0x50, + 0x8f, 0x4d, 0xff, 0x7b, 0x4e, 0xbb, 0x21, 0xd6, 0x14, 0x4e, 0xff, 0x03, 0xa7, 0xad, 0x6e, 0xdd, + 0x58, 0x4e, 0x3e, 0x03, 0xa3, 0xb5, 0xee, 0x0e, 0xa2, 0x66, 0xa3, 0x1d, 0xc0, 0xef, 0xee, 0x58, + 0x31, 0x74, 0x89, 0x46, 0xae, 0xc3, 0xe8, 0x03, 0xea, 0xf9, 0xd1, 0x6e, 0x88, 0x47, 0xc3, 0x43, + 0x0e, 0x52, 0x09, 0x04, 0x16, 0xb9, 0x13, 0xed, 0xc8, 0xe2, 0x50, 0x9b, 0x8e, 0xed, 0x83, 0xd1, + 0x54, 0x69, 0x09, 0x88, 0x3a, 0x55, 0x24, 0x96, 0xf1, 0xd3, 0x59, 0x28, 0x54, 0xec, 0xc0, 0xde, + 0xb1, 0x7d, 0xd1, 0x9f, 0x0f, 0x6e, 0xb2, 0x3d, 0x5e, 0x69, 0x28, 0xee, 0xf1, 0xec, 0xcb, 0x3f, + 0x76, 0xf3, 0x5e, 0x89, 0x37, 0x6f, 0x9c, 0x9d, 0xb0, 0xa2, 0x79, 0x51, 0xa3, 0xde, 0x3b, 0xb9, + 0x51, 0x05, 0xd1, 0xa8, 0xbc, 0x6c, 0x54, 0xd4, 0x14, 0xf2, 0x1e, 0x0c, 0xd5, 0x3a, 0xb4, 0x2e, + 0x36, 0x11, 0x79, 0x2e, 0xe8, 0x8d, 0x63, 0x08, 0x0f, 0x6e, 0x2e, 0x4d, 0x08, 0x36, 0x43, 0x7e, + 0x87, 0xd6, 0x4d, 0x24, 0x53, 0x16, 0xcd, 0x3f, 0xca, 0xc1, 0x5c, 0x1a, 0x99, 0xda, 0x8e, 0x91, + 0x3e, 0xed, 0xb8, 0x02, 0x79, 0x76, 0x84, 0xb3, 0x63, 0x11, 0xb7, 0x8b, 0xb1, 0xa5, 0x09, 0xf6, + 0xc9, 0xfb, 0x02, 0x66, 0x86, 0xa5, 0xe4, 0xa5, 0x50, 0x22, 0xc8, 0x47, 0xfc, 0x84, 0x44, 0x20, + 0xe5, 0x00, 0x36, 0xd6, 0x72, 0x09, 0xa3, 0xe0, 0x10, 0x75, 0x8b, 0x04, 0x47, 0x63, 0xed, 0x09, + 0x88, 0x76, 0xcc, 0xc8, 0x43, 0x61, 0x19, 0xf2, 0xb2, 0x59, 0xf3, 0x13, 0xc8, 0x68, 0x26, 0xd6, + 0x49, 0x0f, 0x6e, 0xf2, 0xc1, 0x6c, 0x88, 0xdf, 0x2a, 0x1b, 0x89, 0x43, 0x6e, 0x42, 0x7e, 0xc3, + 0x73, 0x1f, 0x1f, 0x56, 0x2b, 0xfe, 0xfc, 0xe4, 0xa5, 0xdc, 0x95, 0xb1, 0xa5, 0x73, 0xc7, 0x47, + 0xc5, 0xd9, 0x0e, 0x83, 0x59, 0x4e, 0x43, 0x3d, 0x69, 0x43, 0xc4, 0xbb, 0x43, 0xf9, 0x4c, 0x21, + 0x7b, 0x77, 0x28, 0x9f, 0x2d, 0xe4, 0xb8, 0x78, 0x71, 0x77, 0x28, 0x3f, 0x54, 0x18, 0xbe, 0x3b, + 0x94, 0x1f, 0x46, 0x81, 0x63, 0xac, 0x00, 0x77, 0x87, 0xf2, 0xe3, 0x85, 0x09, 0xed, 0xb4, 0x47, + 0x06, 0x81, 0x5b, 0x77, 0x9b, 0x66, 0x6e, 0xcb, 0xac, 0x9a, 0x23, 0xe5, 0x52, 0x99, 0x7a, 0x81, + 0x99, 0x2b, 0x6d, 0xd7, 0xcc, 0xc9, 0xca, 0x61, 0xdb, 0x6e, 0x39, 0x75, 0x7e, 0x74, 0x9a, 0xb9, + 0x3b, 0xe5, 0x0d, 0xa3, 0x04, 0x53, 0x51, 0x5b, 0x56, 0x1d, 0x3f, 0x20, 0xd7, 0x61, 0x4c, 0x42, + 0xd8, 0x46, 0x97, 0x4b, 0x6d, 0xb5, 0x19, 0xe1, 0x18, 0xbf, 0x9b, 0x05, 0x88, 0x4a, 0x9e, 0xd1, + 0xb5, 0xf0, 0x39, 0x6d, 0x2d, 0x9c, 0x89, 0xaf, 0x85, 0x9e, 0xab, 0x80, 0x7c, 0x00, 0x23, 0x4c, + 0x2c, 0xe8, 0x4a, 0x91, 0xe8, 0x5c, 0x9c, 0x14, 0x0b, 0x1f, 0xdc, 0x5c, 0x9a, 0x12, 0xc4, 0x23, + 0x3e, 0x42, 0x4c, 0x41, 0xa6, 0x2c, 0xa3, 0x5f, 0x18, 0x8d, 0x06, 0x43, 0x2c, 0xa0, 0x2b, 0x10, + 0x0e, 0xa8, 0xe8, 0x50, 0x5c, 0x19, 0x1d, 0x39, 0xc8, 0x61, 0x29, 0x39, 0x0f, 0x6c, 0xc0, 0x45, + 0xa7, 0x8e, 0x1e, 0x1f, 0x15, 0x73, 0x5d, 0xcf, 0xc1, 0x49, 0x40, 0xae, 0x83, 0x98, 0x06, 0xa2, + 0x03, 0xd9, 0xec, 0x9b, 0xa9, 0xdb, 0x56, 0x9d, 0x7a, 0x41, 0xd4, 0xe3, 0xf3, 0x19, 0x39, 0x5b, + 0x48, 0x07, 0xf4, 0xa9, 0x32, 0x3f, 0x84, 0xd3, 0xe0, 0x4a, 0x6a, 0xaf, 0x5c, 0xd3, 0x50, 0xb9, + 0x18, 0x79, 0x49, 0x9e, 0x4a, 0x0d, 0x5e, 0x66, 0x25, 0x44, 0x4a, 0xbd, 0x02, 0x72, 0x13, 0xd8, + 0x0c, 0x15, 0xbd, 0x0f, 0xa2, 0x9e, 0xd2, 0x76, 0x6d, 0xe9, 0x8c, 0xe0, 0x34, 0x69, 0x3f, 0x52, + 0xc9, 0x19, 0x36, 0x79, 0x07, 0xd8, 0x14, 0x16, 0xfd, 0x4e, 0x04, 0xd1, 0x9d, 0xf2, 0x46, 0xb9, + 0xe9, 0x76, 0x1b, 0xb5, 0x2f, 0xad, 0x46, 0xc4, 0x7b, 0xf5, 0x8e, 0x4a, 0x7c, 0xa7, 0xbc, 0x41, + 0xde, 0x81, 0xe1, 0xd2, 0xf7, 0x76, 0x3d, 0x2a, 0xe4, 0x93, 0x09, 0x59, 0x27, 0x83, 0x2d, 0x9d, + 0x13, 0x84, 0xd3, 0x36, 0xfb, 0xa9, 0xca, 0x75, 0x58, 0xce, 0x6a, 0xde, 0x5c, 0xad, 0x09, 0xd9, + 0x83, 0xc4, 0xba, 0x65, 0x73, 0x55, 0xf9, 0xec, 0x40, 0x6b, 0x35, 0xa3, 0x22, 0xd7, 0x21, 0x5b, + 0xaa, 0xe0, 0x8d, 0x68, 0x7c, 0x71, 0x4c, 0x56, 0x5b, 0x59, 0x9a, 0x13, 0x24, 0x13, 0xb6, 0xba, + 0x0c, 0xb2, 0xa5, 0x0a, 0x59, 0x82, 0xe1, 0xb5, 0xc3, 0xda, 0x97, 0x56, 0xc5, 0x66, 0x36, 0x2b, + 0xe7, 0x35, 0x83, 0xdd, 0xc7, 0x65, 0xef, 0x47, 0x5f, 0xdc, 0x3a, 0xf4, 0xbf, 0xd9, 0x54, 0xbf, + 0x18, 0xd1, 0xc8, 0x06, 0x8c, 0x95, 0x1a, 0x2d, 0xa7, 0xbd, 0xe5, 0x53, 0x6f, 0x7e, 0x1c, 0xf9, + 0xcc, 0xc7, 0xbe, 0x3b, 0x2c, 0x5f, 0x9a, 0x3f, 0x3e, 0x2a, 0xce, 0xd9, 0xec, 0xa7, 0xd5, 0xf5, + 0xa9, 0xa7, 0x70, 0x8b, 0x98, 0x90, 0x0d, 0x80, 0x35, 0xb7, 0xbd, 0xe7, 0x96, 0x82, 0xa6, 0xed, + 0xc7, 0xb6, 0xc7, 0xa8, 0x20, 0x14, 0x1f, 0xce, 0xb4, 0x18, 0xcc, 0xb2, 0x19, 0x50, 0x61, 0xa8, + 0xf0, 0x20, 0xb7, 0x61, 0xe4, 0xbe, 0x67, 0xd7, 0x9b, 0x74, 0x7e, 0x12, 0xb9, 0xcd, 0x09, 0x6e, + 0x1c, 0x28, 0x5b, 0x3a, 0x2f, 0x18, 0x16, 0x5c, 0x04, 0xab, 0xd7, 0x14, 0x8e, 0xb8, 0xb0, 0x0d, + 0x24, 0x39, 0x27, 0x53, 0x2e, 0x09, 0xaf, 0xab, 0x97, 0x84, 0x68, 0xd1, 0x97, 0xdd, 0x56, 0xcb, + 0x6e, 0x37, 0x90, 0xf6, 0xc1, 0xa2, 0x72, 0x77, 0x30, 0xbe, 0x09, 0x33, 0x89, 0xce, 0x3a, 0xe1, + 0x7e, 0xf7, 0x3e, 0x4c, 0x57, 0xe8, 0xae, 0xdd, 0x6d, 0x06, 0xe1, 0x49, 0xc2, 0x97, 0x28, 0xde, + 0xb4, 0x1a, 0xbc, 0xc8, 0x92, 0xc7, 0x87, 0x19, 0x47, 0x36, 0xde, 0x83, 0x49, 0xad, 0xf9, 0xec, + 0xaa, 0x50, 0xea, 0x36, 0x9c, 0x00, 0x07, 0x32, 0x13, 0x5d, 0x15, 0x6c, 0x06, 0xc4, 0xe1, 0x32, + 0x23, 0x04, 0xe3, 0xef, 0xab, 0xd2, 0x8a, 0xd8, 0x89, 0xd8, 0xb5, 0x5a, 0xec, 0x07, 0x99, 0x48, + 0x76, 0x4a, 0xec, 0x07, 0xe1, 0x6e, 0x70, 0x95, 0xaf, 0xcd, 0x6c, 0x62, 0x6d, 0x8e, 0x8b, 0x91, + 0xc8, 0xd9, 0x8f, 0x7c, 0xbe, 0x22, 0xc3, 0x99, 0x9a, 0xfb, 0xf8, 0x33, 0xf5, 0x03, 0x98, 0x58, + 0xb3, 0xdb, 0xf6, 0x1e, 0x6d, 0xb0, 0x16, 0xf0, 0xbd, 0x67, 0x6c, 0xe9, 0xf9, 0xe3, 0xa3, 0xe2, + 0xb9, 0x16, 0x87, 0x63, 0x2b, 0xd5, 0x49, 0xa4, 0x11, 0x90, 0x1b, 0x72, 0x65, 0x0f, 0xa7, 0xac, + 0xec, 0x49, 0x51, 0xfb, 0x30, 0xae, 0x6c, 0xb1, 0x9e, 0x8d, 0xdf, 0x1e, 0xc3, 0x36, 0x92, 0x37, + 0x60, 0xc4, 0xa4, 0x7b, 0xec, 0xa8, 0xc9, 0x44, 0x83, 0xe4, 0x21, 0x44, 0xed, 0x18, 0x8e, 0x83, + 0x72, 0x06, 0x6d, 0xf8, 0xfb, 0xce, 0x6e, 0x20, 0x7a, 0x27, 0x94, 0x33, 0x04, 0x58, 0x91, 0x33, + 0x04, 0x44, 0xbf, 0xce, 0x72, 0x18, 0xdb, 0xfd, 0xcc, 0x4a, 0x4d, 0x74, 0x9a, 0xec, 0x61, 0xb3, + 0xa2, 0x6c, 0x23, 0x9e, 0x26, 0x25, 0x30, 0x6c, 0x72, 0x0b, 0xc6, 0x4a, 0xf5, 0xba, 0xdb, 0x55, + 0xee, 0x8c, 0x7c, 0xdd, 0x72, 0xa0, 0xae, 0x22, 0x89, 0x50, 0x49, 0x0d, 0xc6, 0x97, 0xd9, 0x45, + 0xcb, 0x29, 0xdb, 0xf5, 0x7d, 0xd9, 0x49, 0x72, 0x0f, 0x53, 0x4a, 0xa2, 0x95, 0x4b, 0x11, 0x58, + 0x67, 0x40, 0x55, 0xc9, 0xa0, 0xe0, 0x92, 0x4d, 0x18, 0xaf, 0xd1, 0xba, 0x47, 0x83, 0x5a, 0xe0, + 0x7a, 0x34, 0xb6, 0x25, 0x2b, 0x25, 0x4b, 0x17, 0xe5, 0x5d, 0xcf, 0x47, 0xa0, 0xe5, 0x33, 0xa8, + 0xca, 0x55, 0x41, 0xe6, 0x42, 0x7b, 0xcb, 0xf5, 0x0e, 0x2b, 0x4b, 0x62, 0x9b, 0x8e, 0xce, 0x74, + 0x0e, 0x56, 0x85, 0x76, 0x06, 0x69, 0xec, 0xe8, 0x42, 0x3b, 0xc7, 0xc2, 0x91, 0xaa, 0xd4, 0x50, + 0xb6, 0x12, 0x9b, 0xf6, 0x74, 0xd4, 0xcb, 0x08, 0x56, 0x46, 0xaa, 0xe1, 0xa3, 0x64, 0xa6, 0x8d, + 0x94, 0xc0, 0x22, 0x1d, 0x20, 0x72, 0xd4, 0xb8, 0xa0, 0xdb, 0xa4, 0xbe, 0x2f, 0xf6, 0xf2, 0xf3, + 0xb1, 0xc1, 0x8f, 0x10, 0x96, 0x5e, 0x11, 0xcc, 0x2f, 0xc8, 0x69, 0x20, 0xee, 0x69, 0xac, 0x50, + 0xa9, 0x27, 0x85, 0x37, 0x79, 0x1b, 0x60, 0xf9, 0x71, 0x40, 0xbd, 0xb6, 0xdd, 0x0c, 0xf5, 0x60, + 0xa8, 0xfa, 0xa1, 0x02, 0xaa, 0x0f, 0xb4, 0x82, 0x4c, 0xca, 0x30, 0x59, 0xf2, 0xfd, 0x6e, 0x8b, + 0x9a, 0x6e, 0x93, 0x96, 0xcc, 0x75, 0xdc, 0xf7, 0xc7, 0x96, 0x2e, 0x1c, 0x1f, 0x15, 0xcf, 0xdb, + 0x58, 0x60, 0x79, 0x6e, 0x93, 0x5a, 0xb6, 0xa7, 0xce, 0x6e, 0x9d, 0x86, 0xdc, 0x07, 0xb8, 0xdf, + 0xa1, 0xed, 0x1a, 0xb5, 0xbd, 0xfa, 0x7e, 0x6c, 0x9b, 0x8f, 0x0a, 0x96, 0x5e, 0x10, 0x2d, 0x9c, + 0x73, 0x3b, 0xb4, 0xed, 0x23, 0x4c, 0xfd, 0xaa, 0x08, 0x93, 0x6c, 0xc3, 0x74, 0xb5, 0xb4, 0xb6, + 0xe1, 0x36, 0x9d, 0xfa, 0xa1, 0x90, 0x9c, 0xa6, 0x50, 0x3b, 0x78, 0x56, 0x70, 0x8d, 0x95, 0xf2, + 0xed, 0xc9, 0xb1, 0x5b, 0x56, 0x07, 0xa1, 0x96, 0x90, 0x9f, 0xe2, 0x5c, 0xc8, 0x87, 0x6c, 0x0e, + 0xfa, 0x4c, 0x18, 0xdc, 0xb4, 0xf7, 0xfc, 0xf9, 0x69, 0x4d, 0xdb, 0x55, 0xda, 0xae, 0x5d, 0x53, + 0x4a, 0xb9, 0x98, 0xb2, 0xc0, 0x27, 0x22, 0x42, 0xad, 0xc0, 0xde, 0xf3, 0xf5, 0x89, 0x18, 0x62, + 0x93, 0xbb, 0x00, 0x15, 0xb7, 0xde, 0x6d, 0xd1, 0x76, 0x50, 0x59, 0x9a, 0x2f, 0xe8, 0x57, 0x81, + 0xb0, 0x20, 0xda, 0xda, 0x1a, 0x6e, 0x5d, 0x9b, 0x89, 0x0a, 0xf5, 0xc2, 0xfb, 0x50, 0x88, 0x7f, + 0xc8, 0x29, 0x15, 0x58, 0x93, 0x85, 0x29, 0xa5, 0xf5, 0xcb, 0x8f, 0x1d, 0x3f, 0xf0, 0x8d, 0x6f, + 0x69, 0x2b, 0x90, 0xed, 0x0e, 0xf7, 0xe8, 0xe1, 0x86, 0x47, 0x77, 0x9d, 0xc7, 0x62, 0x33, 0xc3, + 0xdd, 0xe1, 0x80, 0x1e, 0x5a, 0x1d, 0x84, 0xaa, 0xbb, 0x43, 0x88, 0x4a, 0x3e, 0x0b, 0xf9, 0x7b, + 0x6b, 0xb5, 0x7b, 0xf4, 0xb0, 0x5a, 0x11, 0x07, 0x15, 0x27, 0x6b, 0xf9, 0x16, 0x23, 0xd5, 0xe6, + 0x5a, 0x88, 0x69, 0x2c, 0x45, 0x3b, 0x21, 0xab, 0xb9, 0xdc, 0xec, 0xfa, 0x01, 0xf5, 0xaa, 0x15, + 0xb5, 0xe6, 0x3a, 0x07, 0xc6, 0xf6, 0xa5, 0x10, 0xd5, 0xf8, 0xd7, 0x59, 0xdc, 0x05, 0xd9, 0x84, + 0xaf, 0xb6, 0xfd, 0xc0, 0x6e, 0xd7, 0x69, 0xc8, 0x00, 0x27, 0xbc, 0x23, 0xa0, 0xb1, 0x09, 0x1f, + 0x21, 0xeb, 0x55, 0x67, 0x07, 0xae, 0x9a, 0x55, 0x29, 0x35, 0x17, 0xd5, 0x8a, 0xaa, 0x5e, 0xf5, + 0x04, 0x34, 0x56, 0x65, 0x84, 0x4c, 0x2e, 0xc3, 0x68, 0xb5, 0xb4, 0x56, 0xea, 0x06, 0xfb, 0xb8, + 0x07, 0xe7, 0xb9, 0x7c, 0xce, 0x66, 0xab, 0xdd, 0x0d, 0xf6, 0x4d, 0x59, 0x48, 0xae, 0xe3, 0xbd, + 0xa7, 0x4d, 0x03, 0xae, 0x86, 0x15, 0x87, 0xae, 0xcf, 0x41, 0xb1, 0x6b, 0x0f, 0x03, 0x91, 0xd7, + 0x60, 0xf8, 0xc1, 0x46, 0xb9, 0x5a, 0x11, 0x17, 0x67, 0x3c, 0x89, 0x1e, 0x76, 0xea, 0xfa, 0x97, + 0x70, 0x14, 0xb2, 0x0c, 0x53, 0x35, 0x5a, 0xef, 0x7a, 0x4e, 0x70, 0x78, 0xc7, 0x73, 0xbb, 0x1d, + 0x7f, 0x7e, 0x14, 0xeb, 0xc0, 0x95, 0xee, 0x8b, 0x12, 0x6b, 0x0f, 0x8b, 0x14, 0xea, 0x18, 0x91, + 0xf1, 0x3b, 0x99, 0x68, 0x9b, 0x24, 0x97, 0x35, 0xb1, 0x06, 0x75, 0x37, 0x4c, 0xac, 0x51, 0x75, + 0x37, 0x28, 0xe0, 0x98, 0x40, 0xca, 0x5d, 0x3f, 0x70, 0x5b, 0xcb, 0xed, 0x46, 0xc7, 0x75, 0xda, + 0x01, 0x52, 0xf1, 0xce, 0x37, 0x8e, 0x8f, 0x8a, 0x17, 0xeb, 0x58, 0x6a, 0x51, 0x51, 0x6c, 0xc5, + 0xb8, 0xa4, 0x50, 0x3f, 0xc1, 0x78, 0x18, 0xbf, 0x9f, 0xd5, 0x8e, 0x37, 0xf6, 0x79, 0x26, 0xed, + 0x34, 0x9d, 0x3a, 0xde, 0xe8, 0xb1, 0xa1, 0xe1, 0xac, 0xc2, 0xcf, 0xf3, 0xa2, 0x52, 0xde, 0x43, + 0x3a, 0xef, 0x14, 0x6a, 0xf2, 0x45, 0x98, 0x60, 0x92, 0x86, 0xf8, 0xe9, 0xcf, 0x67, 0xb1, 0xb3, + 0x5f, 0x40, 0x2d, 0x9c, 0x4f, 0xbd, 0x90, 0x8d, 0x26, 0xa2, 0xa8, 0x14, 0xa4, 0x01, 0xf3, 0x9b, + 0x9e, 0xdd, 0xf6, 0x9d, 0x60, 0xb9, 0x5d, 0xf7, 0x0e, 0x51, 0x32, 0x5a, 0x6e, 0xdb, 0x3b, 0x4d, + 0xda, 0xc0, 0xe6, 0xe6, 0x97, 0xae, 0x1c, 0x1f, 0x15, 0x5f, 0x0e, 0x38, 0x8e, 0x45, 0x43, 0x24, + 0x8b, 0x72, 0x2c, 0x85, 0x73, 0x4f, 0x4e, 0x4c, 0x92, 0x92, 0xdd, 0x8a, 0x8f, 0x30, 0x5c, 0x48, + 0x40, 0x49, 0x2a, 0x1c, 0x0d, 0xb6, 0x87, 0xa9, 0x9f, 0xa9, 0x12, 0x18, 0xff, 0x6f, 0x26, 0x3a, + 0x80, 0xc9, 0xbb, 0x30, 0x2e, 0x56, 0x8c, 0x32, 0x2f, 0x70, 0x07, 0x95, 0xcb, 0x2b, 0x36, 0xb2, + 0x2a, 0x3a, 0xbb, 0xf7, 0x97, 0xca, 0xab, 0xca, 0xdc, 0xc0, 0x7b, 0xbf, 0x5d, 0x6f, 0xc6, 0xa9, + 0x24, 0x1a, 0x9b, 0x04, 0x9b, 0xab, 0x35, 0xbd, 0x57, 0x70, 0x12, 0x04, 0x4d, 0x3f, 0xa5, 0x1b, + 0x14, 0xe4, 0x27, 0x6f, 0xf8, 0xff, 0x92, 0x49, 0x3b, 0xe7, 0xc9, 0x12, 0x4c, 0x6e, 0xbb, 0xde, + 0x01, 0x8e, 0xaf, 0xd2, 0x09, 0x38, 0xf2, 0x8f, 0x64, 0x41, 0xbc, 0x41, 0x3a, 0x89, 0xfa, 0x6d, + 0x4a, 0x6f, 0xe8, 0xdf, 0x16, 0xe3, 0xa0, 0x11, 0xb0, 0x71, 0x08, 0x39, 0x86, 0xab, 0x03, 0xc7, + 0x21, 0xfa, 0x04, 0x6d, 0x0a, 0xab, 0xe8, 0xc6, 0x7f, 0x95, 0x51, 0xcf, 0x73, 0xd6, 0xc9, 0x15, + 0xb7, 0x65, 0x3b, 0x6d, 0xa5, 0x39, 0xfc, 0x61, 0x09, 0xa1, 0xf1, 0x2f, 0x51, 0x90, 0xc9, 0x4d, + 0xc8, 0xf3, 0x5f, 0xe1, 0x5e, 0x8b, 0x5a, 0x2d, 0x41, 0xa8, 0x1f, 0x14, 0x12, 0x31, 0x31, 0x32, + 0xb9, 0xd3, 0x8e, 0xcc, 0x6f, 0x67, 0xd4, 0xa3, 0xf8, 0xe3, 0x1e, 0x36, 0xb1, 0x43, 0x26, 0x7b, + 0x9a, 0x43, 0xe6, 0x89, 0x9b, 0xf0, 0x7d, 0x19, 0x18, 0x57, 0xb4, 0x14, 0xac, 0x0d, 0x1b, 0x9e, + 0xfb, 0x11, 0xad, 0x07, 0x7a, 0x1b, 0x3a, 0x1c, 0x18, 0x6b, 0x43, 0x88, 0xfa, 0x04, 0x6d, 0x30, + 0xfe, 0x2c, 0x23, 0xee, 0x48, 0x03, 0x6f, 0xf3, 0xfa, 0x96, 0x9c, 0x3d, 0xcd, 0x11, 0xf9, 0x45, + 0x18, 0x36, 0x69, 0xc3, 0xf1, 0xc5, 0xfd, 0x66, 0x46, 0xbd, 0x8f, 0x61, 0x41, 0x24, 0x37, 0x79, + 0xec, 0xa7, 0x7a, 0xbe, 0x61, 0x39, 0x13, 0x64, 0xab, 0xfe, 0xed, 0x26, 0x7d, 0xec, 0xf0, 0xc5, + 0x28, 0x8e, 0x5a, 0x3c, 0xde, 0x1c, 0xdf, 0xda, 0x65, 0x25, 0x42, 0xa2, 0x56, 0x17, 0x9e, 0x46, + 0x63, 0x7c, 0x08, 0x10, 0x55, 0x49, 0xee, 0x41, 0x41, 0xcc, 0x06, 0xa7, 0xbd, 0xc7, 0x05, 0x29, + 0xd1, 0x07, 0xc5, 0xe3, 0xa3, 0xe2, 0xf3, 0xf5, 0xb0, 0x4c, 0x48, 0x9d, 0x0a, 0xdf, 0x04, 0xa1, + 0xf1, 0x1f, 0x66, 0x21, 0x5b, 0xc2, 0x01, 0xb9, 0x47, 0x0f, 0x03, 0x7b, 0xe7, 0xb6, 0xd3, 0xd4, + 0x16, 0xd3, 0x01, 0x42, 0xad, 0x5d, 0x47, 0x53, 0x57, 0x28, 0xc8, 0x6c, 0x31, 0xdd, 0xf3, 0x76, + 0xde, 0x42, 0x42, 0x65, 0x31, 0x1d, 0x78, 0x3b, 0x6f, 0xc5, 0xc9, 0x42, 0x44, 0x62, 0xc0, 0x08, + 0x5f, 0x58, 0x62, 0x0e, 0xc2, 0xf1, 0x51, 0x71, 0x84, 0xaf, 0x3f, 0x53, 0x94, 0x90, 0xf3, 0x90, + 0xab, 0x6d, 0xac, 0x8b, 0x1d, 0x10, 0xd5, 0x82, 0x7e, 0xa7, 0x6d, 0x32, 0x18, 0xab, 0x73, 0xb5, + 0x52, 0xda, 0x40, 0x45, 0xc0, 0x70, 0x54, 0x67, 0xb3, 0x61, 0x77, 0xe2, 0xaa, 0x80, 0x10, 0x91, + 0xbc, 0x07, 0xe3, 0xf7, 0x2a, 0xe5, 0x15, 0xd7, 0xe7, 0xbb, 0xd7, 0x48, 0x34, 0xf9, 0x0f, 0x1a, + 0x75, 0x0b, 0x35, 0xf1, 0xf1, 0x63, 0x40, 0xc1, 0x37, 0x7e, 0x38, 0x0b, 0xe3, 0x8a, 0x9e, 0x8c, + 0x7c, 0x56, 0x3c, 0x90, 0x66, 0xb4, 0x1b, 0x80, 0x82, 0xc1, 0x4a, 0xb9, 0x52, 0xa5, 0xe5, 0x36, + 0xa8, 0x78, 0x2e, 0x8d, 0x14, 0x18, 0xd9, 0x41, 0x14, 0x18, 0x6f, 0x03, 0xf0, 0x39, 0x80, 0x9f, + 0xac, 0x88, 0x13, 0x8a, 0x9d, 0x84, 0x3a, 0x2e, 0x11, 0x32, 0x79, 0x00, 0xb3, 0x9b, 0x5e, 0xd7, + 0x0f, 0x6a, 0x87, 0x7e, 0x40, 0x5b, 0x8c, 0xdb, 0x86, 0xeb, 0x36, 0xc5, 0xfc, 0x7b, 0xf9, 0xf8, + 0xa8, 0x78, 0x09, 0x8d, 0x3b, 0x2c, 0x1f, 0xcb, 0xf1, 0x03, 0xac, 0x8e, 0xeb, 0xaa, 0x6a, 0x8d, + 0x34, 0x06, 0x86, 0x09, 0x13, 0xaa, 0x52, 0x84, 0x9d, 0x2c, 0xe2, 0x31, 0x49, 0xa8, 0xba, 0x95, + 0x93, 0x45, 0x7c, 0x65, 0xf2, 0x71, 0x4b, 0x27, 0x31, 0x3e, 0xab, 0x2a, 0xe4, 0x06, 0x5d, 0xd8, + 0xc6, 0x0f, 0x64, 0xa2, 0x6d, 0xe4, 0xc1, 0x0d, 0xf2, 0x0e, 0x8c, 0xf0, 0xc7, 0x3b, 0xf1, 0xc6, + 0x79, 0x26, 0xbc, 0xd4, 0xaa, 0x2f, 0x7b, 0x5c, 0x13, 0xfe, 0x87, 0xfc, 0x81, 0xff, 0x39, 0x53, + 0x90, 0x84, 0x4a, 0x74, 0x5d, 0x9f, 0x26, 0xb9, 0xa3, 0xba, 0xf8, 0x46, 0x9a, 0x12, 0xdd, 0xf8, + 0xf1, 0x61, 0x98, 0xd2, 0xd1, 0xd4, 0x17, 0xbe, 0xcc, 0x40, 0x2f, 0x7c, 0x5f, 0x84, 0x3c, 0xeb, + 0x0f, 0xa7, 0x4e, 0xa5, 0x44, 0xf6, 0x32, 0x3e, 0x2d, 0x08, 0x98, 0xf6, 0x72, 0x0d, 0x7c, 0x38, + 0xd8, 0x1d, 0xd7, 0x0c, 0xa9, 0xc8, 0xa2, 0xf2, 0x0c, 0x95, 0x8b, 0x84, 0x14, 0xf9, 0x0c, 0xa5, + 0xae, 0x87, 0xf0, 0x41, 0xea, 0x4d, 0x18, 0x61, 0xf2, 0x7d, 0xa8, 0x82, 0xc1, 0xaf, 0x64, 0xa2, + 0x7f, 0xcc, 0x44, 0x85, 0x23, 0x91, 0x6d, 0xc8, 0xaf, 0xda, 0x7e, 0x50, 0xa3, 0xb4, 0x3d, 0xc0, + 0xdb, 0x7d, 0x51, 0x74, 0xd5, 0x2c, 0x3e, 0x8c, 0xfb, 0x94, 0xb6, 0x63, 0x8f, 0xaf, 0x21, 0x33, + 0xf2, 0x35, 0x80, 0xb2, 0xdb, 0x0e, 0x3c, 0xb7, 0xb9, 0xea, 0xee, 0xcd, 0x8f, 0xe0, 0xdd, 0xf7, + 0x62, 0x6c, 0x00, 0x22, 0x04, 0x7e, 0xfd, 0x0d, 0x15, 0x3c, 0x75, 0x5e, 0x60, 0x35, 0xdd, 0x3d, + 0x75, 0x1d, 0x44, 0xf8, 0xe4, 0x36, 0x14, 0xa4, 0x62, 0x61, 0xab, 0xb3, 0xe7, 0xe1, 0x04, 0x19, + 0x8d, 0x24, 0x0f, 0xfa, 0x38, 0xb0, 0xba, 0x02, 0xae, 0xee, 0x94, 0x71, 0x1a, 0xf2, 0x55, 0x38, + 0x17, 0x87, 0xc9, 0x51, 0xce, 0x47, 0x32, 0xb9, 0xca, 0x2e, 0x65, 0xde, 0xf7, 0x62, 0x41, 0xee, + 0xc0, 0x34, 0xeb, 0x90, 0x35, 0x6a, 0xfb, 0x5d, 0x6e, 0x60, 0x25, 0x54, 0x33, 0x17, 0xa4, 0x26, + 0x8a, 0xaf, 0xc2, 0xa6, 0x5b, 0x3f, 0x50, 0x90, 0xcc, 0x38, 0x95, 0x71, 0x94, 0x85, 0xb3, 0xe9, + 0xb8, 0xe4, 0x6f, 0xc0, 0x19, 0xd1, 0x2f, 0x4d, 0xea, 0x29, 0x38, 0x03, 0xd8, 0x04, 0xbc, 0x29, + 0xfa, 0xfb, 0xc5, 0x7a, 0xc8, 0x20, 0xdc, 0x38, 0x18, 0x8b, 0xd8, 0xe0, 0xa6, 0xd7, 0x43, 0xbe, + 0x01, 0xe3, 0x6a, 0xb5, 0xd9, 0xc1, 0xcd, 0x2b, 0xfa, 0xd4, 0xa5, 0xb2, 0x24, 0x36, 0x4c, 0x9b, + 0xf4, 0x9b, 0x5d, 0xea, 0x07, 0xd2, 0xc0, 0x43, 0x1c, 0xdd, 0xe7, 0x13, 0xb5, 0x48, 0x84, 0x50, + 0xff, 0x53, 0xf0, 0x38, 0xa5, 0x25, 0xcd, 0xf0, 0xbe, 0xcd, 0xd8, 0xc7, 0xf9, 0x19, 0xdf, 0xcd, + 0xc2, 0xb9, 0x1e, 0xd3, 0x92, 0xed, 0x5c, 0x28, 0x58, 0x29, 0x3b, 0x57, 0x4c, 0x9e, 0xe2, 0xd6, + 0x61, 0x97, 0x20, 0x2b, 0x44, 0x91, 0xa1, 0xa5, 0xc2, 0xf1, 0x51, 0x71, 0x42, 0x5b, 0x71, 0xd9, + 0x6a, 0x85, 0xdc, 0x85, 0x21, 0xd6, 0x0d, 0x03, 0x18, 0x39, 0x48, 0xed, 0xdf, 0x54, 0xe0, 0xa8, + 0x0b, 0x1d, 0xfb, 0x06, 0x79, 0x90, 0xcf, 0x42, 0x6e, 0x73, 0x73, 0x15, 0x57, 0x79, 0x0e, 0x67, + 0xe9, 0x64, 0x10, 0x34, 0xb5, 0x4d, 0x65, 0x92, 0xd1, 0x86, 0x3d, 0x62, 0x32, 0x74, 0xf2, 0xe5, + 0x98, 0xf1, 0xd5, 0x6b, 0xfd, 0x97, 0xe4, 0xe0, 0xb6, 0x58, 0x4f, 0x60, 0x02, 0x65, 0xfc, 0x7c, + 0x36, 0xda, 0x6d, 0x6f, 0x3b, 0xcd, 0x80, 0x7a, 0x64, 0x81, 0x6f, 0x9e, 0x91, 0x18, 0x6d, 0x86, + 0xbf, 0xc9, 0x7c, 0xb4, 0x13, 0x73, 0x56, 0xe1, 0x96, 0xfb, 0x9a, 0xb2, 0xe5, 0xe6, 0x70, 0xcb, + 0x9d, 0xea, 0xb9, 0xb9, 0xbe, 0x96, 0xb2, 0x83, 0xe0, 0x96, 0x99, 0xb2, 0x4b, 0xbc, 0x0c, 0x93, + 0xeb, 0xee, 0xf2, 0xe3, 0x20, 0x44, 0x64, 0x5b, 0x65, 0xde, 0xd4, 0x81, 0x8c, 0xe3, 0xfd, 0x66, + 0x83, 0x7a, 0x9b, 0xfb, 0x76, 0x5b, 0xb3, 0x32, 0x30, 0x13, 0x70, 0x86, 0xbb, 0x4e, 0x1f, 0xe9, + 0xb8, 0xa3, 0x1c, 0x37, 0x0e, 0x37, 0xbe, 0x3f, 0x2b, 0x3b, 0xe3, 0xc1, 0xe2, 0x33, 0xfa, 0x9a, + 0xfd, 0x96, 0xf6, 0x9a, 0x3d, 0x1b, 0xea, 0xe1, 0x43, 0xd3, 0x8c, 0xc5, 0x13, 0x2c, 0x3a, 0xfe, + 0xfe, 0x08, 0x4c, 0xa8, 0xe8, 0xac, 0x1f, 0x4a, 0x8d, 0x86, 0xa7, 0xf6, 0x83, 0xdd, 0x68, 0x78, + 0x26, 0x42, 0x35, 0x03, 0x8e, 0x5c, 0x5f, 0x03, 0x8e, 0xaf, 0xc3, 0x58, 0xb9, 0xd5, 0xd0, 0x9e, + 0x95, 0x8d, 0x94, 0xcf, 0xbb, 0x16, 0x22, 0xf1, 0xb5, 0x10, 0xaa, 0x97, 0xeb, 0xad, 0x46, 0xf2, + 0x31, 0x39, 0x62, 0xa9, 0xd9, 0x7e, 0x0c, 0x3f, 0x89, 0xed, 0xc7, 0x2d, 0x18, 0xdb, 0xf2, 0xe9, + 0x66, 0xb7, 0xdd, 0xa6, 0x4d, 0x9c, 0x56, 0x79, 0x7e, 0x2b, 0xeb, 0xfa, 0xd4, 0x0a, 0x10, 0xaa, + 0x7e, 0x40, 0x88, 0xaa, 0x0e, 0xf0, 0x68, 0x9f, 0x01, 0xbe, 0x09, 0xf9, 0x0d, 0x4a, 0x3d, 0xec, + 0xd3, 0xf1, 0x48, 0xf8, 0xee, 0x50, 0xea, 0x59, 0xac, 0x63, 0x35, 0x9b, 0x10, 0x81, 0xa8, 0x19, + 0x92, 0x4c, 0x0c, 0x68, 0x48, 0x42, 0x5e, 0x84, 0x89, 0x4e, 0x77, 0xa7, 0xe9, 0xd4, 0x91, 0xaf, + 0xb0, 0x40, 0x31, 0xc7, 0x39, 0x8c, 0xb1, 0xf5, 0xc9, 0x97, 0x61, 0x12, 0x6f, 0xa3, 0xe1, 0x94, + 0x9b, 0xd2, 0xde, 0x5f, 0xb5, 0x32, 0x2e, 0x93, 0xd6, 0x19, 0xc8, 0x4a, 0x31, 0x94, 0xd2, 0x19, + 0x91, 0xbb, 0x30, 0xba, 0xe7, 0x04, 0xd6, 0x7e, 0x77, 0x67, 0x7e, 0x5a, 0xb3, 0x32, 0xba, 0xe3, + 0x04, 0x2b, 0xdd, 0x1d, 0x3e, 0xe4, 0x21, 0x6b, 0xdc, 0xf1, 0xf6, 0x9c, 0x60, 0xbf, 0xab, 0x2a, + 0xcf, 0x47, 0xf6, 0x10, 0x77, 0xa1, 0x06, 0x53, 0xfa, 0xac, 0x78, 0x0a, 0x4f, 0xba, 0xa1, 0x81, + 0x4d, 0xbe, 0x30, 0x76, 0x77, 0x28, 0x0f, 0x85, 0x71, 0x6e, 0x5a, 0x63, 0xc2, 0x46, 0xd8, 0x3f, + 0x26, 0xb9, 0xd7, 0xdd, 0xa1, 0x5e, 0x9b, 0x06, 0xd4, 0x17, 0x57, 0x3f, 0xdf, 0x1c, 0x2a, 0x75, + 0x3a, 0xbe, 0xf1, 0x9f, 0x66, 0x61, 0xb4, 0xb4, 0x5d, 0xab, 0xb6, 0x77, 0x5d, 0x7c, 0x98, 0x0d, + 0xdf, 0xe3, 0xd4, 0x87, 0xd9, 0xf0, 0x3d, 0x4e, 0x7d, 0x85, 0xbb, 0x9e, 0x72, 0x79, 0x47, 0xdb, + 0x6d, 0xe5, 0xf2, 0xae, 0xa9, 0x1d, 0xa2, 0xa7, 0xc9, 0xdc, 0x00, 0x4f, 0x93, 0xa1, 0xf6, 0x78, + 0xe8, 0x64, 0xed, 0xf1, 0x3b, 0x30, 0x5e, 0x6d, 0x07, 0x74, 0xcf, 0x8b, 0x56, 0x4d, 0xa8, 0x48, + 0x08, 0xc1, 0xea, 0x85, 0x4e, 0xc1, 0x66, 0x53, 0x92, 0x6b, 0xac, 0x43, 0x4d, 0x35, 0x4e, 0x49, + 0xae, 0xd8, 0x8e, 0x69, 0x81, 0x24, 0xa2, 0x51, 0x89, 0xcd, 0x37, 0x69, 0xfe, 0xc1, 0x45, 0xa8, + 0xa9, 0xe8, 0xc9, 0x86, 0x75, 0xec, 0xd2, 0x4c, 0xba, 0xf9, 0x87, 0xf1, 0xb7, 0x33, 0x30, 0x97, + 0x36, 0x8d, 0xc8, 0xfb, 0x30, 0xe1, 0x7a, 0x7b, 0x76, 0xdb, 0xf9, 0x5e, 0xde, 0x22, 0x45, 0x55, + 0xa9, 0xc2, 0x55, 0x05, 0x8d, 0x0a, 0x67, 0x1d, 0xa2, 0xb4, 0x5c, 0xd7, 0xac, 0xa4, 0x76, 0x88, + 0x02, 0x36, 0x7e, 0x24, 0x0b, 0xe3, 0xa5, 0x4e, 0xe7, 0x19, 0x37, 0x0d, 0xfc, 0xbc, 0x76, 0x80, + 0xc8, 0x7b, 0x79, 0xd8, 0xae, 0x81, 0xac, 0x02, 0x7f, 0x35, 0x0b, 0xd3, 0x31, 0x0a, 0xf5, 0xeb, + 0x33, 0x03, 0x1a, 0x04, 0x66, 0x07, 0x34, 0x08, 0xcc, 0x0d, 0x66, 0x10, 0x38, 0xf4, 0x24, 0x87, + 0xc2, 0xab, 0x90, 0x2b, 0x75, 0x3a, 0x71, 0xc3, 0x82, 0x4e, 0xe7, 0xc1, 0x4d, 0xae, 0x5b, 0xb1, + 0x3b, 0x1d, 0x93, 0x61, 0x68, 0x3b, 0xf5, 0xc8, 0x80, 0x3b, 0xb5, 0xf1, 0x26, 0x8c, 0x21, 0x2f, + 0x34, 0xc3, 0xbb, 0x04, 0xb8, 0xc5, 0x08, 0x0b, 0x3c, 0xad, 0x2e, 0xb1, 0xf9, 0xfc, 0xcb, 0x0c, + 0x0c, 0xe3, 0xef, 0x67, 0x74, 0x8e, 0x2d, 0x6a, 0x73, 0xac, 0xa0, 0xcc, 0xb1, 0x41, 0x66, 0xd7, + 0x3f, 0xcc, 0x01, 0x94, 0xef, 0x9b, 0x35, 0xae, 0x82, 0x23, 0xb7, 0x61, 0xda, 0x6e, 0x36, 0xdd, + 0x47, 0xb4, 0x61, 0xb9, 0x9e, 0xb3, 0xe7, 0xb4, 0x79, 0xcf, 0xc9, 0xd7, 0x6e, 0xbd, 0x48, 0x7d, + 0x03, 0x13, 0x45, 0xf7, 0x79, 0x89, 0xca, 0xa7, 0x45, 0x83, 0x7d, 0xb7, 0x21, 0x95, 0x09, 0x1a, + 0x1f, 0x51, 0x94, 0xc2, 0x67, 0x8d, 0x97, 0xa8, 0x7c, 0xf6, 0x51, 0x39, 0x22, 0x25, 0x64, 0x8d, + 0x8f, 0x28, 0x4a, 0xe1, 0xc3, 0x35, 0x2a, 0x3e, 0x59, 0x85, 0x19, 0x84, 0x58, 0x75, 0x8f, 0x36, + 0x68, 0x3b, 0x70, 0xec, 0xa6, 0x2f, 0xd4, 0x4f, 0xa8, 0xa8, 0x4c, 0x14, 0xaa, 0xd7, 0x6f, 0x2c, + 0x2c, 0x47, 0x65, 0xe4, 0x1a, 0x8c, 0xb6, 0xec, 0xc7, 0x96, 0xbd, 0xc7, 0xed, 0x3e, 0x26, 0xb9, + 0xba, 0x42, 0x80, 0xd4, 0x63, 0xa4, 0x65, 0x3f, 0x2e, 0xed, 0x51, 0xd6, 0x0a, 0xfa, 0xb8, 0xe3, + 0xfa, 0x4a, 0x2b, 0x46, 0xa2, 0x56, 0xc4, 0x8a, 0xd4, 0x56, 0x88, 0x22, 0xd1, 0x0a, 0xe3, 0x57, + 0x32, 0xf0, 0x7c, 0x15, 0xbf, 0x22, 0x38, 0x2c, 0xd3, 0x76, 0x40, 0xbd, 0x0d, 0xea, 0xb5, 0x1c, + 0x7c, 0x05, 0xaf, 0xd1, 0x80, 0xbc, 0x04, 0xb9, 0x92, 0xb9, 0x2e, 0xe6, 0x2f, 0xdf, 0xef, 0x35, + 0x9b, 0x04, 0x56, 0x1a, 0x6a, 0xb4, 0xb2, 0x27, 0xa8, 0xaa, 0x4b, 0x30, 0x51, 0xf2, 0x7d, 0x67, + 0xaf, 0xdd, 0xe2, 0xfe, 0x14, 0x39, 0xcd, 0xea, 0x41, 0xc0, 0x13, 0x6f, 0x2c, 0x2a, 0x89, 0xf1, + 0x9f, 0x65, 0x60, 0xa6, 0xd4, 0xe9, 0xe8, 0x9f, 0xac, 0x5b, 0xdc, 0x64, 0x06, 0xb7, 0xb8, 0x71, + 0x60, 0x4a, 0x6b, 0x2e, 0x9f, 0x52, 0x91, 0xe0, 0xdb, 0xa7, 0x67, 0xf8, 0x67, 0x77, 0x42, 0x90, + 0xe5, 0xeb, 0xcf, 0xc5, 0x31, 0xc6, 0xc6, 0xbf, 0x37, 0x8a, 0x7b, 0x88, 0xd8, 0x6d, 0x85, 0x4d, + 0x68, 0x26, 0xc5, 0x26, 0xf4, 0x6d, 0x50, 0x24, 0x1c, 0xf5, 0x88, 0x53, 0x64, 0x45, 0x55, 0x17, + 0x14, 0x21, 0x93, 0x83, 0xb8, 0x75, 0x68, 0x0e, 0x5b, 0xf3, 0x52, 0x7c, 0x01, 0x3f, 0x15, 0xc3, + 0xd0, 0x15, 0x20, 0xd5, 0x36, 0x3e, 0x61, 0xd3, 0xda, 0x81, 0xd3, 0x79, 0x40, 0x3d, 0x67, 0xf7, + 0x50, 0x2c, 0x00, 0xec, 0x7c, 0x47, 0x94, 0x5a, 0xfe, 0x81, 0xd3, 0xb1, 0x1e, 0x62, 0xb9, 0x99, + 0x42, 0x43, 0x3e, 0x80, 0x51, 0x93, 0x3e, 0xf2, 0x9c, 0x40, 0xda, 0x3c, 0x4d, 0x85, 0xaa, 0x4d, + 0x84, 0xf2, 0xb5, 0xe0, 0xf1, 0x1f, 0xea, 0xae, 0x28, 0xca, 0xc9, 0x22, 0x17, 0x52, 0xb8, 0x6d, + 0xd3, 0x64, 0xd4, 0xda, 0xd2, 0x76, 0xad, 0x97, 0x8c, 0x42, 0xae, 0xc2, 0x30, 0x4a, 0x3a, 0xe2, + 0x2e, 0x80, 0xbe, 0x42, 0x28, 0x3b, 0xab, 0x62, 0x18, 0x62, 0x90, 0x8b, 0x00, 0xe1, 0x1b, 0xb1, + 0x3f, 0x9f, 0x47, 0x29, 0x5d, 0x81, 0xc4, 0xc5, 0xb4, 0xb1, 0x53, 0x89, 0x69, 0xab, 0x50, 0x30, + 0xb9, 0xdb, 0x61, 0xa3, 0xd4, 0xc1, 0x87, 0x48, 0x7f, 0x1e, 0x70, 0x25, 0x5f, 0x3a, 0x3e, 0x2a, + 0xbe, 0x20, 0x5c, 0x12, 0x1b, 0x96, 0xdd, 0xe1, 0xef, 0x97, 0xda, 0x36, 0x12, 0xa7, 0x24, 0x6f, + 0xc3, 0x10, 0xdb, 0x7a, 0x85, 0x1d, 0xa9, 0x7c, 0xd0, 0x89, 0x76, 0x63, 0xbe, 0x38, 0xeb, 0xae, + 0xb6, 0x27, 0x20, 0x09, 0xb1, 0x60, 0x4a, 0x9f, 0xee, 0xc2, 0xa4, 0x68, 0x3e, 0xea, 0x4f, 0xbd, + 0x5c, 0xbc, 0xf2, 0x08, 0x98, 0x55, 0x47, 0xa0, 0xba, 0x02, 0x62, 0x8b, 0x74, 0x19, 0xf2, 0x9b, + 0xe5, 0x8d, 0x0d, 0xd7, 0x0b, 0xf8, 0x55, 0x27, 0x3a, 0x59, 0x18, 0xcc, 0xb4, 0xdb, 0x7b, 0x94, + 0x9f, 0xc5, 0x41, 0xbd, 0x63, 0x75, 0x18, 0x9a, 0x7a, 0x16, 0x4b, 0xd2, 0x4f, 0xce, 0x86, 0xf4, + 0x57, 0xb3, 0xf0, 0x52, 0x28, 0x15, 0xdd, 0xf7, 0x6a, 0xa5, 0xb5, 0xd5, 0x6a, 0x63, 0x43, 0xa8, + 0x49, 0x36, 0x3c, 0xf7, 0xa1, 0xd3, 0xa0, 0xde, 0x83, 0x1b, 0x27, 0x9c, 0xe9, 0xab, 0x7c, 0x99, + 0xf3, 0xd7, 0xb0, 0xac, 0x66, 0x6d, 0xa7, 0x08, 0x9f, 0x62, 0x7b, 0xea, 0x74, 0x12, 0x8f, 0x63, + 0x2b, 0xcf, 0x99, 0x11, 0x03, 0xf2, 0x03, 0x19, 0x38, 0x9b, 0xfe, 0x21, 0x42, 0x75, 0x56, 0x94, + 0x57, 0xf4, 0x1e, 0x5f, 0xbb, 0xf4, 0xea, 0xf1, 0x51, 0xf1, 0x25, 0xdf, 0x6e, 0x35, 0x2d, 0xa7, + 0xc1, 0x6b, 0x73, 0xea, 0xd4, 0xea, 0x08, 0x04, 0xad, 0xde, 0x1e, 0x35, 0x7d, 0x01, 0xe4, 0xd1, + 0x3e, 0x9f, 0x59, 0x02, 0xc8, 0xcb, 0x07, 0x07, 0xe3, 0x37, 0x32, 0xa0, 0x2c, 0xc1, 0xbc, 0x49, + 0x1b, 0x8e, 0x47, 0xeb, 0x81, 0x38, 0xde, 0x85, 0xaf, 0x20, 0x87, 0xc5, 0x8c, 0x2b, 0x11, 0x46, + 0xde, 0x87, 0x51, 0x71, 0x0c, 0x89, 0x6d, 0x57, 0x2e, 0x5d, 0xf1, 0x94, 0xc1, 0x9d, 0x4a, 0x13, + 0x47, 0x98, 0x24, 0x62, 0xbb, 0xfe, 0xdd, 0xed, 0xcd, 0x72, 0xd3, 0x76, 0x5a, 0xbe, 0x38, 0x4b, + 0xb0, 0x5b, 0x3f, 0x7a, 0x14, 0x58, 0x75, 0x84, 0xaa, 0xbb, 0x7e, 0x88, 0x6a, 0xdc, 0x91, 0x2f, + 0x29, 0x27, 0x58, 0x08, 0x17, 0x61, 0xf8, 0x41, 0xa4, 0xa7, 0x5b, 0x1a, 0x3b, 0x3e, 0x2a, 0xf2, + 0xe9, 0x62, 0x72, 0xb8, 0xf1, 0x15, 0x18, 0x0b, 0xa7, 0x2e, 0xe3, 0xc5, 0x7e, 0x20, 0xaf, 0x49, + 0xce, 0x8b, 0x4d, 0x62, 0x13, 0xa1, 0x4c, 0xd4, 0x5b, 0x6e, 0x37, 0x10, 0x21, 0x8b, 0x08, 0xd8, + 0x3d, 0xb4, 0xdd, 0xc0, 0x99, 0xae, 0xb6, 0x4e, 0xa0, 0x19, 0x3f, 0x96, 0x81, 0x29, 0x7d, 0xb2, + 0x92, 0x6b, 0x30, 0x22, 0x9c, 0x00, 0x33, 0xa8, 0xec, 0x64, 0x3c, 0x46, 0xb8, 0xfb, 0x9f, 0xe6, + 0xf4, 0x27, 0xb0, 0x98, 0xb4, 0x28, 0x38, 0x08, 0x51, 0x09, 0xa5, 0xc5, 0x3a, 0x07, 0x99, 0xb2, + 0x8c, 0x18, 0xec, 0x02, 0xeb, 0x77, 0x9b, 0x81, 0xfa, 0x5a, 0xe9, 0x21, 0xc4, 0x14, 0x25, 0x46, + 0x19, 0x46, 0xf8, 0x86, 0x1a, 0x33, 0x7b, 0xcc, 0x9c, 0xc2, 0xec, 0xd1, 0x38, 0xca, 0x00, 0xd4, + 0x6a, 0x2b, 0xf7, 0xe8, 0xe1, 0x86, 0xed, 0xe0, 0xa9, 0xcd, 0x0f, 0xaf, 0x7b, 0x62, 0xe5, 0x4e, + 0x88, 0xe7, 0x75, 0x7e, 0xd0, 0x1d, 0xd0, 0x43, 0xed, 0x79, 0x5d, 0xa2, 0xe2, 0x09, 0xe9, 0x39, + 0x0f, 0xed, 0x80, 0x32, 0xc2, 0x2c, 0x12, 0xf2, 0x13, 0x92, 0x43, 0x63, 0x94, 0x0a, 0x32, 0xf9, + 0x1a, 0x4c, 0x45, 0xbf, 0x42, 0x23, 0x81, 0xa9, 0x70, 0x77, 0xd0, 0x0b, 0x97, 0x2e, 0x1e, 0x1f, + 0x15, 0x17, 0x14, 0xae, 0x71, 0xf3, 0x81, 0x18, 0x33, 0xe3, 0x97, 0x32, 0x68, 0x1a, 0x23, 0x1b, + 0x78, 0x19, 0x86, 0x42, 0x63, 0xee, 0x09, 0xb1, 0xf5, 0xea, 0x0f, 0xa1, 0x58, 0xce, 0x84, 0xac, + 0xa8, 0x25, 0x78, 0x60, 0xe9, 0x2d, 0x60, 0xa5, 0xe4, 0x0e, 0x8c, 0x0e, 0xf4, 0xcd, 0x38, 0xb1, + 0x52, 0xbe, 0x55, 0x52, 0xe3, 0x28, 0xdc, 0xdd, 0xde, 0xfc, 0xf4, 0x8e, 0xc2, 0x4f, 0x66, 0x61, + 0x9a, 0xf5, 0x6b, 0xa9, 0x1b, 0xec, 0xbb, 0x9e, 0x13, 0x1c, 0x3e, 0xb3, 0xda, 0xe2, 0x77, 0xb5, + 0x8b, 0xd8, 0x82, 0x3c, 0xc2, 0xd4, 0xb6, 0x0d, 0xa4, 0x34, 0xfe, 0xef, 0x87, 0x61, 0x36, 0x85, + 0x8a, 0xbc, 0xa1, 0x3d, 0xe8, 0xcc, 0x4b, 0x27, 0xff, 0xef, 0x1e, 0x15, 0x27, 0x24, 0xfa, 0x66, + 0xe4, 0xf4, 0xbf, 0xa8, 0xdb, 0x99, 0xf1, 0x9e, 0xc2, 0xf7, 0x1d, 0xd5, 0xce, 0x4c, 0xb7, 0x2e, + 0xbb, 0x0a, 0xc3, 0xa6, 0xdb, 0xa4, 0xd2, 0xb6, 0x12, 0xc5, 0x2c, 0x8f, 0x01, 0x34, 0x5b, 0x12, + 0x06, 0x20, 0x2b, 0x30, 0xca, 0xfe, 0x58, 0xb3, 0x3b, 0xe2, 0x95, 0x94, 0x84, 0xaa, 0x00, 0x84, + 0x76, 0x9c, 0xf6, 0x9e, 0xaa, 0x0d, 0x68, 0x52, 0xab, 0x65, 0x77, 0x34, 0x79, 0x90, 0x23, 0x6a, + 0x5a, 0x85, 0x7c, 0x6f, 0xad, 0x42, 0xe6, 0x44, 0xad, 0xc2, 0x2e, 0x40, 0xcd, 0xd9, 0x6b, 0x3b, + 0xed, 0xbd, 0x52, 0x73, 0x4f, 0x84, 0x4a, 0xb8, 0xda, 0x7b, 0x14, 0xae, 0x45, 0xc8, 0x38, 0x71, + 0x9f, 0x47, 0x53, 0x06, 0x0e, 0xb3, 0xec, 0xe6, 0x9e, 0xe6, 0xd2, 0xa5, 0x70, 0x26, 0xeb, 0x00, + 0xa5, 0x7a, 0xe0, 0x3c, 0x64, 0x53, 0xd8, 0x17, 0xc2, 0x9b, 0xfc, 0xe4, 0x72, 0xe9, 0x1e, 0x3d, + 0xc4, 0x0b, 0x87, 0x7c, 0x14, 0xb6, 0x11, 0x95, 0xad, 0x04, 0xcd, 0x5f, 0x27, 0xe2, 0x40, 0x3a, + 0x70, 0xa6, 0xd4, 0x68, 0x38, 0xac, 0x0d, 0x76, 0x73, 0x93, 0x07, 0xb9, 0x40, 0xd6, 0x13, 0xe9, + 0xac, 0xaf, 0xca, 0xf7, 0x4f, 0x3b, 0xa4, 0xb2, 0x64, 0x6c, 0x8c, 0x58, 0x35, 0xe9, 0x8c, 0x8d, + 0x1a, 0x4c, 0xe9, 0x8d, 0xd7, 0x43, 0x3c, 0x4c, 0x40, 0xde, 0xac, 0x95, 0xac, 0xda, 0x4a, 0xe9, + 0x46, 0x21, 0x43, 0x0a, 0x30, 0x21, 0x7e, 0x2d, 0x5a, 0x8b, 0x6f, 0xdd, 0x2a, 0x64, 0x35, 0xc8, + 0x5b, 0x37, 0x16, 0x0b, 0xb9, 0x85, 0xec, 0x7c, 0x26, 0xe6, 0x5d, 0x39, 0x5a, 0xc8, 0x73, 0x45, + 0xb0, 0xf1, 0x6b, 0x19, 0xc8, 0xcb, 0x6f, 0x27, 0xb7, 0x20, 0x57, 0xab, 0xad, 0xc4, 0xfc, 0x21, + 0xa3, 0x53, 0x86, 0xef, 0xa7, 0xbe, 0xaf, 0x1a, 0xbd, 0x33, 0x02, 0x46, 0xb7, 0xb9, 0x5a, 0x13, + 0x92, 0x87, 0xa4, 0x8b, 0x36, 0x6f, 0x4e, 0x97, 0xe2, 0x24, 0x76, 0x0b, 0x72, 0x77, 0xb7, 0x37, + 0xc5, 0xd5, 0x4a, 0xd2, 0x45, 0xfb, 0x29, 0xa7, 0xfb, 0xe8, 0x91, 0xba, 0xcb, 0x33, 0x02, 0xc3, + 0x84, 0x71, 0x65, 0x22, 0xf3, 0x43, 0xb7, 0xe5, 0x86, 0x71, 0x0d, 0xc4, 0xa1, 0xcb, 0x20, 0xa6, + 0x28, 0x61, 0x02, 0xc8, 0xaa, 0x5b, 0xb7, 0x9b, 0xe2, 0xf4, 0x46, 0x01, 0xa4, 0xc9, 0x00, 0x26, + 0x87, 0x1b, 0xbf, 0x93, 0x81, 0x02, 0x8a, 0x69, 0x68, 0xb4, 0xee, 0x1e, 0xd0, 0xf6, 0x83, 0x1b, + 0xe4, 0x4d, 0xb9, 0xe4, 0x32, 0xa1, 0x7a, 0x6b, 0x18, 0x97, 0x5c, 0xec, 0x05, 0x50, 0x2c, 0x3b, + 0x25, 0x74, 0x44, 0x76, 0x70, 0x97, 0xf3, 0x13, 0x42, 0x47, 0x14, 0x61, 0x18, 0x3f, 0x47, 0x6c, + 0x8e, 0xf8, 0xe5, 0x01, 0x03, 0x98, 0x1c, 0xae, 0xec, 0x4d, 0x3f, 0x9d, 0x4d, 0xb4, 0x61, 0xf1, + 0x53, 0xe5, 0xb6, 0xad, 0x37, 0x6e, 0xa0, 0xfd, 0xfa, 0x43, 0x98, 0x8b, 0x77, 0x09, 0xaa, 0x1e, + 0x4b, 0x30, 0xad, 0xc3, 0xa5, 0x16, 0xf2, 0x5c, 0x6a, 0x5d, 0x0f, 0x16, 0xcd, 0x38, 0xbe, 0xf1, + 0x7f, 0x64, 0x60, 0x0c, 0xff, 0x34, 0xbb, 0x4d, 0x34, 0x1e, 0x2c, 0x6d, 0xd7, 0x84, 0x42, 0x44, + 0x15, 0xe6, 0xec, 0x47, 0xbe, 0x25, 0xb4, 0x27, 0xda, 0x1e, 0x13, 0x22, 0x0b, 0x52, 0xfe, 0xaa, + 0x21, 0x55, 0x71, 0x21, 0x29, 0x7f, 0xfe, 0xf0, 0x63, 0xa4, 0x02, 0x19, 0x4d, 0x8e, 0xb7, 0x6b, + 0x6c, 0xfa, 0xa9, 0xd6, 0x3c, 0x48, 0xe7, 0x36, 0x75, 0x93, 0x63, 0x8e, 0x86, 0xc6, 0x3c, 0xdb, + 0xb5, 0x92, 0xb9, 0xae, 0x19, 0xf3, 0xb0, 0x6f, 0xd4, 0xb4, 0x51, 0x02, 0xc9, 0xf8, 0xf9, 0xf1, + 0x78, 0x07, 0x8a, 0x03, 0xef, 0x94, 0x6b, 0xe3, 0x1d, 0x18, 0x2e, 0x35, 0x9b, 0xee, 0x23, 0xb1, + 0x4b, 0xc8, 0xfb, 0x6a, 0xd8, 0x7f, 0xfc, 0x3c, 0x43, 0x65, 0x9e, 0xe6, 0x8a, 0xca, 0x00, 0xa4, + 0x0c, 0x63, 0xa5, 0xed, 0x5a, 0xb5, 0x5a, 0xd9, 0xdc, 0xe4, 0x6e, 0x77, 0xb9, 0xa5, 0x57, 0x64, + 0xff, 0x38, 0x4e, 0xc3, 0x8a, 0x5b, 0x29, 0x44, 0xf2, 0x7b, 0x44, 0x47, 0xde, 0x03, 0xb8, 0xeb, + 0x3a, 0x6d, 0xae, 0xbc, 0x14, 0x8d, 0x67, 0xf7, 0xee, 0xf1, 0x8f, 0x5c, 0xa7, 0x2d, 0xb4, 0x9d, + 0xec, 0xdb, 0x23, 0x24, 0x53, 0xf9, 0x9b, 0xf5, 0xf4, 0x92, 0xcb, 0x0d, 0x02, 0x87, 0xa3, 0x9e, + 0xde, 0x71, 0x13, 0x5a, 0x36, 0x89, 0x46, 0x5a, 0x30, 0x5d, 0xeb, 0xee, 0xed, 0x51, 0xb6, 0xb3, + 0x0b, 0x2d, 0xd2, 0x88, 0xb8, 0x40, 0x87, 0xc1, 0x8e, 0xf8, 0x7d, 0x84, 0x5d, 0x81, 0xfc, 0xa5, + 0x37, 0xd8, 0x44, 0xfe, 0xce, 0x51, 0x51, 0x58, 0x3f, 0x30, 0x51, 0xcd, 0x97, 0xf4, 0x49, 0x1d, + 0x52, 0x9c, 0x37, 0xb9, 0x0f, 0x23, 0xfc, 0xa5, 0x48, 0xb8, 0x91, 0xbd, 0xd8, 0x67, 0xd1, 0x70, + 0xc4, 0x5e, 0x6f, 0x91, 0xbc, 0x94, 0x6c, 0x43, 0xbe, 0xec, 0x78, 0xf5, 0x26, 0x2d, 0x57, 0xc5, + 0xd9, 0xff, 0x52, 0x1f, 0x96, 0x12, 0x95, 0xf7, 0x4b, 0x1d, 0x7f, 0xd5, 0x1d, 0x55, 0x16, 0x90, + 0x18, 0xe4, 0x6f, 0x67, 0xe0, 0xf9, 0xf0, 0xeb, 0x4b, 0x7b, 0xb4, 0x1d, 0xac, 0xd9, 0x41, 0x7d, + 0x9f, 0x7a, 0xa2, 0x97, 0xc6, 0xfa, 0xf5, 0xd2, 0x17, 0x12, 0xbd, 0x74, 0x25, 0xea, 0x25, 0x9b, + 0x31, 0xb3, 0x5a, 0x9c, 0x5b, 0xb2, 0xcf, 0xfa, 0xd5, 0x4a, 0x2c, 0x80, 0xe8, 0x0d, 0x54, 0xb8, + 0x21, 0xbf, 0xd2, 0xa7, 0xc1, 0x11, 0xb2, 0x70, 0x1f, 0x0a, 0x7f, 0x6b, 0xf6, 0xaf, 0x21, 0x94, + 0xdc, 0x93, 0x3e, 0x9b, 0x5c, 0x2a, 0xb9, 0xd4, 0x87, 0x37, 0xf7, 0xe3, 0x9c, 0xed, 0xe3, 0x9d, + 0xcd, 0x47, 0x7b, 0xd5, 0xde, 0x11, 0x82, 0xc8, 0x09, 0xa3, 0xbd, 0x6a, 0x47, 0xa3, 0xdd, 0xb4, + 0xe3, 0xa3, 0xbd, 0x6a, 0xef, 0x90, 0x32, 0x77, 0x34, 0xe7, 0x5e, 0xc9, 0x17, 0xfb, 0x71, 0x2b, + 0x6f, 0xf0, 0x93, 0x39, 0xc5, 0xe1, 0xfc, 0x2b, 0x30, 0x56, 0xeb, 0xd8, 0x75, 0xda, 0x74, 0x76, + 0x03, 0xf1, 0xc0, 0xfe, 0x72, 0x1f, 0x56, 0x21, 0xae, 0x78, 0x50, 0x95, 0x3f, 0xd5, 0x6b, 0x52, + 0x88, 0xc3, 0xbe, 0x70, 0x73, 0x63, 0x4d, 0xbc, 0xb1, 0xf7, 0xfb, 0xc2, 0xcd, 0x8d, 0x35, 0x21, + 0x73, 0x74, 0x5a, 0x9a, 0xcc, 0xb1, 0xb1, 0x46, 0x3a, 0x30, 0xb5, 0x49, 0x3d, 0xcf, 0xde, 0x75, + 0xbd, 0x16, 0xd7, 0x5a, 0x72, 0x4f, 0xb7, 0xab, 0xfd, 0xf8, 0x69, 0x04, 0x5c, 0x59, 0x17, 0x48, + 0x98, 0x15, 0x57, 0x75, 0xc6, 0xf8, 0xb3, 0x3e, 0x59, 0x72, 0x82, 0x9d, 0x6e, 0xfd, 0x80, 0x06, + 0xf3, 0x33, 0x27, 0xf6, 0x49, 0x88, 0xcb, 0xfb, 0x64, 0x47, 0xfe, 0x54, 0xfb, 0x24, 0xc4, 0x31, + 0x7e, 0x33, 0x07, 0xe7, 0x7a, 0x74, 0x01, 0x59, 0x97, 0x5b, 0x6e, 0x46, 0xd3, 0x5d, 0xf7, 0x40, + 0xbf, 0x76, 0xe2, 0x2e, 0xbc, 0x0a, 0x85, 0xe5, 0x7b, 0x28, 0xab, 0xf3, 0xe7, 0x9b, 0x72, 0x49, + 0x1e, 0x56, 0xa8, 0x5f, 0xa5, 0x07, 0x68, 0x19, 0x2c, 0x9f, 0x7d, 0xea, 0x9a, 0x0b, 0x7c, 0x82, + 0x72, 0xe1, 0xfb, 0xb3, 0x30, 0x84, 0x07, 0x67, 0x2c, 0xf0, 0x57, 0xe6, 0x54, 0x81, 0xbf, 0xbe, + 0x08, 0x13, 0xcb, 0xf7, 0xf8, 0x4d, 0x7a, 0xc5, 0xf6, 0xf7, 0xc5, 0xb6, 0x8e, 0xe6, 0x1b, 0xf4, + 0xc0, 0x12, 0x17, 0xef, 0x7d, 0x5b, 0x93, 0x59, 0x35, 0x0a, 0xb2, 0x05, 0xb3, 0xfc, 0xdb, 0x9c, + 0x5d, 0xa7, 0xce, 0xe3, 0x07, 0x39, 0x76, 0x53, 0xec, 0xf1, 0x2f, 0x1d, 0x1f, 0x15, 0x8b, 0xf4, + 0x00, 0x6d, 0x9e, 0x45, 0xb9, 0xe5, 0x23, 0x82, 0x6a, 0xfc, 0x9c, 0x42, 0xaf, 0x06, 0x35, 0x31, + 0xc7, 0xb0, 0x42, 0x56, 0x1b, 0xab, 0x9b, 0xe1, 0x72, 0x24, 0xe3, 0x4f, 0x87, 0x61, 0xa1, 0xf7, + 0xf6, 0x4c, 0xbe, 0xa4, 0x0f, 0xe0, 0xe5, 0x13, 0x37, 0xf4, 0x93, 0xc7, 0xf0, 0xcb, 0x30, 0xb7, + 0xdc, 0x0e, 0xa8, 0xd7, 0xf1, 0x1c, 0x19, 0xc6, 0x66, 0xc5, 0xf5, 0xa5, 0x8d, 0x39, 0x1a, 0x7b, + 0xd3, 0xb0, 0x5c, 0x68, 0x54, 0xd1, 0xe2, 0x5d, 0x61, 0x95, 0xca, 0x81, 0x2c, 0xc3, 0x94, 0x02, + 0x6f, 0x76, 0xf7, 0xd4, 0x37, 0x29, 0x95, 0x67, 0xb3, 0xab, 0x1a, 0xe0, 0xc6, 0x88, 0xd0, 0x8e, + 0x9d, 0x5d, 0x19, 0xeb, 0x77, 0xb7, 0xef, 0xd5, 0xc4, 0x70, 0x72, 0x3b, 0x76, 0x84, 0x5a, 0x1f, + 0x3d, 0x3a, 0xd0, 0xf6, 0xd7, 0x08, 0x79, 0xe1, 0x97, 0x72, 0x62, 0x46, 0xbd, 0x04, 0xb9, 0x5a, + 0x77, 0x47, 0x7d, 0x69, 0xf3, 0xb5, 0x03, 0x8e, 0x95, 0x92, 0xcf, 0x03, 0x98, 0xb4, 0xe3, 0xfa, + 0x4e, 0xe0, 0x7a, 0x87, 0xaa, 0x23, 0xa5, 0x17, 0x42, 0x75, 0x5f, 0x0f, 0x09, 0x25, 0x2b, 0x30, + 0x1d, 0xfd, 0xba, 0xff, 0xa8, 0x2d, 0x34, 0xc8, 0x63, 0x5c, 0xbb, 0x12, 0x91, 0x5b, 0x2e, 0x2b, + 0x53, 0x8f, 0xec, 0x18, 0x19, 0x59, 0x84, 0xfc, 0xb6, 0xeb, 0x1d, 0xec, 0xb2, 0x31, 0x1e, 0x8a, + 0x84, 0x8a, 0x47, 0x02, 0xa6, 0x1e, 0x9e, 0x12, 0x8f, 0x2d, 0x97, 0xe5, 0xf6, 0x43, 0xc7, 0x73, + 0xf1, 0x1d, 0x4f, 0xb5, 0x64, 0xa1, 0x11, 0x58, 0x73, 0x61, 0x8f, 0xc0, 0xe4, 0x2a, 0x0c, 0x97, + 0xea, 0x81, 0xeb, 0x09, 0x33, 0x16, 0x3e, 0x53, 0x18, 0x40, 0x9b, 0x29, 0x0c, 0xc0, 0x3a, 0xd1, + 0xa4, 0xbb, 0xe2, 0x4d, 0x07, 0x3b, 0xd1, 0xa3, 0xbb, 0x9a, 0x7f, 0x3e, 0xdd, 0x65, 0x42, 0x91, + 0x49, 0x77, 0x51, 0xf1, 0xa1, 0x85, 0xb5, 0xdb, 0x4d, 0xa8, 0xcc, 0x04, 0x9a, 0xf1, 0x7b, 0x63, + 0x3d, 0xa7, 0x3c, 0x3b, 0x85, 0x4e, 0x37, 0xe5, 0x57, 0xed, 0x01, 0xa6, 0xfc, 0x1b, 0xa1, 0x07, + 0x89, 0x1a, 0x94, 0x02, 0x21, 0xea, 0x31, 0xc8, 0x71, 0x16, 0x7e, 0x39, 0x7f, 0x9a, 0x49, 0x24, + 0x3a, 0x29, 0x3b, 0x68, 0x27, 0xe5, 0x06, 0xea, 0x24, 0xb2, 0x04, 0x93, 0x61, 0x60, 0xc4, 0x0d, + 0x3b, 0xd0, 0xb6, 0xb5, 0x30, 0x9a, 0xa5, 0xd5, 0xb1, 0x03, 0x75, 0x5b, 0xd3, 0x49, 0xc8, 0xbb, + 0x30, 0x2e, 0xdc, 0xa8, 0x90, 0xc3, 0x70, 0x64, 0x1f, 0x24, 0x7d, 0xae, 0x62, 0xf4, 0x2a, 0x3a, + 0x5b, 0xcd, 0x1b, 0x4e, 0x87, 0x36, 0x9d, 0x36, 0xad, 0xe1, 0x13, 0x85, 0x98, 0x31, 0xfc, 0xa9, + 0x56, 0x94, 0x58, 0xfc, 0xf5, 0x42, 0xd3, 0x1f, 0x6a, 0x44, 0xf1, 0xc9, 0x3a, 0x7a, 0xaa, 0xc9, + 0xca, 0xad, 0x13, 0xbd, 0x55, 0x77, 0xcf, 0x91, 0x96, 0xf3, 0xd2, 0x3a, 0xd1, 0xb3, 0x9a, 0x0c, + 0x1a, 0xb3, 0x4e, 0xe4, 0xa8, 0xec, 0x86, 0xc3, 0x7e, 0x54, 0x2b, 0xe2, 0xfd, 0x10, 0x6f, 0x38, + 0x48, 0xa4, 0xbb, 0x2b, 0x70, 0x24, 0x59, 0xcd, 0x72, 0xcb, 0x76, 0x9a, 0x22, 0xf6, 0x40, 0x54, + 0x0d, 0x65, 0xd0, 0x78, 0x35, 0x88, 0x4a, 0xea, 0x30, 0x61, 0xd2, 0xdd, 0x0d, 0xcf, 0x0d, 0x68, + 0x3d, 0xa0, 0x0d, 0x21, 0xd5, 0xc9, 0x8b, 0xcd, 0x92, 0xeb, 0x72, 0x89, 0x15, 0x2d, 0xe2, 0x33, + 0xdf, 0x39, 0x2a, 0x02, 0x03, 0x71, 0x5f, 0x98, 0xe3, 0xa3, 0xe2, 0x39, 0x36, 0xfe, 0x1d, 0x49, + 0xac, 0x9e, 0x4e, 0x2a, 0x53, 0xf2, 0x2d, 0xb6, 0x5f, 0x87, 0x5d, 0x12, 0x55, 0x36, 0xd1, 0xa3, + 0xb2, 0xb7, 0x52, 0x2b, 0x2b, 0x2a, 0xbd, 0x9d, 0x5a, 0x69, 0x6a, 0x25, 0xe4, 0x3d, 0x18, 0x2f, + 0x57, 0xcb, 0x6e, 0x7b, 0xd7, 0xd9, 0xab, 0xad, 0x94, 0x50, 0x34, 0x14, 0x7e, 0x50, 0x75, 0xc7, + 0xaa, 0x23, 0xdc, 0xf2, 0xf7, 0x6d, 0xcd, 0x1d, 0x36, 0xc2, 0x27, 0x77, 0x60, 0x4a, 0xfe, 0x34, + 0xe9, 0xee, 0x96, 0x59, 0x45, 0x89, 0x50, 0x3a, 0x9f, 0x85, 0x1c, 0x58, 0x47, 0x74, 0x3d, 0xf5, + 0xa6, 0x10, 0x23, 0x63, 0x93, 0xb1, 0x42, 0x3b, 0x4d, 0xf7, 0x90, 0x7d, 0xde, 0xa6, 0x43, 0x3d, + 0x94, 0x01, 0xc5, 0x64, 0x6c, 0x84, 0x25, 0x56, 0xe0, 0xe8, 0xaf, 0xa6, 0x3a, 0x11, 0x59, 0x87, + 0x19, 0x31, 0xc5, 0x1f, 0x38, 0xbe, 0xb3, 0xe3, 0x34, 0x9d, 0xe0, 0x10, 0xa5, 0x3f, 0x21, 0xc0, + 0xc8, 0x75, 0xf1, 0x30, 0x2c, 0x55, 0x98, 0x25, 0x49, 0x8d, 0x5f, 0xcb, 0xc2, 0x0b, 0xfd, 0x6e, + 0x42, 0xa4, 0xa6, 0x6f, 0x66, 0x57, 0x06, 0xb8, 0x3d, 0x9d, 0xbc, 0x9d, 0x2d, 0xc3, 0xd4, 0x7d, + 0xc5, 0x90, 0x2f, 0x34, 0xac, 0xc4, 0xce, 0x50, 0x4d, 0xfc, 0xf4, 0xd9, 0x1e, 0x23, 0x5a, 0x78, + 0x28, 0xb6, 0xb9, 0x8f, 0xeb, 0x98, 0x79, 0x0b, 0xc6, 0xca, 0x6e, 0x3b, 0xa0, 0x8f, 0x83, 0x58, + 0x18, 0x02, 0x0e, 0x8c, 0x3b, 0xa5, 0x4a, 0x54, 0xe3, 0x5f, 0x67, 0xe1, 0x42, 0xdf, 0xab, 0x00, + 0xd9, 0xd4, 0x7b, 0xed, 0xea, 0x20, 0xf7, 0x87, 0x93, 0xbb, 0x6d, 0x31, 0x61, 0x6d, 0x77, 0xa2, + 0xdf, 0xd3, 0xc2, 0xff, 0x98, 0x11, 0x9d, 0xf4, 0x19, 0x18, 0xc5, 0xaa, 0xc2, 0x2e, 0xe2, 0x5a, + 0x32, 0xdc, 0x85, 0x1d, 0x5d, 0x4b, 0xc6, 0xd1, 0xc8, 0x4d, 0xc8, 0x97, 0xed, 0x66, 0x53, 0x09, + 0xd2, 0x80, 0xd2, 0x7c, 0x1d, 0x61, 0x31, 0x93, 0x51, 0x89, 0xc8, 0x64, 0x1f, 0xfe, 0xb7, 0x72, + 0x56, 0xe0, 0x66, 0x29, 0xc8, 0x62, 0xc7, 0x85, 0x82, 0x8c, 0xa1, 0x5d, 0xeb, 0x6e, 0xe8, 0x06, + 0xce, 0x43, 0xbb, 0x32, 0x80, 0x16, 0xda, 0x95, 0x01, 0x8c, 0x5f, 0xcf, 0xc1, 0xc5, 0xfe, 0xf7, + 0x59, 0xb2, 0xa5, 0x0f, 0xc1, 0x6b, 0x03, 0xdd, 0x82, 0x4f, 0x1e, 0x03, 0x19, 0x28, 0x99, 0x77, + 0xc8, 0x95, 0xa4, 0xd3, 0xcb, 0x77, 0x8f, 0x8a, 0x8a, 0x1d, 0xf2, 0x5d, 0xd7, 0x69, 0x2b, 0x6f, + 0x26, 0xdf, 0xd4, 0x24, 0x43, 0xfe, 0x66, 0x7f, 0x6b, 0xb0, 0x2f, 0x8b, 0xe8, 0xf8, 0xbe, 0x32, + 0xa8, 0x44, 0xf9, 0x05, 0x28, 0xc4, 0x49, 0xc9, 0x65, 0x18, 0xc2, 0x0f, 0x50, 0x3c, 0x77, 0x62, + 0x1c, 0xb0, 0x7c, 0x61, 0x4d, 0xcc, 0x1d, 0x8c, 0x5b, 0x81, 0x56, 0x00, 0xba, 0x6e, 0x50, 0xc4, + 0xad, 0xe0, 0x46, 0x04, 0x49, 0xfd, 0x60, 0x8c, 0xc8, 0xf8, 0xf3, 0x0c, 0x9c, 0xef, 0xa9, 0x29, + 0x20, 0x1b, 0xfa, 0x80, 0xbd, 0x72, 0x92, 0x6a, 0xe1, 0xc4, 0xb1, 0x5a, 0xf8, 0x71, 0x39, 0xf7, + 0xdf, 0x87, 0x89, 0x5a, 0x77, 0x27, 0x7e, 0x3f, 0xe3, 0x51, 0x65, 0x14, 0xb8, 0x7a, 0x82, 0xa9, + 0xf8, 0xac, 0xfd, 0xd2, 0xcc, 0x41, 0x98, 0xfd, 0x28, 0xb6, 0x86, 0xa1, 0x63, 0x75, 0x32, 0x6e, + 0x87, 0x4e, 0x64, 0xfc, 0x6a, 0x36, 0xfd, 0xa2, 0x7b, 0xa7, 0xbc, 0x71, 0x9a, 0x8b, 0xee, 0x9d, + 0xf2, 0xc6, 0xc9, 0x6d, 0xff, 0xc7, 0xb2, 0xed, 0xf8, 0x30, 0x2b, 0x76, 0x3c, 0xa9, 0xe8, 0x14, + 0x0f, 0xb3, 0x72, 0x77, 0xf4, 0xf5, 0x87, 0x59, 0x89, 0x4c, 0xde, 0x82, 0xb1, 0x55, 0x97, 0x87, + 0xd4, 0x90, 0x2d, 0xe6, 0x9e, 0xc7, 0x12, 0xa8, 0x6e, 0x8f, 0x21, 0x26, 0xbb, 0x5b, 0xe8, 0x03, + 0x2f, 0x4d, 0x2a, 0xf1, 0x6e, 0x11, 0x9b, 0x2e, 0xba, 0x3a, 0x50, 0x27, 0x33, 0xfe, 0x93, 0x61, + 0x30, 0x4e, 0x56, 0x66, 0x90, 0x0f, 0xf5, 0xbe, 0xbb, 0x36, 0xb0, 0x1a, 0x64, 0xa0, 0x2d, 0xb7, + 0xd4, 0x6d, 0x38, 0xb4, 0x5d, 0xd7, 0xe3, 0x61, 0x08, 0x98, 0xba, 0x05, 0x4a, 0xbc, 0x8f, 0xe3, + 0x9e, 0xba, 0xf0, 0xdf, 0xe6, 0xa2, 0xa5, 0x16, 0x3b, 0x1a, 0x33, 0x1f, 0xe3, 0x68, 0x24, 0xf7, + 0xa0, 0xa0, 0x42, 0x94, 0x17, 0x5a, 0x94, 0x5c, 0x34, 0x46, 0xb1, 0x8f, 0x4a, 0x10, 0xea, 0xe7, + 0x6b, 0x6e, 0xf0, 0xf3, 0x35, 0x12, 0xdf, 0xb1, 0xfe, 0xa1, 0xa4, 0xf8, 0x1e, 0x77, 0x41, 0x57, + 0xd0, 0x65, 0xfc, 0x0c, 0x5f, 0x1c, 0x5a, 0xc3, 0x7a, 0xfc, 0x8c, 0x94, 0x83, 0x4b, 0x45, 0x97, + 0x21, 0x40, 0xf0, 0xa7, 0xe2, 0x01, 0x1f, 0x86, 0x00, 0xe1, 0xf4, 0x69, 0x21, 0x40, 0x42, 0x12, + 0x76, 0x00, 0x9a, 0xdd, 0x36, 0x8f, 0x21, 0x3e, 0x1a, 0x1d, 0x80, 0x5e, 0xb7, 0x6d, 0xc5, 0xe3, + 0x88, 0x87, 0x88, 0xc6, 0x3f, 0x1a, 0x4a, 0x17, 0x0e, 0x42, 0x7d, 0xd7, 0x69, 0x84, 0x83, 0x90, + 0xe8, 0x93, 0x99, 0xa9, 0x5b, 0x30, 0x2b, 0xad, 0xf2, 0xa4, 0x79, 0xd7, 0x96, 0xb9, 0x2a, 0x86, + 0x18, 0xf5, 0x46, 0xa1, 0x3d, 0x9f, 0x34, 0x11, 0xb3, 0xba, 0x9e, 0xa6, 0x37, 0x4a, 0xa1, 0x5f, + 0xf8, 0x0d, 0xa9, 0x16, 0x53, 0x07, 0x61, 0x6b, 0x2b, 0x9c, 0xcb, 0xb1, 0x41, 0xe8, 0x76, 0xb5, + 0x61, 0xd4, 0x49, 0xf8, 0xde, 0x2b, 0x55, 0x0e, 0xc8, 0x44, 0x91, 0x15, 0x15, 0x45, 0x45, 0x8c, + 0x4b, 0x8c, 0x88, 0xec, 0xc1, 0xf9, 0x48, 0x94, 0x56, 0x6e, 0x0a, 0xc8, 0x91, 0x37, 0xf8, 0xea, + 0xf1, 0x51, 0xf1, 0x15, 0x45, 0x14, 0x57, 0x2f, 0x1c, 0x31, 0xee, 0xbd, 0x79, 0xb1, 0xfd, 0x76, + 0xc9, 0xb3, 0xdb, 0xf5, 0x7d, 0x65, 0xce, 0xe3, 0x7e, 0xbb, 0x83, 0xd0, 0x44, 0x10, 0x83, 0x08, + 0xd9, 0xf8, 0xf1, 0x2c, 0x4c, 0xf1, 0xb3, 0x9a, 0xbf, 0xce, 0x3d, 0xb3, 0x2f, 0x9f, 0xef, 0x68, + 0x2f, 0x9f, 0x32, 0xde, 0x9e, 0xda, 0xb4, 0x81, 0xde, 0x3d, 0xf7, 0x81, 0x24, 0x69, 0x88, 0x09, + 0x13, 0x2a, 0xb4, 0xff, 0x93, 0xe7, 0x8d, 0x28, 0x34, 0xa3, 0x10, 0x95, 0xf0, 0xdd, 0xd9, 0x37, + 0x35, 0x1e, 0xc6, 0x8f, 0x65, 0x61, 0x52, 0xb1, 0x53, 0x79, 0x66, 0x3b, 0xfe, 0x0b, 0x5a, 0xc7, + 0xcf, 0x87, 0x7e, 0x81, 0x61, 0xcb, 0x06, 0xea, 0xf7, 0x2e, 0xcc, 0x24, 0x48, 0xe2, 0xe6, 0x3e, + 0x99, 0x41, 0xcc, 0x7d, 0xde, 0x48, 0xc6, 0x79, 0xe3, 0xe9, 0x12, 0xc2, 0xa8, 0x3f, 0x6a, 0x60, + 0xb9, 0x9f, 0xcc, 0xc2, 0x9c, 0xf8, 0x85, 0x81, 0x51, 0xb9, 0xb0, 0xfa, 0xcc, 0x8e, 0x45, 0x49, + 0x1b, 0x8b, 0xa2, 0x3e, 0x16, 0x4a, 0x03, 0x7b, 0x0f, 0x89, 0xf1, 0x43, 0x00, 0xf3, 0xbd, 0x08, + 0x06, 0x76, 0xbf, 0x8f, 0x1c, 0x12, 0xb3, 0x03, 0x38, 0x24, 0xae, 0x42, 0x01, 0xab, 0x12, 0xa1, + 0x0f, 0xfd, 0x2d, 0xb3, 0x2a, 0x3a, 0x09, 0xf5, 0x0b, 0x3c, 0x7a, 0xad, 0x08, 0xc5, 0xe8, 0xc7, + 0x74, 0x1e, 0x09, 0x4a, 0xf2, 0x4b, 0x19, 0x98, 0x42, 0xe0, 0xf2, 0x43, 0xda, 0x0e, 0x90, 0xd9, + 0x90, 0xf0, 0x54, 0x0b, 0x1f, 0x46, 0x6b, 0x81, 0xe7, 0xb4, 0xf7, 0xc4, 0xcb, 0xe8, 0x8e, 0x78, + 0x19, 0x7d, 0x97, 0xbf, 0xe8, 0x5e, 0xab, 0xbb, 0xad, 0xeb, 0x7b, 0x9e, 0xfd, 0xd0, 0xe1, 0x26, + 0x58, 0x76, 0xf3, 0x7a, 0x94, 0xe5, 0xa7, 0xe3, 0xc4, 0xf2, 0xef, 0x08, 0x56, 0xf8, 0xea, 0xcc, + 0x3f, 0x94, 0x62, 0xb5, 0x71, 0xd5, 0x8c, 0xfe, 0x45, 0xe4, 0x7b, 0xe0, 0x1c, 0x0f, 0x48, 0xc6, + 0x6e, 0xf8, 0x4e, 0xbb, 0xeb, 0x76, 0xfd, 0x25, 0xbb, 0x7e, 0xc0, 0xc4, 0x7c, 0xee, 0x4f, 0x8c, + 0x2d, 0xaf, 0x87, 0x85, 0xd6, 0x0e, 0x2f, 0xd5, 0x22, 0x5d, 0xa4, 0x33, 0x20, 0x2b, 0x30, 0xc3, + 0x8b, 0x4a, 0xdd, 0xc0, 0xad, 0xd5, 0xed, 0xa6, 0xd3, 0xde, 0x43, 0x59, 0x22, 0xcf, 0x45, 0x19, + 0xbb, 0x1b, 0xb8, 0x96, 0xcf, 0xe1, 0xaa, 0xa6, 0x26, 0x41, 0x44, 0xaa, 0x30, 0x6d, 0x52, 0xbb, + 0xb1, 0x66, 0x3f, 0x2e, 0xdb, 0x1d, 0xbb, 0xee, 0x04, 0x3c, 0x42, 0x6a, 0x8e, 0x0b, 0x74, 0x1e, + 0xb5, 0x1b, 0x56, 0xcb, 0x7e, 0x6c, 0xd5, 0x45, 0xa1, 0xae, 0xb2, 0xd7, 0xe8, 0x42, 0x56, 0x4e, + 0x3b, 0x64, 0x35, 0x16, 0x67, 0xe5, 0xb4, 0x7b, 0xb3, 0x8a, 0xe8, 0x24, 0xab, 0x4d, 0xdb, 0xdb, + 0xa3, 0x01, 0x37, 0x8f, 0x86, 0x4b, 0x99, 0x2b, 0x19, 0x85, 0x55, 0x80, 0x65, 0x16, 0x9a, 0x4a, + 0xc7, 0x59, 0x29, 0x74, 0x6c, 0xe6, 0x6d, 0x7b, 0x4e, 0x40, 0xd5, 0x16, 0x8e, 0xe3, 0x67, 0x61, + 0xff, 0xa3, 0x61, 0x79, 0xaf, 0x26, 0x26, 0x28, 0x23, 0x6e, 0x4a, 0x23, 0x27, 0x12, 0xdc, 0xd2, + 0x5b, 0x99, 0xa0, 0x0c, 0xb9, 0xa9, 0xed, 0x9c, 0xc4, 0x76, 0x2a, 0xdc, 0x7a, 0x34, 0x34, 0x41, + 0x49, 0xd6, 0x59, 0xa7, 0x05, 0x4c, 0x6e, 0x72, 0xdb, 0xc2, 0x82, 0x7b, 0x0a, 0x3f, 0xed, 0x65, + 0x61, 0x86, 0x58, 0xf0, 0x64, 0xb1, 0x95, 0x62, 0xcf, 0x1d, 0x27, 0x26, 0x7f, 0x0d, 0xa6, 0xb7, + 0x7c, 0x7a, 0xbb, 0xba, 0x51, 0x93, 0xf1, 0xcb, 0x50, 0xb9, 0x38, 0xb5, 0x78, 0xe3, 0x84, 0x4d, + 0xe7, 0x9a, 0x4a, 0x83, 0x49, 0x73, 0xf8, 0xb8, 0x75, 0x7d, 0x6a, 0xed, 0x3a, 0x1d, 0x3f, 0x0c, + 0x06, 0xa9, 0x8e, 0x5b, 0xac, 0x2a, 0x63, 0x05, 0x66, 0x12, 0x6c, 0xc8, 0x14, 0x00, 0x03, 0x5a, + 0x5b, 0xeb, 0xb5, 0xe5, 0xcd, 0xc2, 0x73, 0xa4, 0x00, 0x13, 0xf8, 0x7b, 0x79, 0xbd, 0xb4, 0xb4, + 0xba, 0x5c, 0x29, 0x64, 0xc8, 0x0c, 0x4c, 0x22, 0xa4, 0x52, 0xad, 0x71, 0x50, 0x96, 0xa7, 0x4c, + 0x30, 0x0b, 0x7c, 0xe9, 0x06, 0x6c, 0x01, 0xe0, 0x99, 0x62, 0xfc, 0xdd, 0x2c, 0x9c, 0x97, 0xc7, + 0x0a, 0x0d, 0x98, 0xe0, 0xe8, 0xb4, 0xf7, 0x9e, 0xf1, 0xd3, 0xe1, 0xb6, 0x76, 0x3a, 0xbc, 0x1c, + 0x3b, 0xa9, 0x63, 0xad, 0xec, 0x73, 0x44, 0xfc, 0xf6, 0x18, 0x5c, 0xe8, 0x4b, 0x45, 0xbe, 0xc4, + 0x4e, 0x73, 0x87, 0xb6, 0x83, 0x6a, 0xa3, 0x49, 0x37, 0x9d, 0x16, 0x75, 0xbb, 0x81, 0xf0, 0x18, + 0x78, 0x09, 0xf5, 0x79, 0x58, 0x68, 0x39, 0x8d, 0x26, 0xb5, 0x02, 0x5e, 0xac, 0x4d, 0xb7, 0x24, + 0x35, 0x63, 0x19, 0x26, 0xf0, 0xaa, 0xb6, 0x03, 0xea, 0x3d, 0x44, 0xab, 0xc4, 0x90, 0xe5, 0x01, + 0xa5, 0x1d, 0xcb, 0x66, 0xa5, 0x96, 0x23, 0x8a, 0x75, 0x96, 0x09, 0x6a, 0x72, 0x5b, 0x61, 0x59, + 0x66, 0xb7, 0xff, 0x35, 0xfb, 0xb1, 0x30, 0x93, 0x12, 0xf1, 0x70, 0x43, 0x96, 0xdc, 0x89, 0xaf, + 0x65, 0x3f, 0x36, 0x93, 0x24, 0xe4, 0x6b, 0x70, 0x46, 0x1c, 0x40, 0x22, 0x64, 0x8b, 0x6c, 0x31, + 0x0f, 0x08, 0xf3, 0xea, 0xf1, 0x51, 0xf1, 0x9c, 0x8c, 0x24, 0x2c, 0xc3, 0x29, 0xa5, 0xb5, 0x3a, + 0x9d, 0x0b, 0xd9, 0x64, 0x07, 0x72, 0xac, 0x3b, 0xd6, 0xa8, 0xef, 0x4b, 0x4f, 0x4d, 0x71, 0x33, + 0x56, 0x3b, 0xd3, 0x6a, 0xf1, 0x72, 0xb3, 0x27, 0x25, 0x59, 0x81, 0xa9, 0x6d, 0xba, 0xa3, 0x8e, + 0xcf, 0x48, 0xb8, 0x55, 0x15, 0x1e, 0xd1, 0x9d, 0xde, 0x83, 0x13, 0xa3, 0x23, 0x0e, 0xbe, 0x0f, + 0x3c, 0x3e, 0x5c, 0x75, 0xfc, 0x80, 0xb6, 0xa9, 0x87, 0x41, 0xdb, 0x46, 0x71, 0x33, 0x98, 0x8f, + 0x24, 0x64, 0xbd, 0x7c, 0xe9, 0xc5, 0xe3, 0xa3, 0xe2, 0x05, 0xee, 0xf2, 0xdc, 0x14, 0x70, 0x2b, + 0x96, 0xfe, 0x2a, 0xc9, 0x95, 0x7c, 0x03, 0xa6, 0x4d, 0xb7, 0x1b, 0x38, 0xed, 0xbd, 0x5a, 0xe0, + 0xd9, 0x01, 0xdd, 0xe3, 0x07, 0x52, 0x14, 0x1d, 0x2e, 0x56, 0x2a, 0x9e, 0x96, 0x39, 0xd0, 0xf2, + 0x05, 0x54, 0x3b, 0x11, 0x74, 0x02, 0xf2, 0x75, 0x98, 0xe2, 0xc1, 0x3a, 0xc2, 0x0a, 0xc6, 0xb4, + 0xd4, 0x1d, 0x7a, 0xe1, 0x83, 0x1b, 0xc2, 0xaa, 0x05, 0xa1, 0x69, 0x15, 0xc4, 0xb8, 0x91, 0xaf, + 0x88, 0xce, 0xda, 0x70, 0xda, 0x7b, 0xe1, 0x34, 0x06, 0xec, 0xf9, 0x37, 0xa3, 0x2e, 0xe9, 0xb0, + 0xcf, 0x95, 0xd3, 0xb8, 0x87, 0x89, 0x5e, 0x92, 0x0f, 0x09, 0xe0, 0x42, 0xc9, 0xf7, 0x1d, 0x3f, + 0x10, 0x7e, 0x35, 0xcb, 0x8f, 0x69, 0xbd, 0xcb, 0x90, 0xd9, 0xf5, 0x96, 0x7a, 0xdc, 0xae, 0x7b, + 0x78, 0xe9, 0xda, 0xf1, 0x51, 0xf1, 0x35, 0x1b, 0x11, 0x2d, 0xe1, 0x8a, 0x63, 0x51, 0x89, 0x6a, + 0x3d, 0xe2, 0xb8, 0x4a, 0x1b, 0xfa, 0x33, 0x25, 0x5f, 0x87, 0xb3, 0x65, 0xdb, 0xa7, 0xd5, 0xb6, + 0x4f, 0xdb, 0xbe, 0x13, 0x38, 0x0f, 0xa9, 0xe8, 0x54, 0x3c, 0xfc, 0xf2, 0x98, 0x28, 0xcc, 0xa8, + 0xdb, 0x3e, 0x5b, 0x98, 0x21, 0x8a, 0x25, 0x06, 0x45, 0xa9, 0xa6, 0x07, 0x17, 0x62, 0xc2, 0x54, + 0xad, 0xb6, 0x52, 0x71, 0xec, 0x70, 0x5d, 0x4d, 0x62, 0x7f, 0xbd, 0x86, 0xaa, 0x3d, 0x7f, 0xdf, + 0x6a, 0x38, 0x76, 0xb8, 0xa0, 0x7a, 0x74, 0x56, 0x8c, 0x83, 0x71, 0x94, 0x81, 0x42, 0x7c, 0x28, + 0xc9, 0x97, 0x61, 0x8c, 0xdb, 0xb7, 0x51, 0x7f, 0x5f, 0xc4, 0x9b, 0x90, 0xe6, 0x52, 0x21, 0x5c, + 0x27, 0x12, 0x4e, 0x74, 0xdc, 0x7a, 0x8e, 0xaa, 0xd6, 0x32, 0xe8, 0x44, 0x27, 0x89, 0x48, 0x03, + 0x26, 0xf8, 0x68, 0x51, 0x0c, 0x0d, 0x29, 0xcc, 0x9c, 0x5f, 0x54, 0x57, 0x87, 0x28, 0x8a, 0xf1, + 0xc7, 0x57, 0x43, 0x31, 0x27, 0x38, 0x82, 0x56, 0x85, 0xc6, 0x75, 0x09, 0x20, 0x2f, 0x09, 0x8d, + 0xf3, 0x70, 0xae, 0xc7, 0x37, 0x1b, 0x0f, 0xd1, 0x92, 0xa0, 0x47, 0x8d, 0xe4, 0xcb, 0x30, 0x87, + 0x84, 0x65, 0xb7, 0xdd, 0xa6, 0xf5, 0x00, 0xb7, 0x23, 0xa9, 0x7d, 0xcf, 0x71, 0x4b, 0x17, 0xde, + 0xde, 0x7a, 0x88, 0x60, 0xc5, 0x95, 0xf0, 0xa9, 0x1c, 0x8c, 0x9f, 0xcb, 0xc2, 0xbc, 0xd8, 0xe1, + 0x4c, 0x5a, 0x77, 0xbd, 0xc6, 0xb3, 0x7f, 0xa2, 0x2e, 0x6b, 0x27, 0xea, 0x4b, 0x61, 0xb0, 0xa2, + 0xb4, 0x46, 0xf6, 0x39, 0x50, 0x7f, 0x35, 0x03, 0x2f, 0xf4, 0x23, 0x62, 0xbd, 0x13, 0x86, 0xc2, + 0x1c, 0x4b, 0x84, 0xbc, 0xec, 0xc0, 0x2c, 0x0e, 0x68, 0x79, 0x9f, 0xd6, 0x0f, 0xfc, 0x15, 0xd7, + 0x0f, 0xd0, 0xd3, 0x22, 0xdb, 0xe3, 0xad, 0xfb, 0x8d, 0xd4, 0xb7, 0xee, 0xb3, 0x7c, 0x96, 0xd5, + 0x91, 0x07, 0x0f, 0xd6, 0x79, 0x40, 0x0f, 0x7d, 0x33, 0x8d, 0x35, 0x5a, 0xcc, 0x97, 0xba, 0xc1, + 0xfe, 0x86, 0x47, 0x77, 0xa9, 0x47, 0xdb, 0x75, 0xfa, 0x29, 0xb3, 0x98, 0xd7, 0x1b, 0x37, 0x90, + 0x06, 0xe3, 0x1f, 0x4f, 0xc2, 0x5c, 0x1a, 0x19, 0xeb, 0x17, 0xe5, 0xd2, 0x1c, 0xcf, 0x63, 0xfa, + 0x83, 0x19, 0x98, 0xa8, 0xd1, 0xba, 0xdb, 0x6e, 0xdc, 0x46, 0x8b, 0x22, 0xd1, 0x3b, 0x16, 0x17, + 0x1a, 0x18, 0xdc, 0xda, 0x8d, 0x99, 0x1a, 0x7d, 0xf7, 0xa8, 0xf8, 0xc5, 0xc1, 0xee, 0xaa, 0x75, + 0x17, 0x83, 0x04, 0x05, 0x98, 0x67, 0x23, 0xac, 0x02, 0x1f, 0x07, 0xb5, 0x4a, 0xc9, 0x12, 0x4c, + 0x8a, 0xe5, 0xea, 0xaa, 0x91, 0x50, 0x79, 0x3c, 0x27, 0x59, 0x90, 0x50, 0x5d, 0x6b, 0x24, 0xe4, + 0x26, 0xe4, 0xb6, 0x16, 0x6f, 0x8b, 0x31, 0x90, 0x99, 0x4a, 0xb6, 0x16, 0x6f, 0xa3, 0x3a, 0x8c, + 0x5d, 0x31, 0x26, 0xbb, 0x8b, 0x9a, 0x91, 0xcf, 0xd6, 0xe2, 0x6d, 0xf2, 0x37, 0xe0, 0x4c, 0xc5, + 0xf1, 0x45, 0x15, 0xdc, 0x77, 0xa3, 0x81, 0x1e, 0x8b, 0x23, 0x3d, 0x66, 0xef, 0xe7, 0x52, 0x67, + 0xef, 0x8b, 0x8d, 0x90, 0x89, 0xc5, 0x1d, 0x43, 0x1a, 0xf1, 0x88, 0xaf, 0xe9, 0xf5, 0x90, 0x8f, + 0x60, 0x0a, 0x95, 0xd9, 0xe8, 0xce, 0x82, 0xb1, 0xfa, 0x47, 0x7b, 0xd4, 0xfc, 0x99, 0xd4, 0x9a, + 0x17, 0x78, 0x94, 0x0d, 0x74, 0x8a, 0xc1, 0xb8, 0xfe, 0xda, 0xad, 0x5f, 0xe3, 0x4c, 0xee, 0xc2, + 0xb4, 0x10, 0xbf, 0xee, 0xef, 0x6e, 0xee, 0xd3, 0x8a, 0x7d, 0x28, 0xec, 0x73, 0xf0, 0x46, 0x27, + 0x64, 0x36, 0xcb, 0xdd, 0xb5, 0x82, 0x7d, 0x6a, 0x35, 0x6c, 0x4d, 0x50, 0x89, 0x11, 0x92, 0x6f, + 0xc1, 0xf8, 0xaa, 0x5b, 0x67, 0x92, 0x37, 0xee, 0x0c, 0xdc, 0x64, 0xe7, 0x43, 0xcc, 0x94, 0xc9, + 0xc1, 0x31, 0x71, 0xea, 0xbb, 0x47, 0xc5, 0x77, 0x4e, 0x3b, 0x69, 0x94, 0x0a, 0x4c, 0xb5, 0x36, + 0x52, 0x86, 0xfc, 0x36, 0xdd, 0x61, 0xad, 0x8d, 0x67, 0xd1, 0x93, 0x60, 0x61, 0x91, 0x27, 0x7e, + 0x69, 0x16, 0x79, 0x02, 0x46, 0x3c, 0x98, 0xc1, 0xfe, 0xd9, 0xb0, 0x7d, 0xff, 0x91, 0xeb, 0x35, + 0x30, 0x5d, 0x4a, 0x2f, 0x6b, 0xa0, 0xc5, 0xd4, 0xce, 0x7f, 0x81, 0x77, 0x7e, 0x47, 0xe1, 0xa0, + 0x0a, 0x90, 0x09, 0xf6, 0xe4, 0x1b, 0x30, 0x25, 0x22, 0x16, 0xac, 0xdd, 0x2e, 0xe1, 0xaa, 0x9c, + 0xd0, 0xfc, 0x3e, 0xf5, 0x42, 0x2e, 0xa5, 0x8a, 0x00, 0x08, 0x52, 0x03, 0x65, 0xb5, 0x76, 0x6d, + 0x5d, 0xe9, 0xaf, 0x92, 0x90, 0x0d, 0x18, 0xaf, 0x60, 0x2e, 0x67, 0xf4, 0x4d, 0x13, 0x76, 0xe1, + 0x61, 0x1a, 0xb0, 0xa8, 0x84, 0xeb, 0x62, 0x44, 0xda, 0x67, 0xf4, 0x74, 0xd3, 0x6d, 0x75, 0x43, + 0x44, 0x72, 0x0b, 0x72, 0xd5, 0xca, 0x86, 0x30, 0x0b, 0x9f, 0x09, 0xe3, 0x82, 0x6c, 0xc8, 0xa4, + 0x49, 0x68, 0x3f, 0xe7, 0x34, 0x34, 0xa3, 0xf2, 0x6a, 0x65, 0x83, 0xec, 0xc2, 0x24, 0x76, 0xc0, + 0x0a, 0xb5, 0x79, 0xdf, 0x4e, 0xf7, 0xe8, 0xdb, 0x6b, 0xa9, 0x7d, 0x3b, 0xcf, 0xfb, 0x76, 0x5f, + 0x50, 0x6b, 0x59, 0x60, 0x54, 0xb6, 0x4c, 0xa4, 0x15, 0x99, 0xa9, 0x64, 0xee, 0x92, 0xcd, 0x55, + 0xb4, 0x0f, 0x12, 0x22, 0xad, 0x4c, 0x64, 0x15, 0x26, 0x53, 0xe9, 0xe9, 0x75, 0x92, 0xe4, 0x43, + 0xbe, 0x00, 0x43, 0xf7, 0x0f, 0x02, 0x5b, 0x18, 0x80, 0xcb, 0x7e, 0x64, 0x20, 0xd9, 0x7c, 0xd4, + 0x42, 0xba, 0x07, 0x5a, 0xa4, 0x39, 0xa4, 0x61, 0x43, 0xb1, 0x62, 0x7b, 0x8d, 0x47, 0xb6, 0x87, + 0x0e, 0xc2, 0xb3, 0x1a, 0x0b, 0xa5, 0x84, 0x0f, 0xc5, 0xbe, 0x00, 0xc4, 0xbc, 0x86, 0x55, 0x16, + 0xe4, 0x7b, 0xe0, 0xbc, 0xef, 0xec, 0xb5, 0xed, 0xa0, 0xeb, 0x51, 0xcb, 0x6e, 0xee, 0xb9, 0x9e, + 0x13, 0xec, 0xb7, 0x2c, 0xbf, 0xeb, 0x04, 0x74, 0x7e, 0x4e, 0xcb, 0x63, 0x5d, 0x93, 0x78, 0x25, + 0x89, 0x56, 0x63, 0x58, 0xe6, 0x39, 0x3f, 0xbd, 0x80, 0x7c, 0x05, 0x26, 0xd5, 0x2d, 0xd9, 0x9f, + 0x3f, 0x73, 0x29, 0x77, 0x65, 0x2a, 0xbc, 0x78, 0xc4, 0x37, 0x70, 0x19, 0xff, 0x59, 0x39, 0x21, + 0x7c, 0x3d, 0xfe, 0xb3, 0xc2, 0x2b, 0xcc, 0x0c, 0x49, 0x0a, 0xb3, 0xe6, 0x8c, 0x98, 0xb1, 0xa2, + 0x97, 0xd7, 0x6e, 0x97, 0xcc, 0xd1, 0x8d, 0xea, 0x83, 0x5a, 0xd3, 0x0d, 0x8c, 0xff, 0x22, 0x83, + 0x9b, 0x38, 0x79, 0x0d, 0xc3, 0x47, 0x85, 0xaf, 0x67, 0xa8, 0xbf, 0xb5, 0x3b, 0xb1, 0xe4, 0x01, + 0x1c, 0x85, 0xbc, 0x01, 0x23, 0xb7, 0xed, 0xba, 0x0c, 0x5d, 0x23, 0x90, 0x77, 0x11, 0xa2, 0x2a, + 0x7b, 0x39, 0x0e, 0x93, 0x2f, 0xf9, 0xe4, 0x2e, 0x45, 0x29, 0xd2, 0xcb, 0x25, 0xf9, 0x5c, 0x8f, + 0xf2, 0xa5, 0x58, 0x14, 0x4a, 0x0e, 0xf5, 0x98, 0x55, 0x7c, 0x2a, 0x07, 0xe3, 0x4f, 0x33, 0xd1, + 0xae, 0x44, 0x5e, 0x85, 0x21, 0x73, 0x23, 0xfc, 0x7e, 0xee, 0xf4, 0x1b, 0xfb, 0x7c, 0x44, 0x20, + 0x5f, 0x81, 0x33, 0x0a, 0x9f, 0x84, 0x89, 0xfe, 0x2b, 0xe8, 0x93, 0xaa, 0x7c, 0x49, 0xba, 0x9d, + 0x7e, 0x3a, 0x0f, 0x14, 0xa6, 0xa3, 0x82, 0x0a, 0x6d, 0x3b, 0x9c, 0xb7, 0xd2, 0x58, 0x95, 0x77, + 0x03, 0x11, 0xe2, 0x8d, 0x4d, 0xe3, 0xc0, 0x5d, 0x52, 0x8d, 0xdf, 0xca, 0x68, 0xbb, 0x4d, 0x98, + 0x53, 0x3a, 0x73, 0x42, 0x4e, 0xe9, 0xb7, 0x01, 0x4a, 0xdd, 0xc0, 0x5d, 0x6e, 0x7b, 0x6e, 0x93, + 0x6b, 0x51, 0x44, 0xfe, 0x0c, 0xd4, 0x0d, 0x53, 0x04, 0x6b, 0x9e, 0x73, 0x21, 0x72, 0xaa, 0x37, + 0x43, 0xee, 0xe3, 0x7a, 0x33, 0x18, 0xbf, 0x9f, 0xd1, 0xd6, 0x28, 0x93, 0x12, 0xc5, 0x54, 0x54, + 0x2d, 0xc6, 0x3a, 0xce, 0x43, 0xcb, 0x6f, 0xba, 0x5a, 0x90, 0x0a, 0x81, 0x46, 0xfe, 0xed, 0x0c, + 0x9c, 0xe5, 0x6e, 0x01, 0xeb, 0xdd, 0xd6, 0x0e, 0xf5, 0x1e, 0xd8, 0x4d, 0xa7, 0x11, 0x05, 0xe7, + 0x8b, 0xcc, 0x07, 0x95, 0x6a, 0xd2, 0xf1, 0xf9, 0x45, 0x95, 0xbb, 0x29, 0x58, 0x6d, 0x2c, 0xb4, + 0x1e, 0x86, 0xa5, 0xea, 0x45, 0x35, 0x9d, 0xde, 0xf8, 0xb5, 0x0c, 0xbc, 0x78, 0x62, 0x2d, 0xe4, + 0x3a, 0x8c, 0xca, 0xc4, 0x25, 0x19, 0xec, 0x78, 0xb4, 0xb3, 0x4d, 0x26, 0x2d, 0x91, 0x58, 0xe4, + 0xab, 0x70, 0x46, 0x65, 0xb5, 0xe9, 0xd9, 0x8e, 0x9a, 0x1e, 0x24, 0xe5, 0xab, 0x03, 0x86, 0x12, + 0x97, 0xd6, 0xd2, 0x99, 0x18, 0xff, 0x5f, 0x46, 0xc9, 0x32, 0xff, 0x8c, 0xca, 0xf0, 0xb7, 0x34, + 0x19, 0x5e, 0x86, 0x26, 0x0d, 0x5b, 0xc5, 0xca, 0x52, 0xef, 0x5d, 0xd3, 0x8a, 0xbd, 0x38, 0x02, + 0x7e, 0x24, 0x0b, 0xe3, 0x5b, 0x3e, 0xf5, 0xf8, 0x43, 0xee, 0xa7, 0x2b, 0x40, 0x63, 0xd8, 0xae, + 0x81, 0x42, 0xe8, 0xfd, 0x71, 0x06, 0x15, 0xfc, 0x2a, 0x05, 0xeb, 0x0d, 0x25, 0xb3, 0x24, 0xf6, + 0x06, 0xe6, 0x94, 0x44, 0x28, 0x0f, 0x28, 0xb6, 0xaa, 0x27, 0x99, 0xc5, 0x4c, 0xc3, 0xab, 0xe4, + 0x8b, 0x30, 0xbc, 0x85, 0xea, 0x4a, 0x3d, 0xc8, 0x46, 0xc8, 0x1f, 0x0b, 0xf9, 0x26, 0xdd, 0xf5, + 0xf5, 0x68, 0x73, 0x9c, 0x90, 0xd4, 0x60, 0xb4, 0xec, 0x51, 0xcc, 0x19, 0x3f, 0x34, 0xb8, 0x8b, + 0x78, 0x9d, 0x93, 0xc4, 0x5d, 0xc4, 0x05, 0x27, 0xe3, 0x67, 0xb3, 0x40, 0xa2, 0x36, 0x62, 0x82, + 0x34, 0xff, 0x99, 0x1d, 0xf4, 0x0f, 0xb4, 0x41, 0xbf, 0x90, 0x18, 0x74, 0xde, 0xbc, 0x81, 0xc6, + 0xfe, 0x77, 0x32, 0x70, 0x36, 0x9d, 0x90, 0xbc, 0x04, 0x23, 0xf7, 0x37, 0x37, 0x64, 0x9c, 0x16, + 0xd1, 0x14, 0xb7, 0x83, 0xba, 0x02, 0x53, 0x14, 0x91, 0x37, 0x61, 0xe4, 0x4b, 0x66, 0x99, 0x9d, + 0x43, 0x4a, 0x0a, 0x8e, 0x6f, 0x7a, 0x56, 0x5d, 0x3f, 0x8a, 0x04, 0x92, 0x3a, 0xb6, 0xb9, 0xa7, + 0x36, 0xb6, 0x3f, 0x99, 0x85, 0xe9, 0x52, 0xbd, 0x4e, 0x7d, 0x5f, 0x84, 0x97, 0x7f, 0x66, 0x07, + 0x36, 0x3d, 0x02, 0x8b, 0xd6, 0xb6, 0x81, 0x46, 0xf5, 0x77, 0x33, 0x70, 0x46, 0x52, 0x3d, 0x74, + 0xe8, 0xa3, 0xcd, 0x7d, 0x8f, 0xfa, 0xfb, 0x6e, 0xb3, 0x31, 0x70, 0x9e, 0x1f, 0x26, 0xe8, 0x61, + 0x48, 0x78, 0xf5, 0x55, 0x7f, 0x17, 0x21, 0x9a, 0xa0, 0xc7, 0xc3, 0xc6, 0x5f, 0x87, 0xd1, 0x52, + 0xa7, 0xe3, 0xb9, 0x0f, 0xf9, 0xb2, 0x17, 0xf1, 0x24, 0x6d, 0x0e, 0xd2, 0x3c, 0xec, 0x39, 0x88, + 0x7d, 0x46, 0x85, 0xb6, 0x79, 0x00, 0xbf, 0x49, 0xfe, 0x19, 0x0d, 0xda, 0x56, 0x65, 0x71, 0x2c, + 0x37, 0x6a, 0x40, 0x36, 0x3c, 0xb7, 0xe5, 0x06, 0xb4, 0xc1, 0xdb, 0x83, 0x81, 0x09, 0x4e, 0x0c, + 0xa4, 0xb5, 0xe9, 0x04, 0x4d, 0x2d, 0x90, 0x56, 0xc0, 0x00, 0x26, 0x87, 0x1b, 0xff, 0xcf, 0x30, + 0x4c, 0xa8, 0xbd, 0x43, 0x0c, 0x9e, 0xbc, 0xc3, 0xf5, 0xd4, 0xe8, 0x18, 0x36, 0x42, 0x4c, 0x51, + 0x12, 0x85, 0x96, 0xc9, 0x9e, 0x18, 0x5a, 0x66, 0x1b, 0x26, 0x37, 0x3c, 0x17, 0x03, 0x5f, 0xe2, + 0x6b, 0xa5, 0xd8, 0x0a, 0x67, 0x95, 0x7b, 0x27, 0x1b, 0x48, 0x7c, 0x0f, 0x45, 0xc9, 0xbe, 0x23, + 0xb0, 0x31, 0xa5, 0xa5, 0xa6, 0x75, 0xd1, 0xf8, 0x70, 0x53, 0x0b, 0xdb, 0x17, 0xd1, 0x6b, 0x43, + 0x53, 0x0b, 0x06, 0xd1, 0x4d, 0x2d, 0x18, 0x44, 0x5d, 0x6b, 0xc3, 0x4f, 0x6b, 0xad, 0x91, 0x9f, + 0xcd, 0xc0, 0x78, 0xa9, 0xdd, 0x16, 0x21, 0x6b, 0x4e, 0xf0, 0xd6, 0xff, 0xaa, 0xb0, 0xb6, 0x78, + 0xe7, 0x63, 0x59, 0x5b, 0xa0, 0xdc, 0xe2, 0xa3, 0xa4, 0x1a, 0x55, 0xa8, 0xde, 0xd6, 0x94, 0xef, + 0x20, 0xef, 0x40, 0x21, 0x9c, 0xe4, 0xd5, 0x76, 0x83, 0x3e, 0xa6, 0x3c, 0xf9, 0xe1, 0xa4, 0x88, + 0xa6, 0xad, 0x4a, 0xa6, 0x71, 0x44, 0xb2, 0x09, 0x60, 0x87, 0xb3, 0x2b, 0x96, 0xc5, 0x35, 0x39, + 0xfd, 0x84, 0xf4, 0x8c, 0xbf, 0xf1, 0x41, 0x4b, 0x95, 0x9e, 0x23, 0x3e, 0xa4, 0x05, 0xd3, 0x3c, + 0x85, 0x6a, 0x2d, 0xb0, 0xbd, 0x00, 0x13, 0x50, 0xc0, 0x89, 0xe3, 0xf0, 0xaa, 0xd0, 0x9f, 0x3d, + 0x2f, 0x12, 0xb3, 0xfa, 0x8c, 0xd6, 0x4a, 0xc9, 0x46, 0x11, 0xe7, 0xcd, 0x63, 0x97, 0x9b, 0xe7, + 0x92, 0xdf, 0xcb, 0x27, 0xfd, 0x4f, 0x66, 0xe0, 0xac, 0x3a, 0xe9, 0x6b, 0xdd, 0x1d, 0x11, 0x30, + 0x94, 0x5c, 0x83, 0x31, 0x31, 0x27, 0xc3, 0x4b, 0x54, 0x32, 0x8f, 0x46, 0x84, 0x42, 0x96, 0xd9, + 0x34, 0x64, 0x3c, 0x84, 0xd4, 0x3d, 0x1b, 0xdb, 0xa7, 0x58, 0x51, 0x94, 0x9e, 0xdb, 0xc3, 0xdf, + 0xfa, 0xfc, 0x64, 0x10, 0xe3, 0x7d, 0x98, 0xd1, 0x47, 0xa2, 0x46, 0x03, 0x72, 0x15, 0x46, 0xe5, + 0xf0, 0x65, 0xd2, 0x87, 0x4f, 0x96, 0x1b, 0xdb, 0x40, 0x12, 0xf4, 0x3e, 0x9a, 0x45, 0xb1, 0xfb, + 0x29, 0x37, 0xdb, 0x93, 0x8f, 0x92, 0x09, 0xc4, 0xa5, 0x59, 0xf1, 0x7d, 0xe3, 0x9a, 0x5b, 0x02, + 0x06, 0x4f, 0xfd, 0xd3, 0x29, 0x98, 0x4d, 0xd9, 0x73, 0x4f, 0x90, 0x89, 0x8a, 0xfa, 0x06, 0x31, + 0x16, 0x06, 0xfb, 0x90, 0xdb, 0xc2, 0xfb, 0x30, 0x7c, 0xe2, 0x76, 0xc0, 0x9d, 0x52, 0x62, 0xbb, + 0x00, 0x27, 0xfb, 0x44, 0xe4, 0x22, 0x35, 0x1e, 0xcf, 0xf0, 0x53, 0x8b, 0xc7, 0xb3, 0x04, 0x93, + 0xa2, 0x55, 0x62, 0xbb, 0x52, 0x8c, 0xa3, 0x65, 0x5e, 0x98, 0xc4, 0xb6, 0xa5, 0x93, 0x70, 0x1e, + 0xbe, 0xdb, 0x7c, 0x48, 0x05, 0x8f, 0x51, 0x95, 0x07, 0x16, 0xa4, 0xf2, 0x50, 0x48, 0xc8, 0x7f, + 0x84, 0xe9, 0x1b, 0x11, 0xa2, 0xee, 0x59, 0xf9, 0x7e, 0x7b, 0x56, 0xe3, 0xe9, 0xec, 0x59, 0x17, + 0xe4, 0x37, 0xa6, 0xef, 0x5d, 0x29, 0x9f, 0x45, 0x7e, 0x39, 0x03, 0x33, 0x3c, 0x28, 0x8c, 0xfa, + 0xb1, 0x7d, 0x03, 0x7d, 0xd4, 0x9f, 0xce, 0xc7, 0xbe, 0x20, 0x32, 0x02, 0xa5, 0x7f, 0x6b, 0xf2, + 0xa3, 0xc8, 0xf7, 0x00, 0x84, 0x2b, 0x8a, 0x07, 0x90, 0x1d, 0x5f, 0x7c, 0x21, 0x65, 0x17, 0x08, + 0x91, 0xa2, 0xc4, 0x1d, 0x41, 0x48, 0xa7, 0x25, 0xed, 0x0c, 0xa1, 0xe4, 0x6f, 0xc0, 0x1c, 0x5b, + 0x2f, 0x21, 0x44, 0x84, 0xb0, 0x9a, 0x1f, 0xc7, 0x5a, 0x3e, 0xdb, 0x5b, 0x26, 0xba, 0x96, 0x46, + 0xc6, 0xc3, 0x0d, 0x47, 0xf9, 0xd3, 0x03, 0x35, 0xda, 0x45, 0x6a, 0x45, 0x18, 0x19, 0x0e, 0xbf, + 0x9e, 0x27, 0xd7, 0xe8, 0xb1, 0xbf, 0x9d, 0x97, 0x6b, 0x81, 0xef, 0x6f, 0xbe, 0xee, 0xa3, 0x8c, + 0x20, 0xf2, 0x25, 0x20, 0x61, 0x34, 0x15, 0x0e, 0xa3, 0x32, 0xf1, 0x06, 0x57, 0x37, 0x47, 0x51, + 0x59, 0x3c, 0x59, 0xac, 0x4e, 0x92, 0x24, 0x31, 0xa1, 0x30, 0x27, 0x1a, 0xcd, 0xa0, 0x32, 0xb7, + 0xa2, 0x3f, 0x3f, 0xa5, 0x05, 0x08, 0x8b, 0x4a, 0xa2, 0x44, 0xeb, 0x4a, 0x82, 0x46, 0x4d, 0xe5, + 0x94, 0xc6, 0x8e, 0xdc, 0x82, 0x31, 0x74, 0x14, 0x5e, 0x91, 0xc6, 0x5e, 0xc2, 0xf0, 0x04, 0x5d, + 0x8a, 0xad, 0x7d, 0xdd, 0x64, 0x2b, 0x42, 0x65, 0xd7, 0x81, 0x8a, 0x77, 0x68, 0x76, 0xdb, 0xa8, + 0x14, 0x16, 0xfa, 0x8e, 0x86, 0x77, 0x68, 0x79, 0x5d, 0xdd, 0x93, 0x1c, 0x91, 0xc8, 0x37, 0x60, + 0x7c, 0xcd, 0x7e, 0x1c, 0x66, 0x97, 0x9a, 0x19, 0x3c, 0x87, 0x55, 0xcb, 0x7e, 0x1c, 0xa6, 0x96, + 0x8a, 0xe7, 0xb0, 0x52, 0x58, 0x92, 0xaf, 0x01, 0x28, 0x9a, 0x6a, 0x72, 0x62, 0x05, 0x2f, 0xca, + 0xb0, 0x77, 0xa9, 0x1a, 0x6c, 0xe4, 0xaf, 0x30, 0x8c, 0x49, 0x0e, 0x73, 0x9f, 0x9c, 0xe4, 0x70, + 0xe6, 0x93, 0x93, 0x1c, 0x16, 0x76, 0xe0, 0x7c, 0xcf, 0xa5, 0x93, 0x12, 0xea, 0xf8, 0xba, 0x1e, + 0xea, 0xf8, 0x7c, 0xaf, 0x23, 0xd6, 0xd7, 0xf3, 0xab, 0xcc, 0x16, 0xe6, 0x7a, 0x4b, 0x27, 0xdf, + 0xc9, 0xc6, 0x8e, 0x5c, 0x71, 0xb1, 0xe0, 0xb9, 0xbd, 0x7a, 0xc9, 0x24, 0x59, 0x4c, 0xbc, 0xcd, + 0x0f, 0x65, 0x25, 0x1a, 0x3c, 0x3b, 0x94, 0xd5, 0x43, 0x1d, 0x8f, 0xe7, 0x27, 0x3d, 0x7d, 0xdf, + 0x85, 0x29, 0x9e, 0x2b, 0xf7, 0x1e, 0x3d, 0x7c, 0xe4, 0x7a, 0x0d, 0x9e, 0xb5, 0x48, 0xc8, 0xe0, + 0x89, 0x44, 0xf7, 0x31, 0x5c, 0x52, 0x91, 0xbe, 0xa7, 0xc3, 0x58, 0xfb, 0xf9, 0xd4, 0x5d, 0x8c, + 0x21, 0xf4, 0x73, 0x4b, 0x25, 0x6f, 0x85, 0x82, 0x1a, 0xf5, 0xd4, 0x2c, 0x2b, 0x9e, 0x04, 0xa6, + 0xc8, 0x6b, 0xd4, 0x33, 0xfe, 0x79, 0x0e, 0x08, 0xaf, 0xa9, 0x6c, 0x77, 0x6c, 0xf4, 0xcc, 0x76, + 0x30, 0xd6, 0x52, 0x41, 0xe0, 0xd8, 0x3b, 0x4d, 0xaa, 0x06, 0x2a, 0x13, 0xc6, 0xb5, 0x61, 0x99, + 0x15, 0xbf, 0xe8, 0x24, 0x08, 0x7b, 0x6c, 0x75, 0xd9, 0x27, 0xd9, 0xea, 0xbe, 0x01, 0xcf, 0x97, + 0x3a, 0x98, 0x74, 0x5b, 0xd6, 0x72, 0xdb, 0xf5, 0xe4, 0x26, 0xa5, 0xf9, 0xfc, 0xd9, 0x21, 0x5a, + 0xe2, 0x4b, 0xfb, 0xb1, 0x50, 0xe4, 0x14, 0x36, 0x2f, 0x3b, 0x81, 0x1a, 0x43, 0x42, 0xca, 0x29, + 0x1d, 0x2c, 0x49, 0x91, 0x53, 0x38, 0x89, 0xe4, 0xe1, 0x78, 0x52, 0x4e, 0xc1, 0x1c, 0x65, 0x11, + 0x0f, 0xc7, 0xa3, 0x3d, 0x64, 0x9d, 0x90, 0x84, 0xbc, 0x0b, 0xe3, 0xa5, 0x6e, 0xe0, 0x0a, 0xc6, + 0xc2, 0x2a, 0x3c, 0xb2, 0xdf, 0x16, 0x9f, 0xa2, 0x5d, 0x7d, 0x22, 0x74, 0xe3, 0x4f, 0x72, 0x70, + 0x3e, 0x39, 0xbc, 0xa2, 0x34, 0x5c, 0x1f, 0x99, 0x13, 0xd6, 0x47, 0xda, 0x6c, 0xc8, 0x46, 0xf9, + 0x25, 0x9e, 0xc6, 0x6c, 0xe0, 0xb9, 0xbb, 0x3f, 0xe6, 0x6c, 0xa8, 0xc1, 0xb8, 0x7a, 0xde, 0x0d, + 0x7d, 0xdc, 0xf3, 0x4e, 0xe5, 0xc2, 0x2e, 0xf5, 0x3c, 0x74, 0xc6, 0x70, 0xf4, 0x74, 0x14, 0x8f, + 0x9a, 0xc1, 0x31, 0xc8, 0xbf, 0x05, 0x97, 0xf8, 0x9e, 0x14, 0x6f, 0xec, 0xd2, 0xa1, 0xe4, 0x28, + 0x06, 0x6e, 0xf1, 0xf8, 0xa8, 0x78, 0x8d, 0xab, 0x4a, 0xac, 0x44, 0xb7, 0x59, 0x3b, 0x87, 0x96, + 0xfc, 0x32, 0xa5, 0x92, 0x13, 0x79, 0x1b, 0x65, 0x38, 0x2f, 0x4a, 0x23, 0xa7, 0x6d, 0x59, 0xc8, + 0x06, 0xf9, 0x20, 0xd2, 0x76, 0xe1, 0x20, 0xc7, 0x14, 0x59, 0x58, 0x8e, 0x59, 0xbf, 0x95, 0x8c, + 0xcc, 0x6f, 0xa6, 0xf9, 0xdc, 0xf0, 0xa8, 0xdd, 0x1c, 0xac, 0xbb, 0xdb, 0x48, 0x9d, 0x5a, 0x36, + 0x55, 0xa7, 0x26, 0x95, 0x32, 0xb9, 0x54, 0xa5, 0x4c, 0x05, 0xa6, 0x6b, 0xdd, 0x1d, 0x59, 0x77, + 0xdc, 0x5f, 0xd3, 0xef, 0xee, 0xa4, 0xf5, 0x4a, 0x9c, 0xc4, 0xf8, 0xd1, 0x2c, 0x4c, 0x6c, 0x34, + 0xbb, 0x7b, 0x4e, 0xbb, 0x62, 0x07, 0xf6, 0x33, 0xab, 0xe6, 0x7b, 0x5b, 0x53, 0xf3, 0x85, 0xae, + 0x65, 0x61, 0xc3, 0x06, 0xd2, 0xf1, 0xfd, 0x4c, 0x06, 0xa6, 0x23, 0x12, 0x7e, 0x58, 0xaf, 0xc0, + 0x10, 0xfb, 0x21, 0x2e, 0xbf, 0x97, 0x12, 0x8c, 0x79, 0x72, 0xc9, 0xf0, 0x2f, 0xa1, 0x78, 0xd3, + 0x33, 0xb7, 0x21, 0x87, 0x85, 0xcf, 0xc1, 0x58, 0xc4, 0xf6, 0x34, 0x49, 0x25, 0x7f, 0x3d, 0x03, + 0x85, 0x78, 0x4b, 0xc8, 0x3d, 0x18, 0x65, 0x9c, 0x1c, 0x2a, 0xef, 0xe5, 0x2f, 0xf7, 0x68, 0xf3, + 0x35, 0x81, 0xc6, 0x3f, 0x0f, 0x3b, 0x9f, 0x72, 0x88, 0x29, 0x39, 0x2c, 0x98, 0x30, 0xa1, 0x62, + 0xa5, 0x7c, 0xdd, 0x1b, 0xba, 0x84, 0x72, 0x36, 0xbd, 0x1f, 0xb4, 0x54, 0x98, 0xda, 0x57, 0x0b, + 0xe1, 0xe3, 0xb2, 0x36, 0xb9, 0x52, 0x57, 0x15, 0x4e, 0x9a, 0xc5, 0x28, 0x4b, 0x81, 0x3a, 0xcf, + 0x52, 0x26, 0x74, 0x88, 0x47, 0xde, 0x80, 0x11, 0x5e, 0x9f, 0x9a, 0xc6, 0xad, 0x83, 0x10, 0x55, + 0x4e, 0xe6, 0x38, 0xc6, 0xdf, 0xcb, 0xc1, 0xd9, 0xe8, 0xf3, 0xb6, 0x3a, 0x0d, 0x3b, 0xa0, 0x1b, + 0xb6, 0x67, 0xb7, 0xfc, 0x13, 0x56, 0xc0, 0x95, 0xc4, 0xa7, 0x61, 0x02, 0x2d, 0xf9, 0x69, 0xca, + 0x07, 0x19, 0xb1, 0x0f, 0x42, 0x1d, 0x28, 0xff, 0x20, 0xf9, 0x19, 0xe4, 0x1e, 0xe4, 0x6a, 0x34, + 0x10, 0x7b, 0xef, 0xe5, 0x44, 0xaf, 0xaa, 0xdf, 0x75, 0xad, 0x46, 0x03, 0x3e, 0x88, 0x3c, 0x2e, + 0x94, 0x16, 0x9c, 0x8f, 0x71, 0x21, 0xdb, 0x30, 0xb2, 0xfc, 0xb8, 0x43, 0xeb, 0x81, 0x48, 0x89, + 0x7a, 0xb5, 0x3f, 0x3f, 0x8e, 0xab, 0x64, 0x44, 0xa5, 0x08, 0x50, 0x3b, 0x8b, 0xa3, 0x2c, 0xdc, + 0x82, 0xbc, 0xac, 0xfc, 0x34, 0x33, 0x77, 0xe1, 0x6d, 0x18, 0x57, 0x2a, 0x39, 0xd5, 0xa4, 0xff, + 0x05, 0xb6, 0xaf, 0xba, 0x4d, 0x99, 0x45, 0x75, 0x39, 0x21, 0x2b, 0x2a, 0x39, 0xa8, 0xb8, 0xac, + 0x68, 0x1d, 0x88, 0xa2, 0x3e, 0x42, 0x63, 0x15, 0xa6, 0x6b, 0x07, 0x4e, 0x27, 0x0a, 0x14, 0xab, + 0x9d, 0xc8, 0x98, 0xe7, 0x46, 0x5c, 0xdc, 0xe3, 0x27, 0x72, 0x9c, 0xce, 0xf8, 0xf3, 0x0c, 0x8c, + 0xb0, 0xbf, 0x1e, 0xdc, 0x7a, 0x46, 0xb7, 0xcc, 0x9b, 0xda, 0x96, 0x39, 0xa3, 0xc4, 0x6a, 0xc7, + 0x8d, 0xe3, 0xd6, 0x09, 0x9b, 0xe5, 0x91, 0x18, 0x20, 0x8e, 0x4c, 0xee, 0xc0, 0xa8, 0x30, 0x29, + 0x12, 0xb6, 0xdf, 0x6a, 0xf0, 0x77, 0x69, 0x6c, 0x14, 0xde, 0xf0, 0xdd, 0x4e, 0x5c, 0x25, 0x22, + 0xa9, 0x99, 0x5c, 0x2f, 0x43, 0xf6, 0x6a, 0x59, 0xd2, 0x5d, 0x74, 0xd6, 0xe3, 0xa1, 0xcb, 0xfd, + 0xa5, 0x73, 0x82, 0x53, 0x2f, 0xdf, 0xfa, 0x92, 0x78, 0x0d, 0xc9, 0xf5, 0x63, 0x72, 0x56, 0xa6, + 0x26, 0x4e, 0x7d, 0x28, 0x69, 0xc1, 0xd9, 0x5a, 0x6d, 0x05, 0xcd, 0x0f, 0x37, 0x5c, 0x2f, 0xb8, + 0xed, 0x7a, 0x8f, 0x6c, 0xb4, 0x2d, 0x46, 0x0d, 0x9f, 0x62, 0x83, 0x90, 0x66, 0x14, 0xf6, 0x6a, + 0xaa, 0x51, 0x58, 0x1f, 0x3b, 0x05, 0xa3, 0x0d, 0xe7, 0x6a, 0xb5, 0x15, 0x1e, 0x38, 0xfc, 0x2f, + 0xa2, 0xbe, 0x5f, 0xcf, 0xc0, 0x4c, 0xad, 0xb6, 0x12, 0xab, 0x6a, 0x55, 0x46, 0x2c, 0xcf, 0xe8, + 0xd9, 0xbd, 0x53, 0x3b, 0x02, 0x47, 0x21, 0xc3, 0x25, 0xbc, 0xba, 0x16, 0x9c, 0x92, 0x33, 0x21, + 0x1b, 0x61, 0x8c, 0xf4, 0xac, 0xe6, 0x0f, 0xd0, 0xa3, 0xa1, 0xa8, 0xe1, 0x16, 0xde, 0x74, 0xac, + 0x54, 0xd7, 0x70, 0x33, 0x88, 0xf1, 0xdf, 0x9c, 0xe5, 0x51, 0xd8, 0xe5, 0x6c, 0x79, 0x0f, 0x26, + 0x04, 0x3d, 0x1a, 0xcd, 0x0b, 0x9b, 0x90, 0xf3, 0x6c, 0x83, 0xdc, 0xe5, 0x70, 0x1e, 0x9d, 0xf7, + 0xbb, 0x47, 0xc5, 0x21, 0xd6, 0x35, 0xa6, 0x86, 0x4e, 0xee, 0xc3, 0xe4, 0x9a, 0xfd, 0x58, 0x51, + 0x67, 0x70, 0x97, 0xa8, 0xab, 0x6c, 0x57, 0x69, 0xd9, 0x8f, 0x07, 0x30, 0xba, 0xd3, 0xe9, 0xc9, + 0x01, 0x4c, 0xe9, 0x6d, 0x12, 0x33, 0x30, 0x39, 0x62, 0x37, 0x52, 0x47, 0xec, 0x7c, 0xc7, 0xf5, + 0x02, 0x6b, 0x37, 0x24, 0xd7, 0x32, 0x0e, 0xc4, 0x58, 0x93, 0xf7, 0x60, 0x46, 0x09, 0x01, 0x7a, + 0xdb, 0xf5, 0x5a, 0xb6, 0xbc, 0x70, 0xa1, 0x8e, 0x1f, 0x6d, 0x89, 0x76, 0x11, 0x6c, 0x26, 0x31, + 0xc9, 0x57, 0xd2, 0xdc, 0xcc, 0x86, 0x23, 0xcb, 0xc3, 0x14, 0x37, 0xb3, 0x5e, 0x96, 0x87, 0x49, + 0x87, 0xb3, 0xbd, 0x7e, 0x96, 0xc9, 0x79, 0xde, 0xfa, 0x81, 0x2c, 0x8f, 0xc3, 0x91, 0xeb, 0x61, + 0x81, 0xbc, 0x08, 0xb9, 0xa5, 0x8d, 0xdb, 0xf8, 0x32, 0x25, 0x8d, 0xa8, 0xda, 0xfb, 0x76, 0xbb, + 0x8e, 0x17, 0x21, 0xe1, 0x0d, 0xa0, 0x1e, 0x94, 0x4b, 0x1b, 0xb7, 0x89, 0x0d, 0xb3, 0x98, 0xdd, + 0x2d, 0xf8, 0xf2, 0x8d, 0x1b, 0xca, 0x50, 0xe5, 0xf1, 0xd3, 0xae, 0x8b, 0x4f, 0x2b, 0x62, 0x6e, + 0xb8, 0xc0, 0x7a, 0x7c, 0xe3, 0x46, 0xea, 0x80, 0x84, 0x1f, 0x96, 0xc6, 0x8b, 0x1d, 0x58, 0x6b, + 0xf6, 0xe3, 0xc8, 0x89, 0xc3, 0x17, 0x0e, 0xbb, 0x17, 0xe4, 0xd4, 0x8a, 0x1c, 0x40, 0xb4, 0x03, + 0x4b, 0x27, 0x62, 0xf7, 0xd8, 0x68, 0x82, 0xf9, 0xc2, 0xd5, 0x69, 0x41, 0xaa, 0xeb, 0xa4, 0x57, + 0xb7, 0x7a, 0x19, 0x53, 0xd0, 0xc9, 0x56, 0x78, 0x1b, 0xe7, 0xb7, 0x59, 0x91, 0x0f, 0xf9, 0xba, + 0x7a, 0x1b, 0xe7, 0x4a, 0x32, 0xad, 0x59, 0xd3, 0xa1, 0x0a, 0x87, 0x7b, 0xb5, 0x98, 0x3a, 0x97, + 0xe4, 0x25, 0x7f, 0xe2, 0xf4, 0x97, 0x7c, 0x0a, 0x43, 0xab, 0x6e, 0xfd, 0x40, 0x04, 0xe7, 0xfb, + 0x12, 0xdb, 0x85, 0xf5, 0xe4, 0xf9, 0x4f, 0x6a, 0x71, 0x8d, 0xec, 0xc9, 0x3a, 0xfb, 0x54, 0x36, + 0x0b, 0x44, 0x9f, 0x08, 0x2b, 0xde, 0xb9, 0xf0, 0x96, 0xab, 0x94, 0x71, 0x79, 0x94, 0x4f, 0x1a, + 0xd9, 0xb5, 0xa6, 0x4e, 0x4e, 0x28, 0x14, 0x2a, 0xd4, 0x3f, 0x08, 0xdc, 0x4e, 0xb9, 0xe9, 0x74, + 0x76, 0x5c, 0xdb, 0x93, 0xa1, 0x9c, 0x07, 0xde, 0x93, 0x1b, 0x9c, 0xde, 0xaa, 0x4b, 0x06, 0x66, + 0x82, 0x25, 0xf9, 0x0a, 0x4c, 0xb1, 0xc9, 0xbd, 0xfc, 0x38, 0xa0, 0x6d, 0x3e, 0xf2, 0x33, 0x28, + 0xd1, 0xcd, 0x29, 0xb9, 0x4b, 0xc2, 0x42, 0x3e, 0xa7, 0x70, 0xb1, 0xd3, 0x90, 0x40, 0x0b, 0x6c, + 0xa8, 0xb1, 0x22, 0x0d, 0x98, 0x5f, 0xb3, 0x1f, 0x2b, 0x99, 0x97, 0x95, 0x49, 0x4a, 0x70, 0x82, + 0x5d, 0x39, 0x3e, 0x2a, 0xbe, 0xcc, 0x26, 0x58, 0x14, 0x5d, 0xbc, 0xc7, 0x7c, 0xed, 0xc9, 0x89, + 0x7c, 0x0b, 0xce, 0x89, 0x66, 0x55, 0x30, 0x5b, 0x98, 0xeb, 0x1d, 0xd6, 0xf6, 0x6d, 0xf4, 0xdf, + 0x9a, 0xed, 0xd1, 0x61, 0xd7, 0xd3, 0xb7, 0x44, 0xd9, 0x61, 0x0d, 0xc9, 0xc7, 0xf2, 0x39, 0x23, + 0xb3, 0x57, 0x0d, 0xe4, 0x23, 0x98, 0xe2, 0xcf, 0x71, 0x2b, 0xae, 0x1f, 0xa0, 0xb2, 0x66, 0xee, + 0x74, 0x6e, 0x09, 0xfc, 0x8d, 0x8f, 0x3b, 0xf2, 0xc4, 0x94, 0x3b, 0x31, 0xce, 0xe4, 0x1d, 0x18, + 0xdf, 0x70, 0xda, 0x3c, 0xf4, 0x68, 0x75, 0x03, 0xd5, 0xca, 0xe2, 0x04, 0xea, 0x38, 0x6d, 0x4b, + 0x6a, 0x4c, 0x3a, 0xe1, 0x76, 0xa1, 0x62, 0x93, 0x6d, 0x18, 0xaf, 0xd5, 0x56, 0x6e, 0x3b, 0x4c, + 0x2e, 0xe9, 0x1c, 0xce, 0x9f, 0xed, 0xf1, 0x95, 0x2f, 0xa5, 0x7e, 0xe5, 0xa4, 0xef, 0xef, 0x5b, + 0xbb, 0x4e, 0x93, 0x5a, 0x75, 0xb7, 0x73, 0x68, 0xaa, 0x9c, 0x52, 0x4c, 0xf5, 0xcf, 0x3d, 0x65, + 0x53, 0xfd, 0x2a, 0x4c, 0x2b, 0xc6, 0xb3, 0x68, 0x38, 0x3b, 0x1f, 0xc5, 0xab, 0x52, 0x4d, 0xf3, + 0xe3, 0xae, 0xa9, 0x71, 0x3a, 0x69, 0xa3, 0x7f, 0xfe, 0xb4, 0x36, 0xfa, 0x0e, 0xcc, 0xf0, 0xc1, + 0x10, 0xf3, 0x00, 0x47, 0x7a, 0xa1, 0x47, 0x1f, 0x5e, 0x4d, 0xed, 0xc3, 0x59, 0x31, 0xd2, 0x72, + 0x92, 0xe1, 0xf3, 0x73, 0x92, 0x2b, 0xd9, 0x05, 0x22, 0x80, 0x76, 0x60, 0xef, 0xd8, 0x3e, 0xc5, + 0xba, 0x9e, 0xef, 0x51, 0xd7, 0xcb, 0xa9, 0x75, 0x4d, 0xc9, 0xba, 0x76, 0x78, 0x35, 0x29, 0x1c, + 0x49, 0x5b, 0xd6, 0x23, 0xe7, 0x17, 0x76, 0xec, 0x0b, 0x9a, 0x8e, 0x3b, 0x89, 0xc0, 0x43, 0x3f, + 0xc5, 0x27, 0x6d, 0xbc, 0xdf, 0x53, 0x38, 0x93, 0xc7, 0x70, 0x36, 0xf9, 0x15, 0x58, 0xe7, 0x05, + 0xac, 0xf3, 0x82, 0x56, 0x67, 0x1c, 0x89, 0xcf, 0x1b, 0xbd, 0x59, 0xf1, 0x5a, 0x7b, 0xf0, 0x27, + 0x3f, 0x94, 0x81, 0x73, 0x6b, 0xb7, 0x4b, 0x98, 0x43, 0xd4, 0xe1, 0x91, 0xe8, 0x42, 0x97, 0xde, + 0x8b, 0xe2, 0x1d, 0x24, 0xfe, 0x36, 0x23, 0x25, 0x0e, 0xdc, 0x2a, 0x98, 0xe8, 0xfe, 0x52, 0x6b, + 0xd7, 0xe6, 0xa9, 0x49, 0x05, 0x8b, 0x14, 0xbf, 0xdf, 0x6f, 0xff, 0x51, 0x31, 0x63, 0xf6, 0xaa, + 0x8a, 0x34, 0x61, 0x41, 0xef, 0x16, 0xe9, 0x45, 0xb1, 0x4f, 0x9b, 0xcd, 0xf9, 0x22, 0xce, 0xe8, + 0x37, 0x8e, 0x8f, 0x8a, 0x57, 0x12, 0xbd, 0x1b, 0x7a, 0x66, 0x30, 0x4c, 0xa5, 0xc1, 0x7d, 0xf8, + 0x91, 0x56, 0x8a, 0xd0, 0x3d, 0x7f, 0x49, 0x8b, 0xfd, 0x93, 0x28, 0x5f, 0x7a, 0x45, 0x48, 0x24, + 0x17, 0xd8, 0x7a, 0xef, 0x29, 0x20, 0x9a, 0x49, 0xce, 0x77, 0x87, 0xf2, 0x93, 0x85, 0xa9, 0x14, + 0x97, 0x05, 0xe3, 0xb7, 0xb3, 0xb1, 0x83, 0x91, 0x54, 0x61, 0x54, 0xcc, 0xf7, 0x9e, 0x97, 0x8c, + 0x0b, 0xa9, 0xb3, 0x7a, 0x54, 0x2c, 0x1d, 0x53, 0xd2, 0x93, 0x47, 0x8c, 0x15, 0x36, 0x5a, 0xdc, + 0x78, 0xbf, 0xc6, 0xcf, 0x3d, 0x04, 0x69, 0x27, 0x7c, 0xe5, 0xf4, 0x8e, 0x78, 0xba, 0x9f, 0x27, + 0x1e, 0xf5, 0xb2, 0x36, 0x72, 0xc0, 0x53, 0x49, 0xe5, 0x42, 0x6f, 0x2e, 0x3d, 0x6f, 0xd4, 0x53, + 0xab, 0x90, 0xd5, 0x62, 0xfc, 0x56, 0x06, 0x26, 0xb5, 0x93, 0x95, 0xdc, 0x52, 0x5c, 0x15, 0x23, + 0xef, 0x7d, 0x0d, 0x07, 0x37, 0xdb, 0xb8, 0x13, 0xe3, 0x2d, 0xe1, 0x77, 0x90, 0xed, 0x4d, 0x87, + 0x8b, 0x2d, 0xee, 0xb9, 0xda, 0x5f, 0x3f, 0x1c, 0x66, 0xbf, 0x1c, 0xea, 0x91, 0xfd, 0xf2, 0x97, + 0x2e, 0xc0, 0x94, 0x7e, 0x23, 0x26, 0x6f, 0xc0, 0x08, 0xea, 0xe6, 0xa5, 0x7a, 0x05, 0xd5, 0x42, + 0xa8, 0xbe, 0xd7, 0x9c, 0x51, 0x38, 0x0e, 0x79, 0x05, 0x20, 0x34, 0x00, 0x97, 0x2f, 0x53, 0xc3, + 0xc7, 0x47, 0xc5, 0xcc, 0x9b, 0xa6, 0x52, 0x40, 0xbe, 0x0e, 0xb0, 0xee, 0x36, 0x68, 0x98, 0xd2, + 0xb8, 0x8f, 0xf5, 0xc5, 0xab, 0x89, 0x34, 0x2b, 0x67, 0xda, 0x6e, 0x83, 0x26, 0x73, 0xaa, 0x28, + 0x1c, 0xc9, 0x17, 0x60, 0xd8, 0xec, 0x36, 0xa9, 0x7c, 0xc1, 0x18, 0x97, 0x27, 0x5c, 0xb7, 0x49, + 0x23, 0x3d, 0x81, 0xd7, 0x8d, 0x1b, 0x16, 0x32, 0x00, 0xf9, 0x80, 0xa7, 0x5f, 0x11, 0x31, 0x42, + 0x87, 0xa3, 0xb7, 0x3a, 0x45, 0xf2, 0x49, 0x44, 0x09, 0x55, 0x48, 0xc8, 0x7d, 0x18, 0x55, 0x1f, + 0x99, 0x14, 0x9f, 0x77, 0xf5, 0x21, 0x52, 0x51, 0x3a, 0x88, 0x5c, 0xc8, 0xf1, 0xf7, 0x27, 0xc9, + 0x85, 0xbc, 0x0b, 0x63, 0x8c, 0x3d, 0xdb, 0x39, 0x7c, 0x71, 0xab, 0xc1, 0x17, 0x39, 0xe5, 0x83, + 0xd8, 0xee, 0xa3, 0x45, 0xf2, 0x0c, 0x09, 0xc8, 0x57, 0x30, 0x7b, 0xad, 0xe8, 0xea, 0xbe, 0x56, + 0x39, 0x97, 0x13, 0x5d, 0x8d, 0xe9, 0x6c, 0x13, 0x3d, 0x1d, 0xf1, 0x23, 0x7b, 0x61, 0xc8, 0xb5, + 0x41, 0x52, 0xe6, 0xbc, 0x96, 0xa8, 0x60, 0x5e, 0x46, 0x11, 0x4b, 0xa6, 0xa6, 0xd6, 0xf8, 0x92, + 0x0e, 0x14, 0x22, 0xa1, 0x52, 0xd4, 0x05, 0xfd, 0xea, 0x7a, 0x33, 0x51, 0x97, 0x3a, 0x80, 0x89, + 0xea, 0x12, 0xdc, 0x49, 0x03, 0xa6, 0xe4, 0x01, 0x25, 0xea, 0x1b, 0xef, 0x57, 0xdf, 0x2b, 0x89, + 0xfa, 0x66, 0x1b, 0x3b, 0xc9, 0x7a, 0x62, 0x3c, 0xc9, 0xbb, 0x30, 0x29, 0x21, 0x3c, 0x51, 0xf4, + 0x44, 0x94, 0x69, 0xb7, 0xb1, 0x93, 0x48, 0x0f, 0xad, 0x23, 0xab, 0xd4, 0x7c, 0x76, 0x4c, 0x6a, + 0xd4, 0xf1, 0x59, 0xa1, 0x23, 0x93, 0x0f, 0x61, 0xbc, 0xda, 0x62, 0x0d, 0x71, 0xdb, 0x76, 0x40, + 0x85, 0x3f, 0xa4, 0xb4, 0x30, 0x52, 0x4a, 0x94, 0xa9, 0xca, 0x53, 0x60, 0x47, 0x45, 0x5a, 0x0a, + 0xec, 0x08, 0xcc, 0x3a, 0x8f, 0xbf, 0x2a, 0x8a, 0x39, 0x2c, 0x7d, 0x25, 0x2f, 0xa4, 0x58, 0xf9, + 0x28, 0xec, 0x45, 0x3c, 0x48, 0x06, 0x95, 0xaf, 0x7a, 0xb1, 0x58, 0xbc, 0x2a, 0x4f, 0xf2, 0x1e, + 0x8c, 0x8b, 0x6c, 0x62, 0x25, 0x73, 0xdd, 0x9f, 0x2f, 0x60, 0xe3, 0x31, 0xc2, 0x83, 0x4c, 0x3c, + 0x66, 0xd9, 0x5e, 0xcc, 0x9c, 0x35, 0xc2, 0x27, 0x5f, 0x86, 0xb9, 0x6d, 0xa7, 0xdd, 0x70, 0x1f, + 0xf9, 0xe2, 0x98, 0x12, 0x1b, 0xdd, 0x4c, 0xe4, 0x4c, 0xf6, 0x88, 0x97, 0x87, 0xb2, 0x60, 0x62, + 0xe3, 0x4b, 0xe5, 0x40, 0xfe, 0x7a, 0x82, 0x33, 0x9f, 0x41, 0xa4, 0xdf, 0x0c, 0x5a, 0x4c, 0xcc, + 0xa0, 0x64, 0xf5, 0xf1, 0xe9, 0x94, 0x5a, 0x0d, 0x71, 0x81, 0xe8, 0xe7, 0xfb, 0x5d, 0xd7, 0x69, + 0xcf, 0xcf, 0xe2, 0x5e, 0xf8, 0x7c, 0x3c, 0xa6, 0x02, 0xe2, 0x89, 0x54, 0xe2, 0xc6, 0xf1, 0x51, + 0xf1, 0x62, 0x5c, 0xe6, 0xff, 0xc8, 0xd5, 0x9e, 0x4b, 0x52, 0x58, 0x93, 0x0f, 0x61, 0x82, 0xfd, + 0x1f, 0x2a, 0x25, 0xe6, 0x34, 0xbb, 0x50, 0x05, 0x53, 0xd4, 0x83, 0x63, 0x84, 0xe9, 0xce, 0x52, + 0xf4, 0x15, 0x1a, 0x2b, 0xf2, 0x36, 0x00, 0x13, 0x9b, 0xc4, 0x76, 0x7c, 0x26, 0x0a, 0x7d, 0x8c, + 0x52, 0x57, 0x72, 0x23, 0x8e, 0x90, 0xc9, 0xbb, 0x30, 0xce, 0x7e, 0xd5, 0xba, 0x0d, 0x97, 0xad, + 0x8d, 0xb3, 0x48, 0xcb, 0x5d, 0x53, 0x19, 0xad, 0xcf, 0xe1, 0x9a, 0x6b, 0x6a, 0x84, 0x4e, 0x56, + 0x60, 0x1a, 0x43, 0x54, 0x8b, 0xe0, 0xa8, 0x0e, 0xf5, 0xe7, 0xcf, 0x29, 0xd6, 0x10, 0xac, 0xc8, + 0x72, 0xc2, 0x32, 0xf5, 0x2e, 0x13, 0x23, 0x23, 0x3e, 0xcc, 0x26, 0x9f, 0x93, 0xfd, 0xf9, 0x79, + 0xec, 0x24, 0x29, 0xc1, 0x27, 0x31, 0xf8, 0x7e, 0xcc, 0x46, 0x44, 0xd9, 0xb8, 0xe4, 0xa3, 0x92, + 0x5a, 0x61, 0x1a, 0x77, 0x62, 0x02, 0xb9, 0x53, 0xde, 0x88, 0xc7, 0x70, 0x3e, 0x8f, 0x2d, 0xc0, + 0x61, 0xde, 0xab, 0x47, 0xb9, 0xc3, 0x53, 0xe2, 0x38, 0xa7, 0x50, 0x93, 0xef, 0x85, 0x33, 0x72, + 0x07, 0x11, 0x45, 0x62, 0x5e, 0x2f, 0x9c, 0x72, 0x27, 0x6e, 0xec, 0x84, 0x55, 0x27, 0xa6, 0x74, + 0x7a, 0x15, 0xc4, 0x86, 0x71, 0x1c, 0x56, 0x51, 0xe3, 0xf3, 0xfd, 0x6a, 0xbc, 0x92, 0xa8, 0xf1, + 0x2c, 0x4e, 0x94, 0x64, 0x65, 0x2a, 0x4f, 0xb2, 0x04, 0x93, 0x62, 0x1d, 0x89, 0xd9, 0xf6, 0x02, + 0xf6, 0x16, 0x2a, 0xb1, 0xe4, 0x0a, 0x4c, 0x4c, 0x38, 0x9d, 0x44, 0xdd, 0x91, 0xf9, 0x63, 0xd2, + 0x05, 0x6d, 0x47, 0x8e, 0xbf, 0x21, 0xe9, 0xc8, 0x6c, 0x47, 0x8a, 0xa4, 0x98, 0xe5, 0xc7, 0x1d, + 0x4f, 0xa8, 0xa8, 0x2e, 0x46, 0x59, 0x91, 0x14, 0xe1, 0xc7, 0xa2, 0x21, 0x86, 0xba, 0x25, 0xa4, + 0x71, 0x20, 0x5b, 0x30, 0x1b, 0x9e, 0xda, 0x0a, 0xe3, 0x62, 0x14, 0x25, 0x38, 0x3a, 0xea, 0xd3, + 0xf9, 0xa6, 0xd1, 0x13, 0x1b, 0xce, 0x69, 0xe7, 0xb4, 0xc2, 0xfa, 0x12, 0xb2, 0xc6, 0x5c, 0xf5, + 0xfa, 0x21, 0x9f, 0xce, 0xbe, 0x17, 0x1f, 0xf2, 0x11, 0x2c, 0xc4, 0xcf, 0x66, 0xa5, 0x96, 0x17, + 0xb1, 0x96, 0xd7, 0x8e, 0x8f, 0x8a, 0x97, 0x13, 0xc7, 0x7b, 0x7a, 0x45, 0x7d, 0xb8, 0x91, 0xaf, + 0xc3, 0xbc, 0x7e, 0x3e, 0x2b, 0x35, 0x19, 0x58, 0x13, 0x2e, 0x9d, 0xf0, 0x60, 0x4f, 0xaf, 0xa1, + 0x27, 0x0f, 0x12, 0x40, 0x31, 0x75, 0x76, 0x2b, 0xd5, 0xbc, 0x14, 0x35, 0x28, 0xb1, 0x4a, 0xd2, + 0xab, 0x3b, 0x89, 0x25, 0x79, 0x04, 0x17, 0xd3, 0x8e, 0x09, 0xa5, 0xd2, 0x97, 0x43, 0x25, 0xf0, + 0xeb, 0xe9, 0x47, 0x4e, 0x7a, 0xcd, 0x27, 0xb0, 0x25, 0x5f, 0x81, 0x33, 0xca, 0xfa, 0x52, 0xea, + 0x7b, 0x05, 0xeb, 0x43, 0x57, 0x70, 0x75, 0x61, 0xa6, 0xd7, 0x92, 0xce, 0x83, 0xb4, 0x60, 0x56, + 0x36, 0x1c, 0xb5, 0xed, 0xe2, 0xe8, 0xb9, 0xac, 0xed, 0xaa, 0x49, 0x8c, 0xa5, 0x4b, 0x62, 0x57, + 0x9d, 0x6f, 0xec, 0x58, 0x9d, 0x88, 0x50, 0x9d, 0xe9, 0x29, 0x7c, 0xc9, 0x0a, 0x8c, 0xd4, 0x36, + 0xaa, 0xb7, 0x6f, 0x2f, 0xcf, 0xbf, 0x8a, 0x35, 0x48, 0xbf, 0x31, 0x0e, 0xd4, 0x2e, 0x4d, 0xc2, + 0x5c, 0xb1, 0xe3, 0xec, 0xee, 0x6a, 0x0f, 0x56, 0x1c, 0x95, 0xfc, 0x75, 0x34, 0x14, 0x64, 0x3b, + 0x6a, 0xc9, 0xf7, 0x9d, 0x3d, 0x8c, 0x3a, 0xed, 0xcf, 0xbf, 0xa6, 0xbd, 0xf7, 0xcb, 0x88, 0xdc, + 0x65, 0x4c, 0x58, 0x96, 0x40, 0xe7, 0xd2, 0x26, 0xbb, 0xff, 0x8b, 0x9d, 0xdb, 0xb2, 0x23, 0x56, + 0xea, 0x26, 0x9e, 0xac, 0x88, 0xf5, 0xdb, 0x9e, 0x13, 0x58, 0xfb, 0x5d, 0xad, 0xf9, 0xf3, 0xaf, + 0x6b, 0x11, 0x98, 0x79, 0x1a, 0x37, 0xa5, 0xd7, 0x5e, 0x16, 0x15, 0xbe, 0xc0, 0x6f, 0xcb, 0x3d, + 0x7a, 0x6e, 0x66, 0x2f, 0x46, 0xe7, 0xdf, 0x1d, 0xca, 0x5f, 0x29, 0x5c, 0xbd, 0x3b, 0x94, 0xbf, + 0x5a, 0x78, 0xcd, 0x7c, 0xa1, 0x56, 0x5a, 0x5b, 0xad, 0x36, 0xe4, 0xb9, 0x22, 0xc3, 0x8d, 0xf3, + 0xa1, 0x35, 0x2f, 0xf7, 0x2b, 0x8d, 0x06, 0xde, 0xf8, 0x3b, 0x19, 0x28, 0x9e, 0xd0, 0x3f, 0x6c, + 0x2b, 0x8f, 0x3e, 0xa2, 0x46, 0x03, 0x35, 0x68, 0x79, 0xf4, 0xe9, 0x96, 0x6e, 0x31, 0xa1, 0x93, + 0xa0, 0xbf, 0x9d, 0xc8, 0x94, 0xa1, 0xb8, 0x5d, 0x26, 0x33, 0x64, 0x48, 0x2c, 0x63, 0x15, 0x0a, + 0xf1, 0x7e, 0x23, 0x9f, 0x87, 0x49, 0x35, 0x4e, 0xbf, 0xbc, 0x45, 0xf3, 0x18, 0x1b, 0xde, 0x9e, + 0x76, 0x16, 0x68, 0x88, 0xc6, 0x2f, 0x64, 0x60, 0x36, 0x65, 0x72, 0x91, 0xcb, 0x30, 0x84, 0x89, + 0xb4, 0x14, 0x83, 0x99, 0x58, 0x02, 0x2d, 0x2c, 0x27, 0x9f, 0x81, 0xd1, 0xca, 0x7a, 0xad, 0x56, + 0x5a, 0x97, 0xf7, 0x70, 0x7e, 0x06, 0xb5, 0x7d, 0xcb, 0xb7, 0xf5, 0x77, 0x76, 0x81, 0x46, 0xde, + 0x84, 0x91, 0xea, 0x06, 0x12, 0x70, 0xb3, 0x4f, 0x6c, 0xaf, 0xd3, 0x89, 0xe3, 0x0b, 0x24, 0xe3, + 0xc7, 0x33, 0x40, 0x92, 0x2b, 0x85, 0xdc, 0x80, 0x71, 0x75, 0x3d, 0xf2, 0xf6, 0xe2, 0xe3, 0xa3, + 0x32, 0x67, 0x4c, 0x15, 0x87, 0x54, 0x60, 0x18, 0x53, 0xa0, 0x86, 0x0f, 0xfc, 0xa9, 0xa7, 0xfa, + 0xb9, 0xc4, 0xa9, 0x3e, 0x8c, 0x09, 0x56, 0x4d, 0x4e, 0x6c, 0xfc, 0x6e, 0x06, 0x48, 0xba, 0xd9, + 0xde, 0x40, 0x06, 0x46, 0x6f, 0x29, 0x6e, 0xfb, 0x6a, 0xaa, 0x9c, 0x30, 0xcf, 0x99, 0x7a, 0x03, + 0x8e, 0x1c, 0xfc, 0x2f, 0x6b, 0x1a, 0x97, 0xde, 0xbe, 0x9e, 0x57, 0x61, 0xf8, 0x01, 0xf5, 0x76, + 0xa4, 0x45, 0x33, 0x5a, 0x41, 0x3e, 0x64, 0x00, 0x55, 0x03, 0x81, 0x18, 0xc6, 0x9f, 0x64, 0x60, + 0x2e, 0x4d, 0x3c, 0x3f, 0xc1, 0x25, 0xd3, 0x88, 0x79, 0x93, 0xa2, 0x71, 0x11, 0x37, 0x91, 0x0c, + 0x7d, 0x48, 0x8b, 0x30, 0xcc, 0x1a, 0x2b, 0x47, 0x18, 0x35, 0x40, 0xac, 0x37, 0x7c, 0x93, 0xc3, + 0x19, 0x02, 0x0f, 0x4f, 0x37, 0x84, 0x91, 0x0d, 0x11, 0x01, 0x67, 0xb7, 0xc9, 0xe1, 0x0c, 0x61, + 0xcd, 0x6d, 0x84, 0xd9, 0xff, 0x11, 0xa1, 0xc5, 0x00, 0x26, 0x87, 0x93, 0xcb, 0x30, 0x7a, 0xbf, + 0xbd, 0x4a, 0xed, 0x87, 0x32, 0x5d, 0x03, 0x1a, 0x43, 0xb9, 0x6d, 0xab, 0xc9, 0x60, 0xa6, 0x2c, + 0x34, 0x7e, 0x26, 0x03, 0x33, 0x89, 0x9b, 0xc1, 0xc9, 0x5e, 0xa7, 0xfd, 0xdd, 0xbf, 0x06, 0x69, + 0x1f, 0xff, 0xfc, 0xa1, 0xf4, 0xcf, 0x37, 0xfe, 0xbb, 0x11, 0x38, 0xd7, 0x43, 0x51, 0x13, 0xb9, + 0xa7, 0x66, 0x4e, 0x74, 0x4f, 0xfd, 0x2a, 0x4c, 0x96, 0x9b, 0xb6, 0xd3, 0xf2, 0x37, 0xdd, 0xe8, + 0x8b, 0x23, 0x2f, 0x17, 0x2c, 0x13, 0x2e, 0x00, 0xa1, 0x3b, 0xc4, 0xf9, 0x3a, 0x52, 0x58, 0x81, + 0x9b, 0x94, 0x13, 0x35, 0x66, 0x09, 0x07, 0xd1, 0xdc, 0x5f, 0x12, 0x07, 0x51, 0xdd, 0x65, 0x69, + 0xe8, 0xa9, 0xba, 0x2c, 0xa5, 0x9b, 0x3b, 0x0f, 0x3f, 0x89, 0xf1, 0x7b, 0x19, 0x26, 0xb9, 0x35, + 0x58, 0xc9, 0xe7, 0x83, 0x34, 0x92, 0xb0, 0x20, 0xb3, 0xfd, 0xe4, 0x58, 0x68, 0x34, 0x64, 0x45, + 0x77, 0xaf, 0x19, 0xc5, 0xe7, 0xd2, 0xcb, 0xbd, 0xdd, 0x67, 0x34, 0x33, 0x09, 0xcd, 0x8d, 0xe6, + 0x5b, 0x30, 0x97, 0x76, 0xd3, 0x9b, 0xcf, 0x6b, 0x86, 0xa6, 0x3d, 0x0d, 0x94, 0x07, 0xbf, 0x2f, + 0x1e, 0xa4, 0xde, 0x17, 0xa5, 0xdb, 0xf3, 0x98, 0x16, 0xcd, 0xb8, 0xc7, 0x5a, 0xe0, 0xb8, 0xfd, + 0x9d, 0xa3, 0x8d, 0xaf, 0xc2, 0x85, 0xbe, 0xe4, 0xe4, 0x1d, 0x2d, 0xbc, 0xce, 0xab, 0xc9, 0xf0, + 0x3a, 0xdf, 0x3d, 0x2a, 0xce, 0x68, 0x2e, 0x8b, 0x6b, 0xa1, 0xae, 0xdb, 0xf8, 0x99, 0xac, 0xee, + 0x6c, 0xfb, 0x97, 0x71, 0xa1, 0x5e, 0x85, 0xe1, 0xed, 0x7d, 0xea, 0xc9, 0xe3, 0x01, 0x3f, 0xe4, + 0x11, 0x03, 0xa8, 0x1f, 0x82, 0x18, 0xe4, 0x36, 0x4c, 0x6d, 0xf0, 0x89, 0x2b, 0x67, 0xe3, 0x50, + 0xa4, 0x6e, 0xe8, 0x08, 0xa5, 0x58, 0xca, 0x74, 0x8c, 0x51, 0x19, 0x77, 0x62, 0x9d, 0x2e, 0x82, + 0x03, 0x71, 0xa7, 0x20, 0x2e, 0x40, 0x4c, 0x45, 0x6e, 0x50, 0xd1, 0x66, 0x6b, 0xc6, 0xa0, 0xc6, + 0x2e, 0x5c, 0xec, 0xcb, 0x88, 0x9d, 0xdb, 0xd0, 0x09, 0x7f, 0xc5, 0x8c, 0x8e, 0xfb, 0x92, 0x9a, + 0x0a, 0x9d, 0xf1, 0x2d, 0x98, 0x50, 0x7b, 0x19, 0x8f, 0x20, 0xf6, 0x5b, 0xcc, 0x0a, 0x7e, 0x04, + 0x31, 0x80, 0xc9, 0xe1, 0xd1, 0x33, 0x46, 0x36, 0xfd, 0x19, 0x23, 0x1a, 0xfe, 0xdc, 0x49, 0xc3, + 0xcf, 0x2a, 0xc7, 0x1d, 0x4e, 0xa9, 0x1c, 0x7f, 0xab, 0x95, 0x63, 0xf4, 0x1f, 0x93, 0xc3, 0x9f, + 0x6a, 0xe5, 0xff, 0x44, 0xe6, 0xf7, 0x42, 0x9f, 0x23, 0xb9, 0xdc, 0x33, 0x51, 0x92, 0xae, 0xb4, + 0xd5, 0x1b, 0x61, 0x46, 0x32, 0x45, 0xf6, 0x24, 0x99, 0xe2, 0x34, 0x13, 0x11, 0xe5, 0x5e, 0x3e, + 0xa4, 0x43, 0x91, 0x1c, 0x68, 0x27, 0x0c, 0x3d, 0x24, 0x96, 0xf1, 0xed, 0x0c, 0x9c, 0x49, 0x55, + 0x17, 0xb3, 0x5a, 0xb9, 0x5e, 0x5a, 0x59, 0x87, 0x71, 0xa5, 0x34, 0xc7, 0x38, 0x4d, 0xe8, 0x87, + 0xc1, 0xdb, 0x62, 0xbc, 0x08, 0x63, 0xe1, 0x63, 0x25, 0x99, 0x93, 0x43, 0x87, 0x26, 0x81, 0xf2, + 0xcd, 0xab, 0x06, 0xc0, 0xbe, 0xe0, 0xa9, 0x5a, 0x15, 0x1b, 0xff, 0x24, 0xcb, 0x73, 0xbf, 0x3e, + 0xb3, 0x51, 0x5c, 0xd3, 0x4d, 0x81, 0x59, 0x93, 0x7a, 0xc7, 0x6e, 0x25, 0xcb, 0x30, 0x52, 0x0b, + 0xec, 0xa0, 0x2b, 0x23, 0x56, 0xcc, 0xaa, 0x64, 0x58, 0xf0, 0x60, 0x31, 0x8a, 0x59, 0xe0, 0x23, + 0x44, 0xbb, 0x20, 0x23, 0x44, 0xb1, 0x28, 0xfe, 0x83, 0x0c, 0x4c, 0xa8, 0xc4, 0xe4, 0x43, 0x98, + 0x92, 0xb1, 0x29, 0x79, 0x1c, 0x0f, 0xf1, 0xb2, 0x2a, 0xad, 0xa0, 0x64, 0x6c, 0x4a, 0x35, 0xee, + 0x87, 0x86, 0xaf, 0x6e, 0xd5, 0x1d, 0x15, 0x99, 0x34, 0x80, 0xb4, 0x76, 0x6d, 0xeb, 0x11, 0xb5, + 0x0f, 0xa8, 0x1f, 0x58, 0xdc, 0x5a, 0x45, 0x3c, 0xc0, 0x4a, 0xf6, 0x6b, 0xb7, 0x4b, 0xdc, 0x50, + 0x85, 0x8d, 0x84, 0x08, 0x32, 0x9a, 0xa0, 0x51, 0x5f, 0x95, 0x5a, 0xbb, 0xf6, 0x36, 0x2f, 0xe4, + 0x74, 0xc6, 0x9f, 0x8e, 0xf0, 0xe9, 0x26, 0x42, 0xd9, 0xee, 0xc0, 0xd4, 0xfd, 0x6a, 0xa5, 0xac, + 0xe8, 0x98, 0xf5, 0x4c, 0x48, 0xcb, 0x8f, 0x03, 0xea, 0xb5, 0xed, 0xa6, 0xbc, 0xef, 0x46, 0x47, + 0x90, 0xeb, 0x34, 0xea, 0xe9, 0xfa, 0xe7, 0x18, 0x47, 0x56, 0x07, 0xbf, 0x59, 0x87, 0x75, 0x64, + 0x07, 0xac, 0xc3, 0xb7, 0x5b, 0xcd, 0x1e, 0x75, 0xe8, 0x1c, 0xc9, 0x3e, 0x5e, 0x7d, 0xf7, 0xbb, + 0x3b, 0x4a, 0x2d, 0xb9, 0xfe, 0xb5, 0xbc, 0x24, 0x6a, 0x79, 0x5e, 0x68, 0x14, 0x52, 0xeb, 0x49, + 0x70, 0x8d, 0xf6, 0x89, 0xa1, 0x13, 0xf7, 0x89, 0xbf, 0x99, 0x81, 0x11, 0x2e, 0xbe, 0x8a, 0x69, + 0xdc, 0x43, 0x40, 0xde, 0x7e, 0x3a, 0x02, 0x72, 0x01, 0xcf, 0x09, 0x6d, 0x42, 0xf3, 0x32, 0x52, + 0x89, 0xad, 0x0b, 0x69, 0x08, 0x8f, 0xaf, 0x45, 0xbc, 0xe4, 0xe4, 0x65, 0x41, 0xaa, 0x51, 0x14, + 0x89, 0xd1, 0x13, 0x1d, 0x95, 0x65, 0xe4, 0x8d, 0x51, 0x11, 0x45, 0x42, 0x8f, 0x1d, 0xb1, 0x0a, + 0x63, 0x22, 0x36, 0xc5, 0xd2, 0xa1, 0x78, 0x13, 0x2e, 0x68, 0x56, 0x3d, 0x8d, 0xa5, 0xc3, 0x48, + 0x34, 0x17, 0xd1, 0x2d, 0xac, 0x9d, 0x43, 0x2d, 0x95, 0xae, 0x44, 0x24, 0xf7, 0x79, 0x8a, 0x49, + 0x1e, 0xec, 0x57, 0x8f, 0xee, 0x1f, 0xc2, 0x45, 0xd4, 0x2b, 0xe9, 0xe0, 0x9e, 0x12, 0xdb, 0x37, + 0xe2, 0x41, 0x56, 0xa1, 0x80, 0x96, 0x60, 0xb4, 0xc1, 0x57, 0x4d, 0xb5, 0xc2, 0xe3, 0x1f, 0x08, + 0x6b, 0xde, 0x80, 0x97, 0x89, 0xe5, 0x16, 0x73, 0x3d, 0x4c, 0x50, 0xb2, 0xeb, 0x74, 0x21, 0x3e, + 0xfb, 0xc8, 0xbb, 0x30, 0x1e, 0x06, 0x5b, 0x0e, 0x9d, 0x9f, 0xf1, 0x6d, 0x28, 0x8a, 0xce, 0xac, + 0x27, 0x26, 0x54, 0xd0, 0xc9, 0x22, 0xe4, 0xd9, 0x22, 0x8e, 0x27, 0xf1, 0xed, 0x0a, 0x98, 0xea, + 0x8c, 0x24, 0xf1, 0x48, 0x0d, 0x66, 0xd9, 0xa2, 0xa9, 0x39, 0xed, 0xbd, 0x26, 0x5d, 0x75, 0xf7, + 0xdc, 0x6e, 0x10, 0xe5, 0xe9, 0xe3, 0x17, 0x18, 0xbb, 0xd5, 0xd4, 0x8a, 0xf5, 0x2c, 0x7d, 0x29, + 0xd4, 0xca, 0x56, 0xf9, 0x47, 0x59, 0x18, 0x57, 0xe6, 0x13, 0xb9, 0x0a, 0xf9, 0xaa, 0xbf, 0xea, + 0xd6, 0x0f, 0xc2, 0xb0, 0x88, 0x93, 0xc7, 0x47, 0xc5, 0x31, 0xc7, 0xb7, 0x9a, 0x08, 0x34, 0xc3, + 0x62, 0xb2, 0x04, 0x93, 0xfc, 0x2f, 0x99, 0x04, 0x23, 0x1b, 0x29, 0xcb, 0x38, 0xb2, 0x4c, 0x7f, + 0xa1, 0xee, 0x9e, 0x1a, 0x09, 0xf9, 0x1a, 0x00, 0x07, 0xa0, 0x23, 0x7d, 0x6e, 0xf0, 0x10, 0x00, + 0xa2, 0x82, 0x14, 0x17, 0x7a, 0x85, 0x21, 0xf9, 0x06, 0x0f, 0xce, 0x2c, 0xe7, 0xff, 0xd0, 0xe0, + 0x31, 0x0c, 0x18, 0x7f, 0x2b, 0x3d, 0x94, 0x8a, 0xca, 0x52, 0xe4, 0xad, 0x59, 0x30, 0x69, 0xdd, + 0x7d, 0x48, 0xbd, 0xc3, 0x52, 0x80, 0x88, 0x0a, 0x86, 0xf1, 0xbf, 0x66, 0x94, 0x55, 0x43, 0xd6, + 0x31, 0xef, 0x34, 0x9f, 0x11, 0xc2, 0x3c, 0x2a, 0xbc, 0x33, 0x48, 0xb8, 0x49, 0x77, 0x97, 0x9e, + 0x17, 0x96, 0x5a, 0xb3, 0xe1, 0xbc, 0x8a, 0xe5, 0xa3, 0xe6, 0x40, 0xf2, 0x45, 0x18, 0xc2, 0xae, + 0xcb, 0x9e, 0xd8, 0x34, 0x79, 0x6c, 0x0f, 0xb1, 0x3e, 0xc3, 0x86, 0x20, 0x25, 0xf9, 0x8c, 0x70, + 0x42, 0xe6, 0x9d, 0x3f, 0xa5, 0x9c, 0xbd, 0xec, 0x3b, 0xc2, 0xf3, 0x3a, 0x8a, 0xa6, 0xa3, 0xcc, + 0x9e, 0xbf, 0x93, 0x85, 0x42, 0x7c, 0xad, 0x92, 0x0f, 0x60, 0x42, 0x9e, 0xa7, 0x2b, 0xb6, 0xc8, + 0xe0, 0x30, 0x21, 0x32, 0x28, 0xc8, 0x43, 0x75, 0xdf, 0x56, 0xcd, 0xa9, 0x4c, 0x8d, 0x80, 0x09, + 0x37, 0x9b, 0x22, 0xba, 0x9d, 0xb2, 0x4a, 0x02, 0x37, 0xe8, 0xc4, 0x62, 0x02, 0x4b, 0x34, 0xf2, + 0x16, 0xe4, 0xd6, 0x6e, 0x97, 0x84, 0xb3, 0x5a, 0x21, 0x7e, 0xea, 0x72, 0xab, 0x4f, 0xdd, 0x06, + 0x95, 0xe1, 0x93, 0x55, 0x25, 0x7c, 0xf6, 0x88, 0x66, 0x3a, 0x27, 0xc1, 0x61, 0xe3, 0x4e, 0x8e, + 0xa3, 0x7d, 0x77, 0x28, 0x9f, 0x2b, 0x0c, 0x89, 0x80, 0xb0, 0xff, 0x43, 0x0e, 0xc6, 0xc2, 0xfa, + 0x09, 0x51, 0x5d, 0x80, 0xb9, 0xbb, 0x2f, 0x39, 0x0f, 0x79, 0x29, 0xae, 0x09, 0x9f, 0xb5, 0x51, + 0x5f, 0x88, 0x6a, 0xf3, 0x20, 0xe5, 0x32, 0xbe, 0xcc, 0x4d, 0xf9, 0x93, 0xdc, 0x80, 0x50, 0xe8, + 0xea, 0x25, 0x9d, 0x0d, 0xb1, 0x01, 0x33, 0x43, 0x34, 0x32, 0x05, 0x59, 0x87, 0x07, 0x19, 0x1b, + 0x33, 0xb3, 0x4e, 0x83, 0x7c, 0x00, 0x79, 0xbb, 0xd1, 0xa0, 0x0d, 0xcb, 0x96, 0x76, 0x46, 0xfd, + 0x26, 0x4d, 0x9e, 0x71, 0xe3, 0x87, 0x00, 0x52, 0x95, 0x02, 0x52, 0x82, 0xb1, 0xa6, 0xcd, 0x2d, + 0x17, 0x1b, 0x03, 0x9c, 0x28, 0x11, 0x87, 0x3c, 0x23, 0xdb, 0xf2, 0x69, 0x83, 0xbc, 0x0a, 0x43, + 0x6c, 0x34, 0xc5, 0x11, 0x22, 0xa5, 0x44, 0x36, 0x98, 0xbc, 0xc3, 0x56, 0x9e, 0x33, 0x11, 0x81, + 0xbc, 0x0c, 0xb9, 0xee, 0xe2, 0xae, 0x38, 0x1c, 0x0a, 0x51, 0x28, 0xfb, 0x10, 0x8d, 0x15, 0x93, + 0x9b, 0x90, 0x7f, 0xa4, 0x47, 0x41, 0x3f, 0x13, 0x1b, 0xc6, 0x10, 0x3f, 0x44, 0x24, 0xaf, 0x42, + 0xce, 0xf7, 0x5d, 0x61, 0x9c, 0x33, 0x1b, 0x5a, 0x4c, 0xde, 0x0f, 0x47, 0x8d, 0x71, 0xf7, 0x7d, + 0x77, 0x29, 0x0f, 0x23, 0xfc, 0xc4, 0x30, 0x2e, 0x02, 0x44, 0xdf, 0x98, 0xf4, 0x41, 0x34, 0xbe, + 0x06, 0x63, 0xe1, 0xb7, 0x91, 0x0b, 0x00, 0x07, 0xf4, 0xd0, 0xda, 0xb7, 0xdb, 0x8d, 0x26, 0x17, + 0x37, 0x27, 0xcc, 0xb1, 0x03, 0x7a, 0xb8, 0x82, 0x00, 0x72, 0x0e, 0x46, 0x3b, 0x6c, 0xf8, 0xc5, + 0x1c, 0x9f, 0x30, 0x47, 0x3a, 0xdd, 0x1d, 0x36, 0x95, 0xe7, 0x61, 0x14, 0x15, 0xa7, 0x62, 0x45, + 0x4e, 0x9a, 0xf2, 0xa7, 0xf1, 0x67, 0x39, 0x4c, 0x15, 0xa4, 0x34, 0x88, 0xbc, 0x04, 0x93, 0x75, + 0x8f, 0xe2, 0xe1, 0x64, 0x33, 0x91, 0x4b, 0xd4, 0x33, 0x11, 0x01, 0xab, 0x0d, 0x72, 0x19, 0xa6, + 0x3b, 0xdd, 0x9d, 0xa6, 0x53, 0x67, 0xb5, 0x59, 0xf5, 0x1d, 0x91, 0xdb, 0x60, 0xc2, 0x9c, 0xe4, + 0xe0, 0x7b, 0xf4, 0xb0, 0xbc, 0x83, 0x51, 0xf4, 0x0a, 0x6a, 0x10, 0xe4, 0x20, 0x4c, 0xe2, 0x6e, + 0x4e, 0x2b, 0x70, 0xb4, 0x33, 0x3c, 0x0b, 0x23, 0xb6, 0xbd, 0xd7, 0x75, 0x78, 0xb4, 0xab, 0x09, + 0x53, 0xfc, 0x22, 0xaf, 0xc3, 0x4c, 0x14, 0x97, 0x5b, 0x36, 0x63, 0x18, 0x9b, 0x51, 0x08, 0x0b, + 0xca, 0x1c, 0x4e, 0xde, 0x04, 0xa2, 0xd6, 0xe7, 0xee, 0x7c, 0x44, 0xeb, 0x7c, 0x4e, 0x4e, 0x98, + 0x33, 0x4a, 0xc9, 0x7d, 0x2c, 0x20, 0x2f, 0xc2, 0x84, 0x47, 0x7d, 0x14, 0xf7, 0xb0, 0xdb, 0x30, + 0x93, 0x9e, 0x39, 0x2e, 0x61, 0xac, 0xef, 0xae, 0x40, 0x41, 0xe9, 0x0e, 0x8c, 0x33, 0xcd, 0x03, + 0xfb, 0x9b, 0x53, 0x11, 0xdc, 0xec, 0x54, 0x1b, 0xe4, 0xcb, 0xb0, 0xa0, 0x60, 0xf2, 0xa4, 0x7e, + 0x16, 0x6d, 0x3a, 0x7b, 0xce, 0x4e, 0x93, 0x8a, 0xf9, 0x96, 0x9c, 0xd5, 0xe1, 0x9d, 0xd0, 0x9c, + 0x8f, 0xa8, 0x79, 0xba, 0xbf, 0x65, 0x41, 0x4b, 0x56, 0x61, 0x2e, 0xc6, 0x99, 0x36, 0xac, 0x6e, + 0xa7, 0x67, 0x78, 0xb9, 0x88, 0x27, 0xd1, 0x79, 0xd2, 0xc6, 0x56, 0xc7, 0xf8, 0x16, 0x4c, 0xa8, + 0x73, 0x92, 0x75, 0x82, 0x2a, 0x68, 0x88, 0xd9, 0x37, 0x1e, 0xc2, 0xaa, 0xec, 0xa2, 0x37, 0x15, + 0xa1, 0x04, 0x61, 0xbe, 0x7a, 0x73, 0x32, 0x84, 0xe2, 0x10, 0xbe, 0x08, 0x13, 0x0d, 0xc7, 0xef, + 0x34, 0xed, 0x43, 0x2b, 0xca, 0x56, 0x6d, 0x8e, 0x0b, 0x18, 0x6a, 0x72, 0x96, 0x60, 0x26, 0xb1, + 0x0f, 0x92, 0x37, 0xf9, 0x0d, 0x55, 0x08, 0x3f, 0x13, 0xfc, 0x96, 0x8f, 0x56, 0xcc, 0x9a, 0xdc, + 0x23, 0x90, 0x8c, 0x36, 0x4c, 0xa8, 0xe7, 0xda, 0x09, 0x49, 0x38, 0xce, 0x62, 0x48, 0x19, 0xbe, + 0xe9, 0x8f, 0x1c, 0x1f, 0x15, 0xb3, 0x4e, 0x03, 0x03, 0xc9, 0x5c, 0x81, 0xbc, 0x14, 0xc1, 0x84, + 0xe4, 0x83, 0xaf, 0x03, 0x32, 0x43, 0xb1, 0x19, 0x96, 0x1a, 0xaf, 0xc2, 0xa8, 0x38, 0xba, 0xfa, + 0xbf, 0x09, 0x18, 0x3f, 0x9c, 0x85, 0x69, 0x93, 0xb2, 0x8d, 0x95, 0xf2, 0xcc, 0x3b, 0xcf, 0xec, + 0x9d, 0x3b, 0x3d, 0x30, 0xa9, 0xd6, 0xb6, 0x3e, 0x39, 0x6f, 0x7e, 0x25, 0x03, 0xb3, 0x29, 0xb8, + 0x1f, 0x2b, 0xe7, 0xeb, 0x2d, 0x18, 0xab, 0x38, 0x76, 0xb3, 0xd4, 0x68, 0x84, 0xf1, 0x65, 0x50, + 0x70, 0xc7, 0xc4, 0x50, 0x36, 0x83, 0xaa, 0x42, 0x4c, 0x88, 0x4a, 0x5e, 0x13, 0x93, 0x22, 0xca, + 0x98, 0x8e, 0x93, 0xe2, 0xbb, 0x47, 0x45, 0xe0, 0xdf, 0xb4, 0x19, 0x4e, 0x11, 0x0c, 0x16, 0xcc, + 0x81, 0x91, 0x8f, 0xd0, 0x33, 0x3b, 0x74, 0xe9, 0xc1, 0x82, 0xe3, 0xcd, 0x1b, 0x28, 0xed, 0xcd, + 0x4f, 0x64, 0xe1, 0x6c, 0x3a, 0xe1, 0xc7, 0x4d, 0xdf, 0x8b, 0x09, 0x87, 0x94, 0x00, 0xe7, 0x98, + 0xbe, 0x97, 0x67, 0x27, 0x42, 0xfc, 0x08, 0x81, 0xec, 0xc2, 0xe4, 0xaa, 0xed, 0x07, 0x2b, 0xd4, + 0xf6, 0x82, 0x1d, 0x6a, 0x07, 0x03, 0x48, 0xf2, 0xd2, 0x32, 0x60, 0x1e, 0x85, 0x89, 0x7d, 0x49, + 0x19, 0x93, 0xb5, 0x75, 0xb6, 0xe1, 0x44, 0x19, 0x1a, 0x60, 0xa2, 0x7c, 0x13, 0xa6, 0x6b, 0xb4, + 0x65, 0x77, 0xf6, 0x5d, 0x4f, 0xfa, 0xfe, 0x5f, 0x83, 0xc9, 0x10, 0x94, 0x3a, 0x5b, 0xf4, 0x62, + 0x0d, 0x5f, 0xe9, 0x88, 0x68, 0x2b, 0xd1, 0x8b, 0x8d, 0xbf, 0x9b, 0x85, 0x73, 0xa5, 0xba, 0x30, + 0x73, 0x14, 0x05, 0xd2, 0x1a, 0xfb, 0x13, 0xae, 0x9b, 0x5c, 0x87, 0xb1, 0x35, 0xfb, 0xf1, 0x2a, + 0xb5, 0x7d, 0xea, 0x8b, 0xe4, 0x89, 0x5c, 0xec, 0xb5, 0x1f, 0x47, 0xaf, 0x39, 0x66, 0x84, 0xa3, + 0xea, 0x05, 0x86, 0x9e, 0x50, 0x2f, 0x60, 0xc0, 0xc8, 0x8a, 0xdb, 0x6c, 0x88, 0xb3, 0x5e, 0x3c, + 0x21, 0xef, 0x23, 0xc4, 0x14, 0x25, 0xec, 0x3a, 0x3d, 0x15, 0x7e, 0x31, 0x7e, 0xc2, 0x27, 0xde, + 0x25, 0x97, 0x61, 0x14, 0x2b, 0x0a, 0xb3, 0xbc, 0xe3, 0xa1, 0xd1, 0xa4, 0x98, 0x02, 0xaf, 0x61, + 0xca, 0x42, 0xb5, 0x27, 0x86, 0x9f, 0xac, 0x27, 0x8c, 0x7f, 0x88, 0xaf, 0xd3, 0x6a, 0x2b, 0xd9, + 0x49, 0xa4, 0x7c, 0x48, 0x66, 0xc0, 0x0f, 0xc9, 0x3e, 0xb5, 0x21, 0xc9, 0xf5, 0x1c, 0x92, 0x1f, + 0xc9, 0xc2, 0x78, 0xf8, 0xb1, 0x9f, 0xb2, 0x28, 0xfb, 0x61, 0xbb, 0x06, 0x8a, 0xd7, 0x53, 0x53, + 0xf6, 0x0a, 0x11, 0x16, 0xe7, 0x8b, 0x30, 0x22, 0x16, 0x53, 0x26, 0x66, 0x95, 0x1c, 0x1b, 0xdd, + 0xa5, 0x29, 0xc1, 0x7a, 0x04, 0x07, 0xd4, 0x37, 0x05, 0x1d, 0x06, 0x44, 0xda, 0xa6, 0x3b, 0xc2, + 0x58, 0xe1, 0x99, 0x3d, 0xa3, 0xd2, 0x03, 0x22, 0x45, 0x0d, 0x1b, 0xe8, 0x74, 0xfa, 0xa7, 0x79, + 0x28, 0xc4, 0x49, 0x4e, 0xce, 0x63, 0xb0, 0xd1, 0xdd, 0xe1, 0x57, 0x15, 0x9e, 0xc7, 0xa0, 0xd3, + 0xdd, 0x31, 0x19, 0x0c, 0x6d, 0x99, 0x3c, 0xe7, 0x21, 0xb6, 0x7a, 0x42, 0xd8, 0x32, 0x79, 0xce, + 0x43, 0xcd, 0x96, 0xc9, 0x73, 0x1e, 0xa2, 0x22, 0x61, 0xb5, 0x86, 0xc1, 0x02, 0xf0, 0x9e, 0x22, + 0x14, 0x09, 0x4d, 0x3f, 0x9e, 0x93, 0x4c, 0xa2, 0xb1, 0xa3, 0x72, 0x89, 0xda, 0x9e, 0x88, 0xb9, + 0x2f, 0xb6, 0x33, 0x3c, 0x2a, 0x77, 0x10, 0x6c, 0x05, 0x0c, 0x6e, 0xaa, 0x48, 0xa4, 0x09, 0x44, + 0xf9, 0x29, 0x17, 0xf0, 0xc9, 0x77, 0x6b, 0x69, 0x51, 0x38, 0xa7, 0xb2, 0xb6, 0xd4, 0xd5, 0x9c, + 0xc2, 0xf7, 0x69, 0xaa, 0x73, 0x37, 0x44, 0x20, 0x51, 0x54, 0x20, 0xe5, 0x4f, 0x64, 0x26, 0x83, + 0x9c, 0x00, 0x0f, 0x34, 0x1a, 0xaa, 0x91, 0x22, 0x26, 0xe4, 0x7d, 0x18, 0x57, 0x43, 0x40, 0xf0, + 0x40, 0x05, 0x2f, 0xf0, 0xd8, 0x90, 0x3d, 0xb2, 0xd8, 0xaa, 0x04, 0x64, 0x07, 0xce, 0x95, 0xdd, + 0xb6, 0xdf, 0x6d, 0xc9, 0x28, 0x94, 0x51, 0xec, 0x6b, 0xc0, 0xa1, 0x40, 0x7f, 0xf2, 0xba, 0x40, + 0x11, 0x11, 0x07, 0xa4, 0xcb, 0x87, 0x7e, 0x01, 0xe9, 0xc5, 0x88, 0x6c, 0xc2, 0x38, 0xaa, 0x44, + 0x85, 0x4d, 0xe9, 0xb8, 0xbe, 0x6d, 0x44, 0x25, 0x15, 0xb6, 0x30, 0x78, 0x04, 0x34, 0xbb, 0xd5, + 0x94, 0x1e, 0x07, 0xaa, 0x6a, 0x57, 0x41, 0x26, 0x5f, 0x83, 0x29, 0x7e, 0x45, 0xdb, 0xa6, 0x3b, + 0x7c, 0xee, 0x4c, 0x68, 0x9a, 0x08, 0xbd, 0x90, 0xbf, 0xce, 0x0b, 0x45, 0xf4, 0x23, 0xba, 0xc3, + 0xc7, 0x5e, 0xf3, 0xf7, 0xd1, 0xf0, 0xc9, 0x16, 0xcc, 0xae, 0xd8, 0x3e, 0x07, 0x2a, 0xbe, 0xfc, + 0x93, 0xa8, 0xa1, 0x45, 0x3b, 0xec, 0x7d, 0xdb, 0x97, 0x9a, 0xed, 0x54, 0xdf, 0xfd, 0x34, 0x7a, + 0xf2, 0xc3, 0x19, 0x98, 0xd7, 0x14, 0xdf, 0xc2, 0x70, 0xac, 0x45, 0xdb, 0x01, 0x3a, 0xf6, 0x4c, + 0x2d, 0x16, 0xa5, 0x50, 0xda, 0x03, 0x8d, 0x0f, 0x49, 0x4c, 0xb7, 0xee, 0x45, 0xe5, 0xaa, 0x81, + 0x73, 0x2f, 0x1e, 0x62, 0xa1, 0xe2, 0x9a, 0x9e, 0xd6, 0x17, 0x6a, 0x6c, 0x5d, 0x4b, 0x34, 0xe3, + 0x56, 0xbc, 0xbf, 0x85, 0xa2, 0x2b, 0x13, 0x2a, 0xba, 0xe6, 0x60, 0x18, 0x7b, 0x55, 0x46, 0x84, + 0xc2, 0x1f, 0xc6, 0x67, 0xd4, 0x7d, 0x48, 0x88, 0x85, 0x7d, 0xf7, 0x21, 0xe3, 0x7f, 0x1a, 0x81, + 0xe9, 0xd8, 0xb4, 0x10, 0xf7, 0xd4, 0x4c, 0xe2, 0x9e, 0x5a, 0x03, 0xe0, 0xaa, 0xde, 0x01, 0x75, + 0xb2, 0xd2, 0xa9, 0x70, 0x5c, 0xb8, 0x04, 0x87, 0x6b, 0x4a, 0x61, 0xc3, 0x98, 0xf2, 0x15, 0x3b, + 0xa0, 0x8e, 0x3c, 0x64, 0xca, 0x17, 0xbd, 0xc2, 0x34, 0x62, 0x43, 0x8a, 0x30, 0x8c, 0xb1, 0x60, + 0x55, 0x9f, 0x4e, 0x87, 0x01, 0x4c, 0x0e, 0x27, 0x2f, 0xc1, 0x08, 0x13, 0xa2, 0xaa, 0x15, 0xb1, + 0x09, 0xe2, 0xd9, 0xc2, 0xa4, 0x2c, 0x26, 0xb1, 0x88, 0x22, 0x72, 0x0b, 0x26, 0xf8, 0x5f, 0x22, + 0x64, 0xcc, 0x88, 0x6e, 0xcd, 0x68, 0x39, 0x0d, 0x19, 0x35, 0x46, 0xc3, 0x63, 0xb7, 0x8b, 0x5a, + 0x17, 0xd5, 0x3a, 0xd5, 0x8a, 0x08, 0x1e, 0x8e, 0xb7, 0x0b, 0x9f, 0x03, 0x59, 0x15, 0x11, 0x02, + 0x93, 0x65, 0x84, 0x67, 0x45, 0x1e, 0xef, 0x94, 0x28, 0xcb, 0x70, 0x8f, 0x0a, 0x53, 0x94, 0x90, + 0xab, 0xfc, 0x69, 0x05, 0xc5, 0x42, 0x9e, 0x83, 0x11, 0xdf, 0x2d, 0x50, 0x31, 0x81, 0xb2, 0x61, + 0x58, 0xcc, 0x2a, 0x67, 0x7f, 0x2f, 0xb7, 0x6c, 0xa7, 0x29, 0xb6, 0x15, 0xac, 0x1c, 0x71, 0x29, + 0x83, 0x9a, 0x11, 0x02, 0x79, 0x17, 0xa6, 0xd8, 0x8f, 0xb2, 0xdb, 0x6a, 0xb9, 0x6d, 0x64, 0x3f, + 0x1e, 0x05, 0x85, 0x43, 0x92, 0x3a, 0x16, 0xf1, 0x5a, 0x62, 0xb8, 0xec, 0x3c, 0xc1, 0x67, 0xdb, + 0x2e, 0x7f, 0xf4, 0x99, 0x88, 0xce, 0x13, 0x24, 0xf5, 0x39, 0xdc, 0x54, 0x91, 0xc8, 0xdb, 0x30, + 0xc9, 0x7e, 0xde, 0x71, 0x1e, 0x52, 0x5e, 0xe1, 0x64, 0x64, 0xaf, 0x80, 0x54, 0x7b, 0xac, 0x84, + 0xd7, 0xa7, 0x63, 0x92, 0x2f, 0xc1, 0x19, 0xe4, 0x54, 0x77, 0x3b, 0xb4, 0x51, 0xda, 0xdd, 0x75, + 0x9a, 0x0e, 0x37, 0x2f, 0xe3, 0xc1, 0x51, 0x50, 0x07, 0xcf, 0x2b, 0x46, 0x0c, 0xcb, 0x8e, 0x50, + 0xcc, 0x74, 0x4a, 0xb2, 0x0d, 0x85, 0x72, 0xd7, 0x0f, 0xdc, 0x56, 0x29, 0x08, 0x3c, 0x67, 0xa7, + 0x1b, 0x50, 0x7f, 0x7e, 0x5a, 0x0b, 0x21, 0xc2, 0x16, 0x47, 0x58, 0xc8, 0xf5, 0x41, 0x75, 0xa4, + 0xb0, 0xec, 0x90, 0xc4, 0x4c, 0x30, 0x31, 0xfe, 0x59, 0x06, 0x26, 0x35, 0x52, 0xf2, 0x16, 0x4c, + 0xdc, 0xf6, 0x1c, 0xda, 0x6e, 0x34, 0x0f, 0x95, 0x8b, 0x2a, 0xde, 0x62, 0x76, 0x05, 0x9c, 0xb7, + 0x5a, 0x43, 0x0b, 0xf5, 0x3c, 0xd9, 0x54, 0xdb, 0xcf, 0xeb, 0xdc, 0xb5, 0x58, 0x4c, 0xd0, 0x5c, + 0x14, 0xd3, 0x08, 0x27, 0xa8, 0x98, 0x9d, 0x0a, 0x0a, 0x79, 0x0f, 0x46, 0xf8, 0x03, 0xaf, 0x30, + 0x44, 0x3c, 0x9f, 0xd6, 0x4c, 0xee, 0xc6, 0x8e, 0x13, 0x11, 0xad, 0x78, 0x7c, 0x53, 0x10, 0x19, + 0x3f, 0x9b, 0x01, 0x92, 0x44, 0x3d, 0x41, 0xef, 0x75, 0xa2, 0x75, 0xd0, 0x17, 0xc3, 0xd5, 0x98, + 0xd3, 0x74, 0xe6, 0xac, 0x26, 0x5e, 0xc0, 0x3b, 0x5e, 0xac, 0x3a, 0x55, 0x11, 0xc7, 0x8b, 0x8d, + 0x1f, 0xca, 0x02, 0x44, 0xd8, 0xe4, 0xf3, 0x3c, 0xe5, 0xd6, 0x97, 0xba, 0x76, 0xd3, 0xd9, 0x75, + 0xf4, 0x18, 0xb4, 0xc8, 0xe4, 0x9b, 0xb2, 0xc4, 0xd4, 0x11, 0xc9, 0x07, 0x30, 0x5d, 0xdb, 0xd0, + 0x69, 0x15, 0x3b, 0x77, 0xbf, 0x63, 0xc5, 0xc8, 0xe3, 0xd8, 0x68, 0x70, 0xac, 0x8e, 0x06, 0x37, + 0x38, 0xe6, 0x03, 0x21, 0x4a, 0xd8, 0xc6, 0x52, 0xdb, 0x10, 0xa6, 0xfc, 0x8d, 0x6a, 0x45, 0xec, + 0x52, 0xf8, 0x75, 0x7e, 0xc7, 0xea, 0x08, 0x1b, 0x7f, 0xb6, 0x4f, 0x68, 0x78, 0x51, 0x47, 0x0e, + 0xf7, 0x70, 0x55, 0xff, 0x39, 0x54, 0xfb, 0xb5, 0xdc, 0x80, 0x0a, 0x6d, 0xc7, 0x33, 0x7b, 0xef, + 0x89, 0xac, 0x03, 0x86, 0x35, 0x0f, 0x5c, 0xad, 0x75, 0xc2, 0x02, 0xe6, 0x66, 0x74, 0x49, 0xe1, + 0x76, 0x02, 0x29, 0x46, 0x33, 0xff, 0x20, 0x03, 0x67, 0x52, 0x69, 0xc9, 0x35, 0x80, 0x48, 0xa7, + 0x24, 0x7a, 0x09, 0x77, 0xcc, 0x28, 0x92, 0x8f, 0xa9, 0x60, 0x90, 0xaf, 0xc6, 0xb5, 0x41, 0x27, + 0x1f, 0x84, 0x0b, 0x32, 0x80, 0x9e, 0xae, 0x0d, 0x4a, 0xd1, 0x01, 0x19, 0xbf, 0x92, 0x83, 0x19, + 0x25, 0x50, 0x10, 0xff, 0xd6, 0x13, 0x0c, 0xc0, 0x0f, 0x60, 0x82, 0xb5, 0xc6, 0xa9, 0x0b, 0x37, + 0x40, 0x6e, 0xc9, 0xf2, 0x5a, 0xc2, 0x87, 0x52, 0x70, 0xbb, 0xa6, 0x22, 0xf3, 0xb0, 0x96, 0xb8, + 0x75, 0xe2, 0x83, 0x44, 0x3d, 0xe9, 0x0e, 0xa8, 0x31, 0x27, 0x3e, 0x4c, 0x56, 0x0e, 0xdb, 0x76, + 0x2b, 0xac, 0x8d, 0x5b, 0xb4, 0xbc, 0xde, 0xb3, 0x36, 0x0d, 0x9b, 0x57, 0x17, 0x79, 0x1b, 0xf1, + 0xb2, 0x14, 0x47, 0x77, 0x8d, 0x6a, 0xe1, 0x03, 0x98, 0x49, 0x7c, 0xf4, 0xa9, 0x22, 0x6c, 0x6e, + 0x03, 0x49, 0x7e, 0x47, 0x0a, 0x87, 0xd7, 0xf5, 0xf8, 0xad, 0x67, 0xc2, 0xc7, 0xeb, 0x56, 0xcb, + 0x6e, 0x37, 0xb8, 0x7d, 0xcc, 0xa2, 0x1a, 0x7f, 0xf3, 0xe7, 0xb2, 0xaa, 0x1f, 0xeb, 0xb3, 0xbe, + 0xea, 0xbe, 0xa8, 0xdd, 0x86, 0x2f, 0xf6, 0x1a, 0xd3, 0x81, 0xb4, 0x0e, 0xdf, 0xc9, 0xc1, 0xb9, + 0x1e, 0x94, 0xe4, 0x30, 0x3e, 0x89, 0xb8, 0x16, 0xe2, 0x46, 0xff, 0x0a, 0x9f, 0xc6, 0x54, 0x22, + 0x9f, 0xe7, 0x91, 0x2c, 0xea, 0x98, 0xf8, 0x5e, 0xdc, 0xbf, 0x51, 0x8d, 0x7f, 0x10, 0x42, 0xe3, + 0x21, 0x2c, 0x38, 0x94, 0x7c, 0x00, 0xc3, 0xe8, 0xc4, 0x1c, 0x0b, 0x55, 0xc8, 0x30, 0x10, 0xae, + 0x04, 0xdb, 0x64, 0x3f, 0xb5, 0x60, 0x9b, 0x0c, 0x40, 0x3e, 0x07, 0xb9, 0xd2, 0x76, 0x4d, 0x8c, + 0xcb, 0x94, 0x4a, 0xbe, 0x5d, 0x8b, 0x12, 0x85, 0xd8, 0x5a, 0x46, 0x0f, 0x46, 0xc1, 0x08, 0xef, + 0x94, 0x37, 0xc4, 0xa8, 0xa8, 0x84, 0x77, 0xca, 0x1b, 0x11, 0xe1, 0x5e, 0x5d, 0x0b, 0xfc, 0x74, + 0xa7, 0xbc, 0xf1, 0xc9, 0x4d, 0xfb, 0x7f, 0x27, 0xcb, 0xc3, 0x6f, 0xf0, 0x86, 0x7d, 0x00, 0x13, + 0x5a, 0x7c, 0xed, 0x4c, 0x24, 0x8f, 0x85, 0xb1, 0xd0, 0x63, 0x26, 0x40, 0x1a, 0x81, 0x4c, 0xb9, + 0xc3, 0x7e, 0xa3, 0xc4, 0xab, 0x1a, 0xdb, 0x84, 0x1c, 0x50, 0x26, 0x8e, 0xa7, 0xdc, 0x09, 0x49, + 0xc8, 0x4d, 0xc8, 0x6f, 0xd2, 0xb6, 0xdd, 0x0e, 0x42, 0x85, 0x28, 0x5a, 0x0b, 0x07, 0x08, 0xd3, + 0xa5, 0x86, 0x10, 0x11, 0x2d, 0x5b, 0xbb, 0x3b, 0x7e, 0xdd, 0x73, 0x30, 0x4c, 0x4f, 0x78, 0x16, + 0x73, 0xcb, 0x56, 0xa5, 0x44, 0x67, 0x10, 0x23, 0x32, 0x7e, 0x2e, 0x03, 0xa3, 0x62, 0x20, 0x79, + 0xaa, 0xb4, 0xbd, 0xe8, 0x2c, 0x11, 0xde, 0x00, 0x7b, 0x4e, 0xdc, 0x1b, 0x60, 0x8f, 0xc7, 0xc2, + 0x19, 0x13, 0x9e, 0x72, 0xe1, 0xd3, 0x20, 0xce, 0x46, 0xe9, 0xc2, 0xa8, 0x67, 0xc2, 0x0a, 0x51, + 0x07, 0xf5, 0xb0, 0x32, 0xfe, 0x9e, 0xf8, 0xb2, 0x3b, 0xe5, 0x0d, 0xb2, 0x08, 0xf9, 0x55, 0x97, + 0x87, 0x75, 0x52, 0xf3, 0xde, 0x36, 0x05, 0x4c, 0xed, 0x20, 0x89, 0xc7, 0xbe, 0x6f, 0xc3, 0x73, + 0xc5, 0x5d, 0x46, 0xf9, 0xbe, 0x0e, 0x07, 0xc6, 0xbe, 0x2f, 0x44, 0x1d, 0xf8, 0xfb, 0x68, 0xca, + 0x26, 0xf1, 0xe0, 0x26, 0xe6, 0x22, 0xb9, 0xab, 0x7a, 0xae, 0x89, 0x22, 0xb9, 0x53, 0x2c, 0xf4, + 0xda, 0x29, 0x1e, 0xdc, 0x34, 0x53, 0xa8, 0xf0, 0x5d, 0x2d, 0x02, 0xd7, 0xa8, 0xf7, 0xf0, 0x19, + 0xde, 0xa5, 0xd3, 0xdf, 0xd5, 0xe2, 0xcd, 0x1b, 0x68, 0x93, 0xfe, 0x83, 0x2c, 0x9c, 0x4d, 0x27, + 0x54, 0xdb, 0x92, 0xe9, 0xd3, 0x96, 0x2b, 0x90, 0x5f, 0x71, 0xfd, 0x40, 0xb1, 0xfa, 0x43, 0xf5, + 0xff, 0xbe, 0x80, 0x99, 0x61, 0x29, 0xbb, 0x73, 0xb3, 0xbf, 0xc3, 0xe5, 0x89, 0xfc, 0x30, 0xe8, + 0x04, 0xbb, 0x73, 0xf3, 0x22, 0x72, 0x07, 0xf2, 0xa6, 0xf0, 0x9c, 0x8a, 0x75, 0x8d, 0x04, 0x87, + 0xd2, 0x14, 0xf1, 0x04, 0x44, 0x0b, 0x73, 0x2e, 0x60, 0xa4, 0x04, 0xa3, 0x62, 0xf4, 0x63, 0x4f, + 0xc7, 0x29, 0x53, 0x46, 0xcf, 0x3c, 0x20, 0xe9, 0xd8, 0x8e, 0x82, 0x8f, 0x80, 0xd5, 0x8a, 0x74, + 0x82, 0xc2, 0x1d, 0x85, 0x3f, 0x12, 0xea, 0x06, 0x96, 0x21, 0xa2, 0xf1, 0xc3, 0x59, 0x00, 0xa9, + 0xb5, 0x79, 0x66, 0x67, 0xd8, 0xe7, 0xb4, 0x19, 0xa6, 0xd8, 0x1b, 0x0d, 0x9e, 0xda, 0xf7, 0x3e, + 0x9a, 0xf3, 0x0c, 0x9e, 0xd8, 0xb7, 0x08, 0xc3, 0x9b, 0x91, 0x42, 0x4b, 0xf8, 0x98, 0xa0, 0x3a, + 0x9a, 0xc3, 0x8d, 0x1d, 0x98, 0xbb, 0x43, 0x83, 0x48, 0xbd, 0x25, 0x9f, 0x1e, 0xfb, 0xb3, 0x7d, + 0x03, 0xc6, 0x04, 0x7e, 0xb8, 0x7f, 0x71, 0x5d, 0x8c, 0x88, 0xe3, 0x82, 0xba, 0x18, 0x89, 0xc0, + 0x76, 0xa3, 0x0a, 0x6d, 0xd2, 0x80, 0x7e, 0xb2, 0xd5, 0xd4, 0x80, 0xf0, 0xa6, 0x60, 0xcb, 0x06, + 0xab, 0xe1, 0xc4, 0xfe, 0x79, 0x00, 0x67, 0xc2, 0x6f, 0x7f, 0x9a, 0x7c, 0xaf, 0xb3, 0x2b, 0xa5, + 0x08, 0xda, 0x1f, 0x71, 0xec, 0x63, 0x7b, 0xf2, 0x18, 0x16, 0x24, 0xc1, 0xb6, 0x13, 0x1a, 0x4e, + 0x0e, 0x44, 0x4b, 0xde, 0x85, 0x71, 0x85, 0x46, 0x04, 0x9d, 0x47, 0x35, 0xf5, 0x23, 0x27, 0xd8, + 0xb7, 0x7c, 0x0e, 0x57, 0xd5, 0xd4, 0x0a, 0xba, 0xf1, 0x15, 0x78, 0x3e, 0xf4, 0x03, 0x4a, 0xa9, + 0x3a, 0xc6, 0x3c, 0x73, 0x3a, 0xe6, 0xeb, 0x51, 0xb3, 0xaa, 0xed, 0xd0, 0xd5, 0x59, 0xf2, 0x26, + 0x6a, 0xb3, 0x44, 0x63, 0x5e, 0x48, 0x38, 0x4f, 0x2b, 0x3e, 0xd2, 0xc6, 0x3b, 0xca, 0xc7, 0xa6, + 0x30, 0xd4, 0x88, 0x33, 0x71, 0xe2, 0x1f, 0xce, 0xc2, 0xf4, 0xfd, 0x6a, 0xa5, 0x1c, 0x5a, 0x1f, + 0x7d, 0xca, 0x12, 0x0f, 0x6b, 0x6d, 0xeb, 0xbd, 0xdf, 0x18, 0x5b, 0x30, 0x1b, 0xeb, 0x06, 0x14, + 0x1d, 0xde, 0xe7, 0x1e, 0x24, 0x21, 0x58, 0x8a, 0x0d, 0x67, 0xd3, 0xd8, 0x3f, 0xb8, 0x69, 0xc6, + 0xb0, 0x8d, 0xff, 0x12, 0x62, 0x7c, 0xc5, 0x16, 0xf6, 0x06, 0x8c, 0x55, 0x7d, 0xbf, 0x4b, 0xbd, + 0x2d, 0x73, 0x55, 0x55, 0x15, 0x38, 0x08, 0xb4, 0xba, 0x5e, 0xd3, 0x8c, 0x10, 0xc8, 0x55, 0xc8, + 0x8b, 0x80, 0xdf, 0x72, 0x4f, 0x40, 0xad, 0x6d, 0x18, 0x2f, 0xdc, 0x0c, 0x8b, 0xc9, 0x5b, 0x30, + 0xc1, 0xff, 0xe6, 0xb3, 0x4d, 0x74, 0x38, 0x2a, 0x07, 0x05, 0x3a, 0x9f, 0x9d, 0xa6, 0x86, 0x46, + 0x5e, 0x83, 0x5c, 0xa9, 0x6c, 0x0a, 0x75, 0x90, 0x90, 0x1b, 0x3d, 0x8b, 0xeb, 0xec, 0xb4, 0x4b, + 0x44, 0xd9, 0x64, 0xd2, 0x9f, 0x8c, 0x1e, 0x21, 0x34, 0xd9, 0x38, 0x03, 0xa4, 0xb6, 0x29, 0x76, + 0x98, 0x21, 0x8c, 0x5c, 0x87, 0xd1, 0x0a, 0x37, 0x99, 0x13, 0x7a, 0x6c, 0x9e, 0x55, 0x8f, 0x83, + 0xb4, 0x68, 0x09, 0x1c, 0x44, 0xae, 0xca, 0x6c, 0x63, 0xf9, 0xc8, 0x11, 0xa5, 0x47, 0x4a, 0xb1, + 0x37, 0x60, 0x44, 0x84, 0xc5, 0x1e, 0x53, 0xf2, 0x90, 0xc4, 0xc3, 0x61, 0x0b, 0x9c, 0xa4, 0x47, + 0x2a, 0x3c, 0x4d, 0x8f, 0xd4, 0x1d, 0x38, 0x77, 0x07, 0xb5, 0x37, 0x7a, 0x70, 0xa7, 0x2d, 0xb3, + 0x2a, 0xf4, 0xe1, 0xf8, 0x0c, 0xc4, 0x15, 0x3c, 0xf1, 0xf8, 0x50, 0x56, 0xd7, 0x53, 0x93, 0xc4, + 0xf6, 0x62, 0x44, 0xbe, 0x0c, 0x73, 0x69, 0x45, 0x42, 0x6b, 0x8e, 0x61, 0x8c, 0xd2, 0x2b, 0x50, + 0xc3, 0x18, 0xa5, 0x71, 0x20, 0xab, 0x50, 0xe0, 0xf0, 0x52, 0xa3, 0xe5, 0xb4, 0xb9, 0xe6, 0x9f, + 0x6b, 0xd5, 0xd1, 0x33, 0x44, 0x70, 0xb5, 0x59, 0x21, 0x7f, 0x01, 0xd0, 0x7c, 0x89, 0x62, 0x94, + 0xe4, 0xa7, 0x32, 0xec, 0x36, 0xc7, 0x83, 0x48, 0x6f, 0x99, 0xab, 0xbe, 0x08, 0x81, 0x77, 0x36, + 0x72, 0x13, 0xaa, 0x05, 0x9e, 0xd3, 0xde, 0x13, 0x7e, 0x42, 0x9b, 0xc2, 0x4f, 0xe8, 0xdd, 0x8f, + 0xe5, 0x27, 0xc4, 0x59, 0xf9, 0xc7, 0x47, 0xc5, 0x09, 0x4f, 0xd4, 0x89, 0xab, 0x48, 0xfb, 0x02, + 0xd6, 0x75, 0xe8, 0x2c, 0xbb, 0xd5, 0xe6, 0x21, 0x6c, 0x69, 0x83, 0x37, 0x72, 0x1a, 0x77, 0x70, + 0xec, 0x3a, 0xcc, 0x6f, 0x61, 0x75, 0x43, 0x84, 0x44, 0x43, 0x53, 0x39, 0xb0, 0x8b, 0xa7, 0xf4, + 0x45, 0xe1, 0xee, 0xb5, 0x85, 0xe8, 0xe2, 0x29, 0x1d, 0x57, 0x2c, 0x9c, 0x46, 0xea, 0xe4, 0xd1, + 0x48, 0xc8, 0x75, 0x18, 0x59, 0xb3, 0x1f, 0x97, 0xf6, 0xa8, 0xc8, 0x22, 0x39, 0x29, 0xb7, 0x3f, + 0x04, 0x2e, 0xe5, 0xff, 0x90, 0xfb, 0x3a, 0x3c, 0x67, 0x0a, 0x34, 0xf2, 0x7d, 0x19, 0x38, 0xcb, + 0x97, 0xb1, 0x6c, 0x65, 0x8d, 0x06, 0x01, 0xeb, 0x07, 0x11, 0x0b, 0xef, 0x52, 0x64, 0xb0, 0x9d, + 0x8e, 0x87, 0xae, 0xf4, 0x86, 0xd8, 0x19, 0xc2, 0x8e, 0xf3, 0x45, 0xa9, 0x16, 0x54, 0x38, 0x95, + 0x9e, 0x6c, 0xc2, 0xf8, 0xda, 0xed, 0x52, 0x58, 0x2d, 0x8f, 0x34, 0x5e, 0x4c, 0xdb, 0x1d, 0x15, + 0xb4, 0x34, 0x4f, 0x03, 0x95, 0x8d, 0xf0, 0x0e, 0xf8, 0x9c, 0xec, 0x0f, 0xf2, 0xa6, 0xea, 0x5b, + 0x9a, 0x43, 0xe9, 0x79, 0xb4, 0x65, 0x3f, 0xb6, 0xec, 0x3d, 0xaa, 0xbd, 0x92, 0x0b, 0xed, 0xf5, + 0xcf, 0x64, 0xe0, 0x7c, 0xcf, 0x26, 0x93, 0x5b, 0x70, 0xce, 0xe6, 0x1e, 0xd3, 0xd6, 0x7e, 0x10, + 0x74, 0x7c, 0x4b, 0x5e, 0x31, 0x84, 0x37, 0xaa, 0x79, 0x46, 0x14, 0xaf, 0xb0, 0x52, 0x79, 0xeb, + 0xf0, 0xc9, 0x07, 0xf0, 0x82, 0xd3, 0xf6, 0x69, 0xbd, 0xeb, 0x51, 0x4b, 0x32, 0xa8, 0x3b, 0x0d, + 0xcf, 0xf2, 0xec, 0xf6, 0x9e, 0x74, 0xad, 0x35, 0xcf, 0x4b, 0x1c, 0xe1, 0x95, 0x5d, 0x76, 0x1a, + 0x9e, 0x89, 0x08, 0xc6, 0x3f, 0xcb, 0xc0, 0x7c, 0xaf, 0x2e, 0x21, 0xf3, 0x30, 0x4a, 0x95, 0x9c, + 0x23, 0x79, 0x53, 0xfe, 0x24, 0xcf, 0x43, 0xb4, 0xd3, 0x8b, 0xd3, 0x3f, 0x5f, 0x17, 0xf9, 0x1f, + 0xd0, 0xb4, 0x5d, 0xdd, 0xd7, 0x85, 0x81, 0xf2, 0x44, 0x5d, 0xdd, 0xdd, 0x2f, 0x00, 0x44, 0xdb, + 0x39, 0x57, 0x4c, 0x98, 0x63, 0x76, 0xdd, 0xe3, 0x2b, 0x8f, 0x9c, 0x85, 0x11, 0xbe, 0x5d, 0x0a, + 0xff, 0x07, 0xf1, 0x8b, 0x9d, 0xdb, 0xa2, 0x93, 0x71, 0x9f, 0xcf, 0x2d, 0x4d, 0x68, 0x9d, 0x3d, + 0xd2, 0xc2, 0xc1, 0x31, 0x7e, 0x7a, 0x92, 0x8b, 0x10, 0xa5, 0x6e, 0xb0, 0x2f, 0x85, 0x8e, 0xc5, + 0x34, 0x07, 0x30, 0x6e, 0x4b, 0xa9, 0xd8, 0x65, 0xeb, 0x6e, 0x5f, 0xf2, 0xed, 0x27, 0x9b, 0xfa, + 0xf6, 0xf3, 0x06, 0x8c, 0x95, 0xf7, 0x69, 0xfd, 0x20, 0x74, 0xc2, 0xc9, 0x0b, 0xe5, 0x3a, 0x03, + 0xf2, 0xf0, 0xde, 0x11, 0x02, 0xb9, 0x0e, 0x80, 0x7e, 0xa7, 0x5c, 0x22, 0x55, 0x52, 0x74, 0xa0, + 0x9b, 0xaa, 0x30, 0x4f, 0x51, 0x50, 0x90, 0x7d, 0xcd, 0xbc, 0xad, 0xda, 0xb3, 0x70, 0xf6, 0xbe, + 0xb7, 0x2b, 0xd0, 0x23, 0x04, 0xd6, 0x3c, 0x65, 0x5f, 0x11, 0xa7, 0x60, 0x21, 0xb1, 0xf9, 0xa8, + 0x48, 0xe4, 0x1a, 0x8c, 0x6d, 0x48, 0x47, 0x02, 0x3c, 0x04, 0x27, 0x90, 0x02, 0x22, 0xa7, 0x83, + 0xf9, 0x8c, 0x19, 0xa1, 0x90, 0xcf, 0xc1, 0x68, 0x99, 0x7a, 0xc1, 0xe6, 0xe6, 0x2a, 0x1a, 0x9d, + 0xf0, 0x4c, 0x16, 0x79, 0xcc, 0x3a, 0x10, 0x04, 0xcd, 0xef, 0x1e, 0x15, 0x27, 0x03, 0xa7, 0x45, + 0xc3, 0x08, 0xdd, 0xa6, 0xc4, 0x26, 0x4b, 0x50, 0xe0, 0xcf, 0xe2, 0xd1, 0xdd, 0x03, 0x4f, 0xc6, + 0x3c, 0x3f, 0xa7, 0xc5, 0x1b, 0xfa, 0x23, 0xba, 0x13, 0xe6, 0x5c, 0x48, 0xe0, 0x93, 0x65, 0x99, + 0xaa, 0x44, 0x6d, 0x26, 0x44, 0xca, 0xb0, 0xf8, 0x8e, 0xc1, 0x5a, 0x9b, 0xa4, 0x20, 0x25, 0x98, + 0x2c, 0xbb, 0xad, 0x8e, 0x1d, 0x38, 0x98, 0xd3, 0xf1, 0x50, 0x1c, 0x82, 0xa8, 0xd0, 0xab, 0xab, + 0x05, 0xda, 0x89, 0xaa, 0x16, 0x90, 0xdb, 0x30, 0x65, 0xba, 0x5d, 0x36, 0x4c, 0xf2, 0x16, 0xce, + 0xcf, 0x39, 0x34, 0x0d, 0xf1, 0x58, 0x09, 0x3b, 0x96, 0xc5, 0x95, 0x5b, 0x8b, 0x66, 0xaa, 0x51, + 0x91, 0xf5, 0x94, 0xe7, 0x10, 0xf5, 0x70, 0x53, 0x33, 0x2f, 0x24, 0x98, 0xa5, 0xbc, 0xa4, 0xdc, + 0x84, 0xf1, 0x5a, 0xed, 0xfe, 0x26, 0xf5, 0x83, 0xdb, 0x4d, 0xf7, 0x11, 0x9e, 0x6d, 0x79, 0x91, + 0x28, 0xcc, 0x77, 0xad, 0x80, 0xfa, 0x81, 0xb5, 0xdb, 0x74, 0x1f, 0x99, 0x2a, 0x16, 0xf9, 0x3a, + 0xeb, 0x0f, 0x45, 0x12, 0x14, 0x71, 0x5b, 0xfb, 0x09, 0xab, 0x78, 0x82, 0x44, 0x8b, 0x86, 0x89, + 0xac, 0x7a, 0x67, 0x29, 0xe8, 0xe8, 0x53, 0xe6, 0xb9, 0x8f, 0x0f, 0x4b, 0x8d, 0x86, 0x47, 0x7d, + 0x5f, 0x1c, 0x42, 0xdc, 0xa7, 0x0c, 0x95, 0x0d, 0x36, 0x2f, 0xd0, 0x7c, 0xca, 0x14, 0x02, 0xf2, + 0xa3, 0x19, 0x38, 0xa3, 0x7a, 0x9b, 0xe0, 0x72, 0x41, 0x33, 0x17, 0x7e, 0x24, 0xbd, 0x79, 0x4d, + 0x1e, 0xc2, 0xd7, 0x14, 0xb4, 0x6b, 0x0f, 0x6f, 0x5c, 0x2b, 0x45, 0x3f, 0x6b, 0x92, 0x08, 0x63, + 0xd0, 0x15, 0x53, 0xf9, 0x69, 0x79, 0x76, 0xe6, 0xec, 0x14, 0x62, 0x52, 0x66, 0x92, 0x1a, 0x9b, + 0x51, 0x68, 0x38, 0x55, 0xdd, 0xc0, 0x33, 0x4d, 0x68, 0x54, 0xc5, 0xfc, 0xe3, 0x26, 0x56, 0x4e, + 0x47, 0x17, 0xc8, 0x14, 0x1a, 0x52, 0x85, 0x69, 0x0e, 0x60, 0xdb, 0x02, 0x4f, 0x59, 0x34, 0x1b, + 0x25, 0x4d, 0x10, 0x6c, 0xf0, 0xad, 0x1f, 0xd3, 0x16, 0xa9, 0x81, 0x46, 0x63, 0x74, 0xe4, 0x03, + 0x98, 0xc2, 0x78, 0xf0, 0xd1, 0x7a, 0x9d, 0xc3, 0x55, 0x8c, 0xf1, 0x52, 0x45, 0x49, 0xcc, 0xf3, + 0x6e, 0xc2, 0xf7, 0xf7, 0xa3, 0x15, 0xfd, 0x01, 0x4c, 0xa1, 0xad, 0x4e, 0xc4, 0xe0, 0x4c, 0xc4, + 0x40, 0x94, 0xc4, 0x19, 0x04, 0x4d, 0x3f, 0x62, 0xf0, 0xb7, 0x32, 0x70, 0x9e, 0x55, 0x94, 0x3e, + 0x42, 0x67, 0x3f, 0xce, 0x08, 0x61, 0x04, 0xc9, 0x9e, 0x3c, 0x55, 0x71, 0xd4, 0xf7, 0xf7, 0xd3, + 0x38, 0xe0, 0x47, 0xb1, 0x8f, 0x4f, 0xff, 0xa8, 0x73, 0x1f, 0xfb, 0xa3, 0x7a, 0xf2, 0x54, 0x3f, + 0x2a, 0x68, 0xfa, 0x69, 0x1c, 0xf0, 0x5a, 0x5b, 0x2b, 0xad, 0xad, 0x46, 0x77, 0xb3, 0x4f, 0x97, + 0xdb, 0x8a, 0xd6, 0xb6, 0x3e, 0x6e, 0x2b, 0x5b, 0xdc, 0x2d, 0x5a, 0xe9, 0x06, 0x79, 0xad, 0xd5, + 0xc0, 0xf1, 0x6b, 0x6d, 0x8c, 0xc6, 0x8c, 0x61, 0x1b, 0xbf, 0x04, 0x31, 0xbe, 0xc2, 0x54, 0xd5, + 0x80, 0x11, 0x7e, 0x6b, 0x15, 0x9d, 0x8c, 0x36, 0x0b, 0xfc, 0x4e, 0x6b, 0x8a, 0x12, 0x72, 0x1e, + 0x72, 0xb5, 0xda, 0x7d, 0xd1, 0xc9, 0x68, 0xb0, 0xea, 0xfb, 0xae, 0xc9, 0x60, 0x6c, 0x84, 0xd0, + 0x0a, 0x55, 0x89, 0xaf, 0xcf, 0xce, 0x3b, 0x13, 0xa1, 0xac, 0xbf, 0xe5, 0x1d, 0x72, 0x28, 0xea, + 0x6f, 0x71, 0x87, 0x8c, 0x6e, 0x8e, 0x65, 0x98, 0x2f, 0xf9, 0x3e, 0xf5, 0xd8, 0x84, 0x10, 0xc6, + 0x8d, 0x9e, 0xb8, 0xe7, 0x88, 0x83, 0x1d, 0x2b, 0xb5, 0xeb, 0xbe, 0xd9, 0x13, 0x91, 0x5c, 0x81, + 0x7c, 0xa9, 0xdb, 0x70, 0x68, 0xbb, 0xae, 0xc5, 0x59, 0xb3, 0x05, 0xcc, 0x0c, 0x4b, 0xc9, 0x97, + 0xe0, 0x4c, 0x2c, 0xa4, 0xa2, 0xe8, 0x81, 0xd1, 0x68, 0xef, 0x95, 0xf7, 0xb0, 0xc8, 0x20, 0x83, + 0x77, 0x49, 0x3a, 0x25, 0x29, 0x41, 0x61, 0x19, 0xdd, 0xb4, 0x2a, 0x94, 0xbf, 0x0d, 0xb9, 0x1e, + 0xf7, 0xcf, 0xe3, 0xb7, 0x66, 0xee, 0xc2, 0x65, 0x35, 0xc2, 0x42, 0x33, 0x81, 0x4e, 0xee, 0xc1, + 0x6c, 0x1c, 0xc6, 0x4e, 0x70, 0x7e, 0x41, 0xc6, 0xfd, 0x26, 0xc1, 0x05, 0xcf, 0xf0, 0x34, 0x2a, + 0xb2, 0x03, 0x33, 0x91, 0x41, 0x92, 0x7e, 0x6d, 0x96, 0x76, 0xce, 0x61, 0xb9, 0xbc, 0x3a, 0x3f, + 0x2f, 0x26, 0xe3, 0x6c, 0x64, 0xdc, 0x14, 0x5e, 0x9f, 0xcd, 0x24, 0x3b, 0xd2, 0x80, 0xa9, 0x9a, + 0xb3, 0xd7, 0x76, 0xda, 0x7b, 0xf7, 0xe8, 0xe1, 0x86, 0xed, 0x78, 0xc2, 0xe2, 0x54, 0xda, 0x93, + 0x97, 0xfc, 0xc3, 0x56, 0x8b, 0x06, 0x1e, 0x6e, 0x84, 0xac, 0x1c, 0x7d, 0xd0, 0xd9, 0x75, 0x68, + 0xc1, 0xe7, 0x74, 0xe8, 0xb6, 0xd9, 0xb1, 0x1d, 0x4d, 0x08, 0xd0, 0x79, 0x6a, 0xaa, 0x8b, 0x89, + 0x01, 0x55, 0x17, 0x4d, 0x98, 0x59, 0x6e, 0xd7, 0xbd, 0x43, 0x7c, 0xa2, 0x93, 0x1f, 0x37, 0x79, + 0xc2, 0xc7, 0xbd, 0x2c, 0x3e, 0xee, 0x05, 0x5b, 0xce, 0xb0, 0xb4, 0xcf, 0x4b, 0x32, 0x26, 0x35, + 0x98, 0xc1, 0x8b, 0x43, 0xb5, 0xb2, 0x51, 0x6d, 0x3b, 0x81, 0x63, 0x07, 0xb4, 0x21, 0x84, 0x8b, + 0x30, 0x2b, 0x09, 0xbf, 0xa2, 0x3a, 0x8d, 0x8e, 0xe5, 0x48, 0x14, 0x95, 0x69, 0x82, 0xbe, 0xdf, + 0x3d, 0x71, 0xfa, 0x2f, 0xe8, 0x9e, 0x58, 0x85, 0xe9, 0x78, 0x6c, 0x86, 0x42, 0x74, 0x0e, 0xfb, + 0x58, 0xc4, 0x8e, 0x73, 0xb7, 0x8b, 0xc2, 0xa4, 0x96, 0x08, 0x54, 0xa7, 0x8b, 0x5f, 0x39, 0x67, + 0xb4, 0x2b, 0xa7, 0xb6, 0x2b, 0x9d, 0xe2, 0xca, 0x49, 0x36, 0x00, 0x6e, 0xbb, 0x5e, 0x9d, 0x96, + 0xd0, 0x3f, 0x9a, 0x68, 0xb9, 0x9b, 0x18, 0xd3, 0xa8, 0x90, 0xaf, 0x9f, 0x5d, 0xf6, 0xdb, 0x8a, + 0xbb, 0xb9, 0x2b, 0x3c, 0x8c, 0x1f, 0xcb, 0xc2, 0x7c, 0xaf, 0xcf, 0xe9, 0x73, 0xdd, 0x7b, 0x1d, + 0x92, 0x2b, 0x5c, 0x5c, 0xfb, 0x0a, 0x34, 0xbe, 0xce, 0x17, 0x21, 0x7d, 0x21, 0x8b, 0x6b, 0xe0, + 0x6c, 0x9c, 0x60, 0xcb, 0x6b, 0x92, 0x5b, 0x30, 0xae, 0x7c, 0x3c, 0xee, 0xa5, 0xbd, 0x9a, 0x6a, + 0xc2, 0x6e, 0xf8, 0x37, 0xbb, 0x26, 0xf2, 0x7d, 0x4b, 0x5e, 0x13, 0xf9, 0x2f, 0x52, 0xe0, 0x2e, + 0xe2, 0x23, 0xdc, 0x0a, 0xc0, 0xf7, 0x5d, 0x42, 0x00, 0xf7, 0x6d, 0xbe, 0x05, 0x9a, 0xf8, 0xb7, + 0xf1, 0x1b, 0x13, 0xfc, 0x44, 0x56, 0x6f, 0x89, 0xbd, 0xec, 0x83, 0x63, 0xb7, 0xc7, 0xec, 0x69, + 0x6e, 0x8f, 0xb9, 0x93, 0x6f, 0x8f, 0x43, 0x27, 0xdd, 0x1e, 0x63, 0xd7, 0xbb, 0xe1, 0x53, 0x5f, + 0xef, 0x46, 0x4e, 0x75, 0xbd, 0x1b, 0x3d, 0xd5, 0xf5, 0x4e, 0xbb, 0xa9, 0xe6, 0x4f, 0xba, 0xa9, + 0xfe, 0xd5, 0x65, 0xf0, 0x59, 0xbd, 0x0c, 0xa6, 0x89, 0x78, 0xa7, 0xba, 0x0c, 0xfe, 0x48, 0xcf, + 0xbb, 0x5c, 0xe1, 0xe3, 0x08, 0xe5, 0x2f, 0x0d, 0x70, 0x97, 0x1b, 0xf4, 0x26, 0x37, 0xf3, 0x74, + 0x6e, 0x72, 0xe4, 0xa9, 0xdd, 0xe4, 0x66, 0x9f, 0xf4, 0x26, 0x37, 0xf7, 0x34, 0x6f, 0x72, 0x67, + 0xfe, 0x32, 0xde, 0xe4, 0xce, 0xfe, 0x9b, 0xb9, 0xc9, 0xfd, 0x35, 0x28, 0xc4, 0x85, 0xcb, 0x93, + 0xc3, 0x18, 0x3f, 0xb5, 0x18, 0x92, 0x4c, 0xf4, 0x8d, 0x0b, 0x77, 0xe4, 0x3a, 0xc0, 0x86, 0xe7, + 0x3c, 0xb4, 0x03, 0x7a, 0x4f, 0x5a, 0xbf, 0x89, 0x10, 0xdc, 0x1c, 0xca, 0x46, 0xde, 0x54, 0x50, + 0xc2, 0x7b, 0x4d, 0x36, 0xed, 0x5e, 0x63, 0xfc, 0x68, 0x16, 0x66, 0x78, 0x20, 0xb6, 0x67, 0xff, + 0x11, 0xf6, 0x7d, 0xed, 0xb6, 0xfa, 0x42, 0x14, 0xef, 0x5e, 0x6d, 0x5d, 0x9f, 0x67, 0xd8, 0xaf, + 0xc1, 0x99, 0x44, 0x57, 0xe0, 0x8d, 0xb5, 0x22, 0x43, 0xe0, 0x25, 0xee, 0xac, 0xf3, 0xe9, 0x95, + 0x3c, 0xb8, 0x69, 0x26, 0x28, 0x8c, 0x3f, 0x1b, 0x4a, 0xf0, 0x17, 0x0f, 0xb2, 0xea, 0x13, 0x6b, + 0xe6, 0x74, 0x4f, 0xac, 0xd9, 0xc1, 0x9e, 0x58, 0x63, 0x42, 0x45, 0x6e, 0x10, 0xa1, 0xe2, 0x4b, + 0x30, 0xb9, 0x49, 0xed, 0x96, 0xbf, 0xe9, 0x8a, 0xe4, 0x49, 0xdc, 0xd7, 0x42, 0x46, 0xb8, 0x63, + 0x65, 0xf2, 0xc2, 0x15, 0xda, 0x8c, 0x06, 0x8c, 0x80, 0x1d, 0x83, 0x3c, 0x9b, 0x92, 0xa9, 0x73, + 0x50, 0x6f, 0xd1, 0xc3, 0x7d, 0x6e, 0xd1, 0x35, 0x98, 0x10, 0x74, 0x51, 0xec, 0xe6, 0xe8, 0xba, + 0xc7, 0x8a, 0x10, 0x2e, 0x6b, 0x0f, 0x33, 0xbb, 0x87, 0xb5, 0xf3, 0x9b, 0x9e, 0xc6, 0x84, 0x75, + 0xc1, 0x72, 0xbb, 0xd1, 0x71, 0x9d, 0x36, 0x76, 0xc1, 0x68, 0xd4, 0x05, 0x54, 0x80, 0x79, 0x17, + 0x28, 0x48, 0xe4, 0x5d, 0x98, 0x2a, 0x6d, 0x54, 0x55, 0xb2, 0x7c, 0xf4, 0xca, 0x6b, 0x77, 0x1c, + 0x4b, 0x23, 0x8d, 0xe1, 0xf6, 0xbb, 0xf9, 0x8c, 0xfd, 0xc5, 0xdc, 0x7c, 0x8c, 0x7f, 0x39, 0x21, + 0x97, 0xf7, 0x27, 0xfb, 0x40, 0xa2, 0x3f, 0x79, 0xe4, 0x4e, 0xf9, 0xe4, 0x31, 0x74, 0x92, 0x20, + 0xa9, 0xc9, 0xb7, 0xc3, 0xa7, 0x92, 0x6f, 0x47, 0x9e, 0xf8, 0xf9, 0x62, 0xf4, 0x94, 0x12, 0x6b, + 0x6c, 0xad, 0xe5, 0x07, 0x59, 0x6b, 0xa9, 0x52, 0xee, 0xd8, 0x93, 0x4b, 0xb9, 0x70, 0x6a, 0x29, + 0xb7, 0x16, 0xf9, 0x2e, 0x8f, 0x9f, 0xe8, 0x12, 0x72, 0x41, 0x68, 0x05, 0x66, 0xd2, 0xa3, 0xf0, + 0x85, 0x5e, 0xcc, 0x9f, 0x2a, 0xd1, 0xf9, 0x1b, 0xe9, 0xa2, 0x73, 0xff, 0xf3, 0xe6, 0x54, 0xc2, + 0xf3, 0x8f, 0x3e, 0x5d, 0xe1, 0xf9, 0xe9, 0x3e, 0x84, 0xfc, 0x95, 0xf8, 0xfc, 0x57, 0xe2, 0xf3, + 0x80, 0xe2, 0xb3, 0x87, 0xcb, 0x6b, 0xdb, 0xf6, 0xda, 0xa8, 0x76, 0xba, 0x0e, 0xa3, 0x32, 0x0c, + 0x69, 0x26, 0xd2, 0x28, 0x27, 0xe3, 0x8f, 0x4a, 0x2c, 0xb2, 0x08, 0x79, 0x49, 0xac, 0x26, 0xba, + 0x79, 0x24, 0x60, 0x5a, 0x84, 0x47, 0x01, 0x33, 0xfe, 0x83, 0x21, 0xb9, 0x85, 0xb3, 0x39, 0xb3, + 0x61, 0x7b, 0x76, 0x0b, 0xd3, 0xbf, 0x85, 0x2b, 0x4c, 0x11, 0xde, 0x63, 0x8b, 0x32, 0x66, 0xda, + 0xaf, 0x93, 0x7c, 0xac, 0xc0, 0xb0, 0x51, 0x86, 0xdd, 0xdc, 0x00, 0x19, 0x76, 0xdf, 0xd6, 0xd2, + 0xd3, 0x0e, 0x45, 0xf9, 0x10, 0xd9, 0xb6, 0xd6, 0x3f, 0x31, 0xed, 0x2d, 0x35, 0x8f, 0xec, 0x70, + 0x14, 0xd5, 0x0b, 0x29, 0xfb, 0x64, 0x90, 0x0d, 0x6f, 0x23, 0x23, 0xa7, 0x09, 0xb9, 0x3c, 0xfa, + 0x6f, 0x34, 0xe4, 0xf2, 0x32, 0x80, 0x38, 0x6a, 0x23, 0xf3, 0x84, 0x57, 0x70, 0xf5, 0x0b, 0x33, + 0xe5, 0x20, 0x68, 0xf6, 0xc8, 0xc9, 0xa1, 0x10, 0x1a, 0xbf, 0x4f, 0x60, 0xa6, 0x56, 0xbb, 0x5f, + 0x71, 0xec, 0xbd, 0xb6, 0xeb, 0x07, 0x4e, 0xbd, 0xda, 0xde, 0x75, 0x99, 0x28, 0x1e, 0x1e, 0x07, + 0x4a, 0x6c, 0xdd, 0xe8, 0x28, 0x08, 0x8b, 0xd9, 0x55, 0x6f, 0xd9, 0xf3, 0xa4, 0x7e, 0x94, 0x5f, + 0xf5, 0x28, 0x03, 0x98, 0x1c, 0xce, 0xa4, 0xdd, 0x5a, 0x17, 0x23, 0x5b, 0x08, 0x9b, 0x11, 0x94, + 0x76, 0x7d, 0x0e, 0x32, 0x65, 0x19, 0xa1, 0xc9, 0x09, 0x2b, 0x6e, 0x3f, 0xe7, 0xb4, 0xc0, 0xcd, + 0x51, 0x31, 0x3f, 0xec, 0x84, 0x30, 0x82, 0xdb, 0x66, 0x07, 0xe1, 0xaa, 0x45, 0x5c, 0x62, 0x0d, + 0x1c, 0xc2, 0x19, 0xcd, 0xe7, 0x79, 0xd0, 0xc7, 0x94, 0xd7, 0x84, 0x74, 0x6d, 0x60, 0x88, 0x8d, + 0x94, 0x17, 0x15, 0x35, 0x9f, 0x5b, 0x6a, 0x0d, 0xec, 0x3c, 0xbb, 0x90, 0x5a, 0x12, 0xae, 0xee, + 0x71, 0x2d, 0x78, 0xb6, 0xb2, 0x69, 0xf0, 0xcc, 0x75, 0xbd, 0xaa, 0xb6, 0x52, 0xb6, 0x82, 0xfe, + 0x35, 0x91, 0xdf, 0xcc, 0xc0, 0x39, 0x0d, 0x23, 0xdc, 0xae, 0xfc, 0x30, 0x1c, 0x48, 0xea, 0xbc, + 0xfe, 0xe8, 0xe9, 0xcc, 0xeb, 0x97, 0xf4, 0xb6, 0x44, 0x1b, 0xaa, 0xda, 0x86, 0x5e, 0x5f, 0x48, + 0x1e, 0xc2, 0x0c, 0x16, 0xc9, 0x87, 0x1d, 0x36, 0x67, 0xc5, 0x7b, 0xd0, 0x5c, 0xf4, 0xd9, 0xdc, + 0x8f, 0x1f, 0xb3, 0x8f, 0x2f, 0x7e, 0xe7, 0xa8, 0x38, 0xa9, 0xa1, 0xcb, 0x70, 0xd4, 0x56, 0xf4, + 0x3a, 0xe4, 0xb4, 0x77, 0x5d, 0x2d, 0xb5, 0x7c, 0xbc, 0x0a, 0xf2, 0x5f, 0x67, 0xf8, 0x73, 0x02, + 0x6f, 0xc6, 0x6d, 0xcf, 0x6d, 0x85, 0xe5, 0xd2, 0xb4, 0xb2, 0x47, 0xb7, 0x35, 0x9f, 0x4e, 0xb7, + 0xbd, 0x82, 0x9f, 0xcc, 0xf7, 0x04, 0x6b, 0xd7, 0x73, 0x5b, 0xd1, 0xe7, 0xab, 0x1d, 0xd7, 0xf3, + 0x23, 0xc9, 0xf7, 0x67, 0xe0, 0xbc, 0xa6, 0xd5, 0x54, 0x73, 0x83, 0x88, 0x68, 0x09, 0xb3, 0x61, + 0x1c, 0x95, 0xa8, 0x68, 0xe9, 0x9a, 0x98, 0xff, 0x97, 0xf1, 0x0b, 0x94, 0xb0, 0x9d, 0x0c, 0xc9, + 0x6a, 0x71, 0x2c, 0xe5, 0x13, 0x7a, 0xd7, 0x42, 0x1c, 0x98, 0x41, 0x2b, 0x1b, 0xcd, 0x04, 0x78, + 0xae, 0xb7, 0x09, 0x70, 0x98, 0xf5, 0x07, 0x33, 0x02, 0xf4, 0xb6, 0x03, 0x4e, 0x72, 0x25, 0x7f, + 0x1d, 0xce, 0x27, 0x80, 0xe1, 0x6a, 0x3b, 0xd3, 0x73, 0xb5, 0xbd, 0x7e, 0x7c, 0x54, 0x7c, 0x35, + 0xad, 0xb6, 0xb4, 0x95, 0xd6, 0xbb, 0x06, 0x62, 0x03, 0x44, 0x85, 0x42, 0xfc, 0x48, 0x9f, 0xa0, + 0xaf, 0x8b, 0xf9, 0xa1, 0xe0, 0xb3, 0xbd, 0x5c, 0xf9, 0x06, 0xf5, 0xc8, 0x8b, 0x90, 0x08, 0x85, + 0x09, 0x25, 0x1b, 0xc2, 0xa1, 0x30, 0xf6, 0xe8, 0x51, 0xc9, 0x77, 0x8e, 0x8a, 0x1a, 0x36, 0xbb, + 0x10, 0xa9, 0x69, 0x16, 0x34, 0x69, 0x4f, 0x45, 0x24, 0xbf, 0x9e, 0x81, 0x39, 0x06, 0x88, 0x26, + 0x95, 0x68, 0xd4, 0x7c, 0xbf, 0x59, 0xbf, 0xff, 0x74, 0x66, 0xfd, 0x8b, 0xf8, 0x8d, 0xea, 0xac, + 0x4f, 0x74, 0x49, 0xea, 0xc7, 0xe1, 0x6c, 0xd7, 0x0c, 0xba, 0xb4, 0xd9, 0x7e, 0x7e, 0x80, 0xd9, + 0xce, 0x07, 0xe0, 0xe4, 0xd9, 0xde, 0xb3, 0x16, 0xb2, 0x09, 0x13, 0xe2, 0x2e, 0xc4, 0x3b, 0xec, + 0xa2, 0x16, 0xc6, 0x59, 0x2d, 0xe2, 0x17, 0x54, 0x91, 0x2c, 0x22, 0xd1, 0x42, 0x8d, 0x0b, 0x69, + 0xc3, 0x2c, 0xff, 0xad, 0xeb, 0xa6, 0x8a, 0x3d, 0x75, 0x53, 0x57, 0x44, 0x8b, 0x2e, 0x09, 0xfe, + 0x31, 0x15, 0x95, 0x1a, 0x7e, 0x29, 0x85, 0x31, 0xe9, 0x00, 0xd1, 0xc0, 0x7c, 0xd1, 0x5e, 0xea, + 0xaf, 0x91, 0x7a, 0x55, 0xd4, 0x59, 0x8c, 0xd7, 0x19, 0x5f, 0xb9, 0x29, 0xbc, 0x89, 0x0d, 0xd3, + 0x02, 0xea, 0x1e, 0x50, 0xbe, 0xc3, 0xbf, 0xa8, 0x05, 0xc0, 0x8a, 0x95, 0xf2, 0x4b, 0x94, 0xac, + 0x09, 0x03, 0x94, 0xc5, 0x36, 0xf4, 0x38, 0x3f, 0x72, 0x1f, 0x66, 0x4a, 0x9d, 0x4e, 0xd3, 0xa1, + 0x0d, 0x6c, 0xa5, 0xd9, 0x65, 0x6d, 0x32, 0xa2, 0x7c, 0x6b, 0x36, 0x2f, 0x14, 0x37, 0x3b, 0xaf, + 0x1b, 0xdb, 0x6e, 0x12, 0xb4, 0xc6, 0x8f, 0x64, 0x12, 0x1f, 0x4d, 0xde, 0x80, 0x31, 0xfc, 0xa1, + 0xc4, 0x54, 0x41, 0x15, 0x0f, 0xff, 0x44, 0x54, 0x1e, 0x45, 0x08, 0x4c, 0x58, 0x52, 0xe3, 0x2a, + 0xe6, 0xb8, 0xb0, 0x24, 0xf4, 0x0a, 0x91, 0x26, 0xa1, 0x28, 0x5d, 0x33, 0x72, 0x91, 0xd0, 0x85, + 0xae, 0x19, 0xc2, 0x21, 0xc3, 0xf8, 0xfe, 0xac, 0x3e, 0xed, 0xc8, 0x15, 0x45, 0x6e, 0x57, 0x22, + 0x3b, 0x4a, 0xb9, 0x5d, 0x91, 0xd6, 0xff, 0x41, 0x06, 0x66, 0xef, 0x2b, 0x89, 0x3a, 0x37, 0x5d, + 0x1c, 0x97, 0xfe, 0xa9, 0x2b, 0x9f, 0x56, 0x0a, 0x3e, 0x35, 0x43, 0x28, 0x9b, 0x29, 0x38, 0x65, + 0xcc, 0xb4, 0xef, 0x41, 0x67, 0x37, 0xfc, 0x30, 0x25, 0x13, 0x22, 0x47, 0xe7, 0x70, 0xe3, 0x27, + 0xb2, 0x30, 0xae, 0x2c, 0x01, 0xf2, 0x59, 0x98, 0x50, 0xf9, 0xa8, 0x0a, 0x3f, 0xb5, 0x5a, 0x53, + 0xc3, 0x42, 0x8d, 0x1f, 0xb5, 0x5b, 0x9a, 0xc6, 0x8f, 0x4d, 0x74, 0x84, 0x9e, 0xf2, 0x6a, 0xf3, + 0x41, 0xca, 0xd5, 0x06, 0xa7, 0xad, 0xa2, 0xb1, 0xe9, 0x7b, 0xc1, 0x79, 0x37, 0x79, 0xc1, 0x41, + 0xe5, 0x91, 0x42, 0xdf, 0xfb, 0x9a, 0x63, 0xfc, 0x74, 0x06, 0x0a, 0xf1, 0x45, 0xfa, 0x89, 0xf4, + 0xca, 0x29, 0x5e, 0x77, 0x7e, 0x3c, 0x1b, 0xa6, 0x42, 0x91, 0x2e, 0xbc, 0xcf, 0xaa, 0x99, 0xe0, + 0x7b, 0xda, 0xc3, 0xcb, 0xf3, 0x7a, 0x34, 0x3a, 0x35, 0xf8, 0x45, 0x7a, 0x08, 0xca, 0xa1, 0x6f, + 0xff, 0x62, 0xf1, 0x39, 0xe3, 0x43, 0x98, 0x8b, 0x77, 0x07, 0x3e, 0xbe, 0x94, 0x60, 0x5a, 0x87, + 0xc7, 0x13, 0x29, 0xc5, 0xa9, 0xcc, 0x38, 0xbe, 0xf1, 0x87, 0xd9, 0x38, 0x6f, 0x61, 0x32, 0xc8, + 0x36, 0x1d, 0xd5, 0x10, 0x46, 0x6c, 0x3a, 0x1c, 0x64, 0xca, 0xb2, 0xd3, 0x24, 0x30, 0x0b, 0x1d, + 0x51, 0x73, 0xe9, 0x8e, 0xa8, 0xe4, 0x56, 0xcc, 0x4a, 0x5a, 0x89, 0x9a, 0xf4, 0x88, 0xee, 0x58, + 0x91, 0xa5, 0x74, 0xcc, 0x38, 0xba, 0x0c, 0x73, 0x5a, 0x08, 0x70, 0x49, 0x3f, 0x1c, 0xe9, 0xda, + 0x03, 0x2c, 0xe0, 0xc4, 0xa9, 0xc8, 0x64, 0x05, 0x46, 0xd9, 0x67, 0xae, 0xd9, 0x1d, 0xf1, 0xa6, + 0x42, 0x42, 0xb7, 0xf4, 0x66, 0x78, 0xe1, 0x53, 0x3c, 0xd3, 0x9b, 0x94, 0x1d, 0xf9, 0xea, 0xc4, + 0x12, 0x88, 0xc6, 0xbf, 0xc8, 0xb0, 0xf5, 0x5f, 0x3f, 0xf8, 0x94, 0x65, 0x41, 0x63, 0x4d, 0xea, + 0x63, 0xd1, 0xfa, 0xc7, 0x59, 0x9e, 0x0b, 0x47, 0x4c, 0x9f, 0xb7, 0x61, 0x64, 0xd3, 0xf6, 0xf6, + 0x44, 0x0e, 0x6a, 0x9d, 0x0b, 0x2f, 0x88, 0x62, 0x3a, 0x05, 0xf8, 0xdb, 0x14, 0x04, 0xaa, 0x2e, + 0x2c, 0x3b, 0x90, 0x2e, 0x4c, 0xd1, 0xcb, 0xe7, 0x9e, 0x9a, 0x5e, 0xfe, 0x7b, 0xc2, 0xb4, 0x37, + 0xa5, 0x60, 0x80, 0x08, 0xd3, 0x97, 0xe2, 0x69, 0xa3, 0x12, 0xb1, 0xc0, 0x23, 0x76, 0xe4, 0x96, + 0x9a, 0x88, 0x4a, 0xf1, 0xed, 0x3c, 0x21, 0xe5, 0x94, 0xf1, 0xc7, 0x39, 0xde, 0xc7, 0xa2, 0xa3, + 0x2e, 0x6b, 0x7e, 0xdf, 0xb8, 0x4e, 0xd8, 0x46, 0xaf, 0x86, 0xe0, 0x40, 0xb3, 0xa9, 0xcb, 0x30, + 0xc4, 0xe6, 0xa6, 0xe8, 0x4d, 0xc4, 0x63, 0xf3, 0x57, 0xc5, 0x63, 0xe5, 0x6c, 0x2d, 0xe3, 0x99, + 0xa4, 0x66, 0x18, 0xc4, 0x63, 0x4b, 0x5d, 0xcb, 0x88, 0x41, 0xae, 0xc0, 0xd0, 0xba, 0xdb, 0x90, + 0x91, 0xcc, 0xe7, 0x30, 0xfa, 0x87, 0x96, 0xc2, 0x74, 0x3e, 0x63, 0x22, 0x06, 0x6b, 0x6b, 0x98, + 0xff, 0x41, 0x6d, 0x6b, 0x6b, 0xd7, 0x4e, 0x66, 0x8e, 0x53, 0x92, 0xce, 0x2c, 0xc3, 0x94, 0x9e, + 0x67, 0x5f, 0xd8, 0xfb, 0xa2, 0x76, 0x3d, 0x96, 0xae, 0x5f, 0x7d, 0x16, 0xd1, 0x89, 0xc8, 0x12, + 0x4c, 0x6a, 0x11, 0x54, 0xc5, 0xe3, 0x26, 0xaa, 0x37, 0xf5, 0xf8, 0xab, 0xaa, 0x7a, 0x53, 0x23, + 0x61, 0xe7, 0xb9, 0xf8, 0x7e, 0xe5, 0x89, 0x33, 0xf1, 0xed, 0x02, 0x87, 0xdc, 0x84, 0x3c, 0x0f, + 0xb3, 0x51, 0xad, 0xa8, 0xcf, 0x54, 0x3e, 0xc2, 0x62, 0x61, 0x6a, 0x24, 0xa2, 0x12, 0x56, 0xe1, + 0x33, 0x50, 0x10, 0x5b, 0x52, 0x94, 0xfc, 0xfc, 0x05, 0x18, 0x2a, 0x57, 0x2b, 0xa6, 0xba, 0x8d, + 0xd4, 0x9d, 0x86, 0x67, 0x22, 0x14, 0xbd, 0xea, 0xd6, 0x69, 0xf0, 0xc8, 0xf5, 0x0e, 0x4c, 0xea, + 0x07, 0x9e, 0xc3, 0x13, 0x54, 0xe2, 0x42, 0xfc, 0x2c, 0x79, 0x17, 0x86, 0xd1, 0xf0, 0x34, 0x76, + 0x32, 0xc4, 0xeb, 0x58, 0x9a, 0x14, 0x13, 0x78, 0x18, 0xad, 0x58, 0x4d, 0x4e, 0x44, 0xde, 0x86, + 0xa1, 0x0a, 0x6d, 0x1f, 0xc6, 0x72, 0xe7, 0x25, 0x88, 0xc3, 0x0d, 0xa1, 0x41, 0xdb, 0x87, 0x26, + 0x92, 0x18, 0x3f, 0x9d, 0x85, 0x33, 0x29, 0x9f, 0xf5, 0xe0, 0xb3, 0xcf, 0xe8, 0xae, 0xb8, 0xa4, + 0xed, 0x8a, 0xf2, 0x7d, 0xba, 0x67, 0xc7, 0xa7, 0x6e, 0x92, 0x3f, 0x9f, 0x81, 0x73, 0xfa, 0x04, + 0x15, 0x96, 0xe6, 0x0f, 0x6e, 0x92, 0x77, 0x60, 0x64, 0x85, 0xda, 0x0d, 0x2a, 0xf3, 0x6a, 0x9d, + 0x09, 0x03, 0xe2, 0xf1, 0x18, 0x02, 0xbc, 0x90, 0xb3, 0x8d, 0x3c, 0x4e, 0x39, 0x94, 0x54, 0xc4, + 0xc7, 0x71, 0x79, 0xdc, 0x90, 0xf1, 0x3c, 0xd2, 0xaa, 0xea, 0x63, 0xe5, 0xf1, 0x9d, 0x0c, 0x3c, + 0xdf, 0x87, 0x86, 0x0d, 0x1c, 0x1b, 0x7a, 0x75, 0xe0, 0xf0, 0x44, 0x45, 0x28, 0x79, 0x1f, 0xa6, + 0x37, 0x85, 0x3c, 0x2f, 0x87, 0x23, 0x1b, 0xad, 0x17, 0x29, 0xea, 0x5b, 0x72, 0x5c, 0xe2, 0xc8, + 0x5a, 0xa0, 0x99, 0x5c, 0xdf, 0x40, 0x33, 0x6a, 0xdc, 0x96, 0xa1, 0x41, 0xe3, 0xb6, 0x7c, 0x08, + 0x73, 0x7a, 0xdb, 0x44, 0xf8, 0xdc, 0x28, 0x6a, 0x4d, 0xa6, 0x77, 0xd4, 0x9a, 0xbe, 0x41, 0x3a, + 0x8d, 0x9f, 0xc8, 0x40, 0x41, 0xe7, 0xfd, 0xa4, 0xe3, 0xf9, 0x9e, 0x36, 0x9e, 0xcf, 0xa7, 0x8f, + 0x67, 0xef, 0x81, 0xfc, 0xbf, 0x33, 0xf1, 0xc6, 0x0e, 0x34, 0x82, 0x06, 0x8c, 0x54, 0xdc, 0x96, + 0xed, 0xb4, 0xd5, 0x5c, 0xfa, 0x0d, 0x84, 0x98, 0xa2, 0x64, 0xb0, 0x20, 0x3f, 0x97, 0x60, 0x78, + 0xdd, 0x6d, 0x97, 0x2a, 0xc2, 0xa4, 0x17, 0xf9, 0xb4, 0xdd, 0xb6, 0x65, 0x37, 0x4c, 0x5e, 0x40, + 0x56, 0x01, 0x6a, 0x75, 0x8f, 0xd2, 0x76, 0xcd, 0xf9, 0x5e, 0x1a, 0x93, 0x34, 0x58, 0x0f, 0x35, + 0xbb, 0xb8, 0xb1, 0xf0, 0xa7, 0x4b, 0x44, 0xb4, 0x7c, 0xe7, 0x7b, 0xd5, 0xfd, 0x56, 0xa1, 0xc7, + 0x75, 0x25, 0xe2, 0xa0, 0xc5, 0xc6, 0xe1, 0xc6, 0x27, 0xb1, 0xae, 0x52, 0xab, 0xc2, 0x1e, 0xbe, + 0x91, 0x3a, 0x1c, 0x7f, 0x90, 0x81, 0xe7, 0xfb, 0xd0, 0x3c, 0x85, 0x51, 0xf9, 0x8b, 0xee, 0x70, + 0x0a, 0x10, 0x11, 0x61, 0x6a, 0x62, 0xa7, 0x11, 0xf0, 0x5c, 0x79, 0x93, 0x22, 0x35, 0x31, 0x03, + 0x68, 0xa9, 0x89, 0x19, 0x80, 0x9d, 0xa5, 0x2b, 0xd4, 0xd9, 0xdb, 0xe7, 0xe6, 0x59, 0x93, 0x7c, + 0x6f, 0xd8, 0x47, 0x88, 0x7a, 0x96, 0x72, 0x1c, 0xe3, 0x5f, 0x0d, 0xc3, 0x79, 0x93, 0xee, 0x39, + 0xec, 0x5e, 0xb2, 0xe5, 0x3b, 0xed, 0x3d, 0x2d, 0xee, 0x8d, 0x11, 0x5b, 0xb9, 0x22, 0x49, 0x04, + 0x83, 0x84, 0x33, 0xf1, 0x2a, 0xe4, 0x99, 0x18, 0xa2, 0x2c, 0x5e, 0x7c, 0xb4, 0x62, 0xc2, 0x8a, + 0x08, 0xac, 0x2c, 0x8b, 0xc9, 0x6b, 0x42, 0x4c, 0x52, 0xd2, 0xf8, 0x30, 0x31, 0xe9, 0xbb, 0x47, + 0x45, 0xa8, 0x1d, 0xfa, 0x01, 0xc5, 0x2b, 0xb2, 0x10, 0x95, 0xc2, 0xbb, 0xcc, 0x50, 0x8f, 0xbb, + 0xcc, 0x1a, 0xcc, 0x95, 0x1a, 0xfc, 0x74, 0xb4, 0x9b, 0x1b, 0x9e, 0xd3, 0xae, 0x3b, 0x1d, 0xbb, + 0x29, 0xef, 0xe7, 0xd8, 0xcb, 0x76, 0x58, 0x6e, 0x75, 0x42, 0x04, 0x33, 0x95, 0x8c, 0x35, 0xa3, + 0xb2, 0x5e, 0xc3, 0xf0, 0x30, 0xe2, 0x3d, 0x12, 0x9b, 0xd1, 0x68, 0xfb, 0xd8, 0x0a, 0xdf, 0x0c, + 0x8b, 0xf1, 0x16, 0x85, 0x0f, 0xf2, 0x9b, 0xab, 0xb5, 0xc8, 0xa5, 0x99, 0x67, 0x19, 0xe0, 0x0f, + 0xfb, 0x41, 0xd3, 0x47, 0x53, 0x48, 0x0d, 0x2f, 0xa2, 0xab, 0xd5, 0x56, 0x18, 0x5d, 0x3e, 0x41, + 0xe7, 0xfb, 0xfb, 0x2a, 0x1d, 0xc7, 0x23, 0xd7, 0xd9, 0x54, 0x68, 0xb9, 0x01, 0xc5, 0x29, 0x3c, + 0x16, 0xdd, 0xb9, 0x3c, 0x84, 0xf2, 0x3b, 0x97, 0x82, 0x42, 0xde, 0x85, 0xd9, 0xe5, 0xf2, 0xa2, + 0xd4, 0x22, 0x57, 0xdc, 0x7a, 0x17, 0x1f, 0xe2, 0x01, 0xeb, 0xc3, 0x31, 0xa4, 0xf5, 0x45, 0xb6, + 0x9b, 0xa4, 0xa1, 0x91, 0xcb, 0x30, 0x5a, 0xad, 0xf0, 0xbe, 0x1f, 0x57, 0x53, 0x69, 0x09, 0xcb, + 0x28, 0x59, 0x48, 0xee, 0x47, 0x97, 0x82, 0x89, 0x13, 0xa5, 0xf7, 0xf3, 0x03, 0x5c, 0x08, 0xde, + 0x86, 0xc9, 0x25, 0x37, 0xa8, 0xb6, 0xfd, 0xc0, 0x6e, 0xd7, 0x69, 0xb5, 0xa2, 0xc6, 0xb5, 0xde, + 0x71, 0x03, 0xcb, 0x11, 0x25, 0xec, 0xcb, 0x75, 0x4c, 0xf2, 0x79, 0x24, 0xbd, 0x43, 0xdb, 0xd4, + 0x8b, 0xe2, 0x59, 0x0f, 0xf3, 0xbe, 0x65, 0xa4, 0x7b, 0x61, 0x89, 0xa9, 0x23, 0x8a, 0x34, 0x5f, + 0x3c, 0x39, 0x67, 0xd9, 0x6d, 0x50, 0x9f, 0xef, 0x16, 0x9f, 0xa2, 0x34, 0x5f, 0x4a, 0xdb, 0xfa, + 0xec, 0xa0, 0xff, 0x2e, 0xa6, 0xf9, 0x4a, 0xe0, 0x92, 0xcf, 0xc3, 0x30, 0xfe, 0x14, 0xd2, 0xed, + 0x6c, 0x0a, 0xdb, 0x48, 0xb2, 0xad, 0x33, 0x4c, 0x93, 0x13, 0x90, 0x2a, 0x8c, 0x8a, 0x8b, 0xd5, + 0x69, 0x92, 0xd5, 0x88, 0x1b, 0x1a, 0x9f, 0x19, 0x82, 0xde, 0x68, 0xc0, 0x84, 0x5a, 0x21, 0x5b, + 0x11, 0x2b, 0xb6, 0xbf, 0x4f, 0x1b, 0xec, 0x97, 0xc8, 0x33, 0x87, 0x2b, 0x62, 0x1f, 0xa1, 0x16, + 0xfb, 0x0e, 0x53, 0x41, 0x61, 0x67, 0x6a, 0xd5, 0xdf, 0xf2, 0xc5, 0xa7, 0x08, 0x55, 0x8b, 0x83, + 0x6a, 0xbb, 0x86, 0x29, 0x8a, 0x8c, 0xef, 0x81, 0xb9, 0xf5, 0x6e, 0xb3, 0x69, 0xef, 0x34, 0xa9, + 0xcc, 0x43, 0x82, 0x19, 0xbc, 0x97, 0x60, 0xb8, 0xa6, 0xe4, 0x04, 0x0f, 0x73, 0x41, 0x2a, 0x38, + 0x68, 0x84, 0x9a, 0xc1, 0x50, 0x3d, 0xb1, 0x6c, 0xe0, 0x9c, 0xd4, 0xf8, 0xbd, 0x0c, 0xcc, 0xc9, + 0xf7, 0x7f, 0xcf, 0xae, 0x1f, 0x84, 0x89, 0xe1, 0x2f, 0x6b, 0x73, 0x0d, 0x27, 0x6c, 0x6c, 0x1a, + 0xf1, 0x59, 0x77, 0x57, 0x7e, 0x84, 0x2e, 0xb0, 0xa4, 0x7d, 0xf0, 0x49, 0x1f, 0x43, 0xde, 0x85, + 0x71, 0x71, 0x3c, 0x2a, 0x01, 0x26, 0x31, 0x8a, 0x97, 0xb8, 0xee, 0xc5, 0xad, 0x51, 0x54, 0x74, + 0x94, 0xc5, 0xf4, 0xa6, 0x3c, 0xa9, 0x0c, 0x90, 0x2e, 0x8b, 0xe9, 0x75, 0xf4, 0x99, 0xba, 0xbf, + 0x3d, 0x1e, 0xef, 0x5b, 0x31, 0x77, 0x6f, 0xa9, 0x21, 0xe5, 0x32, 0xd1, 0xcd, 0x38, 0x0a, 0x29, + 0xa7, 0xde, 0x8c, 0x43, 0xd4, 0x70, 0x4c, 0xb2, 0x27, 0x8c, 0xc9, 0xfb, 0x72, 0x4c, 0x72, 0xbd, + 0x27, 0xc6, 0x6c, 0x9f, 0x71, 0xa8, 0x45, 0x2b, 0x64, 0x68, 0x20, 0xb5, 0xca, 0x73, 0x18, 0x3b, + 0x9f, 0x93, 0xc4, 0x77, 0x51, 0xc1, 0x49, 0xd5, 0xd5, 0x0c, 0x0f, 0xce, 0xf4, 0x84, 0xad, 0xf9, + 0x0b, 0x30, 0x51, 0x0a, 0x02, 0xbb, 0xbe, 0x4f, 0x1b, 0x15, 0xb6, 0x3d, 0x29, 0xd1, 0xaf, 0x6c, + 0x01, 0x57, 0x1f, 0xcd, 0x54, 0x5c, 0x1e, 0xcd, 0xd5, 0xf6, 0x85, 0x31, 0x6b, 0x18, 0xcd, 0x95, + 0x41, 0xf4, 0x68, 0xae, 0x0c, 0x42, 0xae, 0xc3, 0x68, 0xb5, 0xfd, 0xd0, 0x61, 0x7d, 0xc2, 0x03, + 0x60, 0xa1, 0x6e, 0xca, 0xe1, 0x20, 0x75, 0x73, 0x15, 0x58, 0xe4, 0x6d, 0xe5, 0x52, 0x33, 0x16, + 0x29, 0x30, 0xb8, 0xca, 0x2b, 0x8c, 0x70, 0xa3, 0x5e, 0x58, 0xc2, 0x5b, 0xce, 0x2d, 0x18, 0x95, + 0x9a, 0x4c, 0x88, 0x94, 0x16, 0x82, 0x32, 0x19, 0x30, 0x42, 0x22, 0x63, 0x92, 0x6f, 0x25, 0x5f, + 0xde, 0xb8, 0x92, 0xe4, 0x5b, 0xc9, 0x97, 0xa7, 0x25, 0xf9, 0x56, 0x32, 0xe7, 0x85, 0x4a, 0xa0, + 0x89, 0x13, 0x95, 0x40, 0x0f, 0x60, 0x62, 0xc3, 0xf6, 0x02, 0x87, 0xc9, 0x28, 0xed, 0xc0, 0x9f, + 0x9f, 0xd4, 0xf4, 0xa6, 0x4a, 0xd1, 0xd2, 0x45, 0x99, 0x97, 0xba, 0xa3, 0xe0, 0xeb, 0x09, 0x94, + 0x23, 0x78, 0xba, 0x29, 0xeb, 0xd4, 0x93, 0x98, 0xb2, 0x62, 0xa7, 0xa2, 0xae, 0x6c, 0x3a, 0xd2, + 0xc8, 0xe0, 0xa5, 0x25, 0xa6, 0x30, 0x0b, 0x11, 0xc9, 0x57, 0x61, 0x82, 0xfd, 0xbd, 0xe1, 0x36, + 0x9d, 0xba, 0x43, 0xfd, 0xf9, 0x02, 0x36, 0xee, 0x62, 0xea, 0xea, 0x47, 0xa4, 0xc3, 0x1a, 0x0d, + 0xf8, 0x02, 0x46, 0xc6, 0x71, 0x25, 0xb8, 0xc6, 0x8d, 0x7c, 0x00, 0x13, 0x6c, 0xf6, 0xed, 0xd8, + 0x3e, 0x17, 0x4d, 0x67, 0x22, 0x63, 0xe4, 0x86, 0x80, 0x27, 0x02, 0x2a, 0xab, 0x04, 0xec, 0x98, + 0x2f, 0x75, 0xf8, 0x06, 0x49, 0x94, 0xd9, 0xde, 0x49, 0x6c, 0x8e, 0x12, 0x8d, 0x7c, 0x11, 0x26, + 0x4a, 0x9d, 0x4e, 0xb4, 0xe3, 0xcc, 0x2a, 0x8a, 0xb0, 0x4e, 0xc7, 0x4a, 0xdd, 0x75, 0x34, 0x8a, + 0xf8, 0xc6, 0x3c, 0x77, 0xaa, 0x8d, 0x99, 0xbc, 0x19, 0x4a, 0xeb, 0x67, 0x22, 0xad, 0xae, 0xb8, + 0x38, 0x6a, 0xa2, 0x3f, 0x17, 0xdc, 0xcb, 0x30, 0xc9, 0xd5, 0x9c, 0x52, 0x9a, 0x39, 0x9b, 0x58, + 0x3d, 0x29, 0x42, 0x8d, 0x4e, 0x43, 0x96, 0x61, 0x8a, 0x7b, 0x5b, 0x37, 0x45, 0xa4, 0xeb, 0xf9, + 0x73, 0xb8, 0x6a, 0x91, 0x0b, 0x77, 0xd2, 0x6e, 0x62, 0x02, 0x14, 0x5b, 0xe3, 0x12, 0x23, 0x32, + 0xfe, 0x24, 0x03, 0xe7, 0x7a, 0x8c, 0x78, 0x18, 0x07, 0x39, 0xd3, 0x3f, 0x0e, 0x32, 0xdb, 0x39, + 0x74, 0xad, 0x08, 0xb6, 0x5f, 0x48, 0x59, 0xea, 0x78, 0x49, 0x79, 0xcb, 0x05, 0x22, 0x72, 0x0c, + 0x89, 0xaa, 0xef, 0xba, 0xa8, 0x9a, 0xcd, 0x25, 0x0f, 0x21, 0x81, 0xc7, 0x3f, 0x6a, 0xc9, 0x38, + 0x3e, 0x2a, 0x5e, 0x14, 0x29, 0x8c, 0xc2, 0x61, 0xfd, 0xc8, 0xd5, 0x56, 0x70, 0x0a, 0x6b, 0xe3, + 0x28, 0x03, 0xe3, 0xca, 0x3a, 0x24, 0x97, 0x14, 0x2f, 0xe0, 0x02, 0x4f, 0x82, 0xa5, 0x70, 0xc8, + 0xf2, 0x93, 0x08, 0x17, 0x55, 0xf6, 0x64, 0x05, 0xf4, 0x1a, 0x13, 0x85, 0x94, 0x58, 0xd1, 0x2d, + 0x4d, 0x5b, 0x6c, 0x62, 0x39, 0xa6, 0xd3, 0xb7, 0xfd, 0xa0, 0x54, 0x0f, 0x9c, 0x87, 0x74, 0x80, + 0x43, 0x27, 0x4a, 0xa7, 0x6f, 0xfb, 0x81, 0x65, 0x23, 0x59, 0x22, 0x9d, 0x7e, 0xc8, 0xd0, 0xf8, + 0x81, 0x0c, 0xc0, 0x56, 0xb5, 0x8c, 0xc1, 0xde, 0x9f, 0x54, 0x28, 0x48, 0x0f, 0xa0, 0x2b, 0xb9, + 0xf7, 0x11, 0x07, 0xfe, 0xe7, 0x0c, 0x4c, 0xe9, 0x68, 0xe4, 0x7d, 0x98, 0xae, 0xd5, 0x3d, 0xb7, + 0xd9, 0xdc, 0xb1, 0xeb, 0x07, 0xab, 0x4e, 0x9b, 0xf2, 0xd0, 0xa5, 0xc3, 0xfc, 0x2c, 0xf2, 0xc3, + 0x22, 0xab, 0xc9, 0xca, 0xcc, 0x38, 0x32, 0xf9, 0xc1, 0x0c, 0x4c, 0xd6, 0xf6, 0xdd, 0x47, 0x61, + 0xb4, 0x51, 0x31, 0x20, 0x5f, 0x63, 0x6b, 0xdb, 0xdf, 0x77, 0x1f, 0x45, 0x19, 0x34, 0x35, 0xe3, + 0xcf, 0xf7, 0x06, 0x7b, 0x97, 0xaf, 0xbb, 0x78, 0x93, 0x09, 0xfc, 0x6b, 0x5a, 0x25, 0xa6, 0x5e, + 0xa7, 0xf1, 0xe7, 0x19, 0x18, 0xc7, 0x3b, 0x4f, 0xb3, 0x89, 0x32, 0xd7, 0xa7, 0x29, 0x1d, 0x63, + 0xd8, 0xae, 0x3e, 0x03, 0xfb, 0x16, 0x4c, 0xc7, 0xd0, 0x88, 0x01, 0x23, 0x35, 0x74, 0xf0, 0x57, + 0x15, 0x14, 0xdc, 0xe5, 0xdf, 0x14, 0x25, 0xc6, 0xb2, 0x42, 0xf6, 0xe0, 0x06, 0x3e, 0xeb, 0x2e, + 0x02, 0x38, 0x12, 0x24, 0x6f, 0x36, 0x24, 0xfe, 0x25, 0x0f, 0x6e, 0x98, 0x0a, 0x96, 0xb1, 0x0e, + 0x23, 0x35, 0xd7, 0x0b, 0x96, 0x0e, 0xf9, 0x65, 0xa2, 0x42, 0xfd, 0xba, 0xfa, 0x6e, 0xeb, 0xe0, + 0x5b, 0x49, 0xdd, 0x14, 0x45, 0xa4, 0x08, 0xc3, 0xb7, 0x1d, 0xda, 0x6c, 0xa8, 0x06, 0xba, 0xbb, + 0x0c, 0x60, 0x72, 0x38, 0xbb, 0x70, 0x9d, 0x8d, 0x72, 0xa2, 0x44, 0x96, 0xc0, 0x4f, 0xba, 0x6e, + 0xca, 0x5a, 0xff, 0xbe, 0x18, 0xe6, 0x21, 0x48, 0xd6, 0xd4, 0xa7, 0xab, 0xff, 0xe3, 0x0c, 0x2c, + 0xf4, 0x26, 0x51, 0x8d, 0x8b, 0x33, 0x7d, 0x8c, 0x8b, 0x5f, 0x89, 0xbf, 0x33, 0x22, 0x9a, 0x78, + 0x67, 0x8c, 0x5e, 0x17, 0x2b, 0x68, 0xdb, 0x5d, 0xa7, 0x32, 0x11, 0xca, 0xa5, 0x3e, 0xdf, 0x8c, + 0x88, 0x7c, 0x98, 0x03, 0xa4, 0x31, 0x05, 0xad, 0xf1, 0x5b, 0x43, 0x70, 0xbe, 0x27, 0x05, 0x59, + 0x51, 0xd2, 0x2b, 0x4d, 0x85, 0x89, 0x5d, 0x7a, 0xe2, 0x5f, 0xc3, 0x7f, 0xd1, 0x7c, 0x2f, 0xee, + 0x6d, 0x76, 0x3f, 0x4c, 0xab, 0x93, 0x45, 0x5e, 0xaf, 0x9f, 0xc8, 0x8b, 0xa3, 0x23, 0x33, 0x48, + 0x66, 0xd8, 0x41, 0xbf, 0x44, 0x1a, 0xd8, 0x4e, 0xd3, 0x57, 0x97, 0x5d, 0x83, 0x83, 0x4c, 0x59, + 0x16, 0x59, 0x7c, 0x0f, 0xa5, 0x5b, 0x7c, 0x1b, 0xff, 0x2a, 0x03, 0x63, 0xe1, 0x67, 0x93, 0x05, + 0x38, 0xbb, 0x69, 0x96, 0xca, 0xcb, 0xd6, 0xe6, 0x87, 0x1b, 0xcb, 0xd6, 0xd6, 0x7a, 0x6d, 0x63, + 0xb9, 0x5c, 0xbd, 0x5d, 0x5d, 0xae, 0x14, 0x9e, 0x23, 0x33, 0x30, 0xb9, 0xb5, 0x7e, 0x6f, 0xfd, + 0xfe, 0xf6, 0xba, 0xb5, 0x6c, 0x9a, 0xf7, 0xcd, 0x42, 0x86, 0x4c, 0xc2, 0x98, 0xb9, 0x54, 0x2a, + 0x5b, 0xeb, 0xf7, 0x2b, 0xcb, 0x85, 0x2c, 0x29, 0xc0, 0x44, 0xf9, 0xfe, 0xfa, 0xfa, 0x72, 0x79, + 0xb3, 0xfa, 0xa0, 0xba, 0xf9, 0x61, 0x21, 0x47, 0x08, 0x4c, 0x21, 0xc2, 0x86, 0x59, 0x5d, 0x2f, + 0x57, 0x37, 0x4a, 0xab, 0x85, 0x21, 0x06, 0x63, 0xf8, 0x0a, 0x6c, 0x38, 0x64, 0x74, 0x6f, 0x6b, + 0x69, 0xb9, 0x30, 0xc2, 0x50, 0xd8, 0x5f, 0x0a, 0xca, 0x28, 0xab, 0x1e, 0x51, 0x2a, 0xa5, 0xcd, + 0xd2, 0x52, 0xa9, 0xb6, 0x5c, 0xc8, 0x93, 0x73, 0x30, 0xab, 0x81, 0xac, 0xd5, 0xfb, 0x77, 0xaa, + 0xeb, 0x85, 0x31, 0x32, 0x07, 0x85, 0x10, 0x56, 0x59, 0xb2, 0xb6, 0x6a, 0xcb, 0x66, 0x01, 0xe2, + 0xd0, 0xf5, 0xd2, 0xda, 0x72, 0x61, 0xdc, 0x78, 0x8f, 0xfb, 0x01, 0xf2, 0xae, 0x26, 0x67, 0x81, + 0xd4, 0x36, 0x4b, 0x9b, 0x5b, 0xb5, 0x58, 0xe3, 0xc7, 0x61, 0xb4, 0xb6, 0x55, 0x2e, 0x2f, 0xd7, + 0x6a, 0x85, 0x0c, 0x01, 0x18, 0xb9, 0x5d, 0xaa, 0xae, 0x2e, 0x57, 0x0a, 0x59, 0xe3, 0xa7, 0x32, + 0x30, 0x23, 0x25, 0x40, 0xf9, 0x68, 0xf4, 0x84, 0x6b, 0xf1, 0x7d, 0xed, 0x62, 0x2b, 0x9d, 0xb4, + 0x62, 0x95, 0xf4, 0x59, 0x86, 0x3f, 0x9f, 0x81, 0x33, 0xa9, 0xd8, 0xe4, 0x43, 0x28, 0xc8, 0x2f, + 0x58, 0xb3, 0x83, 0xfa, 0x7e, 0xb4, 0x8f, 0x5d, 0x8c, 0xd5, 0x12, 0x43, 0xe3, 0x6a, 0xcd, 0x28, + 0xe1, 0x73, 0x82, 0xcd, 0xe0, 0xe9, 0x08, 0x8c, 0x6f, 0x67, 0xe0, 0x5c, 0x8f, 0x6a, 0x48, 0x19, + 0x46, 0xc2, 0xc4, 0x34, 0x7d, 0x2c, 0xd8, 0xe6, 0xbe, 0x73, 0x54, 0x14, 0x88, 0x98, 0x21, 0x17, + 0xff, 0x32, 0x47, 0xc2, 0x4c, 0x33, 0x98, 0xee, 0x85, 0x77, 0xdf, 0xf9, 0x58, 0xcf, 0x8b, 0x9a, + 0x4a, 0xdb, 0xb5, 0xa5, 0x71, 0xd1, 0x77, 0x39, 0xfb, 0x91, 0x8f, 0xf9, 0x5e, 0x8c, 0x9f, 0xc9, + 0x30, 0xe1, 0x2e, 0x8e, 0xc8, 0x64, 0xde, 0x92, 0xef, 0x77, 0x5b, 0xd4, 0x74, 0x9b, 0xb4, 0x64, + 0xae, 0x8b, 0x63, 0x03, 0xa5, 0x55, 0x1b, 0x0b, 0xf0, 0x5a, 0x61, 0xd9, 0x5e, 0x5b, 0x7b, 0xad, + 0x56, 0x69, 0xc8, 0xdb, 0x00, 0xcb, 0x8f, 0x03, 0xea, 0xb5, 0xed, 0x66, 0x18, 0xa3, 0x85, 0x47, + 0x96, 0x12, 0x50, 0x5d, 0xde, 0x56, 0x90, 0x8d, 0xbf, 0x99, 0x81, 0x09, 0x71, 0x69, 0x2a, 0x35, + 0xa9, 0x17, 0x3c, 0xd9, 0xf4, 0x7a, 0x5b, 0x9b, 0x5e, 0xa1, 0xc3, 0x86, 0xc2, 0x9f, 0x15, 0xa7, + 0xce, 0xac, 0x7f, 0x9a, 0x81, 0x42, 0x1c, 0x91, 0xbc, 0x0f, 0xf9, 0x1a, 0x7d, 0x48, 0x3d, 0x27, + 0x38, 0x14, 0x1b, 0xa5, 0x4c, 0xe1, 0xc7, 0x71, 0x44, 0x19, 0x9f, 0x0f, 0xbe, 0xf8, 0x65, 0x86, + 0x34, 0x83, 0xee, 0xf7, 0x8a, 0xda, 0x23, 0xf7, 0xb4, 0xd4, 0x1e, 0xc6, 0xff, 0x9e, 0x85, 0x73, + 0x77, 0x68, 0xa0, 0xb6, 0x29, 0x34, 0x2f, 0xf8, 0xcc, 0x60, 0xed, 0x52, 0x5a, 0x32, 0x0f, 0xa3, + 0x58, 0x24, 0xc7, 0xd7, 0x94, 0x3f, 0xc9, 0x52, 0x38, 0xaf, 0x73, 0x5a, 0x8e, 0xb0, 0x1e, 0x75, + 0x5f, 0x53, 0xb2, 0x06, 0x85, 0xd3, 0xfa, 0x32, 0x4c, 0x61, 0x58, 0xfc, 0x2e, 0x5b, 0x0e, 0xb4, + 0x21, 0xd4, 0x3f, 0x79, 0x33, 0x06, 0x25, 0xaf, 0x41, 0x81, 0x41, 0x4a, 0xf5, 0x83, 0xb6, 0xfb, + 0xa8, 0x49, 0x1b, 0x7b, 0xb4, 0x81, 0xc7, 0x7a, 0xde, 0x4c, 0xc0, 0x25, 0xcf, 0xad, 0x36, 0xbf, + 0xba, 0xd1, 0x06, 0xea, 0x68, 0x04, 0xcf, 0x08, 0xba, 0xf0, 0x36, 0x8c, 0x7f, 0xcc, 0x0c, 0x60, + 0xc6, 0xff, 0x96, 0x81, 0x39, 0x6c, 0x9c, 0x52, 0xb1, 0xcc, 0xce, 0x2a, 0x7b, 0x4b, 0x49, 0x8a, + 0x63, 0x33, 0x90, 0xbe, 0x14, 0xc2, 0x5e, 0x8c, 0x74, 0x42, 0xd9, 0x01, 0x74, 0x42, 0xb5, 0xd3, + 0x64, 0xa2, 0x1f, 0x50, 0xa5, 0x75, 0x77, 0x28, 0x9f, 0x2b, 0x0c, 0x45, 0x43, 0x6e, 0xfc, 0x60, + 0x16, 0x46, 0x4d, 0x8a, 0x29, 0xba, 0xc9, 0x65, 0x18, 0x5d, 0x77, 0x03, 0xea, 0xaf, 0x69, 0xf9, + 0xd8, 0xdb, 0x0c, 0x64, 0xb5, 0x1a, 0xa6, 0x2c, 0x64, 0x13, 0x7e, 0xc3, 0x73, 0x1b, 0xdd, 0x7a, + 0xa0, 0x4e, 0xf8, 0x0e, 0x07, 0x99, 0xb2, 0x8c, 0xbc, 0x01, 0x63, 0x82, 0x73, 0xf8, 0xa8, 0x8b, + 0xc6, 0xc8, 0x1e, 0x0d, 0x53, 0xbc, 0x47, 0x08, 0x28, 0xd3, 0x72, 0x01, 0x63, 0x48, 0x91, 0x69, + 0x13, 0x32, 0x83, 0x14, 0xd5, 0x87, 0xfb, 0x88, 0xea, 0x9f, 0x81, 0x91, 0x92, 0xef, 0xd3, 0x40, + 0x46, 0x31, 0x98, 0x08, 0xc3, 0xb6, 0xf9, 0x34, 0xe0, 0x8c, 0x6d, 0x2c, 0x37, 0x05, 0x9e, 0xf1, + 0x2f, 0xb2, 0x30, 0x8c, 0x7f, 0xe2, 0x93, 0xa9, 0x57, 0xdf, 0xd7, 0x9e, 0x4c, 0xbd, 0xfa, 0xbe, + 0x89, 0x50, 0x72, 0x03, 0x35, 0x15, 0x32, 0x7f, 0x93, 0x68, 0x3d, 0xaa, 0xe0, 0x1b, 0x11, 0xd8, + 0x54, 0x71, 0xc2, 0x17, 0xfe, 0x5c, 0x6a, 0xec, 0x92, 0xb3, 0x90, 0xbd, 0x5f, 0x13, 0x2d, 0xc6, + 0x88, 0x58, 0xae, 0x6f, 0x66, 0xef, 0xd7, 0xb0, 0x37, 0x56, 0x4a, 0x8b, 0x6f, 0xdd, 0x12, 0x0d, + 0xe5, 0xbd, 0xb1, 0x6f, 0x2f, 0xbe, 0x75, 0xcb, 0x14, 0x25, 0xac, 0x7f, 0xf1, 0x9b, 0xf1, 0xe1, + 0x95, 0xfb, 0xdc, 0x63, 0xff, 0x62, 0xdb, 0xf0, 0x91, 0xd5, 0x8c, 0x10, 0xc8, 0x22, 0x8c, 0x8b, + 0x58, 0x0f, 0x88, 0xaf, 0xc4, 0x62, 0x10, 0xb1, 0x20, 0x38, 0x85, 0x8a, 0xc4, 0x9f, 0xe0, 0xc4, + 0x00, 0xc9, 0x2c, 0xb3, 0xe2, 0x09, 0x4e, 0x0e, 0xa1, 0x6f, 0x2a, 0x28, 0xec, 0x93, 0xf8, 0x1b, + 0x5e, 0xe4, 0x4b, 0x3f, 0xa5, 0x04, 0x0d, 0xc0, 0x34, 0x07, 0x21, 0x82, 0xf1, 0xcb, 0x59, 0xc8, + 0x6f, 0x34, 0xbb, 0x7b, 0x4e, 0xfb, 0xc1, 0x0d, 0x42, 0x00, 0xaf, 0x71, 0x32, 0x0f, 0x06, 0xfb, + 0x9b, 0x9c, 0x87, 0xbc, 0xbc, 0xb9, 0xc9, 0x0d, 0xc9, 0x17, 0xb7, 0xb6, 0x79, 0x90, 0xe3, 0x2e, + 0x42, 0x9f, 0xc9, 0x9f, 0xe4, 0x06, 0x84, 0xf7, 0xaf, 0x5e, 0x17, 0xb5, 0x21, 0xb6, 0x58, 0xcc, + 0x10, 0x8d, 0xbc, 0x09, 0x78, 0x48, 0x88, 0xcb, 0x83, 0x54, 0x68, 0xf3, 0x4f, 0x13, 0x72, 0x0a, + 0x27, 0x41, 0x34, 0x72, 0x13, 0xc4, 0xc4, 0x14, 0xd9, 0xcc, 0xcf, 0xe8, 0x04, 0x3c, 0x3f, 0xa4, + 0x24, 0x11, 0xa8, 0xe4, 0x5d, 0x18, 0xaf, 0x7b, 0x14, 0x5f, 0x1d, 0xed, 0x66, 0x94, 0xa4, 0x5c, + 0xa5, 0x2c, 0x47, 0xe5, 0x0f, 0x6e, 0x98, 0x2a, 0xba, 0xf1, 0xcb, 0x79, 0x98, 0x50, 0xbf, 0x87, + 0x98, 0x30, 0xeb, 0x37, 0xd9, 0xdd, 0x5d, 0x18, 0x9b, 0x75, 0xb0, 0x50, 0x1c, 0xa7, 0x97, 0xf4, + 0x0f, 0x62, 0x78, 0xdc, 0xf2, 0x4c, 0x06, 0xa9, 0x58, 0x79, 0xce, 0x9c, 0xf1, 0x23, 0x30, 0xc7, + 0x23, 0x25, 0xc8, 0xbb, 0x1d, 0x7f, 0x8f, 0xb6, 0x1d, 0xf9, 0xde, 0xf2, 0x92, 0xc6, 0xe8, 0xbe, + 0x28, 0x4c, 0xf0, 0x0a, 0xc9, 0xc8, 0x5b, 0x30, 0xe2, 0x76, 0x68, 0xdb, 0x76, 0xc4, 0x19, 0xf7, + 0x7c, 0x8c, 0x01, 0x6d, 0x97, 0xaa, 0x0a, 0xa1, 0x40, 0x26, 0xd7, 0x61, 0xc8, 0x3d, 0x08, 0xc7, + 0xeb, 0xbc, 0x4e, 0x74, 0x10, 0xd8, 0x0a, 0x09, 0x22, 0x32, 0x82, 0x8f, 0xec, 0xd6, 0xae, 0x18, + 0x31, 0x9d, 0xe0, 0xae, 0xdd, 0xda, 0x55, 0x09, 0x18, 0x22, 0xf9, 0x00, 0xa0, 0x63, 0xef, 0x51, + 0xcf, 0x6a, 0x74, 0x83, 0x43, 0x31, 0x6e, 0x17, 0x35, 0xb2, 0x0d, 0x56, 0x5c, 0xe9, 0x06, 0x87, + 0x0a, 0xed, 0x58, 0x47, 0x02, 0x49, 0x09, 0xa0, 0x65, 0x07, 0x01, 0xf5, 0x5a, 0xae, 0xb0, 0xf6, + 0x8b, 0x82, 0x10, 0x72, 0x06, 0x6b, 0x61, 0xb1, 0xc2, 0x41, 0x21, 0xc2, 0x8f, 0x76, 0x3c, 0x5b, + 0xe4, 0x94, 0x8f, 0x7d, 0xb4, 0xe3, 0x69, 0xad, 0x64, 0x88, 0xe4, 0xf3, 0x30, 0xda, 0x70, 0xfc, + 0xba, 0xeb, 0x35, 0x44, 0xf4, 0x92, 0x17, 0x34, 0x9a, 0x0a, 0x2f, 0x53, 0xc8, 0x24, 0x3a, 0xfb, + 0x5a, 0x11, 0x84, 0x74, 0xdd, 0x7d, 0x84, 0x6a, 0xfe, 0xf8, 0xd7, 0xd6, 0xc2, 0x62, 0xf5, 0x6b, + 0x23, 0x22, 0x36, 0x94, 0x7b, 0x4e, 0xd0, 0xb4, 0x77, 0xc4, 0x3b, 0xb7, 0x3e, 0x94, 0x77, 0xb0, + 0x48, 0x1d, 0x4a, 0x8e, 0x4c, 0xde, 0x86, 0x3c, 0x6d, 0x07, 0x9e, 0x6d, 0x39, 0x0d, 0xe1, 0x25, + 0xa9, 0x7f, 0x34, 0x3b, 0x80, 0xed, 0x6a, 0x45, 0xfd, 0x68, 0xc4, 0xaf, 0x36, 0x58, 0xff, 0xf8, + 0x75, 0xa7, 0x25, 0x9c, 0x1b, 0xf5, 0xfe, 0xa9, 0x95, 0xab, 0x6b, 0x6a, 0xff, 0x30, 0x44, 0xf2, + 0x3e, 0x8c, 0xb2, 0xf5, 0xdb, 0x70, 0xf7, 0x44, 0x40, 0x08, 0x43, 0xef, 0x1f, 0x5e, 0x96, 0x98, + 0xae, 0x92, 0x88, 0x2d, 0x64, 0xfb, 0x91, 0x6f, 0x39, 0x75, 0x11, 0xe4, 0x41, 0x5f, 0x8e, 0xa5, + 0xed, 0x5a, 0xb5, 0xac, 0x90, 0x0d, 0xdb, 0x8f, 0xfc, 0x6a, 0x9d, 0x2c, 0xc2, 0x30, 0xa6, 0x88, + 0x10, 0x81, 0x28, 0x75, 0x1a, 0x4c, 0x0e, 0xa1, 0xd2, 0x20, 0x2a, 0x1b, 0xc8, 0x96, 0x8f, 0xfe, + 0x22, 0x22, 0x51, 0x83, 0xde, 0x27, 0x6b, 0x35, 0x74, 0x22, 0x51, 0x3f, 0x51, 0xa0, 0x93, 0x8b, + 0x00, 0xd1, 0x2b, 0x3e, 0x7f, 0x73, 0x31, 0x15, 0xc8, 0x17, 0x86, 0xfe, 0xaf, 0x5f, 0x2c, 0x66, + 0x96, 0x00, 0xf2, 0x32, 0x42, 0x8d, 0xb1, 0x0a, 0xe7, 0x7b, 0xae, 0x7b, 0x72, 0x15, 0x0a, 0xbb, + 0xb6, 0xd0, 0xfa, 0xd5, 0xf7, 0xed, 0x76, 0x9b, 0x36, 0xc5, 0x8e, 0x3b, 0x2d, 0xe1, 0x65, 0x0e, + 0xe6, 0x9c, 0x8d, 0x0f, 0x60, 0x2e, 0x6d, 0xc0, 0xc9, 0x8b, 0x30, 0xa1, 0x06, 0xe3, 0x11, 0x4c, + 0xc6, 0xed, 0x8e, 0x23, 0xc3, 0xf1, 0x08, 0x06, 0xbf, 0x99, 0x81, 0x17, 0xfa, 0x6d, 0x1f, 0x64, + 0x01, 0xf2, 0x1d, 0xcf, 0x71, 0x51, 0x4c, 0x15, 0xd9, 0x0e, 0xe4, 0x6f, 0x4c, 0x64, 0x80, 0xf2, + 0x54, 0x60, 0xef, 0x09, 0x07, 0x0f, 0x73, 0x0c, 0x21, 0x9b, 0xf6, 0x9e, 0x4f, 0x5e, 0x87, 0x99, + 0x06, 0xdd, 0xb5, 0xbb, 0xcd, 0xc0, 0xf2, 0xeb, 0xfb, 0xb4, 0x81, 0x3e, 0x55, 0x68, 0xb8, 0x67, + 0x16, 0x44, 0x41, 0x4d, 0xc2, 0x13, 0x5f, 0x3c, 0xdc, 0xe3, 0x8b, 0xef, 0x0e, 0xe5, 0x33, 0xff, + 0x3f, 0x7b, 0xcf, 0x12, 0xe3, 0x46, 0x72, 0x9d, 0x9a, 0xe4, 0xcc, 0x70, 0x1e, 0xe7, 0xd3, 0x53, + 0xfa, 0xcc, 0xac, 0xbe, 0xab, 0x5e, 0x49, 0x96, 0xb8, 0xde, 0xb5, 0xa5, 0xcd, 0x7a, 0x77, 0x6d, + 0xaf, 0xed, 0x1e, 0x4e, 0xcf, 0x90, 0x12, 0x7f, 0xee, 0x26, 0x47, 0x96, 0x65, 0xbb, 0xdd, 0x22, + 0x7b, 0x66, 0xda, 0xe6, 0xb0, 0x69, 0x36, 0xb9, 0xb2, 0x8c, 0x00, 0xb1, 0x11, 0xc0, 0x06, 0xf2, + 0x73, 0xe2, 0x24, 0xc8, 0x22, 0x17, 0x1f, 0x62, 0x04, 0x39, 0xe4, 0x1a, 0x24, 0x48, 0x72, 0xf1, + 0xcd, 0x80, 0x61, 0xc0, 0x40, 0x6e, 0x4e, 0xb0, 0x48, 0x16, 0x48, 0x80, 0x7c, 0x6e, 0x41, 0x72, + 0xf0, 0x29, 0xa8, 0x57, 0x55, 0xdd, 0xd5, 0x1f, 0x52, 0x23, 0xef, 0x3a, 0x89, 0x01, 0x9f, 0x66, + 0xf8, 0xea, 0xbd, 0xd7, 0xf5, 0xaf, 0x57, 0xaf, 0xde, 0x47, 0xcd, 0x99, 0x68, 0x29, 0xa5, 0x7d, + 0x3d, 0x07, 0x5b, 0xb3, 0xd6, 0x0b, 0x79, 0x33, 0xab, 0x0f, 0xd8, 0xc3, 0x85, 0x0c, 0x97, 0x1f, + 0x2e, 0xa4, 0xaf, 0x91, 0x3b, 0x10, 0x7a, 0x44, 0x3d, 0x2d, 0xba, 0x81, 0x80, 0x51, 0x9a, 0x91, + 0x13, 0x04, 0x8f, 0xe9, 0x96, 0x90, 0x97, 0x02, 0xda, 0x72, 0x98, 0x4c, 0x23, 0x60, 0xe4, 0x35, + 0x80, 0xde, 0xc0, 0x0f, 0x5c, 0xb4, 0x0f, 0xe0, 0xb2, 0x06, 0x33, 0x0b, 0x0f, 0xa1, 0xf2, 0x83, + 0x30, 0x42, 0x2b, 0x7e, 0xdf, 0xe5, 0x03, 0xe8, 0xc0, 0xe6, 0x8c, 0x0d, 0x92, 0x0e, 0x4f, 0x94, + 0x1d, 0x5e, 0xe4, 0x9a, 0x9a, 0x86, 0x39, 0xe2, 0x93, 0x3d, 0x9e, 0x9b, 0x35, 0x47, 0x9e, 0x00, + 0x49, 0xef, 0x82, 0x94, 0x3b, 0x37, 0x6e, 0x9e, 0x8e, 0x43, 0xee, 0x0c, 0xd2, 0x1d, 0x0f, 0xc8, + 0x15, 0x28, 0x89, 0x5c, 0x92, 0x54, 0x96, 0x67, 0xcc, 0x81, 0x83, 0xee, 0xb9, 0x38, 0x79, 0x30, + 0x62, 0x29, 0xfa, 0xbd, 0x71, 0x29, 0x61, 0x19, 0x21, 0x9d, 0x27, 0x23, 0xd1, 0xba, 0x8b, 0x62, + 0x7e, 0xc7, 0xcf, 0x26, 0x5e, 0xfa, 0x87, 0x8a, 0x18, 0xfe, 0xf4, 0xe6, 0xfe, 0xb4, 0xfa, 0x11, + 0x40, 0x2f, 0x25, 0x5e, 0x31, 0xfc, 0x9f, 0x4a, 0x2d, 0x62, 0xd5, 0x71, 0xa9, 0x85, 0xff, 0x24, + 0x37, 0x60, 0x7d, 0xcc, 0xec, 0x58, 0x27, 0x3e, 0xef, 0x4f, 0x96, 0xb7, 0x63, 0x95, 0x81, 0x3b, + 0x3e, 0xf6, 0x29, 0xaf, 0xd7, 0xdd, 0xb0, 0xc3, 0xa4, 0xb3, 0x8e, 0xbc, 0x0c, 0xcb, 0xf4, 0xac, + 0xc3, 0x48, 0x37, 0x09, 0xf7, 0x08, 0xc4, 0x43, 0xc9, 0xc1, 0x2c, 0x7e, 0x89, 0xff, 0xcf, 0x79, + 0xbd, 0x9d, 0x13, 0xcc, 0xe4, 0x93, 0x96, 0x6c, 0xc2, 0x92, 0x3f, 0x3e, 0x94, 0x9a, 0xb6, 0xe8, + 0x8f, 0x0f, 0x69, 0xbb, 0x6e, 0x82, 0xca, 0xbc, 0x75, 0x58, 0x18, 0x84, 0xe0, 0xc9, 0x90, 0x5d, + 0xc5, 0x8b, 0xe6, 0x1a, 0x83, 0x63, 0xc2, 0xfc, 0x27, 0xc3, 0x1e, 0xc5, 0x0c, 0x02, 0xdf, 0x96, + 0x03, 0x5c, 0xf1, 0x66, 0xaf, 0x05, 0x81, 0x1f, 0x45, 0xba, 0xea, 0x93, 0x6d, 0x58, 0xa5, 0x7c, + 0xc2, 0x30, 0x5b, 0x5c, 0x10, 0xb8, 0x94, 0x16, 0x04, 0x9e, 0x0c, 0x7b, 0xa2, 0x8a, 0xe6, 0x4a, + 0x20, 0xfd, 0x22, 0xf7, 0x40, 0x95, 0x24, 0x26, 0xf4, 0xc7, 0x4c, 0xd8, 0x54, 0x47, 0x6c, 0x24, + 0x49, 0xab, 0x36, 0x3c, 0xf0, 0xcd, 0xf5, 0x5e, 0x1c, 0xc0, 0xbb, 0xe6, 0xbb, 0x8a, 0xd8, 0x4b, + 0x33, 0x88, 0x88, 0x06, 0xab, 0x47, 0x4e, 0x60, 0x07, 0xc1, 0x31, 0xb3, 0x11, 0xe3, 0x81, 0x7d, + 0x4b, 0x47, 0x4e, 0x60, 0x05, 0xc7, 0x22, 0x71, 0xc8, 0x59, 0x8a, 0xe3, 0x3b, 0xd3, 0xc9, 0x91, + 0x2d, 0xcb, 0x7f, 0xac, 0xc7, 0x4e, 0x1f, 0x39, 0x41, 0x8b, 0x96, 0x49, 0xbc, 0xc9, 0x35, 0x58, + 0x43, 0xbe, 0x3d, 0x4f, 0x30, 0xc6, 0x50, 0x16, 0xe6, 0x0a, 0x65, 0xdc, 0xf3, 0x18, 0x67, 0x5e, + 0xc3, 0x7f, 0xcd, 0xc1, 0xb9, 0xec, 0xde, 0xc1, 0xe9, 0x49, 0xfb, 0x14, 0x7d, 0xf4, 0x78, 0xdd, + 0x96, 0x29, 0x84, 0x85, 0x21, 0xc9, 0x1a, 0x9c, 0x5c, 0xe6, 0xe0, 0x94, 0x61, 0x03, 0x19, 0x71, + 0x49, 0x73, 0xe0, 0x05, 0x13, 0x1e, 0x5d, 0xc3, 0x5c, 0xa7, 0x05, 0x6c, 0x3f, 0xaf, 0x53, 0x30, + 0xb9, 0x0e, 0x6b, 0x62, 0x47, 0xf6, 0x1f, 0x0f, 0xe9, 0x87, 0xd9, 0x76, 0xbc, 0xca, 0xa1, 0x2d, + 0x04, 0x92, 0xb3, 0xb0, 0xe8, 0x8c, 0x46, 0xf4, 0x93, 0x6c, 0x17, 0x5e, 0x70, 0x46, 0x23, 0x96, + 0xdc, 0x06, 0x3d, 0x12, 0xed, 0x03, 0xb4, 0x12, 0xe2, 0x26, 0x89, 0xe6, 0x0a, 0x02, 0x99, 0xe5, + 0x50, 0x40, 0xd7, 0x3d, 0xa5, 0x15, 0x28, 0x4b, 0x88, 0x02, 0xce, 0x28, 0x44, 0x78, 0x0e, 0x8a, + 0xe2, 0xbd, 0x9a, 0x39, 0x56, 0x98, 0x4b, 0x0e, 0x7f, 0xab, 0x7e, 0x15, 0x36, 0xfb, 0x5e, 0x80, + 0x93, 0x97, 0x35, 0x69, 0x34, 0xe2, 0x3e, 0x90, 0x2c, 0x48, 0xae, 0x79, 0x86, 0x17, 0xd3, 0x9e, + 0xd4, 0x47, 0x23, 0xe6, 0x09, 0xc9, 0xfb, 0xfa, 0x75, 0x58, 0xe7, 0x12, 0x17, 0x3f, 0x22, 0xb1, + 0x2e, 0x7c, 0x01, 0xd3, 0xab, 0x10, 0x4f, 0x27, 0x04, 0x1c, 0x54, 0xeb, 0x0b, 0xca, 0x7f, 0x50, + 0xe0, 0x6c, 0xa6, 0xc8, 0x46, 0xbe, 0x08, 0xcc, 0xe5, 0x6b, 0xe2, 0xdb, 0x63, 0xb7, 0xe7, 0x8d, + 0x3c, 0x0c, 0x8a, 0xc1, 0x54, 0x9a, 0x77, 0xe6, 0x09, 0x7b, 0xe8, 0x3e, 0xd6, 0xf1, 0xcd, 0x90, + 0x88, 0xe9, 0x5a, 0xd4, 0x71, 0x02, 0x7c, 0xfe, 0x21, 0x9c, 0xcd, 0x44, 0xcd, 0xd0, 0x81, 0x7c, + 0x30, 0x9e, 0xcc, 0x59, 0x3c, 0x52, 0x25, 0x1a, 0x2d, 0xe9, 0x46, 0x78, 0xf3, 0xbe, 0x1f, 0x36, + 0x2f, 0x21, 0xdc, 0x11, 0x23, 0xb9, 0xae, 0xb3, 0xee, 0x27, 0x82, 0x68, 0xf6, 0xd2, 0x7e, 0x08, + 0x67, 0xf9, 0xe4, 0x3b, 0x1c, 0x3b, 0xa3, 0xa3, 0x88, 0x1d, 0xab, 0xe8, 0x07, 0xb2, 0xd8, 0xb1, + 0x59, 0xb9, 0x47, 0xf1, 0x43, 0xae, 0xa7, 0x9d, 0x34, 0x90, 0xb7, 0xe1, 0x1b, 0x39, 0xb1, 0xd4, + 0x33, 0xaa, 0x93, 0x31, 0xad, 0x95, 0xac, 0x69, 0x7d, 0xf2, 0x35, 0xd5, 0x04, 0x22, 0x6f, 0x56, + 0x4c, 0xeb, 0xc9, 0x0d, 0xaa, 0x84, 0x9c, 0xce, 0x2b, 0x22, 0x6d, 0x0d, 0x16, 0x4b, 0xa6, 0xb9, + 0xd1, 0x4b, 0x82, 0xc8, 0x05, 0x58, 0x0e, 0xf3, 0x55, 0xf3, 0x83, 0xa3, 0xc8, 0x00, 0xb5, 0x3e, + 0x79, 0x1e, 0x56, 0x98, 0x48, 0x1e, 0x5b, 0x73, 0x80, 0x30, 0x9d, 0x2e, 0x3c, 0xd1, 0x07, 0x0a, + 0x3c, 0xff, 0xb4, 0x3e, 0x24, 0xf7, 0xe1, 0x1c, 0x9a, 0x75, 0x04, 0x7e, 0x38, 0x0c, 0x76, 0xcf, + 0xe9, 0x1d, 0xb9, 0x7c, 0xd6, 0x6a, 0x99, 0x83, 0x31, 0x1a, 0x59, 0x56, 0x4b, 0x1a, 0x87, 0xd1, + 0xc8, 0x0a, 0x7c, 0xf1, 0xbb, 0x42, 0xc9, 0x79, 0x1d, 0xfa, 0x70, 0x61, 0x0e, 0xa5, 0xb4, 0x71, + 0x28, 0xf2, 0xc6, 0x71, 0x13, 0xd4, 0x03, 0xb7, 0x4f, 0x65, 0x62, 0xb7, 0x8f, 0x55, 0x7b, 0xeb, + 0x0e, 0xcb, 0xd0, 0x6e, 0xae, 0x85, 0x70, 0x2b, 0xf0, 0xf7, 0xef, 0xf0, 0xaf, 0x1c, 0x8b, 0x23, + 0x4f, 0xbe, 0x56, 0x90, 0x97, 0xe1, 0x74, 0x22, 0xe0, 0x48, 0xe4, 0xc1, 0x6e, 0x6e, 0xd0, 0xa2, + 0x78, 0x78, 0xaa, 0xab, 0xb0, 0x22, 0x66, 0xc5, 0x38, 0xf4, 0x83, 0x33, 0x4b, 0x1c, 0x46, 0x57, + 0x1d, 0xff, 0xdc, 0x54, 0x34, 0x2a, 0xf3, 0x46, 0x72, 0x02, 0x59, 0x9a, 0xbc, 0x04, 0x24, 0x94, + 0xdb, 0xc3, 0x8d, 0x82, 0x7f, 0x70, 0x43, 0x94, 0x84, 0x2b, 0x9c, 0x7f, 0xf6, 0x6f, 0x73, 0x70, + 0x3a, 0xe3, 0x2a, 0x43, 0x2f, 0x01, 0xde, 0x70, 0xe2, 0x1e, 0xb2, 0x2b, 0x84, 0xdc, 0xc8, 0x75, + 0x09, 0xce, 0xf5, 0x53, 0x8b, 0x2c, 0x03, 0x39, 0xff, 0x16, 0xff, 0x45, 0x37, 0x0f, 0x67, 0x2c, + 0x54, 0x2f, 0xf4, 0x5f, 0x52, 0x83, 0x0d, 0x4c, 0xab, 0x10, 0x78, 0x3e, 0x66, 0x67, 0x40, 0x21, + 0xa4, 0x10, 0xbb, 0xec, 0x60, 0x2d, 0xda, 0x12, 0x12, 0x95, 0x42, 0x4c, 0x75, 0x94, 0x80, 0x90, + 0x8f, 0xc1, 0x79, 0xe9, 0xac, 0xb1, 0x13, 0x2b, 0x0f, 0x2d, 0xdd, 0xcd, 0x4d, 0x27, 0x3c, 0x75, + 0x76, 0x62, 0x6b, 0x70, 0x1b, 0x2e, 0xe3, 0x20, 0x7a, 0xfd, 0x91, 0x9d, 0xca, 0xc3, 0x81, 0x4d, + 0x65, 0x81, 0xeb, 0xcf, 0x53, 0xac, 0x5a, 0x7f, 0x94, 0x48, 0xc9, 0x41, 0x5b, 0xcd, 0xbb, 0xef, + 0x21, 0x9c, 0xcd, 0xac, 0x31, 0x3d, 0x60, 0xd0, 0x90, 0x2a, 0x92, 0x8d, 0x96, 0xe8, 0x6f, 0x2a, + 0x1c, 0x5d, 0x85, 0x95, 0x47, 0xae, 0x33, 0x76, 0xc7, 0xfc, 0xe4, 0xe6, 0x53, 0x82, 0xc1, 0xe4, + 0x83, 0xbb, 0x1f, 0x1f, 0x1a, 0xae, 0x33, 0x22, 0x0d, 0x38, 0xcd, 0x4e, 0x40, 0xef, 0x18, 0x85, + 0x41, 0xae, 0x67, 0x52, 0x62, 0xe2, 0x10, 0x92, 0xe0, 0xd1, 0x54, 0x43, 0x2c, 0x46, 0x6d, 0x6e, + 0x1c, 0x26, 0x41, 0x74, 0x45, 0x9f, 0xcb, 0xc6, 0x26, 0xdb, 0x50, 0x62, 0xcc, 0xd9, 0xb5, 0x80, + 0x3d, 0x10, 0x5c, 0x9d, 0xfb, 0x85, 0x0a, 0xda, 0x17, 0x07, 0xe1, 0xff, 0xf4, 0xbc, 0xc6, 0xb7, + 0x58, 0xfb, 0x58, 0x7e, 0xff, 0x30, 0x57, 0x10, 0xc8, 0xdf, 0x3d, 0xb4, 0xbf, 0x53, 0x44, 0x53, + 0x63, 0x97, 0x63, 0x3a, 0xb5, 0x02, 0x77, 0x28, 0xde, 0x80, 0x96, 0x4d, 0xfe, 0xeb, 0x19, 0xa7, + 0x3a, 0x79, 0x0d, 0x56, 0x28, 0xdb, 0xc3, 0xe9, 0x90, 0x4d, 0xb9, 0x7c, 0x2c, 0xd0, 0x4e, 0x83, + 0x15, 0xd1, 0x61, 0xab, 0x9e, 0x32, 0x4b, 0xc7, 0xd1, 0x4f, 0x2a, 0x2d, 0x07, 0xc7, 0x93, 0x91, + 0x3c, 0x51, 0x85, 0xa2, 0xd0, 0x6a, 0x74, 0xda, 0x9c, 0xa4, 0x48, 0x71, 0x22, 0x69, 0x79, 0x7b, + 0x91, 0xa9, 0x0a, 0xb5, 0x17, 0xa1, 0x24, 0xf1, 0xa6, 0x8d, 0x61, 0x9e, 0x33, 0xa2, 0x31, 0xec, + 0x17, 0x1f, 0xec, 0x47, 0x50, 0x14, 0x2c, 0xe9, 0xb5, 0xe0, 0xc8, 0x0f, 0xc4, 0x22, 0xc7, 0xff, + 0x29, 0x8c, 0xf6, 0x32, 0x36, 0x72, 0xc1, 0xc4, 0xff, 0xf1, 0x2c, 0x99, 0x38, 0xf4, 0x3e, 0x30, + 0x08, 0xec, 0x11, 0x5a, 0x60, 0x85, 0xc2, 0x33, 0x85, 0x77, 0x06, 0x01, 0xb3, 0xcb, 0xe2, 0xdf, + 0xf8, 0xab, 0xf0, 0x10, 0x4e, 0x68, 0x13, 0x66, 0xed, 0x99, 0xb1, 0x23, 0x23, 0x97, 0x3e, 0x32, + 0x58, 0x00, 0x15, 0x4e, 0xc9, 0xbe, 0x0c, 0x08, 0xc3, 0x23, 0x43, 0xda, 0x19, 0x0a, 0xb1, 0x9d, + 0x41, 0xba, 0x93, 0x47, 0xa3, 0xc7, 0x4e, 0x1c, 0x71, 0x27, 0x4f, 0xee, 0x53, 0x7f, 0x9a, 0x13, + 0x2a, 0x82, 0x6d, 0xdf, 0x9f, 0x04, 0x93, 0xb1, 0x33, 0x8a, 0xa9, 0x42, 0xc9, 0x31, 0x3c, 0x87, + 0x12, 0xf4, 0x1d, 0x4c, 0x61, 0xe1, 0x8f, 0x45, 0xcc, 0x8e, 0x70, 0xe6, 0x96, 0xee, 0x7c, 0x28, + 0x2e, 0xe3, 0xeb, 0x14, 0x5b, 0x97, 0x91, 0xe9, 0x84, 0x95, 0xb8, 0x56, 0x4f, 0x99, 0x9b, 0x8c, + 0x67, 0x0a, 0x8b, 0x54, 0x33, 0x16, 0x71, 0x52, 0x17, 0xba, 0x1d, 0xad, 0xe8, 0x38, 0x57, 0x79, + 0xad, 0x93, 0x4f, 0xc0, 0xb2, 0xd7, 0x97, 0x33, 0x35, 0x26, 0xb5, 0x70, 0xb5, 0x3e, 0x8b, 0x16, + 0x1d, 0xf1, 0xa0, 0x73, 0xce, 0xe3, 0xd0, 0xed, 0xd5, 0x98, 0xd2, 0x58, 0xdb, 0x16, 0xb7, 0xd1, + 0x34, 0x19, 0x59, 0x83, 0x5c, 0x38, 0xc2, 0x39, 0xaf, 0xcf, 0x96, 0x57, 0x14, 0xaf, 0xda, 0xe4, + 0xbf, 0xb4, 0x5f, 0x85, 0x9b, 0x27, 0xed, 0x23, 0xba, 0x14, 0x67, 0x74, 0xf8, 0xb2, 0xb9, 0xe1, + 0xa4, 0xfa, 0xed, 0x2a, 0xc8, 0xe1, 0x76, 0x3d, 0xb1, 0xf9, 0x09, 0x58, 0x77, 0xec, 0x69, 0x7f, + 0x99, 0x87, 0xb5, 0xb8, 0x9a, 0x9c, 0xbc, 0x08, 0x05, 0x69, 0x07, 0xda, 0xcc, 0xd0, 0xa5, 0xe3, + 0xbe, 0x83, 0x48, 0x27, 0xda, 0x71, 0xc8, 0x5d, 0x58, 0x43, 0xc3, 0x3d, 0x14, 0x3d, 0x27, 0x1e, + 0x7f, 0x7c, 0x99, 0xff, 0x7e, 0x56, 0xfc, 0xc1, 0x3b, 0x57, 0x4e, 0xe1, 0x53, 0xd9, 0x0a, 0xa5, + 0xa5, 0xd2, 0x1f, 0x2d, 0x94, 0xb4, 0xa0, 0x85, 0xd9, 0x5a, 0x50, 0xde, 0x94, 0x19, 0x5a, 0xd0, + 0x85, 0x39, 0x5a, 0xd0, 0x88, 0x52, 0xd6, 0x82, 0xa2, 0x2e, 0x7c, 0x69, 0x96, 0x2e, 0x3c, 0xa2, + 0x61, 0xba, 0xf0, 0x48, 0x8b, 0x59, 0x9c, 0xa9, 0xc5, 0x8c, 0x68, 0xb8, 0x16, 0xf3, 0x1a, 0xef, + 0xa3, 0xb1, 0xf3, 0xd8, 0xc6, 0xce, 0xe3, 0xc7, 0x22, 0xb6, 0xde, 0x74, 0x1e, 0xa3, 0x71, 0xcd, + 0xf6, 0x32, 0x08, 0x8b, 0x1c, 0xed, 0xf7, 0x95, 0x84, 0x26, 0x50, 0x8c, 0xdf, 0x75, 0x58, 0x63, + 0x87, 0x95, 0xdb, 0x97, 0xee, 0x9a, 0xab, 0xe6, 0xaa, 0x80, 0xb2, 0xfb, 0xe6, 0x07, 0x60, 0x3d, + 0x44, 0xe3, 0x57, 0x2e, 0xf4, 0xd4, 0x33, 0x43, 0x6a, 0x1e, 0x76, 0xe6, 0x45, 0xd8, 0x08, 0x11, + 0xb9, 0x36, 0x87, 0x5d, 0x37, 0x57, 0x4d, 0x55, 0x14, 0xb4, 0x39, 0x5c, 0x3b, 0x4c, 0xde, 0x3c, + 0x7e, 0x4e, 0xb5, 0xd2, 0xbe, 0x9f, 0x8f, 0x69, 0x49, 0xc4, 0x67, 0xe8, 0x29, 0x1a, 0xf8, 0x36, + 0xef, 0x24, 0xbe, 0x17, 0x5d, 0x9d, 0x31, 0x66, 0xdc, 0xa6, 0xc9, 0xb2, 0x5a, 0x26, 0x04, 0x81, + 0x2f, 0x4c, 0x9c, 0x6c, 0x26, 0x51, 0xb3, 0x73, 0x1f, 0xe7, 0xac, 0x60, 0xc7, 0x36, 0x9e, 0xf2, + 0x7c, 0x76, 0xe2, 0x9a, 0x4a, 0xa7, 0x2c, 0x4a, 0xd6, 0xe1, 0x2f, 0xf1, 0x81, 0x2e, 0xa0, 0x52, + 0x31, 0x88, 0x33, 0xcf, 0x67, 0xdc, 0x9d, 0x52, 0xcc, 0xb1, 0x97, 0x90, 0xb3, 0x3a, 0x15, 0xff, + 0x0a, 0xb6, 0x06, 0xac, 0xa0, 0x8e, 0x42, 0x30, 0x2c, 0x64, 0xa8, 0xe0, 0xd3, 0x8d, 0xaf, 0xd4, + 0x1a, 0x66, 0x89, 0xd2, 0x09, 0x36, 0x47, 0xf0, 0x9c, 0xac, 0x59, 0x88, 0x57, 0x72, 0x41, 0x44, + 0xd1, 0x9d, 0xdb, 0x03, 0x91, 0x02, 0x02, 0xab, 0x7a, 0xce, 0x89, 0x03, 0x38, 0x9a, 0x76, 0x04, + 0xe7, 0x67, 0x0f, 0xc9, 0x9c, 0x0c, 0x4d, 0xd1, 0x01, 0x9a, 0x93, 0x0f, 0x50, 0x59, 0xcf, 0x90, + 0x8f, 0xe9, 0x19, 0xb4, 0x3f, 0xc9, 0xc3, 0x0b, 0x27, 0x18, 0xae, 0x39, 0xdf, 0xfc, 0x54, 0x5c, + 0x3c, 0xcb, 0xc5, 0x6e, 0x86, 0x94, 0x29, 0xdf, 0x20, 0xe9, 0x2d, 0x35, 0x5b, 0x38, 0xfb, 0x22, + 0xac, 0xb3, 0x5d, 0x90, 0x99, 0x25, 0x1e, 0x4c, 0x07, 0x27, 0xd8, 0x06, 0x2f, 0x08, 0x1f, 0xaa, + 0x04, 0x29, 0xee, 0x8c, 0xb8, 0x63, 0x58, 0x21, 0x8c, 0x74, 0xa0, 0x84, 0x68, 0x07, 0x8e, 0x37, + 0x38, 0x91, 0x33, 0x8f, 0xf0, 0xd0, 0x92, 0xc9, 0x98, 0x35, 0x35, 0x05, 0xec, 0xe2, 0x6f, 0x72, + 0x03, 0xd6, 0x87, 0xd3, 0x63, 0x2a, 0x78, 0xb0, 0xb9, 0xc0, 0xad, 0x3f, 0x16, 0xcc, 0xd5, 0xe1, + 0xf4, 0x58, 0x1f, 0x8d, 0x70, 0x48, 0xd1, 0x4c, 0x64, 0x83, 0xe2, 0xb1, 0x55, 0x2b, 0x30, 0x17, + 0x11, 0x93, 0x32, 0x60, 0xeb, 0x96, 0xe3, 0x9e, 0x01, 0x66, 0x34, 0xc8, 0x33, 0x54, 0xb1, 0x1f, + 0xda, 0x7f, 0xe7, 0xc4, 0x7d, 0x77, 0xf6, 0xbc, 0xff, 0xe5, 0x10, 0x65, 0x0c, 0xd1, 0x4d, 0x50, + 0x69, 0xd7, 0x47, 0x9b, 0x4a, 0x38, 0x46, 0x6b, 0xc3, 0xe9, 0x71, 0xd8, 0x77, 0x72, 0xc7, 0x2f, + 0xca, 0x1d, 0xff, 0x9a, 0xb8, 0x0f, 0x67, 0x6e, 0x0f, 0xb3, 0xbb, 0x5c, 0xfb, 0x8f, 0x3c, 0xdc, + 0x38, 0xd9, 0x26, 0xf0, 0xcb, 0x71, 0xcb, 0x18, 0xb7, 0x84, 0xea, 0x74, 0x21, 0xa5, 0x3a, 0xcd, + 0x58, 0x7b, 0x8b, 0x59, 0x6b, 0x2f, 0xa5, 0xa8, 0x5d, 0xca, 0x50, 0xd4, 0x66, 0x2e, 0xd0, 0xe2, + 0x53, 0x16, 0xe8, 0xb2, 0x3c, 0x4f, 0xfe, 0x25, 0x54, 0x60, 0xc4, 0xef, 0x03, 0x0f, 0xe1, 0xb4, + 0xb8, 0x0f, 0xb0, 0x93, 0x23, 0xd2, 0xbf, 0x97, 0xee, 0xdc, 0xca, 0xba, 0x09, 0x20, 0x5a, 0x86, + 0xb4, 0xbe, 0xc1, 0xef, 0x00, 0x51, 0xf9, 0xff, 0x1f, 0xe9, 0x9f, 0x3c, 0x80, 0x73, 0x18, 0xdf, + 0xbd, 0x27, 0xbf, 0x1c, 0xd8, 0x63, 0xf7, 0x80, 0xcf, 0x87, 0xab, 0x29, 0x59, 0xd9, 0xeb, 0x49, + 0xd5, 0x31, 0xdd, 0x83, 0xea, 0x29, 0xf3, 0x4c, 0x90, 0x01, 0x4f, 0x5e, 0x2c, 0xfe, 0x5c, 0x01, + 0xed, 0xe9, 0xfd, 0x85, 0x8a, 0xaa, 0x64, 0x87, 0x2f, 0x9b, 0x25, 0x47, 0xea, 0xbd, 0x17, 0x60, + 0x75, 0xec, 0x1e, 0x8c, 0xdd, 0xe0, 0x28, 0xa6, 0x01, 0x59, 0xe1, 0x40, 0xd1, 0x31, 0x22, 0xca, + 0xe4, 0x33, 0x49, 0xe6, 0x82, 0x48, 0xdb, 0x0d, 0xef, 0x8b, 0x99, 0xe3, 0x40, 0x67, 0x93, 0x5c, + 0x41, 0xf6, 0xe3, 0x6e, 0xa1, 0x98, 0x53, 0xf3, 0x26, 0x8f, 0x85, 0x79, 0xe0, 0x0d, 0x5c, 0xed, + 0xaf, 0x15, 0x21, 0x11, 0x64, 0x75, 0x1e, 0x79, 0x28, 0x19, 0xf3, 0xe6, 0x53, 0x62, 0x48, 0x16, + 0x89, 0x6c, 0xf7, 0xc8, 0xc3, 0x33, 0x22, 0x20, 0x16, 0x9e, 0x11, 0x21, 0xef, 0xc1, 0x22, 0x91, + 0xdf, 0x9a, 0xdf, 0x10, 0x16, 0x41, 0x74, 0xcf, 0xdb, 0xbf, 0x4d, 0x6e, 0xc1, 0x12, 0x33, 0x02, + 0x12, 0xd5, 0x5d, 0x8f, 0x55, 0x77, 0xff, 0xb6, 0x29, 0xca, 0xb5, 0xb7, 0xc3, 0x77, 0xad, 0x54, + 0x23, 0xf6, 0x6f, 0x93, 0xd7, 0x4e, 0x66, 0x9c, 0x5b, 0x14, 0xc6, 0xb9, 0xa1, 0x61, 0xee, 0xeb, + 0x31, 0xc3, 0xdc, 0x6b, 0xf3, 0x7b, 0x8b, 0xbf, 0x46, 0xb2, 0x70, 0x84, 0x51, 0x98, 0xaa, 0x9f, + 0xe4, 0xe0, 0xd2, 0x5c, 0x0a, 0x72, 0x11, 0x8a, 0x7a, 0xbb, 0xd6, 0x89, 0xc6, 0x97, 0xae, 0x19, + 0x01, 0x21, 0x7b, 0xb0, 0xbc, 0xed, 0x04, 0x5e, 0x8f, 0x4e, 0xe3, 0xcc, 0xe7, 0x81, 0x14, 0xdb, + 0x10, 0xbd, 0x7a, 0xca, 0x8c, 0x68, 0x89, 0x0d, 0x1b, 0xb8, 0x16, 0x62, 0xa9, 0x9f, 0xf2, 0x19, + 0xba, 0x86, 0x14, 0xc3, 0x14, 0x19, 0xdd, 0x67, 0x52, 0x40, 0xf2, 0x08, 0x88, 0x65, 0x55, 0x2b, + 0xee, 0x78, 0xc2, 0xef, 0xe0, 0x13, 0x2f, 0xb4, 0xf4, 0xfc, 0xf0, 0x53, 0xfa, 0x2e, 0x45, 0x57, + 0x3d, 0x65, 0x66, 0x70, 0x4b, 0x2e, 0xf3, 0xb7, 0x84, 0xbc, 0x33, 0xbb, 0x13, 0x9e, 0x21, 0x76, + 0xeb, 0x4d, 0x28, 0xb6, 0x85, 0x2d, 0x82, 0x64, 0x31, 0x2f, 0xec, 0x0e, 0xcc, 0xb0, 0x54, 0xfb, + 0x2d, 0x45, 0x28, 0x1d, 0x9e, 0xde, 0x59, 0x52, 0x66, 0xae, 0xfe, 0xfc, 0xcc, 0x5c, 0xfd, 0x9f, + 0x31, 0x33, 0x97, 0xe6, 0xc1, 0xad, 0x13, 0x77, 0x2c, 0xf9, 0x38, 0xa8, 0x98, 0xc4, 0xc8, 0x91, + 0x06, 0x89, 0xad, 0xaf, 0x8d, 0x30, 0x98, 0x77, 0x95, 0x67, 0x8a, 0x33, 0xd7, 0x7b, 0x71, 0x6a, + 0xed, 0xcf, 0x78, 0x10, 0xf7, 0x5a, 0xbf, 0x9d, 0x50, 0x34, 0xbf, 0x57, 0x27, 0x0b, 0x23, 0xb6, + 0xd8, 0x5e, 0x90, 0x92, 0x48, 0xa6, 0xbf, 0x35, 0xdb, 0xd7, 0x42, 0x5a, 0x79, 0x7f, 0x94, 0x87, + 0x8b, 0xf3, 0xc8, 0x33, 0xd3, 0x54, 0x2b, 0xcf, 0x96, 0xa6, 0xfa, 0x16, 0x14, 0x19, 0x2c, 0xf4, + 0x20, 0xc0, 0xb1, 0xe5, 0xa4, 0x74, 0x6c, 0x45, 0x31, 0x79, 0x01, 0x16, 0xf5, 0x8a, 0x15, 0x65, + 0x4e, 0x43, 0x53, 0x5f, 0xa7, 0x17, 0xa0, 0x11, 0x29, 0x2f, 0x22, 0x5f, 0x48, 0x27, 0x0b, 0xe4, + 0x29, 0xd3, 0x2e, 0x48, 0x1d, 0x92, 0xca, 0xaf, 0x80, 0xf5, 0x8d, 0xf2, 0x01, 0xf0, 0x10, 0xdb, + 0x66, 0x3a, 0xf1, 0xa0, 0x06, 0x8b, 0xed, 0xb1, 0x1b, 0xb8, 0x13, 0xd9, 0x0c, 0x77, 0x84, 0x10, + 0x93, 0x97, 0x70, 0x23, 0x59, 0xe7, 0x09, 0x8b, 0x89, 0xb0, 0x28, 0xc7, 0xa9, 0x41, 0xab, 0x5a, + 0x0a, 0x36, 0x25, 0x14, 0x4a, 0x50, 0x77, 0xa6, 0xc3, 0xde, 0x51, 0xd7, 0xac, 0x73, 0xc9, 0x89, + 0x11, 0x0c, 0x10, 0x4a, 0x1b, 0x18, 0x98, 0x12, 0x8a, 0xf6, 0x2d, 0x05, 0xce, 0x64, 0xb5, 0x83, + 0x5c, 0x84, 0xc2, 0x30, 0x33, 0x2f, 0xe2, 0x90, 0xb9, 0x72, 0x97, 0xe8, 0x5f, 0xfb, 0xc0, 0x1f, + 0x1f, 0x3b, 0x13, 0xd9, 0x58, 0x59, 0x02, 0x9b, 0x40, 0x7f, 0xec, 0xe2, 0xff, 0xe4, 0x8a, 0x38, + 0x72, 0xf2, 0xa9, 0x4c, 0x8a, 0xf8, 0x47, 0xd3, 0x01, 0x6a, 0xfd, 0x76, 0x6b, 0xc4, 0xe2, 0xfb, + 0xbf, 0x02, 0x05, 0x5a, 0xad, 0xc4, 0xec, 0xa5, 0xf3, 0x47, 0x6f, 0xd4, 0x39, 0x12, 0xab, 0x55, + 0xe0, 0x1c, 0x0f, 0x4c, 0x44, 0xd6, 0xee, 0xc3, 0x5a, 0x1c, 0x83, 0x18, 0xf1, 0x88, 0xb0, 0xa5, + 0x3b, 0x2a, 0xe7, 0xb4, 0xed, 0xfb, 0xcc, 0x61, 0x66, 0xfb, 0xb9, 0x9f, 0xbc, 0x73, 0x05, 0xe8, + 0x4f, 0x46, 0x93, 0x15, 0x31, 0x56, 0xfb, 0x76, 0x0e, 0xce, 0x44, 0x3e, 0xfa, 0x62, 0x0d, 0xfd, + 0xc2, 0x3a, 0x8c, 0xea, 0x31, 0x87, 0x46, 0x21, 0x37, 0xa6, 0x1b, 0x38, 0xc7, 0x8f, 0x6a, 0x0f, + 0xb6, 0x66, 0xe1, 0x93, 0x17, 0x61, 0x19, 0xc3, 0x3a, 0x8d, 0x9c, 0x9e, 0x2b, 0x6f, 0xb3, 0x43, + 0x01, 0x34, 0xa3, 0x72, 0xed, 0x47, 0x0a, 0x9c, 0xe7, 0x6e, 0x1e, 0x0d, 0xc7, 0x1b, 0xe2, 0x2b, + 0x41, 0xcf, 0x7d, 0x7f, 0x1c, 0x9e, 0xf7, 0x62, 0xfb, 0xd8, 0xf5, 0xb8, 0x37, 0x4f, 0xea, 0x6b, + 0xb3, 0x5b, 0x4b, 0x6e, 0x61, 0xa8, 0x32, 0xfe, 0x8a, 0x5e, 0x60, 0x01, 0x26, 0x86, 0x14, 0x20, + 0x07, 0x98, 0x40, 0x0c, 0xed, 0xd7, 0xe0, 0xf2, 0xfc, 0x0f, 0x90, 0xcf, 0xc3, 0x2a, 0xe6, 0xbe, + 0xea, 0x8e, 0x0e, 0xc7, 0x4e, 0xdf, 0x15, 0x9a, 0x3d, 0xa1, 0x8d, 0x95, 0xcb, 0x58, 0xe4, 0x35, + 0x1e, 0xf0, 0xe0, 0x10, 0xb3, 0x6a, 0x71, 0xa2, 0x98, 0x2f, 0x95, 0xcc, 0x4d, 0xfb, 0xba, 0x02, + 0x24, 0xcd, 0x83, 0x7c, 0x04, 0x56, 0xba, 0x9d, 0x8a, 0x35, 0x71, 0xc6, 0x93, 0xaa, 0x3f, 0x1d, + 0xf3, 0xb0, 0x67, 0xcc, 0xff, 0x7d, 0xd2, 0xb3, 0xd9, 0x7b, 0xd0, 0x91, 0x3f, 0x1d, 0x9b, 0x31, + 0x3c, 0x4c, 0xda, 0xe4, 0xba, 0x5f, 0xee, 0x3b, 0x4f, 0xe2, 0x49, 0x9b, 0x38, 0x2c, 0x96, 0xb4, + 0x89, 0xc3, 0xb4, 0xef, 0x29, 0x70, 0x41, 0x18, 0x47, 0xf6, 0x33, 0xea, 0x52, 0xc1, 0x28, 0x2f, + 0x63, 0x11, 0x67, 0x77, 0x9e, 0x84, 0xbe, 0x21, 0x02, 0x21, 0x61, 0x05, 0x51, 0x54, 0x67, 0xb4, + 0xe4, 0x53, 0x50, 0xb0, 0x26, 0xfe, 0xe8, 0x04, 0x91, 0x90, 0xd4, 0x70, 0x44, 0x27, 0xfe, 0x08, + 0x59, 0x20, 0xa5, 0xe6, 0xc2, 0x19, 0xb9, 0x72, 0xa2, 0xc6, 0xa4, 0x01, 0x4b, 0x3c, 0xe4, 0x5d, + 0xc2, 0xee, 0x60, 0x4e, 0x9b, 0xb6, 0xd7, 0x45, 0xb8, 0x25, 0x1e, 0xe7, 0xd5, 0x14, 0x3c, 0xb4, + 0xdf, 0x51, 0xa0, 0x44, 0x05, 0x1b, 0xbc, 0x94, 0xbe, 0xd7, 0x29, 0x1d, 0x97, 0x83, 0x85, 0x19, + 0x4d, 0xc8, 0xfe, 0x44, 0xa7, 0xf1, 0xab, 0xb0, 0x9e, 0x20, 0x20, 0x1a, 0x06, 0xda, 0x18, 0x78, + 0x3d, 0x87, 0xe5, 0x80, 0x61, 0x26, 0x28, 0x31, 0x98, 0xf6, 0x1b, 0x0a, 0x9c, 0x69, 0x7d, 0x79, + 0xe2, 0xb0, 0x67, 0x5b, 0x73, 0x3a, 0x10, 0xeb, 0x9d, 0x0a, 0x6b, 0xc2, 0xca, 0x96, 0x05, 0x01, + 0x60, 0xc2, 0x1a, 0x87, 0x99, 0x61, 0x29, 0xa9, 0x42, 0x91, 0x9f, 0x2f, 0x01, 0x0f, 0xcf, 0x7a, + 0x59, 0xd2, 0x8d, 0x44, 0x8c, 0x39, 0x12, 0x6d, 0x09, 0x6e, 0x61, 0x9c, 0xc6, 0x0c, 0xa9, 0xb5, + 0xff, 0x54, 0x60, 0x73, 0x06, 0x0d, 0x79, 0x13, 0x16, 0xd0, 0x41, 0x91, 0x8f, 0xde, 0xc5, 0x19, + 0x9f, 0x98, 0xf4, 0x8e, 0xf6, 0x6f, 0xb3, 0x83, 0xe8, 0x98, 0xfe, 0x30, 0x19, 0x15, 0x79, 0x08, + 0xcb, 0x7a, 0xbf, 0xcf, 0x6f, 0x67, 0xb9, 0xd8, 0xed, 0x6c, 0xc6, 0x17, 0x5f, 0x0e, 0xf1, 0xd9, + 0xed, 0x8c, 0xb9, 0xca, 0xf4, 0xfb, 0x36, 0x77, 0xbe, 0x8c, 0xf8, 0x9d, 0xff, 0x38, 0xac, 0xc5, + 0x91, 0x9f, 0xc9, 0x5f, 0xec, 0x6d, 0x05, 0xd4, 0x78, 0x1d, 0x7e, 0x3e, 0x81, 0xa2, 0xb2, 0x86, + 0xf9, 0x29, 0x93, 0xea, 0xf7, 0x72, 0x70, 0x36, 0xb3, 0x87, 0xc9, 0x4b, 0xb0, 0xa8, 0x8f, 0x46, + 0xb5, 0x1d, 0x3e, 0xab, 0xb8, 0x84, 0x84, 0x4a, 0xef, 0xd8, 0xe5, 0x95, 0x21, 0x91, 0x57, 0xa0, + 0xc8, 0xac, 0x03, 0x76, 0xc4, 0x86, 0x83, 0x91, 0x6f, 0xb8, 0xe9, 0x42, 0x3c, 0x50, 0xaa, 0x40, + 0x24, 0xbb, 0xb0, 0xc6, 0x63, 0xc6, 0x98, 0xee, 0xa1, 0xfb, 0xd5, 0x30, 0x62, 0x3f, 0x26, 0x15, + 0x10, 0x9a, 0x74, 0x7b, 0xcc, 0xca, 0xe4, 0xa8, 0x29, 0x71, 0x2a, 0x52, 0x07, 0x15, 0x79, 0xca, + 0x9c, 0x58, 0xb4, 0x56, 0x8c, 0xe2, 0xc3, 0x2a, 0x31, 0x83, 0x57, 0x8a, 0x32, 0x1c, 0x2e, 0x3d, + 0x08, 0xbc, 0xc3, 0xe1, 0xb1, 0x3b, 0x9c, 0xfc, 0xfc, 0x86, 0x2b, 0xfa, 0xc6, 0x89, 0x86, 0xeb, + 0x0f, 0x0a, 0x6c, 0x31, 0x27, 0xc9, 0xa8, 0x44, 0x23, 0x05, 0xe8, 0x46, 0x89, 0x86, 0xde, 0xcf, + 0x78, 0x54, 0x94, 0x1d, 0x58, 0x62, 0xd1, 0x6a, 0xc4, 0xca, 0xb8, 0x94, 0x59, 0x05, 0x86, 0xb3, + 0x7f, 0x9b, 0x89, 0x2f, 0xcc, 0x53, 0x32, 0x30, 0x05, 0x29, 0xd9, 0x87, 0x52, 0x65, 0xe0, 0x3a, + 0xc3, 0xe9, 0xa8, 0x73, 0xb2, 0x17, 0xd4, 0x2d, 0xde, 0x96, 0x95, 0x1e, 0x23, 0xc3, 0x97, 0x57, + 0xdc, 0xc9, 0x65, 0x46, 0xa4, 0x13, 0x3a, 0x4f, 0x15, 0x50, 0xf1, 0xfa, 0xe1, 0x39, 0xfd, 0x93, + 0x04, 0x22, 0x5d, 0xdc, 0x33, 0x90, 0x7b, 0x57, 0xd9, 0xb0, 0x56, 0x77, 0x82, 0x49, 0x67, 0xec, + 0x0c, 0x03, 0x8c, 0x72, 0x79, 0x82, 0x28, 0x60, 0x17, 0x44, 0x06, 0x65, 0x54, 0x99, 0x4e, 0x42, + 0x52, 0xa6, 0x90, 0x8d, 0xb3, 0xa3, 0xf2, 0xd2, 0xae, 0x37, 0x74, 0x06, 0xde, 0xd7, 0x84, 0x8f, + 0x29, 0x93, 0x97, 0x0e, 0x04, 0xd0, 0x8c, 0xca, 0xb5, 0xcf, 0xa5, 0xc6, 0x8d, 0xd5, 0xb2, 0x04, + 0x4b, 0x3c, 0x02, 0x01, 0xf3, 0xc8, 0x6f, 0x1b, 0xcd, 0x9d, 0x5a, 0x73, 0x4f, 0x55, 0xc8, 0x1a, + 0x40, 0xdb, 0x6c, 0x55, 0x0c, 0xcb, 0xa2, 0xbf, 0x73, 0xf4, 0x37, 0x77, 0xd7, 0xdf, 0xed, 0xd6, + 0xd5, 0xbc, 0xe4, 0xb1, 0x5f, 0xd0, 0x7e, 0xa8, 0xc0, 0xb9, 0xec, 0xa1, 0x24, 0x1d, 0xc0, 0x98, + 0x0d, 0xfc, 0x2d, 0xfd, 0x23, 0x73, 0xc7, 0x3d, 0x13, 0x9c, 0x8c, 0xfd, 0x30, 0x61, 0x31, 0x05, + 0x72, 0xe2, 0xed, 0x8b, 0x39, 0x29, 0x7a, 0x7d, 0x33, 0xe7, 0xf5, 0xb5, 0x0a, 0x6c, 0xcd, 0xe2, + 0x11, 0x6f, 0xea, 0x3a, 0x94, 0xf4, 0x76, 0xbb, 0x5e, 0xab, 0xe8, 0x9d, 0x5a, 0xab, 0xa9, 0x2a, + 0x64, 0x19, 0x16, 0xf6, 0xcc, 0x56, 0xb7, 0xad, 0xe6, 0xb4, 0xef, 0x28, 0xb0, 0x5a, 0x8b, 0xac, + 0xce, 0xde, 0xeb, 0xe2, 0xfb, 0x68, 0x6c, 0xf1, 0x6d, 0x85, 0xd1, 0x4d, 0xc2, 0x0f, 0x9c, 0x68, + 0xe5, 0xbd, 0x9b, 0x83, 0x8d, 0x14, 0x0d, 0xb1, 0x60, 0x49, 0xbf, 0x6f, 0xb5, 0x6a, 0x3b, 0x15, + 0x5e, 0xb3, 0x2b, 0x91, 0xb9, 0x14, 0x26, 0xb0, 0x4a, 0x7d, 0x85, 0x79, 0x04, 0x3f, 0x0e, 0x6c, + 0xdf, 0xeb, 0x4b, 0xc9, 0x67, 0xab, 0xa7, 0x4c, 0xc1, 0x09, 0x4f, 0xb2, 0xaf, 0x4d, 0xc7, 0x2e, + 0xb2, 0xcd, 0xc5, 0xf4, 0xba, 0x21, 0x3c, 0xcd, 0x18, 0xfd, 0x37, 0x1c, 0x5a, 0x9e, 0x66, 0x1d, + 0xf1, 0x23, 0x4d, 0x58, 0xdc, 0xf3, 0x26, 0xd5, 0xe9, 0x23, 0xbe, 0x7e, 0x2f, 0x47, 0xe9, 0x8c, + 0xaa, 0xd3, 0x47, 0x69, 0xb6, 0xa8, 0xb2, 0x64, 0xd1, 0x7b, 0x62, 0x2c, 0x39, 0x97, 0xa4, 0x13, + 0x63, 0xe1, 0x99, 0x9c, 0x18, 0xb7, 0x57, 0xa1, 0xc4, 0xef, 0x50, 0x78, 0x3d, 0xf9, 0xbe, 0x02, + 0x5b, 0xb3, 0x7a, 0x8e, 0x5e, 0xcb, 0xe2, 0xc1, 0x0a, 0xce, 0x85, 0xe9, 0x31, 0xe2, 0x51, 0x0a, + 0x04, 0x1a, 0xf9, 0x24, 0x94, 0x6a, 0x41, 0x30, 0x75, 0xc7, 0xd6, 0x2b, 0x5d, 0xb3, 0xc6, 0xa7, + 0xeb, 0xa5, 0x7f, 0x7b, 0xe7, 0xca, 0x26, 0xfa, 0x7c, 0x8c, 0xed, 0xe0, 0x15, 0x7b, 0x3a, 0xf6, + 0x62, 0xa9, 0x04, 0x64, 0x0a, 0x2a, 0x45, 0x3b, 0xd3, 0xbe, 0xe7, 0x8a, 0x3b, 0x84, 0x70, 0xe8, + 0xe6, 0x30, 0xf9, 0x4c, 0x13, 0x30, 0xed, 0x9b, 0x0a, 0x9c, 0x9f, 0x3d, 0x4c, 0xf4, 0x9c, 0xec, + 0x30, 0x93, 0x2a, 0xe1, 0x52, 0x8d, 0xe7, 0x64, 0x68, 0x77, 0x25, 0xf3, 0x14, 0x88, 0x94, 0x28, + 0x4c, 0x4d, 0x9f, 0x4b, 0xe5, 0xa3, 0x8e, 0x13, 0x09, 0x44, 0xed, 0x01, 0x6c, 0xce, 0x18, 0x54, + 0xf2, 0x89, 0xcc, 0xa4, 0x3b, 0xe8, 0xa6, 0x24, 0x27, 0xdd, 0x89, 0xa5, 0x63, 0x93, 0xe0, 0xda, + 0xbf, 0xe7, 0xe0, 0x1c, 0x5d, 0x5d, 0x03, 0x37, 0x08, 0xf4, 0xe9, 0xe4, 0x88, 0x0e, 0x27, 0x93, + 0x37, 0xc9, 0x6b, 0xb0, 0x78, 0xf4, 0x6c, 0xaa, 0x62, 0x86, 0x4e, 0x08, 0xe0, 0x89, 0x25, 0x9c, + 0x63, 0xe8, 0xff, 0xe4, 0x2a, 0xc8, 0xc9, 0xc5, 0xf3, 0x18, 0xde, 0x34, 0xb7, 0xa5, 0x98, 0xcb, + 0xa3, 0x30, 0x0f, 0xf0, 0xeb, 0xb0, 0x80, 0xfa, 0x14, 0x7e, 0x76, 0x08, 0x99, 0x3f, 0xbb, 0x76, + 0xa8, 0x6d, 0x31, 0x19, 0x01, 0xf9, 0x10, 0x40, 0x94, 0x19, 0x82, 0x1f, 0x0e, 0x42, 0xcf, 0x10, + 0x26, 0x87, 0x30, 0x97, 0x8f, 0x0f, 0x1c, 0x9e, 0x6e, 0xa1, 0x0c, 0x1b, 0xa2, 0xc7, 0x47, 0x22, + 0x2a, 0x22, 0x7f, 0xc5, 0x5c, 0x67, 0x05, 0xb5, 0x91, 0x88, 0x8c, 0x78, 0x2d, 0x95, 0x20, 0x19, + 0x83, 0x23, 0x27, 0xb2, 0x20, 0x5f, 0x4b, 0x65, 0x41, 0x2e, 0x32, 0x2c, 0x39, 0xd5, 0xb1, 0xf6, + 0xcf, 0x39, 0x58, 0xbe, 0x4f, 0xa5, 0x32, 0xd4, 0x35, 0xcc, 0xd7, 0x5d, 0xdc, 0x81, 0x52, 0xdd, + 0x77, 0xf8, 0x73, 0x11, 0xf7, 0x29, 0x61, 0x3e, 0xdd, 0x03, 0xdf, 0x11, 0x2f, 0x4f, 0x81, 0x29, + 0x23, 0x3d, 0xc5, 0x1f, 0xfd, 0x2e, 0x2c, 0xb2, 0xe7, 0x3b, 0xae, 0x46, 0x13, 0x72, 0x79, 0x58, + 0xa3, 0x97, 0x59, 0xb1, 0xf4, 0xc2, 0xc1, 0x9e, 0x00, 0x65, 0x21, 0x91, 0xc7, 0x78, 0x95, 0x34, + 0x2b, 0x0b, 0x27, 0xd3, 0xac, 0x48, 0xb1, 0xec, 0x16, 0x4f, 0x12, 0xcb, 0xee, 0xfc, 0x1b, 0x50, + 0x92, 0xea, 0xf3, 0x4c, 0x62, 0xfa, 0x37, 0x72, 0xb0, 0x8a, 0xad, 0x0a, 0x6d, 0x79, 0x7e, 0x31, + 0xf5, 0x44, 0x1f, 0x8d, 0xe9, 0x89, 0xb6, 0xe4, 0xf1, 0x62, 0x2d, 0x9b, 0xa3, 0x20, 0xba, 0x0b, + 0x1b, 0x29, 0x44, 0xf2, 0x2a, 0x2c, 0xd0, 0xea, 0x8b, 0x7b, 0xb5, 0x9a, 0x9c, 0x01, 0x51, 0xdc, + 0x63, 0xda, 0xf0, 0xc0, 0x64, 0xd8, 0xda, 0x7f, 0x29, 0xb0, 0xc2, 0xd3, 0x8e, 0x0c, 0x0f, 0xfc, + 0xa7, 0x76, 0xe7, 0x8d, 0x64, 0x77, 0xb2, 0xe8, 0x2a, 0xbc, 0x3b, 0xff, 0xb7, 0x3b, 0xf1, 0x8d, + 0x58, 0x27, 0x6e, 0x86, 0x51, 0x10, 0x45, 0x73, 0xe6, 0xf4, 0xe1, 0xdf, 0x60, 0x5c, 0xe0, 0x38, + 0x22, 0xf9, 0x02, 0x2c, 0x37, 0xdd, 0xc7, 0xb1, 0xeb, 0xe9, 0x8d, 0x19, 0x4c, 0x5f, 0x0e, 0x11, + 0xd9, 0x9a, 0xc2, 0x93, 0x7d, 0xe8, 0x3e, 0xb6, 0x53, 0x2f, 0x87, 0x11, 0x4b, 0x7a, 0x43, 0x8d, + 0x93, 0x3d, 0xcb, 0xd4, 0xe7, 0x0e, 0xae, 0x18, 0x30, 0xe8, 0x5b, 0x79, 0x80, 0xc8, 0x37, 0x90, + 0x2e, 0xc0, 0x98, 0xd1, 0x84, 0xd0, 0xec, 0x23, 0x48, 0x9e, 0xe3, 0xc2, 0x96, 0xe2, 0x06, 0xd7, + 0x40, 0xe7, 0x66, 0x47, 0xa9, 0x44, 0x5d, 0x74, 0x85, 0x3b, 0xa3, 0xf5, 0xdd, 0x81, 0xc3, 0xf6, + 0xf6, 0xfc, 0xf6, 0x35, 0x0c, 0x4a, 0x1c, 0x42, 0x67, 0xe4, 0x8f, 0x46, 0x97, 0xb5, 0x1d, 0x8a, + 0x90, 0xf2, 0xb7, 0x2d, 0x3c, 0x9b, 0xbf, 0x6d, 0x1b, 0x96, 0xbd, 0xe1, 0x5b, 0xee, 0x70, 0xe2, + 0x8f, 0x9f, 0xa0, 0xda, 0x3d, 0xd2, 0xe7, 0xd1, 0x2e, 0xa8, 0x89, 0x32, 0x36, 0x0e, 0x78, 0xe6, + 0x86, 0xf8, 0xf2, 0x30, 0x84, 0xc0, 0xd0, 0x5f, 0x78, 0x41, 0x5d, 0xbc, 0x5b, 0x28, 0x2e, 0xaa, + 0x4b, 0x77, 0x0b, 0xc5, 0xa2, 0xba, 0x7c, 0xb7, 0x50, 0x5c, 0x56, 0xc1, 0x94, 0xde, 0xcc, 0xc2, + 0x37, 0x31, 0xe9, 0x19, 0x2b, 0xfe, 0x44, 0xa5, 0xfd, 0x34, 0x07, 0x24, 0x5d, 0x0d, 0xf2, 0x51, + 0x28, 0xb1, 0x0d, 0xd6, 0x1e, 0x07, 0x5f, 0xe1, 0xee, 0x06, 0x2c, 0xec, 0x92, 0x04, 0x96, 0xc3, + 0x2e, 0x31, 0xb0, 0x19, 0x7c, 0x65, 0x40, 0x3e, 0x0f, 0xa7, 0xb1, 0x7b, 0x47, 0xee, 0xd8, 0xf3, + 0xfb, 0x36, 0xc6, 0xc8, 0x75, 0x06, 0x3c, 0xd7, 0xe3, 0x4b, 0x98, 0x94, 0x38, 0x5d, 0x3c, 0x63, + 0x18, 0xd0, 0x05, 0xb0, 0x8d, 0x98, 0x6d, 0x86, 0x48, 0x3a, 0xa0, 0xca, 0xf4, 0x07, 0xd3, 0xc1, + 0x80, 0x8f, 0x6c, 0x99, 0xde, 0xe8, 0x93, 0x65, 0x33, 0x18, 0xaf, 0x45, 0x8c, 0x77, 0xa7, 0x83, + 0x01, 0x79, 0x0d, 0xc0, 0x1f, 0xda, 0xc7, 0x5e, 0x10, 0xb0, 0xc7, 0x9c, 0xd0, 0x5b, 0x39, 0x82, + 0xca, 0x83, 0xe1, 0x0f, 0x1b, 0x0c, 0x48, 0x7e, 0x05, 0x30, 0x5a, 0x03, 0x86, 0x31, 0x61, 0xd6, + 0x48, 0x3c, 0x7b, 0x8b, 0x00, 0xc6, 0x9d, 0xa3, 0x0f, 0x5d, 0xcb, 0xfb, 0x9a, 0x70, 0xf5, 0xf8, + 0x2c, 0x6c, 0x70, 0xe3, 0xe1, 0xfb, 0xde, 0xe4, 0x88, 0x5f, 0x25, 0xde, 0xcb, 0x3d, 0x44, 0xba, + 0x4b, 0xfc, 0x7d, 0x01, 0x40, 0xbf, 0x6f, 0x89, 0x08, 0x61, 0xb7, 0x60, 0x81, 0x5e, 0x90, 0x84, + 0xa2, 0x05, 0xd5, 0xd4, 0xc8, 0x57, 0x56, 0x53, 0x23, 0x06, 0x5d, 0x8d, 0x26, 0x1a, 0xd5, 0x0b, + 0x25, 0x0b, 0xae, 0x46, 0x66, 0x67, 0x1f, 0x8b, 0xd0, 0xcc, 0xb1, 0x48, 0x1d, 0x20, 0x8a, 0xd9, + 0xc5, 0x45, 0xfe, 0x8d, 0x28, 0xf8, 0x0d, 0x2f, 0xe0, 0x59, 0x22, 0xa2, 0xb8, 0x5f, 0xf2, 0xf4, + 0x89, 0xd0, 0xc8, 0x3d, 0x28, 0x74, 0x9c, 0xd0, 0x17, 0x77, 0x46, 0x24, 0xb3, 0xe7, 0x79, 0x2e, + 0xce, 0x28, 0x9a, 0xd9, 0xda, 0xc4, 0x89, 0xa5, 0x2c, 0x46, 0x26, 0xc4, 0x80, 0x45, 0x9e, 0x67, + 0x7d, 0x46, 0x04, 0x4c, 0x9e, 0x66, 0x9d, 0xc7, 0xbd, 0x46, 0xa0, 0x2c, 0x53, 0xf0, 0x8c, 0xea, + 0x77, 0x20, 0x6f, 0x59, 0x0d, 0x1e, 0xbf, 0x63, 0x35, 0xba, 0x7e, 0x59, 0x56, 0x83, 0xbd, 0xfb, + 0x06, 0xc1, 0xb1, 0x44, 0x46, 0x91, 0xc9, 0xc7, 0xa0, 0x24, 0x09, 0xc5, 0x3c, 0xf2, 0x0d, 0xf6, + 0x81, 0xe4, 0xed, 0x24, 0x6f, 0x1a, 0x12, 0x36, 0xa9, 0x83, 0x7a, 0x6f, 0xfa, 0xc8, 0xd5, 0x47, + 0x23, 0x74, 0x83, 0x7c, 0xcb, 0x1d, 0x33, 0xb1, 0xad, 0x18, 0x85, 0x8c, 0x46, 0x1f, 0x89, 0xbe, + 0x28, 0x95, 0x95, 0x4d, 0x49, 0x4a, 0xd2, 0x86, 0x0d, 0xcb, 0x9d, 0x4c, 0x47, 0xcc, 0xbe, 0x66, + 0xd7, 0x1f, 0xd3, 0xfb, 0x0d, 0x8b, 0x93, 0x83, 0xd1, 0x75, 0x03, 0x5a, 0x28, 0x8c, 0x9a, 0x0e, + 0xfc, 0x71, 0xe2, 0xae, 0x93, 0x26, 0xd6, 0x5c, 0x79, 0xc8, 0xe9, 0xa9, 0x1a, 0xbf, 0x35, 0xe1, + 0xa9, 0x2a, 0x6e, 0x4d, 0xd1, 0x5d, 0xe9, 0x43, 0x19, 0xb1, 0xdc, 0xf0, 0x65, 0x50, 0x8a, 0xe5, + 0x16, 0x8b, 0xe0, 0xf6, 0xbd, 0x82, 0x14, 0x4e, 0x94, 0x8f, 0xc5, 0x9b, 0x00, 0x77, 0x7d, 0x6f, + 0xd8, 0x70, 0x27, 0x47, 0x7e, 0x5f, 0x0a, 0x29, 0x57, 0xfa, 0x92, 0xef, 0x0d, 0xed, 0x63, 0x04, + 0xff, 0xf4, 0x9d, 0x2b, 0x12, 0x92, 0x29, 0xfd, 0x4f, 0x3e, 0x08, 0xcb, 0xf4, 0x57, 0x27, 0xb2, + 0x12, 0x62, 0x3a, 0x59, 0xa4, 0x66, 0x49, 0x37, 0x22, 0x04, 0xf2, 0x06, 0xa6, 0x99, 0xf1, 0x46, + 0x13, 0x49, 0x78, 0x15, 0x39, 0x65, 0xbc, 0xd1, 0x24, 0x19, 0x21, 0x5a, 0x42, 0x26, 0xd5, 0xb0, + 0xea, 0x22, 0x33, 0x14, 0xcf, 0x66, 0x83, 0x8a, 0x47, 0x3e, 0xd7, 0x6c, 0x11, 0x9a, 0x56, 0xce, + 0xe1, 0x9b, 0x20, 0xc3, 0x4a, 0x58, 0xd5, 0x1d, 0xf6, 0x52, 0xc4, 0x85, 0x5a, 0x56, 0x89, 0xe0, + 0xa8, 0x6f, 0xf7, 0x10, 0x1c, 0xab, 0x44, 0x88, 0x4c, 0xb6, 0x61, 0x9d, 0xc9, 0xf8, 0x61, 0x86, + 0x49, 0x2e, 0xe2, 0xe2, 0xde, 0x16, 0xa5, 0xa0, 0x94, 0x3f, 0x9f, 0x20, 0x20, 0xbb, 0xb0, 0x80, + 0x77, 0x4d, 0xee, 0x1a, 0x70, 0x41, 0x56, 0x13, 0x24, 0xd7, 0x11, 0xee, 0x2b, 0xa8, 0x20, 0x90, + 0xf7, 0x15, 0x44, 0x25, 0x9f, 0x01, 0x30, 0x86, 0x63, 0x7f, 0x30, 0xc0, 0xe0, 0xc9, 0x45, 0xbc, + 0x4a, 0x5d, 0x8a, 0xaf, 0x47, 0xe4, 0x12, 0x21, 0xf1, 0x40, 0x7f, 0xf8, 0xdb, 0x4e, 0x84, 0x58, + 0x96, 0x78, 0x69, 0x35, 0x58, 0x64, 0x8b, 0x11, 0x03, 0x91, 0xf3, 0xd4, 0x2a, 0x52, 0x18, 0x6b, + 0x16, 0x88, 0x9c, 0xc3, 0xd3, 0x81, 0xc8, 0x25, 0x02, 0xed, 0x1e, 0x9c, 0xc9, 0x6a, 0x58, 0xec, + 0x76, 0xac, 0x9c, 0xf4, 0x76, 0xfc, 0xdd, 0x3c, 0xac, 0x20, 0x37, 0xb1, 0x0b, 0xeb, 0xb0, 0x6a, + 0x4d, 0x1f, 0x85, 0x51, 0xba, 0xc4, 0x6e, 0x8c, 0xf5, 0x0b, 0xe4, 0x02, 0xf9, 0x0d, 0x2f, 0x46, + 0x41, 0x0c, 0x58, 0x13, 0x27, 0xc1, 0x9e, 0xf0, 0x1c, 0x08, 0x63, 0x80, 0x8b, 0x48, 0x93, 0xe9, + 0x0c, 0xbb, 0x09, 0xa2, 0xe8, 0x3c, 0xc8, 0x3f, 0xcb, 0x79, 0x50, 0x38, 0xd1, 0x79, 0xf0, 0x10, + 0x56, 0xc4, 0xd7, 0x70, 0x27, 0x5f, 0x78, 0x6f, 0x3b, 0x79, 0x8c, 0x19, 0xa9, 0x87, 0x3b, 0xfa, + 0xe2, 0xdc, 0x1d, 0x1d, 0x1f, 0x46, 0xc5, 0x2a, 0x1b, 0x21, 0x2c, 0xbd, 0xb1, 0x63, 0x0a, 0xca, + 0xbd, 0x4a, 0xfb, 0x67, 0x38, 0x25, 0x5f, 0x85, 0xe5, 0xba, 0x2f, 0xde, 0xc4, 0xa4, 0xc7, 0x88, + 0x81, 0x00, 0xca, 0xe2, 0x42, 0x88, 0x19, 0x9e, 0x6e, 0xf9, 0xf7, 0xe3, 0x74, 0x7b, 0x03, 0x80, + 0xbb, 0xa4, 0x44, 0xa9, 0xe3, 0x70, 0xc9, 0x88, 0x08, 0x25, 0xf1, 0x37, 0x11, 0x09, 0x99, 0xee, + 0x4e, 0xdc, 0xdc, 0x46, 0xef, 0xf5, 0xfc, 0xe9, 0x70, 0x12, 0xcb, 0xb5, 0x2c, 0x3c, 0x58, 0x1d, + 0x5e, 0x26, 0x6f, 0x0f, 0x09, 0xb2, 0xf7, 0x77, 0x40, 0xc8, 0xa7, 0x43, 0xe3, 0xc7, 0xa5, 0x79, + 0x3d, 0xa4, 0xa5, 0x7a, 0x68, 0xa6, 0xc9, 0xa3, 0xf6, 0x43, 0x45, 0x4e, 0xc0, 0xf0, 0x33, 0x0c, + 0xf5, 0xeb, 0x00, 0xa1, 0x51, 0x82, 0x18, 0x6b, 0x76, 0x5f, 0x0a, 0xa1, 0x72, 0x2f, 0x47, 0xb8, + 0x52, 0x6b, 0xf2, 0xef, 0x57, 0x6b, 0x3a, 0x50, 0x6a, 0x7d, 0x79, 0xe2, 0x44, 0x56, 0x2c, 0x60, + 0x85, 0x92, 0x2c, 0xee, 0x4c, 0xf9, 0xed, 0xeb, 0x78, 0x36, 0x44, 0x72, 0xf0, 0x0c, 0x11, 0x58, + 0x22, 0xd4, 0xfe, 0x42, 0x81, 0x75, 0xd9, 0xed, 0xfe, 0xc9, 0xb0, 0x47, 0x3e, 0xc1, 0xe2, 0xc1, + 0x2a, 0xb1, 0x2b, 0x8b, 0x84, 0x44, 0xb7, 0xdc, 0x27, 0xc3, 0x1e, 0x13, 0x80, 0x9c, 0xc7, 0x72, + 0x65, 0x29, 0x21, 0x79, 0x04, 0x2b, 0x6d, 0x7f, 0x30, 0xa0, 0x62, 0xcd, 0xf8, 0x2d, 0x7e, 0x01, + 0xa0, 0x8c, 0x92, 0x4f, 0x23, 0xa2, 0x42, 0xdb, 0x2f, 0xf0, 0x7b, 0xee, 0xe6, 0x88, 0xee, 0xf7, + 0x1e, 0xa7, 0x8b, 0xd8, 0xbe, 0x8d, 0x7e, 0x72, 0x32, 0x4f, 0xed, 0xc7, 0x0a, 0x90, 0x74, 0x95, + 0xe4, 0x2d, 0x4b, 0xf9, 0x3f, 0x10, 0x61, 0x13, 0xa2, 0x5f, 0xe1, 0x59, 0x44, 0xbf, 0xf2, 0xef, + 0x2a, 0xb0, 0x5e, 0xd3, 0x1b, 0x3c, 0x25, 0x03, 0x7b, 0xc1, 0xb9, 0x0a, 0x97, 0x6a, 0x7a, 0xc3, + 0x6e, 0xb7, 0xea, 0xb5, 0xca, 0x03, 0x3b, 0x33, 0xd2, 0xf2, 0x25, 0x78, 0x2e, 0x8d, 0x12, 0xbd, + 0xf4, 0x5c, 0x84, 0xad, 0x74, 0xb1, 0x88, 0xc6, 0x9c, 0x4d, 0x2c, 0x02, 0x37, 0xe7, 0xcb, 0x9f, + 0x84, 0x75, 0x11, 0x79, 0xb8, 0x53, 0xb7, 0x30, 0xb7, 0xc1, 0x3a, 0x94, 0xf6, 0x0d, 0xb3, 0xb6, + 0xfb, 0xc0, 0xde, 0xed, 0xd6, 0xeb, 0xea, 0x29, 0xb2, 0x0a, 0xcb, 0x1c, 0x50, 0xd1, 0x55, 0x85, + 0xac, 0x40, 0xb1, 0xd6, 0xb4, 0x8c, 0x4a, 0xd7, 0x34, 0xd4, 0x5c, 0xf9, 0x93, 0xb0, 0xd6, 0x1e, + 0x7b, 0x6f, 0x39, 0x13, 0xf7, 0x9e, 0xfb, 0x04, 0x1f, 0x6a, 0x96, 0x20, 0x6f, 0xea, 0xf7, 0xd5, + 0x53, 0x04, 0x60, 0xb1, 0x7d, 0xaf, 0x62, 0xdd, 0xbe, 0xad, 0x2a, 0xa4, 0x04, 0x4b, 0x7b, 0x95, + 0xb6, 0x7d, 0xaf, 0x61, 0xa9, 0x39, 0xfa, 0x43, 0xbf, 0x6f, 0xe1, 0x8f, 0x7c, 0xf9, 0xc3, 0xb0, + 0x81, 0x02, 0x49, 0xdd, 0x0b, 0x26, 0xee, 0xd0, 0x1d, 0x63, 0x1d, 0x56, 0xa0, 0x68, 0xb9, 0x74, + 0x27, 0x99, 0xb8, 0xac, 0x02, 0x8d, 0xe9, 0x60, 0xe2, 0x8d, 0x06, 0xee, 0x57, 0x55, 0xa5, 0xfc, + 0x06, 0xac, 0x9b, 0xfe, 0x74, 0xe2, 0x0d, 0x0f, 0xad, 0x09, 0xc5, 0x38, 0x7c, 0x42, 0xce, 0xc2, + 0x46, 0xb7, 0xa9, 0x37, 0xb6, 0x6b, 0x7b, 0xdd, 0x56, 0xd7, 0xb2, 0x1b, 0x7a, 0xa7, 0x52, 0x65, + 0xcf, 0x44, 0x8d, 0x96, 0xd5, 0xb1, 0x4d, 0xa3, 0x62, 0x34, 0x3b, 0xaa, 0x52, 0xfe, 0x36, 0xea, + 0x56, 0x7a, 0xfe, 0xb0, 0xbf, 0xeb, 0xf4, 0x26, 0xfe, 0x18, 0x2b, 0xac, 0xc1, 0x65, 0xcb, 0xa8, + 0xb4, 0x9a, 0x3b, 0xf6, 0xae, 0x5e, 0xe9, 0xb4, 0xcc, 0xac, 0x50, 0xdf, 0xe7, 0xe1, 0x5c, 0x06, + 0x4e, 0xab, 0xd3, 0x56, 0x15, 0x72, 0x05, 0x2e, 0x64, 0x94, 0xdd, 0x37, 0xb6, 0xf5, 0x6e, 0xa7, + 0xda, 0x54, 0x73, 0x33, 0x88, 0x2d, 0xab, 0xa5, 0xe6, 0xcb, 0xbf, 0xa9, 0xc0, 0x5a, 0x37, 0xe0, + 0x26, 0xe7, 0x5d, 0xf4, 0x36, 0x7d, 0x1e, 0x2e, 0x76, 0x2d, 0xc3, 0xb4, 0x3b, 0xad, 0x7b, 0x46, + 0xd3, 0xee, 0x5a, 0xfa, 0x5e, 0xb2, 0x36, 0x57, 0xe0, 0x82, 0x84, 0x61, 0x1a, 0x95, 0xd6, 0xbe, + 0x61, 0xda, 0x6d, 0xdd, 0xb2, 0xee, 0xb7, 0xcc, 0x1d, 0x55, 0xa1, 0x5f, 0xcc, 0x40, 0x68, 0xec, + 0xea, 0xac, 0x36, 0xb1, 0xb2, 0xa6, 0x71, 0x5f, 0xaf, 0xdb, 0xdb, 0xad, 0x8e, 0x9a, 0x2f, 0x37, + 0xe8, 0xf9, 0x8e, 0x01, 0x77, 0x99, 0x65, 0x61, 0x11, 0x0a, 0xcd, 0x56, 0xd3, 0x48, 0x3e, 0x2e, + 0xae, 0x40, 0x51, 0x6f, 0xb7, 0xcd, 0xd6, 0x3e, 0x4e, 0x31, 0x80, 0xc5, 0x1d, 0xa3, 0x49, 0x6b, + 0x96, 0xa7, 0x25, 0x6d, 0xb3, 0xd5, 0x68, 0x75, 0x8c, 0x1d, 0xb5, 0x50, 0x36, 0xc5, 0x12, 0x16, + 0x4c, 0x7b, 0x3e, 0x7b, 0xc9, 0xdb, 0x31, 0x76, 0xf5, 0x6e, 0xbd, 0xc3, 0x87, 0xe8, 0x81, 0x6d, + 0x1a, 0x9f, 0xee, 0x1a, 0x56, 0xc7, 0x52, 0x15, 0xa2, 0xc2, 0x4a, 0xd3, 0x30, 0x76, 0x2c, 0xdb, + 0x34, 0xf6, 0x6b, 0xc6, 0x7d, 0x35, 0x47, 0x79, 0xb2, 0xff, 0xe9, 0x17, 0xca, 0xdf, 0x53, 0x80, + 0xb0, 0x60, 0xc5, 0x22, 0x03, 0x0e, 0xce, 0x98, 0xcb, 0x70, 0xbe, 0x4a, 0x87, 0x1a, 0x9b, 0xd6, + 0x68, 0xed, 0x24, 0xbb, 0xec, 0x1c, 0x90, 0x44, 0x79, 0x6b, 0x77, 0x57, 0x55, 0xc8, 0x05, 0x38, + 0x9d, 0x80, 0xef, 0x98, 0xad, 0xb6, 0x9a, 0x3b, 0x9f, 0x2b, 0x2a, 0x64, 0x33, 0x55, 0x78, 0xcf, + 0x30, 0xda, 0x6a, 0x9e, 0x0e, 0x51, 0xa2, 0x40, 0x2c, 0x09, 0x46, 0x5e, 0x28, 0x7f, 0x53, 0x81, + 0x73, 0xac, 0x9a, 0x62, 0x7d, 0x85, 0x55, 0xbd, 0x08, 0x5b, 0x3c, 0x04, 0x7b, 0x56, 0x45, 0xcf, + 0x80, 0x1a, 0x2b, 0x65, 0xd5, 0x3c, 0x0b, 0x1b, 0x31, 0x28, 0xd6, 0x23, 0x47, 0x77, 0x8f, 0x18, + 0x78, 0xdb, 0xb0, 0x3a, 0xb6, 0xb1, 0xbb, 0xdb, 0x32, 0x3b, 0xac, 0x22, 0xf9, 0xb2, 0x06, 0x1b, + 0x15, 0x77, 0x3c, 0xa1, 0x57, 0xaf, 0x61, 0xe0, 0xf9, 0x43, 0xac, 0xc2, 0x2a, 0x2c, 0x1b, 0x9f, + 0xe9, 0x18, 0x4d, 0xab, 0xd6, 0x6a, 0xaa, 0xa7, 0xca, 0x17, 0x13, 0x38, 0x62, 0x1d, 0x5b, 0x56, + 0x55, 0x3d, 0x55, 0x76, 0x60, 0x55, 0x18, 0x5e, 0xb3, 0x59, 0x71, 0x19, 0xce, 0x8b, 0xb9, 0x86, + 0x3b, 0x4a, 0xb2, 0x09, 0x5b, 0x70, 0x26, 0x5d, 0x6e, 0x74, 0x54, 0x85, 0x8e, 0x42, 0xa2, 0x84, + 0xc2, 0x73, 0xe5, 0x5f, 0x57, 0x60, 0x35, 0x7c, 0x34, 0x41, 0x35, 0xed, 0x15, 0xb8, 0xd0, 0xd8, + 0xd5, 0xed, 0x1d, 0x63, 0xbf, 0x56, 0x31, 0xec, 0x7b, 0xb5, 0xe6, 0x4e, 0xe2, 0x23, 0xcf, 0xc1, + 0xd9, 0x0c, 0x04, 0xfc, 0xca, 0x16, 0x9c, 0x49, 0x16, 0x75, 0xe8, 0x52, 0xcd, 0xd1, 0xae, 0x4f, + 0x96, 0x84, 0xeb, 0x34, 0x5f, 0xde, 0x87, 0x35, 0x4b, 0x6f, 0xd4, 0x77, 0xfd, 0x71, 0xcf, 0xd5, + 0xa7, 0x93, 0xa3, 0x21, 0xb9, 0x00, 0x9b, 0xbb, 0x2d, 0xb3, 0x62, 0xd8, 0x88, 0x92, 0xa8, 0xc1, + 0x69, 0x58, 0x97, 0x0b, 0x1f, 0x18, 0x74, 0xfa, 0x12, 0x58, 0x93, 0x81, 0xcd, 0x96, 0x9a, 0x2b, + 0x7f, 0x0e, 0x56, 0x62, 0x89, 0xf0, 0x36, 0xe1, 0xb4, 0xfc, 0xbb, 0xed, 0x0e, 0xfb, 0xde, 0xf0, + 0x50, 0x3d, 0x95, 0x2c, 0x30, 0xa7, 0xc3, 0x21, 0x2d, 0xc0, 0xf5, 0x2c, 0x17, 0x74, 0xdc, 0xf1, + 0xb1, 0x37, 0x74, 0x26, 0x6e, 0x5f, 0xcd, 0x95, 0x5f, 0x86, 0xd5, 0x58, 0xf8, 0x6d, 0x3a, 0x70, + 0xf5, 0x16, 0xdf, 0x80, 0x1b, 0xc6, 0x4e, 0xad, 0xdb, 0x50, 0x17, 0xe8, 0x4a, 0xae, 0xd6, 0xf6, + 0xaa, 0x2a, 0x94, 0xbf, 0xa3, 0xd0, 0x7b, 0x06, 0x26, 0xd5, 0x69, 0xec, 0xea, 0x62, 0xa8, 0xe9, + 0x34, 0x63, 0x41, 0xfd, 0x0d, 0xcb, 0x62, 0x6f, 0xea, 0x17, 0x61, 0x8b, 0xff, 0xb0, 0xf5, 0xe6, + 0x8e, 0x5d, 0xd5, 0xcd, 0x9d, 0xfb, 0xba, 0x49, 0xe7, 0xde, 0x03, 0x35, 0x87, 0x0b, 0x4a, 0x82, + 0xd8, 0x9d, 0x56, 0xb7, 0x52, 0x55, 0xf3, 0x74, 0xfe, 0xc6, 0xe0, 0xed, 0x5a, 0x53, 0x2d, 0xe0, + 0xf2, 0x4c, 0x61, 0x23, 0x5b, 0x5a, 0xbe, 0x50, 0x7e, 0x57, 0x81, 0x4d, 0xcb, 0x3b, 0x1c, 0x3a, + 0x93, 0xe9, 0xd8, 0xd5, 0x07, 0x87, 0xfe, 0xd8, 0x9b, 0x1c, 0x1d, 0x5b, 0x53, 0x6f, 0xe2, 0x92, + 0x5b, 0x70, 0xdd, 0xaa, 0xed, 0x35, 0xf5, 0x0e, 0x5d, 0x5e, 0x7a, 0x7d, 0xaf, 0x65, 0xd6, 0x3a, + 0xd5, 0x86, 0x6d, 0x75, 0x6b, 0xa9, 0x99, 0x77, 0x0d, 0x9e, 0x9f, 0x8d, 0x5a, 0x37, 0xf6, 0xf4, + 0xca, 0x03, 0x55, 0x99, 0xcf, 0x70, 0x5b, 0xaf, 0xeb, 0xcd, 0x8a, 0xb1, 0x63, 0xef, 0xdf, 0x56, + 0x73, 0xe4, 0x3a, 0x5c, 0x9d, 0x8d, 0xba, 0x5b, 0x6b, 0x5b, 0x14, 0x2d, 0x3f, 0xff, 0xbb, 0x55, + 0xab, 0x41, 0xb1, 0x0a, 0xe5, 0x3f, 0x56, 0x60, 0x6b, 0x56, 0x0c, 0x26, 0x72, 0x03, 0x34, 0xa3, + 0xd9, 0x31, 0xf5, 0xda, 0x8e, 0x5d, 0x31, 0x8d, 0x1d, 0xa3, 0xd9, 0xa9, 0xe9, 0x75, 0xcb, 0xb6, + 0x5a, 0x5d, 0x3a, 0x9b, 0x22, 0xd3, 0x87, 0x17, 0xe0, 0xca, 0x1c, 0xbc, 0x56, 0x6d, 0xa7, 0xa2, + 0x2a, 0xe4, 0x36, 0xbc, 0x34, 0x07, 0xc9, 0x7a, 0x60, 0x75, 0x8c, 0x86, 0x5c, 0xa2, 0xe6, 0xca, + 0x15, 0x38, 0x3f, 0x3b, 0x48, 0x0b, 0xdd, 0xa6, 0xe3, 0x3d, 0x5d, 0x84, 0xc2, 0x0e, 0x3d, 0x19, + 0x62, 0xb9, 0x1f, 0xca, 0x1e, 0xa8, 0xc9, 0x38, 0x0b, 0x29, 0x1b, 0x15, 0xb3, 0xdb, 0x6c, 0xb2, + 0x63, 0x64, 0x1d, 0x4a, 0xad, 0x4e, 0xd5, 0x30, 0x79, 0xf6, 0x0c, 0x4c, 0x97, 0xd1, 0x6d, 0xd2, + 0x85, 0xd3, 0x32, 0x6b, 0x9f, 0xc5, 0xf3, 0x64, 0x0b, 0xce, 0x58, 0x75, 0xbd, 0x72, 0xcf, 0x6e, + 0xb6, 0x3a, 0x76, 0xad, 0x69, 0x57, 0xaa, 0x7a, 0xb3, 0x69, 0xd4, 0x55, 0xc0, 0xce, 0x9c, 0xe5, + 0x5b, 0x49, 0x3e, 0x08, 0x37, 0x5b, 0xf7, 0x3a, 0xba, 0xdd, 0xae, 0x77, 0xf7, 0x6a, 0x4d, 0xdb, + 0x7a, 0xd0, 0xac, 0x08, 0xd9, 0xa7, 0x92, 0xde, 0x72, 0x6f, 0xc2, 0xb5, 0xb9, 0xd8, 0x51, 0x9e, + 0x8b, 0x1b, 0xa0, 0xcd, 0xc5, 0xe4, 0x0d, 0x29, 0xff, 0x48, 0x81, 0x0b, 0x73, 0xde, 0x90, 0xc9, + 0x4b, 0x70, 0xab, 0x6a, 0xe8, 0x3b, 0x75, 0xc3, 0xb2, 0x70, 0xa3, 0xa0, 0xc3, 0xc0, 0x6c, 0x59, + 0x32, 0x37, 0xd4, 0x5b, 0x70, 0x7d, 0x3e, 0x7a, 0x74, 0x34, 0xdf, 0x84, 0x6b, 0xf3, 0x51, 0xf9, + 0x51, 0x9d, 0x23, 0x65, 0xb8, 0x31, 0x1f, 0x33, 0x3c, 0xe2, 0xf3, 0xe5, 0xdf, 0x56, 0xe0, 0x5c, + 0xb6, 0x22, 0x87, 0xd6, 0xad, 0xd6, 0xb4, 0x3a, 0x7a, 0xbd, 0x6e, 0xb7, 0x75, 0x53, 0x6f, 0xd8, + 0x46, 0xd3, 0x6c, 0xd5, 0xeb, 0x59, 0x47, 0xdb, 0x35, 0x78, 0x7e, 0x36, 0xaa, 0x55, 0x31, 0x6b, + 0x6d, 0xba, 0x7b, 0x6b, 0x70, 0x79, 0x36, 0x96, 0x51, 0xab, 0x18, 0x6a, 0x6e, 0xfb, 0xcd, 0x1f, + 0xfc, 0xd3, 0xe5, 0x53, 0x3f, 0x78, 0xf7, 0xb2, 0xf2, 0xe3, 0x77, 0x2f, 0x2b, 0xff, 0xf8, 0xee, + 0x65, 0xe5, 0xb3, 0x2f, 0x9e, 0x2c, 0x45, 0x14, 0xca, 0xfd, 0x8f, 0x16, 0xf1, 0x86, 0xf2, 0xca, + 0xff, 0x04, 0x00, 0x00, 0xff, 0xff, 0x65, 0x8a, 0xa5, 0x19, 0x70, 0xbd, 0x01, 0x00, } func (this *PluginSpecV1) Equal(that interface{}) bool { @@ -28241,6 +28245,13 @@ func (m *IdentityCenterPermissionSet) MarshalToSizedBuffer(dAtA []byte) (int, er i -= len(m.XXX_unrecognized) copy(dAtA[i:], m.XXX_unrecognized) } + if len(m.AssignmentID) > 0 { + i -= len(m.AssignmentID) + copy(dAtA[i:], m.AssignmentID) + i = encodeVarintTypes(dAtA, i, uint64(len(m.AssignmentID))) + i-- + dAtA[i] = 0x1a + } if len(m.Name) > 0 { i -= len(m.Name) copy(dAtA[i:], m.Name) @@ -51680,6 +51691,10 @@ func (m *IdentityCenterPermissionSet) Size() (n int) { if l > 0 { n += 1 + l + sovTypes(uint64(l)) } + l = len(m.AssignmentID) + if l > 0 { + n += 1 + l + sovTypes(uint64(l)) + } if m.XXX_unrecognized != nil { n += len(m.XXX_unrecognized) } @@ -71007,6 +71022,38 @@ func (m *IdentityCenterPermissionSet) Unmarshal(dAtA []byte) error { } m.Name = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field AssignmentID", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTypes + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTypes + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.AssignmentID = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipTypes(dAtA[iNdEx:]) diff --git a/build.assets/tooling/go.mod b/build.assets/tooling/go.mod index 1571393ad9fd9..5870c74535be8 100644 --- a/build.assets/tooling/go.mod +++ b/build.assets/tooling/go.mod @@ -1,6 +1,6 @@ module github.com/gravitational/teleport/build.assets/tooling -go 1.23.3 +go 1.23.4 require ( github.com/Masterminds/sprig/v3 v3.3.0 diff --git a/build.assets/versions.mk b/build.assets/versions.mk index edd1e5b5d7c86..15a01e3006f58 100644 --- a/build.assets/versions.mk +++ b/build.assets/versions.mk @@ -3,7 +3,7 @@ # Keep versions in sync with devbox.json, when applicable. # Sync with devbox.json. -GOLANG_VERSION ?= go1.23.3 +GOLANG_VERSION ?= go1.23.4 GOLANGCI_LINT_VERSION ?= v1.62.2 NODE_VERSION ?= 20.18.0 diff --git a/docs/config.json b/docs/config.json index 9a92f7ada9a42..10947e64273f4 100644 --- a/docs/config.json +++ b/docs/config.json @@ -132,7 +132,7 @@ "aws_secret_access_key": "zyxw9876-this-is-an-example" }, "cloud": { - "version": "16.4.7", + "version": "16.4.8", "major_version": "16", "sla": { "monthly_percentage": "99.9%", diff --git a/docs/cspell.json b/docs/cspell.json index ce6e144d68667..08c89c4305a08 100644 --- a/docs/cspell.json +++ b/docs/cspell.json @@ -59,7 +59,6 @@ "Elastcsearch", "Elasticvue", "Entra", - "entraid", "Exadata", "Exfiltrate", "Exrch", @@ -457,6 +456,7 @@ "enablerepo", "enterappname", "entityandreplyurl", + "entraid", "envfile", "enzos", "errcode", @@ -602,6 +602,7 @@ "lmnop", "loadbalancer", "localca", + "localinstall", "loginerrortroubleshooting", "loginrule", "loginrules", @@ -795,6 +796,7 @@ "relogged", "remotefx", "removelock", + "removerepo", "replaceall", "replicaset", "replicationgroup", @@ -1014,11 +1016,9 @@ "zxvf", "zztop" ], - "flagWords": [ - "hte" - ], + "flagWords": ["hte"], "ignorePaths": [ "**/reference/terraform-provider/**", "**/reference/operator-resources/**" ] -} \ No newline at end of file +} diff --git a/docs/pages/admin-guides/management/admin/uninstall-teleport.mdx b/docs/pages/admin-guides/management/admin/uninstall-teleport.mdx index c1675c103443e..17ca404890208 100644 --- a/docs/pages/admin-guides/management/admin/uninstall-teleport.mdx +++ b/docs/pages/admin-guides/management/admin/uninstall-teleport.mdx @@ -132,6 +132,22 @@ Follow the instructions for your Linux distribution: ``` + + + + Uninstall the Teleport binary using zypper: + + ```code + # Change the package name to "teleport" for Teleport Community Edition + $ sudo zypper -y remove teleport-ent + ``` + + Uninstall the Teleport zypper repo: + + ```code + $ sudo zypper removerepo teleport + ``` + @@ -160,7 +176,7 @@ Follow the instructions for your Linux distribution: You can use `dirname $(which teleport)` to look this up automatically. - Remove the Teleport binaries from the machine: + Remove the Teleport binaries and links to Teleport software from the machine: ```code $ sudo rm -f /usr/local/bin/tbot @@ -171,10 +187,17 @@ Follow the instructions for your Linux distribution: ``` - If you installed the macOS `tsh` client-only package and/or Teleport Connect for macOS, you can optionally remove those too: + + You may have Teleport software in the `/Applications` folder if you: + - Installed from a macOS tarball for v17+ that includes `tsh.app` and `tctl.app` + - Installed the macOS `tsh` client-only package for v16 or older versions. + - Installed Teleport Connect for macOS + + You can remove those with these commands: ```code $ sudo rm -rf /Applications/tsh.app + $ sudo rm -rf /Applications/tctl.app $ sudo rm -rf /Applications/Teleport\ Connect.app ``` diff --git a/docs/pages/includes/device-trust/prereqs.mdx b/docs/pages/includes/device-trust/prereqs.mdx index 046cfd9fbcc1d..32699c20b21a7 100644 --- a/docs/pages/includes/device-trust/prereqs.mdx +++ b/docs/pages/includes/device-trust/prereqs.mdx @@ -12,3 +12,7 @@ - `tsh` v15.0.0 or newer. [Install tsh for Linux](../../installation.mdx#linux). - To authenticate a Web UI session you need [Teleport Connect]( ../../connect-your-client/teleport-connect.mdx#installation--upgrade) +- Correct end-user IP propagation to your Teleport deployment: + [X-Forwarded-For header](../../reference/config.mdx#proxy-service) (L7 load + balancer) or [PROXY protocol]( + ../../admin-guides/management/security/proxy-protocol.mdx) (L4 load balancer) diff --git a/docs/pages/includes/device-trust/troubleshooting.mdx b/docs/pages/includes/device-trust/troubleshooting.mdx index 3e18fb6d56d67..aeac5c840d216 100644 --- a/docs/pages/includes/device-trust/troubleshooting.mdx +++ b/docs/pages/includes/device-trust/troubleshooting.mdx @@ -80,8 +80,21 @@ follow the steps below: 4. Ask your cluster administrator if device trust is enabled (cluster mode "optional" or higher) -If all of the above steps are done, try logging out from the Web UI and logging -in again. +After the steps above are done try logging out from the Web UI and logging in +again. If the error persists, check your audit log for failed "device +authenticated" or "device web" events and look for failure details within the +events. + +### "device web authentication IP mismatch" errors + +"IP mismatch" errors in audit logs indicate that the IP checks performed by the +device web authentication ceremony failed. In this case it's likely that +end-user IPs are not propagated correctly to your Teleport deployment. + +* L7 load balancer: make sure it propagates the [X-Forwarded-For header]( + ../../reference/config.mdx#proxy-service) +* L4 load balancer: enable [PROXY protocol]( + ../../admin-guides/management/security/proxy-protocol.mdx) ### Checking Device Trust authorization status in the web UI diff --git a/docs/pages/includes/provision-token/github-spec.mdx b/docs/pages/includes/provision-token/github-spec.mdx index 3b252c185af86..9e86dfa0694df 100644 --- a/docs/pages/includes/provision-token/github-spec.mdx +++ b/docs/pages/includes/provision-token/github-spec.mdx @@ -22,6 +22,16 @@ spec: # this value should be configured to the hostname of your GHES instance. enterprise_server_host: ghes.example.com + # static_jwks allows the JSON Web Key Set (JWKS) used to verify the token + # issued by GitHub Actions to be overridden. This can be used in scenarios + # where the Teleport Auth Service is unable to reach a GHES server. + # + # This field is optional and should only be used with GitHub Enterprise + # Server. When unspecified, the JWKS will be fetched automatically using the + # GHES server specified in `enterprise_server_host`. + static_jwks: | + {"keys":[--snip--]} + # enterprise_slug allows the slug of a GitHub Enterprise organisation to be # included in the expected issuer of the OIDC tokens. This is for # compatibility with the include_enterprise_slug option in GHE. diff --git a/docs/pages/installation.mdx b/docs/pages/installation.mdx index bc5793a03d31e..fbc2671d74b92 100644 --- a/docs/pages/installation.mdx +++ b/docs/pages/installation.mdx @@ -317,14 +317,15 @@ repositories. -### TAR archives (self-hosted only) +### Downloading packages and TAR archives (self-hosted only) -For self-hosted deployments, Teleport maintains TAR archives for +Teleport maintains TAR archives as well as DEB and RPM packages for Linux-compatible binaries at `https://cdn.teleport.dev`. This section explains -the Teleport TAR archives and how to use them. +how to install Teleport by manually downloading a release. -It is not possible to install the automatic agent updater using TAR archives. -Teleport Cloud customers must use the [one-line installation +It is not possible to install the automatic agent updater using this method, so +using packages and TAR archives is only available for users who self-hosted +Teleport. Teleport Cloud customers must use the [one-line installation script](#one-line-installation-script) or manually install Teleport from a [package repository](#package-repositories) in order to install the updater. @@ -354,38 +355,98 @@ script](#one-line-installation-script) or manually install Teleport from a The following architecture values are available: - - `amd64` + - `amd64` (`x86_84` if downloading an RPM package) - `arm64` - `arm` - - `386` + - `386` (`i386` if downloading a DEB or RPM package) -1. Run the following commands to download the Teleport archive, unpack it, and - install binaries: +1. Run the following commands to download a Teleport package or archive, unpack + it, and install binaries: + + + ```code $ curl https://cdn.teleport.dev/${TELEPORT_PKG?}-v${TELEPORT_VERSION?}-linux-${SYSTEM_ARCH?}-bin.tar.gz.sha256 # $ curl -O https://cdn.teleport.dev/${TELEPORT_PKG?}-v${TELEPORT_VERSION?}-linux-${SYSTEM_ARCH?}-bin.tar.gz - $ shasum -a 256 ${TELEPORT_PKG?}-v${TELEPORT_VERSION?}-linux-${SYSTEM_ARCH?}-bin.tar.gz - # Verify that the checksums match + $ shasum --check -a 256 ${TELEPORT_PKG?}-v${TELEPORT_VERSION?}-linux-${SYSTEM_ARCH?}-bin.tar.gz $ tar -xvf ${TELEPORT_PKG?}-v${TELEPORT_VERSION?}-linux-${SYSTEM_ARCH?}-bin.tar.gz $ cd ${TELEPORT_PKG?} $ sudo ./install ``` + + + + ```code + $ curl https://cdn.teleport.dev/${TELEPORT_PKG?}_${TELEPORT_VERSION?}_${SYSTEM_ARCH?}.deb.sha256 + # + $ curl -O https://cdn.teleport.dev/${TELEPORT_PKG?}_${TELEPORT_VERSION?}_${SYSTEM_ARCH?}.deb + $ shasum --check -a 256 ${TELEPORT_PKG?}_${TELEPORT_VERSION?}_${SYSTEM_ARCH?}.deb + $ sudo dpkg -i ${TELEPORT_PKG?}_${TELEPORT_VERSION?}_${SYSTEM_ARCH?}.deb + ``` + + + + + ```code + $ curl https://cdn.teleport.dev/${TELEPORT_PKG?}-${TELEPORT_VERSION?}-1.${SYSTEM_ARCH?}.rpm.sha256 + # + $ curl -O https://cdn.teleport.dev/${TELEPORT_PKG?}-${TELEPORT_VERSION?}-1.${SYSTEM_ARCH?}.rpm + $ shasum --check -a 256 https://cdn.teleport.dev/${TELEPORT_PKG?}-${TELEPORT_VERSION?}-1.${SYSTEM_ARCH?}.rpm + # Or use yum localinstall, dnf localinstall etc. + $ sudo rpm -i https://cdn.teleport.dev/${TELEPORT_PKG?}-${TELEPORT_VERSION?}-1.${SYSTEM_ARCH?}.rpm + ``` + + + For FedRAMP/FIPS-compliant installations of Teleport Enterprise, package URLs are slightly different: + + + ```code $ curl https://cdn.teleport.dev/teleport-ent-v${TELEPORT_VERSION?}-linux-${SYSTEM_ARCH?}-fips-bin.tar.gz.sha256 # $ curl -O https://cdn.teleport.dev/teleport-ent-v${TELEPORT_VERSION?}-linux-${SYSTEM_ARCH?}-fips-bin.tar.gz - $ shasum -a 256 teleport-ent-v${TELEPORT_VERSION?}-linux-${SYSTEM_ARCH?}-fips-bin.tar.gz - # Verify that the checksums match + $ shasum --check -a 256 teleport-ent-v${TELEPORT_VERSION?}-linux-${SYSTEM_ARCH?}-fips-bin.tar.gz $ tar -xvf teleport-ent-v${TELEPORT_VERSION?}-linux-${SYSTEM_ARCH?}-fips-bin.tar.gz $ cd teleport-ent $ sudo ./install ``` + + + + FIPS builds are only available for the `arm64` and `amd64` system + architectures. + + ```code + $ curl https://cdn.teleport.dev/teleport-ent_${TELEPORT_VERSION}-fips_${SYSTEM_ARCH}.deb.sha256 + # + $ curl -O https://cdn.teleport.dev/teleport-ent_${TELEPORT_VERSION}-fips_${SYSTEM_ARCH}.deb + $ shasum --check -a 256 teleport-ent_${TELEPORT_VERSION}-fips_${SYSTEM_ARCH}.deb + $ sudo dpkg -i teleport-ent_${TELEPORT_VERSION}-fips_${SYSTEM_ARCH}.deb + ``` + + + + + FIPS builds are only available for the `arm64` and `x86_64` system + architectures. + + ```code + $ curl https://cdn.teleport.dev/teleport-ent-${TELEPORT_VERSION?}-1-fips.${SYSTEM_ARCH?}.rpm.sha256 + # + $ curl -O https://cdn.teleport.dev/teleport-ent-${TELEPORT_VERSION?}-1-fips.${SYSTEM_ARCH?}.rpm + $ shasum --check -a 256 https://cdn.teleport.dev/teleport-ent-${TELEPORT_VERSION?}-1-fips.${SYSTEM_ARCH?}.rpm + # Or use yum localinstall, dnf localinstall etc. + $ sudo rpm -i https://cdn.teleport.dev/teleport-ent-${TELEPORT_VERSION?}-1-fips.${SYSTEM_ARCH?}.rpm + ``` + + + ### From your browser diff --git a/docs/pages/reference/architecture/session-recording.mdx b/docs/pages/reference/architecture/session-recording.mdx index eae3e56e84d33..1f40d9d6eb35d 100644 --- a/docs/pages/reference/architecture/session-recording.mdx +++ b/docs/pages/reference/architecture/session-recording.mdx @@ -91,7 +91,7 @@ Proxy Server cannot see the SSH traffic to the node. It is encrypted end-to-end In **Recording Proxy Mode**, the Proxy Service terminates (decrypts) the SSH connection using the certificate supplied by the client via SSH agent forwarding and then establishes its own SSH connection to the final destination server. -This allows the Proxy Service to forward SSH session data to the auth server to +This allows the Proxy Service to forward SSH session data to the Auth Service to be recorded, as shown below: ![recording-proxy](../../../img/recording-proxy.svg) @@ -124,7 +124,7 @@ Auth Service. When synchronous recording is enabled, the Teleport component doing the recording (which may be the Teleport SSH Service or the Proxy Service instance depending on your configuration) -submits each recording event to Teleport's Auth Server as it occurs. In this mode, +submits each recording event to Teleport's Auth Service as it occurs. In this mode, failure to emit a recording event is considered fatal - the session will be terminated if an event cannot be recorded. This makes synchronous recording best suited for highly regulated environments where you need to be confident that all data is recorded. @@ -132,9 +132,9 @@ This also means that you need a reliable and low-latency connection to the Auth Server for the duration of the session to ensure that the session isn't interrupted or terminated due to temporary connection loss. -In synchronous recording modes, the Auth Server receives a stream of recording +In synchronous recording modes, the Auth Service receives a stream of recording events and is responsible for assembling them into the final artifact and uploading -it to the storage backend. Since data is streamed directly to the Auth Server, +it to the storage backend. Since data is streamed directly to the Auth Service, Teleport administrators don't need to be concerned with disk space on their Teleport SSH Service and Proxy Service instances, as no recording data is written to those disks. @@ -143,7 +143,7 @@ written to those disks. When asynchronous, recording events are written to the local filesystem during the session. When the session completes, Teleport assembles the parts into a -complete recording and submits the entire recording to the Auth Server for storage. +complete recording and submits the entire recording to the Auth Service for storage. Since recording data is flushed to disk, administrators should be careful to ensure that the system has enough disk space to accommodate the expected number of Teleport @@ -152,13 +152,14 @@ is a greater chance that it can be tampered with, deleted, or otherwise corrupte before the upload completes. The advantage of asynchronous recording is that it doesn't require a persistent -connection to the Auth Server. For example, an SSH session can continue to operate -even if Teleport's Auth Server goes down. When the session completes Teleport will -attempt to upload the recording to the Auth Server. If the Auth Server is still +connection to the Auth Service. For example, an SSH session can continue to operate +even if Teleport's Auth Service goes down. When the session completes Teleport will +attempt to upload the recording to the Auth Service. If the Auth Service is still unavailable, Teleport has built-in retry and backoff mechanisms that will upload -the artifact when the Auth Server comes back online. Additionally, asynchronous +the artifact when the Auth Service comes back online. Additionally, asynchronous recording is well-suited towards recording sessions that are extra chatty or in -environments where the connection to the auth server is unreliable or high-latency. +environments where the connection to the Auth Service is unreliable or +high-latency. ## Storage @@ -209,17 +210,17 @@ to be completed. In asynchronous recording modes, if the node goes down during the session, the partially completed recording will sit on the node's disk. The node's upload completer will eventually -detect the abandoned upload and stream it to the Teleport Auth Server where it will be +detect the abandoned upload and stream it to the Teleport Auth Service where it will be written to the storage backend. -In synchronous recording modes, Teleport's Auth Server is streaming the recording directly -to storage. If the Auth Server goes down during a session, the uncompleted upload will sit -as a series of parts (in cloud storage or on the Auth Server's disk) and it is the -responsibility of the Auth Server's upload completer to detect the abandoned upload and +In synchronous recording modes, Teleport's Auth Service is streaming the recording directly +to storage. If the Auth Service goes down during a session, the uncompleted upload will sit +as a series of parts (in cloud storage or on an Auth Service instance's disk) and it is the +responsibility of the Auth Service's upload completer to detect the abandoned upload and complete it. ## Related reading - [Recording Proxy Mode](../../enroll-resources/server-access/guides/recording-proxy-mode.mdx) - [SSH recording modes](../monitoring/audit.mdx) -- [Desktop Access recording](../agent-services/desktop-access-reference/sessions.mdx) +- [Session recording for desktops](../agent-services/desktop-access-reference/sessions.mdx) diff --git a/docs/pages/reference/terraform-provider/data-sources/app.mdx b/docs/pages/reference/terraform-provider/data-sources/app.mdx index b576c7f06628b..db743284d4819 100644 --- a/docs/pages/reference/terraform-provider/data-sources/app.mdx +++ b/docs/pages/reference/terraform-provider/data-sources/app.mdx @@ -95,6 +95,7 @@ Optional: Optional: - `arn` (String) ARN is the fully-formed ARN of the Permission Set. +- `assignment_name` (String) AssignmentID is the ID of the Teelport Account Assignment resource that represents this permission being assigned on the enclosing Account. - `name` (String) Name is the human-readable name of the Permission Set. diff --git a/docs/pages/reference/terraform-provider/resources/app.mdx b/docs/pages/reference/terraform-provider/resources/app.mdx index ef349eadbc766..5176f3452e1f1 100644 --- a/docs/pages/reference/terraform-provider/resources/app.mdx +++ b/docs/pages/reference/terraform-provider/resources/app.mdx @@ -114,6 +114,7 @@ Optional: Optional: - `arn` (String) ARN is the fully-formed ARN of the Permission Set. +- `assignment_name` (String) AssignmentID is the ID of the Teelport Account Assignment resource that represents this permission being assigned on the enclosing Account. - `name` (String) Name is the human-readable name of the Permission Set. diff --git a/e b/e index c230021897f8c..bef544252a504 160000 --- a/e +++ b/e @@ -1 +1 @@ -Subproject commit c230021897f8c46826ac5de3fde3280381f42749 +Subproject commit bef544252a50498a0232998bb942150268fc5efe diff --git a/examples/teleport-usage/Dockerfile b/examples/teleport-usage/Dockerfile index ba959b0c00107..aa9f485221143 100644 --- a/examples/teleport-usage/Dockerfile +++ b/examples/teleport-usage/Dockerfile @@ -1,6 +1,6 @@ ARG BASE_IMAGE=gcr.io/distroless/static-debian12 -FROM golang:1.21-bookworm as builder +FROM golang:1.22-bookworm as builder WORKDIR /go/src/github.com/gravitational/teleport/examples/teleport-usage diff --git a/examples/teleport-usage/go.mod b/examples/teleport-usage/go.mod index eaf6665957da9..9c009bebf497a 100644 --- a/examples/teleport-usage/go.mod +++ b/examples/teleport-usage/go.mod @@ -1,6 +1,6 @@ module usage-script -go 1.19 +go 1.22 require ( github.com/aws/aws-sdk-go v1.47.4 diff --git a/gen/proto/go/teleport/lib/teleterm/v1/app.pb.go b/gen/proto/go/teleport/lib/teleterm/v1/app.pb.go index 1f5f8430eb672..7f6de9c333de0 100644 --- a/gen/proto/go/teleport/lib/teleterm/v1/app.pb.go +++ b/gen/proto/go/teleport/lib/teleterm/v1/app.pb.go @@ -96,6 +96,11 @@ type App struct { Fqdn string `protobuf:"bytes,10,opt,name=fqdn,proto3" json:"fqdn,omitempty"` // aws_roles is a list of AWS IAM roles for the application representing AWS console. AwsRoles []*AWSRole `protobuf:"bytes,11,rep,name=aws_roles,json=awsRoles,proto3" json:"aws_roles,omitempty"` + // TCPPorts is a list of ports and port ranges that an app agent can forward connections to. + // Only applicable to TCP App Access. + // If this field is not empty, URI is expected to contain no port number and start with the tcp + // protocol. + TcpPorts []*PortRange `protobuf:"bytes,12,rep,name=tcp_ports,json=tcpPorts,proto3" json:"tcp_ports,omitempty"` } func (x *App) Reset() { @@ -205,6 +210,13 @@ func (x *App) GetAwsRoles() []*AWSRole { return nil } +func (x *App) GetTcpPorts() []*PortRange { + if x != nil { + return x.TcpPorts + } + return nil +} + // AwsRole describes AWS IAM role. type AWSRole struct { state protoimpl.MessageState @@ -279,6 +291,155 @@ func (x *AWSRole) GetAccountId() string { return "" } +// PortRange describes a port range for TCP apps. The range starts with Port and ends with EndPort. +// PortRange can be used to describe a single port in which case the Port field is the port and the +// EndPort field is 0. +type PortRange struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Port describes the start of the range. It must be between 1 and 65535. + Port uint32 `protobuf:"varint,1,opt,name=port,proto3" json:"port,omitempty"` + // EndPort describes the end of the range, inclusive. If set, it must be between 2 and 65535 and + // be greater than Port when describing a port range. When omitted or set to zero, it signifies + // that the port range defines a single port. + EndPort uint32 `protobuf:"varint,2,opt,name=end_port,json=endPort,proto3" json:"end_port,omitempty"` +} + +func (x *PortRange) Reset() { + *x = PortRange{} + mi := &file_teleport_lib_teleterm_v1_app_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *PortRange) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PortRange) ProtoMessage() {} + +func (x *PortRange) ProtoReflect() protoreflect.Message { + mi := &file_teleport_lib_teleterm_v1_app_proto_msgTypes[2] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use PortRange.ProtoReflect.Descriptor instead. +func (*PortRange) Descriptor() ([]byte, []int) { + return file_teleport_lib_teleterm_v1_app_proto_rawDescGZIP(), []int{2} +} + +func (x *PortRange) GetPort() uint32 { + if x != nil { + return x.Port + } + return 0 +} + +func (x *PortRange) GetEndPort() uint32 { + if x != nil { + return x.EndPort + } + return 0 +} + +// RouteToApp is used by the auth service and the app service during cert generation and routing. +// It's purpose is to point to a specific app within a root cluster. Kind of like an app URI in +// Connect, but with extra data attached. +type RouteToApp struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // name is the name of the app within a cluster. + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + // public_addr is the address under which the app can be reached. It's just the hostname, it does + // not include the schema or the port number. See the docs for public_addr of + // the App message for a more thorough description. + PublicAddr string `protobuf:"bytes,2,opt,name=public_addr,json=publicAddr,proto3" json:"public_addr,omitempty"` + // cluster_name is the name of the cluster that the app belongs to. In the case of the root + // cluster, it's not guaranteed to be equal to the proxy hostname – the root cluster might have a + // distinct name set. + ClusterName string `protobuf:"bytes,3,opt,name=cluster_name,json=clusterName,proto3" json:"cluster_name,omitempty"` + // uri is the URI which the app service is going to proxy requests to. + Uri string `protobuf:"bytes,4,opt,name=uri,proto3" json:"uri,omitempty"` + // target_port is the port of a multi-port TCP app that the connection is going to be proxied to. + TargetPort uint32 `protobuf:"varint,5,opt,name=target_port,json=targetPort,proto3" json:"target_port,omitempty"` +} + +func (x *RouteToApp) Reset() { + *x = RouteToApp{} + mi := &file_teleport_lib_teleterm_v1_app_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *RouteToApp) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*RouteToApp) ProtoMessage() {} + +func (x *RouteToApp) ProtoReflect() protoreflect.Message { + mi := &file_teleport_lib_teleterm_v1_app_proto_msgTypes[3] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use RouteToApp.ProtoReflect.Descriptor instead. +func (*RouteToApp) Descriptor() ([]byte, []int) { + return file_teleport_lib_teleterm_v1_app_proto_rawDescGZIP(), []int{3} +} + +func (x *RouteToApp) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *RouteToApp) GetPublicAddr() string { + if x != nil { + return x.PublicAddr + } + return "" +} + +func (x *RouteToApp) GetClusterName() string { + if x != nil { + return x.ClusterName + } + return "" +} + +func (x *RouteToApp) GetUri() string { + if x != nil { + return x.Uri + } + return "" +} + +func (x *RouteToApp) GetTargetPort() uint32 { + if x != nil { + return x.TargetPort + } + return 0 +} + var File_teleport_lib_teleterm_v1_app_proto protoreflect.FileDescriptor var file_teleport_lib_teleterm_v1_app_proto_rawDesc = []byte{ @@ -288,7 +449,7 @@ var file_teleport_lib_teleterm_v1_app_proto_rawDesc = []byte{ 0x69, 0x62, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x72, 0x6d, 0x2e, 0x76, 0x31, 0x1a, 0x24, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x6c, 0x69, 0x62, 0x2f, 0x74, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x72, 0x6d, 0x2f, 0x76, 0x31, 0x2f, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x2e, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xf1, 0x02, 0x0a, 0x03, 0x41, 0x70, 0x70, 0x12, 0x10, 0x0a, 0x03, + 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xb3, 0x03, 0x0a, 0x03, 0x41, 0x70, 0x70, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x72, 0x69, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x72, 0x69, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x65, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x5f, 0x75, @@ -311,19 +472,37 @@ var file_teleport_lib_teleterm_v1_app_proto_rawDesc = []byte{ 0x72, 0x6f, 0x6c, 0x65, 0x73, 0x18, 0x0b, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x6c, 0x69, 0x62, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x72, 0x6d, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x57, 0x53, 0x52, 0x6f, 0x6c, 0x65, 0x52, 0x08, - 0x61, 0x77, 0x73, 0x52, 0x6f, 0x6c, 0x65, 0x73, 0x22, 0x68, 0x0a, 0x07, 0x41, 0x57, 0x53, 0x52, - 0x6f, 0x6c, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x64, 0x69, 0x73, 0x70, 0x6c, - 0x61, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, - 0x79, 0x12, 0x10, 0x0a, 0x03, 0x61, 0x72, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, - 0x61, 0x72, 0x6e, 0x12, 0x1d, 0x0a, 0x0a, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x69, - 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, - 0x49, 0x64, 0x42, 0x54, 0x5a, 0x52, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, - 0x2f, 0x67, 0x72, 0x61, 0x76, 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x2f, 0x74, - 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x2f, 0x67, 0x6f, 0x2f, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x6c, 0x69, - 0x62, 0x2f, 0x74, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x72, 0x6d, 0x2f, 0x76, 0x31, 0x3b, 0x74, 0x65, - 0x6c, 0x65, 0x74, 0x65, 0x72, 0x6d, 0x76, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x61, 0x77, 0x73, 0x52, 0x6f, 0x6c, 0x65, 0x73, 0x12, 0x40, 0x0a, 0x09, 0x74, 0x63, 0x70, 0x5f, + 0x70, 0x6f, 0x72, 0x74, 0x73, 0x18, 0x0c, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x74, 0x65, + 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x6c, 0x69, 0x62, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x74, + 0x65, 0x72, 0x6d, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x6f, 0x72, 0x74, 0x52, 0x61, 0x6e, 0x67, 0x65, + 0x52, 0x08, 0x74, 0x63, 0x70, 0x50, 0x6f, 0x72, 0x74, 0x73, 0x22, 0x68, 0x0a, 0x07, 0x41, 0x57, + 0x53, 0x52, 0x6f, 0x6c, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x64, 0x69, 0x73, + 0x70, 0x6c, 0x61, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x64, 0x69, 0x73, 0x70, + 0x6c, 0x61, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x61, 0x72, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x03, 0x61, 0x72, 0x6e, 0x12, 0x1d, 0x0a, 0x0a, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, + 0x5f, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x61, 0x63, 0x63, 0x6f, 0x75, + 0x6e, 0x74, 0x49, 0x64, 0x22, 0x3a, 0x0a, 0x09, 0x50, 0x6f, 0x72, 0x74, 0x52, 0x61, 0x6e, 0x67, + 0x65, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, + 0x04, 0x70, 0x6f, 0x72, 0x74, 0x12, 0x19, 0x0a, 0x08, 0x65, 0x6e, 0x64, 0x5f, 0x70, 0x6f, 0x72, + 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x07, 0x65, 0x6e, 0x64, 0x50, 0x6f, 0x72, 0x74, + 0x22, 0x97, 0x01, 0x0a, 0x0a, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x54, 0x6f, 0x41, 0x70, 0x70, 0x12, + 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, + 0x61, 0x6d, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x61, 0x64, + 0x64, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, + 0x41, 0x64, 0x64, 0x72, 0x12, 0x21, 0x0a, 0x0c, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x5f, + 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x63, 0x6c, 0x75, 0x73, + 0x74, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x72, 0x69, 0x18, 0x04, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x72, 0x69, 0x12, 0x1f, 0x0a, 0x0b, 0x74, 0x61, 0x72, + 0x67, 0x65, 0x74, 0x5f, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0a, + 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x50, 0x6f, 0x72, 0x74, 0x42, 0x54, 0x5a, 0x52, 0x67, 0x69, + 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x72, 0x61, 0x76, 0x69, 0x74, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x2f, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2f, + 0x67, 0x65, 0x6e, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x6f, 0x2f, 0x74, 0x65, 0x6c, + 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x6c, 0x69, 0x62, 0x2f, 0x74, 0x65, 0x6c, 0x65, 0x74, 0x65, + 0x72, 0x6d, 0x2f, 0x76, 0x31, 0x3b, 0x74, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x72, 0x6d, 0x76, 0x31, + 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -338,20 +517,23 @@ func file_teleport_lib_teleterm_v1_app_proto_rawDescGZIP() []byte { return file_teleport_lib_teleterm_v1_app_proto_rawDescData } -var file_teleport_lib_teleterm_v1_app_proto_msgTypes = make([]protoimpl.MessageInfo, 2) +var file_teleport_lib_teleterm_v1_app_proto_msgTypes = make([]protoimpl.MessageInfo, 4) var file_teleport_lib_teleterm_v1_app_proto_goTypes = []any{ - (*App)(nil), // 0: teleport.lib.teleterm.v1.App - (*AWSRole)(nil), // 1: teleport.lib.teleterm.v1.AWSRole - (*Label)(nil), // 2: teleport.lib.teleterm.v1.Label + (*App)(nil), // 0: teleport.lib.teleterm.v1.App + (*AWSRole)(nil), // 1: teleport.lib.teleterm.v1.AWSRole + (*PortRange)(nil), // 2: teleport.lib.teleterm.v1.PortRange + (*RouteToApp)(nil), // 3: teleport.lib.teleterm.v1.RouteToApp + (*Label)(nil), // 4: teleport.lib.teleterm.v1.Label } var file_teleport_lib_teleterm_v1_app_proto_depIdxs = []int32{ - 2, // 0: teleport.lib.teleterm.v1.App.labels:type_name -> teleport.lib.teleterm.v1.Label + 4, // 0: teleport.lib.teleterm.v1.App.labels:type_name -> teleport.lib.teleterm.v1.Label 1, // 1: teleport.lib.teleterm.v1.App.aws_roles:type_name -> teleport.lib.teleterm.v1.AWSRole - 2, // [2:2] is the sub-list for method output_type - 2, // [2:2] is the sub-list for method input_type - 2, // [2:2] is the sub-list for extension type_name - 2, // [2:2] is the sub-list for extension extendee - 0, // [0:2] is the sub-list for field type_name + 2, // 2: teleport.lib.teleterm.v1.App.tcp_ports:type_name -> teleport.lib.teleterm.v1.PortRange + 3, // [3:3] is the sub-list for method output_type + 3, // [3:3] is the sub-list for method input_type + 3, // [3:3] is the sub-list for extension type_name + 3, // [3:3] is the sub-list for extension extendee + 0, // [0:3] is the sub-list for field type_name } func init() { file_teleport_lib_teleterm_v1_app_proto_init() } @@ -366,7 +548,7 @@ func file_teleport_lib_teleterm_v1_app_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_teleport_lib_teleterm_v1_app_proto_rawDesc, NumEnums: 0, - NumMessages: 2, + NumMessages: 4, NumExtensions: 0, NumServices: 0, }, diff --git a/gen/proto/go/teleport/lib/teleterm/v1/cluster.pb.go b/gen/proto/go/teleport/lib/teleterm/v1/cluster.pb.go index e27db690a6087..bfd7eae153001 100644 --- a/gen/proto/go/teleport/lib/teleterm/v1/cluster.pb.go +++ b/gen/proto/go/teleport/lib/teleterm/v1/cluster.pb.go @@ -465,6 +465,8 @@ type ACL struct { RecordedSessions *ResourceAccess `protobuf:"bytes,13,opt,name=recorded_sessions,json=recordedSessions,proto3" json:"recorded_sessions,omitempty"` // active_sessions defines access to active sessions. ActiveSessions *ResourceAccess `protobuf:"bytes,14,opt,name=active_sessions,json=activeSessions,proto3" json:"active_sessions,omitempty"` + // review_requests defines the ability to review requests + ReviewRequests bool `protobuf:"varint,15,opt,name=review_requests,json=reviewRequests,proto3" json:"review_requests,omitempty"` } func (x *ACL) Reset() { @@ -588,6 +590,13 @@ func (x *ACL) GetActiveSessions() *ResourceAccess { return nil } +func (x *ACL) GetReviewRequests() bool { + if x != nil { + return x.ReviewRequests + } + return false +} + // ResourceAccess describes access verbs type ResourceAccess struct { state protoimpl.MessageState @@ -814,7 +823,7 @@ var file_teleport_lib_teleterm_v1_cluster_proto_rawDesc = []byte{ 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x13, 0x0a, 0x0f, 0x55, 0x53, 0x45, 0x52, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x4c, 0x4f, 0x43, 0x41, 0x4c, 0x10, 0x01, 0x12, 0x11, 0x0a, 0x0d, 0x55, 0x53, 0x45, 0x52, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x53, 0x53, 0x4f, 0x10, 0x02, 0x22, - 0xc8, 0x07, 0x0a, 0x03, 0x41, 0x43, 0x4c, 0x12, 0x51, 0x0a, 0x0f, 0x61, 0x75, 0x74, 0x68, 0x5f, + 0xf1, 0x07, 0x0a, 0x03, 0x41, 0x43, 0x4c, 0x12, 0x51, 0x0a, 0x0f, 0x61, 0x75, 0x74, 0x68, 0x5f, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x28, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x6c, 0x69, 0x62, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x72, 0x6d, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x73, 0x6f, @@ -873,38 +882,41 @@ var file_teleport_lib_teleterm_v1_cluster_proto_rawDesc = []byte{ 0x32, 0x28, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x6c, 0x69, 0x62, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x72, 0x6d, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x52, 0x0e, 0x61, 0x63, 0x74, 0x69, - 0x76, 0x65, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x4a, 0x04, 0x08, 0x01, 0x10, 0x02, - 0x52, 0x08, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0x8e, 0x01, 0x0a, 0x0e, 0x52, - 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x12, 0x12, 0x0a, - 0x04, 0x6c, 0x69, 0x73, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x04, 0x6c, 0x69, 0x73, - 0x74, 0x12, 0x12, 0x0a, 0x04, 0x72, 0x65, 0x61, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, - 0x04, 0x72, 0x65, 0x61, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x65, 0x64, 0x69, 0x74, 0x18, 0x03, 0x20, - 0x01, 0x28, 0x08, 0x52, 0x04, 0x65, 0x64, 0x69, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x63, 0x72, 0x65, - 0x61, 0x74, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x63, 0x72, 0x65, 0x61, 0x74, - 0x65, 0x12, 0x16, 0x0a, 0x06, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, - 0x08, 0x52, 0x06, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x73, 0x65, - 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x03, 0x75, 0x73, 0x65, 0x22, 0x7b, 0x0a, 0x08, 0x46, - 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x12, 0x3a, 0x0a, 0x19, 0x61, 0x64, 0x76, 0x61, 0x6e, - 0x63, 0x65, 0x64, 0x5f, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x77, 0x6f, 0x72, 0x6b, 0x66, - 0x6c, 0x6f, 0x77, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x17, 0x61, 0x64, 0x76, 0x61, - 0x6e, 0x63, 0x65, 0x64, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, - 0x6f, 0x77, 0x73, 0x12, 0x33, 0x0a, 0x16, 0x69, 0x73, 0x5f, 0x75, 0x73, 0x61, 0x67, 0x65, 0x5f, - 0x62, 0x61, 0x73, 0x65, 0x64, 0x5f, 0x62, 0x69, 0x6c, 0x6c, 0x69, 0x6e, 0x67, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x08, 0x52, 0x13, 0x69, 0x73, 0x55, 0x73, 0x61, 0x67, 0x65, 0x42, 0x61, 0x73, 0x65, - 0x64, 0x42, 0x69, 0x6c, 0x6c, 0x69, 0x6e, 0x67, 0x2a, 0x73, 0x0a, 0x0d, 0x53, 0x68, 0x6f, 0x77, - 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x12, 0x1e, 0x0a, 0x1a, 0x53, 0x48, 0x4f, - 0x57, 0x5f, 0x52, 0x45, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x53, 0x5f, 0x55, 0x4e, 0x53, 0x50, - 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x1e, 0x0a, 0x1a, 0x53, 0x48, 0x4f, - 0x57, 0x5f, 0x52, 0x45, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x53, 0x5f, 0x52, 0x45, 0x51, 0x55, - 0x45, 0x53, 0x54, 0x41, 0x42, 0x4c, 0x45, 0x10, 0x01, 0x12, 0x22, 0x0a, 0x1e, 0x53, 0x48, 0x4f, - 0x57, 0x5f, 0x52, 0x45, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x53, 0x5f, 0x41, 0x43, 0x43, 0x45, - 0x53, 0x53, 0x49, 0x42, 0x4c, 0x45, 0x5f, 0x4f, 0x4e, 0x4c, 0x59, 0x10, 0x02, 0x42, 0x54, 0x5a, - 0x52, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x72, 0x61, 0x76, - 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x2f, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, - 0x72, 0x74, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x6f, 0x2f, - 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x6c, 0x69, 0x62, 0x2f, 0x74, 0x65, 0x6c, - 0x65, 0x74, 0x65, 0x72, 0x6d, 0x2f, 0x76, 0x31, 0x3b, 0x74, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x72, - 0x6d, 0x76, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x76, 0x65, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x27, 0x0a, 0x0f, 0x72, 0x65, + 0x76, 0x69, 0x65, 0x77, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x73, 0x18, 0x0f, 0x20, + 0x01, 0x28, 0x08, 0x52, 0x0e, 0x72, 0x65, 0x76, 0x69, 0x65, 0x77, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x73, 0x4a, 0x04, 0x08, 0x01, 0x10, 0x02, 0x52, 0x08, 0x73, 0x65, 0x73, 0x73, 0x69, + 0x6f, 0x6e, 0x73, 0x22, 0x8e, 0x01, 0x0a, 0x0e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, + 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x6c, 0x69, 0x73, 0x74, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x08, 0x52, 0x04, 0x6c, 0x69, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x72, 0x65, + 0x61, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x04, 0x72, 0x65, 0x61, 0x64, 0x12, 0x12, + 0x0a, 0x04, 0x65, 0x64, 0x69, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x04, 0x65, 0x64, + 0x69, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x18, 0x04, 0x20, 0x01, + 0x28, 0x08, 0x52, 0x06, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x64, 0x65, + 0x6c, 0x65, 0x74, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x64, 0x65, 0x6c, 0x65, + 0x74, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x73, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, + 0x03, 0x75, 0x73, 0x65, 0x22, 0x7b, 0x0a, 0x08, 0x46, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, + 0x12, 0x3a, 0x0a, 0x19, 0x61, 0x64, 0x76, 0x61, 0x6e, 0x63, 0x65, 0x64, 0x5f, 0x61, 0x63, 0x63, + 0x65, 0x73, 0x73, 0x5f, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x73, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x08, 0x52, 0x17, 0x61, 0x64, 0x76, 0x61, 0x6e, 0x63, 0x65, 0x64, 0x41, 0x63, 0x63, + 0x65, 0x73, 0x73, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x73, 0x12, 0x33, 0x0a, 0x16, + 0x69, 0x73, 0x5f, 0x75, 0x73, 0x61, 0x67, 0x65, 0x5f, 0x62, 0x61, 0x73, 0x65, 0x64, 0x5f, 0x62, + 0x69, 0x6c, 0x6c, 0x69, 0x6e, 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x13, 0x69, 0x73, + 0x55, 0x73, 0x61, 0x67, 0x65, 0x42, 0x61, 0x73, 0x65, 0x64, 0x42, 0x69, 0x6c, 0x6c, 0x69, 0x6e, + 0x67, 0x2a, 0x73, 0x0a, 0x0d, 0x53, 0x68, 0x6f, 0x77, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, + 0x65, 0x73, 0x12, 0x1e, 0x0a, 0x1a, 0x53, 0x48, 0x4f, 0x57, 0x5f, 0x52, 0x45, 0x53, 0x4f, 0x55, + 0x52, 0x43, 0x45, 0x53, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, + 0x10, 0x00, 0x12, 0x1e, 0x0a, 0x1a, 0x53, 0x48, 0x4f, 0x57, 0x5f, 0x52, 0x45, 0x53, 0x4f, 0x55, + 0x52, 0x43, 0x45, 0x53, 0x5f, 0x52, 0x45, 0x51, 0x55, 0x45, 0x53, 0x54, 0x41, 0x42, 0x4c, 0x45, + 0x10, 0x01, 0x12, 0x22, 0x0a, 0x1e, 0x53, 0x48, 0x4f, 0x57, 0x5f, 0x52, 0x45, 0x53, 0x4f, 0x55, + 0x52, 0x43, 0x45, 0x53, 0x5f, 0x41, 0x43, 0x43, 0x45, 0x53, 0x53, 0x49, 0x42, 0x4c, 0x45, 0x5f, + 0x4f, 0x4e, 0x4c, 0x59, 0x10, 0x02, 0x42, 0x54, 0x5a, 0x52, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, + 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x72, 0x61, 0x76, 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x61, 0x6c, 0x2f, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x67, 0x65, 0x6e, 0x2f, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x6f, 0x2f, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, + 0x74, 0x2f, 0x6c, 0x69, 0x62, 0x2f, 0x74, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x72, 0x6d, 0x2f, 0x76, + 0x31, 0x3b, 0x74, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x72, 0x6d, 0x76, 0x31, 0x62, 0x06, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/gen/proto/go/teleport/lib/teleterm/v1/tshd_events_service.pb.go b/gen/proto/go/teleport/lib/teleterm/v1/tshd_events_service.pb.go index 0ab11da4e3880..865c753088b11 100644 --- a/gen/proto/go/teleport/lib/teleterm/v1/tshd_events_service.pb.go +++ b/gen/proto/go/teleport/lib/teleterm/v1/tshd_events_service.pb.go @@ -192,8 +192,8 @@ type VnetCertExpired struct { // target_uri for now points solely at apps, but it's not called app_uri to make it future-proof. TargetUri string `protobuf:"bytes,1,opt,name=target_uri,json=targetUri,proto3" json:"target_uri,omitempty"` - // public_addr is the public address of the app that the user tried to access. - PublicAddr string `protobuf:"bytes,2,opt,name=public_addr,json=publicAddr,proto3" json:"public_addr,omitempty"` + // route_to_app is the metadata associated with the app that the user was trying to reach. + RouteToApp *RouteToApp `protobuf:"bytes,3,opt,name=route_to_app,json=routeToApp,proto3" json:"route_to_app,omitempty"` } func (x *VnetCertExpired) Reset() { @@ -233,11 +233,11 @@ func (x *VnetCertExpired) GetTargetUri() string { return "" } -func (x *VnetCertExpired) GetPublicAddr() string { +func (x *VnetCertExpired) GetRouteToApp() *RouteToApp { if x != nil { - return x.PublicAddr + return x.RouteToApp } - return "" + return nil } // Response for Relogin. @@ -435,8 +435,8 @@ type CannotProxyVnetConnection struct { TargetUri string `protobuf:"bytes,1,opt,name=target_uri,json=targetUri,proto3" json:"target_uri,omitempty"` Error string `protobuf:"bytes,2,opt,name=error,proto3" json:"error,omitempty"` - // public_addr is the public address of the app that the user tried to access. - PublicAddr string `protobuf:"bytes,3,opt,name=public_addr,json=publicAddr,proto3" json:"public_addr,omitempty"` + // route_to_app is the metadata associated with the app that the user was trying to reach. + RouteToApp *RouteToApp `protobuf:"bytes,4,opt,name=route_to_app,json=routeToApp,proto3" json:"route_to_app,omitempty"` } func (x *CannotProxyVnetConnection) Reset() { @@ -483,11 +483,11 @@ func (x *CannotProxyVnetConnection) GetError() string { return "" } -func (x *CannotProxyVnetConnection) GetPublicAddr() string { +func (x *CannotProxyVnetConnection) GetRouteToApp() *RouteToApp { if x != nil { - return x.PublicAddr + return x.RouteToApp } - return "" + return nil } // Response for SendNotification. @@ -1441,268 +1441,278 @@ var file_teleport_lib_teleterm_v1_tshd_events_service_proto_rawDesc = []byte{ 0x65, 0x6c, 0x65, 0x74, 0x65, 0x72, 0x6d, 0x2f, 0x76, 0x31, 0x2f, 0x74, 0x73, 0x68, 0x64, 0x5f, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x18, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x6c, - 0x69, 0x62, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x72, 0x6d, 0x2e, 0x76, 0x31, 0x22, 0xff, - 0x01, 0x0a, 0x0e, 0x52, 0x65, 0x6c, 0x6f, 0x67, 0x69, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x12, 0x28, 0x0a, 0x10, 0x72, 0x6f, 0x6f, 0x74, 0x5f, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, - 0x72, 0x5f, 0x75, 0x72, 0x69, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x72, 0x6f, 0x6f, - 0x74, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x55, 0x72, 0x69, 0x12, 0x60, 0x0a, 0x14, 0x67, - 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x5f, 0x63, 0x65, 0x72, 0x74, 0x5f, 0x65, 0x78, 0x70, 0x69, - 0x72, 0x65, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2c, 0x2e, 0x74, 0x65, 0x6c, 0x65, - 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x6c, 0x69, 0x62, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x72, - 0x6d, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x43, 0x65, 0x72, 0x74, - 0x45, 0x78, 0x70, 0x69, 0x72, 0x65, 0x64, 0x48, 0x00, 0x52, 0x12, 0x67, 0x61, 0x74, 0x65, 0x77, - 0x61, 0x79, 0x43, 0x65, 0x72, 0x74, 0x45, 0x78, 0x70, 0x69, 0x72, 0x65, 0x64, 0x12, 0x57, 0x0a, - 0x11, 0x76, 0x6e, 0x65, 0x74, 0x5f, 0x63, 0x65, 0x72, 0x74, 0x5f, 0x65, 0x78, 0x70, 0x69, 0x72, - 0x65, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, - 0x6f, 0x72, 0x74, 0x2e, 0x6c, 0x69, 0x62, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x72, 0x6d, - 0x2e, 0x76, 0x31, 0x2e, 0x56, 0x6e, 0x65, 0x74, 0x43, 0x65, 0x72, 0x74, 0x45, 0x78, 0x70, 0x69, - 0x72, 0x65, 0x64, 0x48, 0x00, 0x52, 0x0f, 0x76, 0x6e, 0x65, 0x74, 0x43, 0x65, 0x72, 0x74, 0x45, - 0x78, 0x70, 0x69, 0x72, 0x65, 0x64, 0x42, 0x08, 0x0a, 0x06, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, - 0x22, 0x54, 0x0a, 0x12, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x43, 0x65, 0x72, 0x74, 0x45, - 0x78, 0x70, 0x69, 0x72, 0x65, 0x64, 0x12, 0x1f, 0x0a, 0x0b, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, - 0x79, 0x5f, 0x75, 0x72, 0x69, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x67, 0x61, 0x74, - 0x65, 0x77, 0x61, 0x79, 0x55, 0x72, 0x69, 0x12, 0x1d, 0x0a, 0x0a, 0x74, 0x61, 0x72, 0x67, 0x65, - 0x74, 0x5f, 0x75, 0x72, 0x69, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x74, 0x61, 0x72, - 0x67, 0x65, 0x74, 0x55, 0x72, 0x69, 0x22, 0x51, 0x0a, 0x0f, 0x56, 0x6e, 0x65, 0x74, 0x43, 0x65, - 0x72, 0x74, 0x45, 0x78, 0x70, 0x69, 0x72, 0x65, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x74, 0x61, 0x72, - 0x67, 0x65, 0x74, 0x5f, 0x75, 0x72, 0x69, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x74, - 0x61, 0x72, 0x67, 0x65, 0x74, 0x55, 0x72, 0x69, 0x12, 0x1f, 0x0a, 0x0b, 0x70, 0x75, 0x62, 0x6c, - 0x69, 0x63, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x70, - 0x75, 0x62, 0x6c, 0x69, 0x63, 0x41, 0x64, 0x64, 0x72, 0x22, 0x11, 0x0a, 0x0f, 0x52, 0x65, 0x6c, - 0x6f, 0x67, 0x69, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x9d, 0x02, 0x0a, - 0x17, 0x53, 0x65, 0x6e, 0x64, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x7f, 0x0a, 0x1f, 0x63, 0x61, 0x6e, 0x6e, - 0x6f, 0x74, 0x5f, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x5f, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, - 0x5f, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x36, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x6c, 0x69, 0x62, - 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x72, 0x6d, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x61, 0x6e, - 0x6e, 0x6f, 0x74, 0x50, 0x72, 0x6f, 0x78, 0x79, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x43, - 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x48, 0x00, 0x52, 0x1c, 0x63, 0x61, 0x6e, - 0x6e, 0x6f, 0x74, 0x50, 0x72, 0x6f, 0x78, 0x79, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x43, - 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x76, 0x0a, 0x1c, 0x63, 0x61, 0x6e, - 0x6e, 0x6f, 0x74, 0x5f, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x5f, 0x76, 0x6e, 0x65, 0x74, 0x5f, 0x63, - 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x33, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x6c, 0x69, 0x62, 0x2e, 0x74, - 0x65, 0x6c, 0x65, 0x74, 0x65, 0x72, 0x6d, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x61, 0x6e, 0x6e, 0x6f, - 0x74, 0x50, 0x72, 0x6f, 0x78, 0x79, 0x56, 0x6e, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, - 0x74, 0x69, 0x6f, 0x6e, 0x48, 0x00, 0x52, 0x19, 0x63, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x50, 0x72, - 0x6f, 0x78, 0x79, 0x56, 0x6e, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, - 0x6e, 0x42, 0x09, 0x0a, 0x07, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x22, 0x74, 0x0a, 0x1c, - 0x43, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x50, 0x72, 0x6f, 0x78, 0x79, 0x47, 0x61, 0x74, 0x65, 0x77, - 0x61, 0x79, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1f, 0x0a, 0x0b, - 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x5f, 0x75, 0x72, 0x69, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x0a, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x55, 0x72, 0x69, 0x12, 0x1d, 0x0a, - 0x0a, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x5f, 0x75, 0x72, 0x69, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x09, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x55, 0x72, 0x69, 0x12, 0x14, 0x0a, 0x05, - 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x72, 0x72, - 0x6f, 0x72, 0x22, 0x71, 0x0a, 0x19, 0x43, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x50, 0x72, 0x6f, 0x78, + 0x69, 0x62, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x72, 0x6d, 0x2e, 0x76, 0x31, 0x1a, 0x22, + 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x6c, 0x69, 0x62, 0x2f, 0x74, 0x65, 0x6c, + 0x65, 0x74, 0x65, 0x72, 0x6d, 0x2f, 0x76, 0x31, 0x2f, 0x61, 0x70, 0x70, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x22, 0xff, 0x01, 0x0a, 0x0e, 0x52, 0x65, 0x6c, 0x6f, 0x67, 0x69, 0x6e, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x28, 0x0a, 0x10, 0x72, 0x6f, 0x6f, 0x74, 0x5f, 0x63, 0x6c, + 0x75, 0x73, 0x74, 0x65, 0x72, 0x5f, 0x75, 0x72, 0x69, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x0e, 0x72, 0x6f, 0x6f, 0x74, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x55, 0x72, 0x69, 0x12, + 0x60, 0x0a, 0x14, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x5f, 0x63, 0x65, 0x72, 0x74, 0x5f, + 0x65, 0x78, 0x70, 0x69, 0x72, 0x65, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2c, 0x2e, + 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x6c, 0x69, 0x62, 0x2e, 0x74, 0x65, 0x6c, + 0x65, 0x74, 0x65, 0x72, 0x6d, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, + 0x43, 0x65, 0x72, 0x74, 0x45, 0x78, 0x70, 0x69, 0x72, 0x65, 0x64, 0x48, 0x00, 0x52, 0x12, 0x67, + 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x43, 0x65, 0x72, 0x74, 0x45, 0x78, 0x70, 0x69, 0x72, 0x65, + 0x64, 0x12, 0x57, 0x0a, 0x11, 0x76, 0x6e, 0x65, 0x74, 0x5f, 0x63, 0x65, 0x72, 0x74, 0x5f, 0x65, + 0x78, 0x70, 0x69, 0x72, 0x65, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x74, + 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x6c, 0x69, 0x62, 0x2e, 0x74, 0x65, 0x6c, 0x65, + 0x74, 0x65, 0x72, 0x6d, 0x2e, 0x76, 0x31, 0x2e, 0x56, 0x6e, 0x65, 0x74, 0x43, 0x65, 0x72, 0x74, + 0x45, 0x78, 0x70, 0x69, 0x72, 0x65, 0x64, 0x48, 0x00, 0x52, 0x0f, 0x76, 0x6e, 0x65, 0x74, 0x43, + 0x65, 0x72, 0x74, 0x45, 0x78, 0x70, 0x69, 0x72, 0x65, 0x64, 0x42, 0x08, 0x0a, 0x06, 0x72, 0x65, + 0x61, 0x73, 0x6f, 0x6e, 0x22, 0x54, 0x0a, 0x12, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x43, + 0x65, 0x72, 0x74, 0x45, 0x78, 0x70, 0x69, 0x72, 0x65, 0x64, 0x12, 0x1f, 0x0a, 0x0b, 0x67, 0x61, + 0x74, 0x65, 0x77, 0x61, 0x79, 0x5f, 0x75, 0x72, 0x69, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x0a, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x55, 0x72, 0x69, 0x12, 0x1d, 0x0a, 0x0a, 0x74, + 0x61, 0x72, 0x67, 0x65, 0x74, 0x5f, 0x75, 0x72, 0x69, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x09, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x55, 0x72, 0x69, 0x22, 0x8b, 0x01, 0x0a, 0x0f, 0x56, + 0x6e, 0x65, 0x74, 0x43, 0x65, 0x72, 0x74, 0x45, 0x78, 0x70, 0x69, 0x72, 0x65, 0x64, 0x12, 0x1d, + 0x0a, 0x0a, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x5f, 0x75, 0x72, 0x69, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x09, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x55, 0x72, 0x69, 0x12, 0x46, 0x0a, + 0x0c, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x5f, 0x74, 0x6f, 0x5f, 0x61, 0x70, 0x70, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x6c, + 0x69, 0x62, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x72, 0x6d, 0x2e, 0x76, 0x31, 0x2e, 0x52, + 0x6f, 0x75, 0x74, 0x65, 0x54, 0x6f, 0x41, 0x70, 0x70, 0x52, 0x0a, 0x72, 0x6f, 0x75, 0x74, 0x65, + 0x54, 0x6f, 0x41, 0x70, 0x70, 0x4a, 0x04, 0x08, 0x02, 0x10, 0x03, 0x52, 0x0b, 0x70, 0x75, 0x62, + 0x6c, 0x69, 0x63, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x22, 0x11, 0x0a, 0x0f, 0x52, 0x65, 0x6c, 0x6f, + 0x67, 0x69, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x9d, 0x02, 0x0a, 0x17, + 0x53, 0x65, 0x6e, 0x64, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x7f, 0x0a, 0x1f, 0x63, 0x61, 0x6e, 0x6e, 0x6f, + 0x74, 0x5f, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x5f, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x5f, + 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x36, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x6c, 0x69, 0x62, 0x2e, + 0x74, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x72, 0x6d, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x61, 0x6e, 0x6e, + 0x6f, 0x74, 0x50, 0x72, 0x6f, 0x78, 0x79, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x43, 0x6f, + 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x48, 0x00, 0x52, 0x1c, 0x63, 0x61, 0x6e, 0x6e, + 0x6f, 0x74, 0x50, 0x72, 0x6f, 0x78, 0x79, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x43, 0x6f, + 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x76, 0x0a, 0x1c, 0x63, 0x61, 0x6e, 0x6e, + 0x6f, 0x74, 0x5f, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x5f, 0x76, 0x6e, 0x65, 0x74, 0x5f, 0x63, 0x6f, + 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x33, + 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x6c, 0x69, 0x62, 0x2e, 0x74, 0x65, + 0x6c, 0x65, 0x74, 0x65, 0x72, 0x6d, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x61, 0x6e, 0x6e, 0x6f, 0x74, + 0x50, 0x72, 0x6f, 0x78, 0x79, 0x56, 0x6e, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x48, 0x00, 0x52, 0x19, 0x63, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x50, 0x72, 0x6f, + 0x78, 0x79, 0x56, 0x6e, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x42, 0x09, 0x0a, 0x07, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x22, 0x74, 0x0a, 0x1c, 0x43, + 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x50, 0x72, 0x6f, 0x78, 0x79, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, + 0x79, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1f, 0x0a, 0x0b, 0x67, + 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x5f, 0x75, 0x72, 0x69, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x0a, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x55, 0x72, 0x69, 0x12, 0x1d, 0x0a, 0x0a, + 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x5f, 0x75, 0x72, 0x69, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x09, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x55, 0x72, 0x69, 0x12, 0x14, 0x0a, 0x05, 0x65, + 0x72, 0x72, 0x6f, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x72, 0x72, 0x6f, + 0x72, 0x22, 0xab, 0x01, 0x0a, 0x19, 0x43, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x50, 0x72, 0x6f, 0x78, 0x79, 0x56, 0x6e, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1d, 0x0a, 0x0a, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x5f, 0x75, 0x72, 0x69, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x55, 0x72, 0x69, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, - 0x72, 0x72, 0x6f, 0x72, 0x12, 0x1f, 0x0a, 0x0b, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x61, - 0x64, 0x64, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x70, 0x75, 0x62, 0x6c, 0x69, - 0x63, 0x41, 0x64, 0x64, 0x72, 0x22, 0x1a, 0x0a, 0x18, 0x53, 0x65, 0x6e, 0x64, 0x4e, 0x6f, 0x74, - 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x22, 0xdd, 0x01, 0x0a, 0x28, 0x53, 0x65, 0x6e, 0x64, 0x50, 0x65, 0x6e, 0x64, 0x69, 0x6e, - 0x67, 0x48, 0x65, 0x61, 0x64, 0x6c, 0x65, 0x73, 0x73, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, - 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x28, - 0x0a, 0x10, 0x72, 0x6f, 0x6f, 0x74, 0x5f, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x5f, 0x75, - 0x72, 0x69, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x72, 0x6f, 0x6f, 0x74, 0x43, 0x6c, - 0x75, 0x73, 0x74, 0x65, 0x72, 0x55, 0x72, 0x69, 0x12, 0x3c, 0x0a, 0x1a, 0x68, 0x65, 0x61, 0x64, - 0x6c, 0x65, 0x73, 0x73, 0x5f, 0x61, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x18, 0x68, 0x65, - 0x61, 0x64, 0x6c, 0x65, 0x73, 0x73, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x49, 0x0a, 0x21, 0x68, 0x65, 0x61, 0x64, 0x6c, 0x65, - 0x73, 0x73, 0x5f, 0x61, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x5f, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x70, 0x18, 0x03, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x1e, 0x68, 0x65, 0x61, 0x64, 0x6c, 0x65, 0x73, 0x73, 0x41, 0x75, 0x74, 0x68, 0x65, - 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x49, - 0x70, 0x22, 0x2b, 0x0a, 0x29, 0x53, 0x65, 0x6e, 0x64, 0x50, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, - 0x48, 0x65, 0x61, 0x64, 0x6c, 0x65, 0x73, 0x73, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, - 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xcd, - 0x01, 0x0a, 0x10, 0x50, 0x72, 0x6f, 0x6d, 0x70, 0x74, 0x4d, 0x46, 0x41, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x06, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x74, - 0x6f, 0x74, 0x70, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x04, 0x74, 0x6f, 0x74, 0x70, 0x12, - 0x1a, 0x0a, 0x08, 0x77, 0x65, 0x62, 0x61, 0x75, 0x74, 0x68, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, - 0x08, 0x52, 0x08, 0x77, 0x65, 0x62, 0x61, 0x75, 0x74, 0x68, 0x6e, 0x12, 0x1f, 0x0a, 0x0b, 0x63, - 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x5f, 0x75, 0x72, 0x69, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x0a, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x55, 0x72, 0x69, 0x12, 0x38, 0x0a, 0x03, - 0x73, 0x73, 0x6f, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x74, 0x65, 0x6c, 0x65, - 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x6c, 0x69, 0x62, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x72, - 0x6d, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x53, 0x4f, 0x43, 0x68, 0x61, 0x6c, 0x6c, 0x65, 0x6e, 0x67, - 0x65, 0x52, 0x03, 0x73, 0x73, 0x6f, 0x4a, 0x04, 0x08, 0x01, 0x10, 0x02, 0x52, 0x10, 0x72, 0x6f, - 0x6f, 0x74, 0x5f, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x5f, 0x75, 0x72, 0x69, 0x22, 0x9e, - 0x01, 0x0a, 0x0c, 0x53, 0x53, 0x4f, 0x43, 0x68, 0x61, 0x6c, 0x6c, 0x65, 0x6e, 0x67, 0x65, 0x12, - 0x21, 0x0a, 0x0c, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x5f, 0x69, 0x64, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, - 0x49, 0x64, 0x12, 0x25, 0x0a, 0x0e, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x5f, - 0x74, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x63, 0x6f, 0x6e, 0x6e, - 0x65, 0x63, 0x74, 0x6f, 0x72, 0x54, 0x79, 0x70, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x64, 0x69, 0x73, - 0x70, 0x6c, 0x61, 0x79, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x0b, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x21, 0x0a, 0x0c, - 0x72, 0x65, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x5f, 0x75, 0x72, 0x6c, 0x18, 0x04, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x0b, 0x72, 0x65, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x55, 0x72, 0x6c, 0x22, - 0x30, 0x0a, 0x11, 0x50, 0x72, 0x6f, 0x6d, 0x70, 0x74, 0x4d, 0x46, 0x41, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x74, 0x6f, 0x74, 0x70, 0x5f, 0x63, 0x6f, 0x64, - 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x74, 0x6f, 0x74, 0x70, 0x43, 0x6f, 0x64, - 0x65, 0x22, 0x6a, 0x0a, 0x1b, 0x50, 0x72, 0x6f, 0x6d, 0x70, 0x74, 0x48, 0x61, 0x72, 0x64, 0x77, - 0x61, 0x72, 0x65, 0x4b, 0x65, 0x79, 0x50, 0x49, 0x4e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x12, 0x28, 0x0a, 0x10, 0x72, 0x6f, 0x6f, 0x74, 0x5f, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, - 0x5f, 0x75, 0x72, 0x69, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x72, 0x6f, 0x6f, 0x74, - 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x55, 0x72, 0x69, 0x12, 0x21, 0x0a, 0x0c, 0x70, 0x69, - 0x6e, 0x5f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, - 0x52, 0x0b, 0x70, 0x69, 0x6e, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x22, 0x30, 0x0a, - 0x1c, 0x50, 0x72, 0x6f, 0x6d, 0x70, 0x74, 0x48, 0x61, 0x72, 0x64, 0x77, 0x61, 0x72, 0x65, 0x4b, - 0x65, 0x79, 0x50, 0x49, 0x4e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x10, 0x0a, - 0x03, 0x70, 0x69, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x70, 0x69, 0x6e, 0x22, - 0x49, 0x0a, 0x1d, 0x50, 0x72, 0x6f, 0x6d, 0x70, 0x74, 0x48, 0x61, 0x72, 0x64, 0x77, 0x61, 0x72, - 0x65, 0x4b, 0x65, 0x79, 0x54, 0x6f, 0x75, 0x63, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x12, 0x28, 0x0a, 0x10, 0x72, 0x6f, 0x6f, 0x74, 0x5f, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, - 0x5f, 0x75, 0x72, 0x69, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x72, 0x6f, 0x6f, 0x74, - 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x55, 0x72, 0x69, 0x22, 0x20, 0x0a, 0x1e, 0x50, 0x72, - 0x6f, 0x6d, 0x70, 0x74, 0x48, 0x61, 0x72, 0x64, 0x77, 0x61, 0x72, 0x65, 0x4b, 0x65, 0x79, 0x54, - 0x6f, 0x75, 0x63, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x4d, 0x0a, 0x21, - 0x50, 0x72, 0x6f, 0x6d, 0x70, 0x74, 0x48, 0x61, 0x72, 0x64, 0x77, 0x61, 0x72, 0x65, 0x4b, 0x65, - 0x79, 0x50, 0x49, 0x4e, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x12, 0x28, 0x0a, 0x10, 0x72, 0x6f, 0x6f, 0x74, 0x5f, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, - 0x72, 0x5f, 0x75, 0x72, 0x69, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x72, 0x6f, 0x6f, - 0x74, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x55, 0x72, 0x69, 0x22, 0x69, 0x0a, 0x22, 0x50, - 0x72, 0x6f, 0x6d, 0x70, 0x74, 0x48, 0x61, 0x72, 0x64, 0x77, 0x61, 0x72, 0x65, 0x4b, 0x65, 0x79, - 0x50, 0x49, 0x4e, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x12, 0x10, 0x0a, 0x03, 0x70, 0x69, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, - 0x70, 0x69, 0x6e, 0x12, 0x10, 0x0a, 0x03, 0x70, 0x75, 0x6b, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x03, 0x70, 0x75, 0x6b, 0x12, 0x1f, 0x0a, 0x0b, 0x70, 0x75, 0x6b, 0x5f, 0x63, 0x68, 0x61, - 0x6e, 0x67, 0x65, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x70, 0x75, 0x6b, 0x43, - 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 0x22, 0x6c, 0x0a, 0x26, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x72, - 0x6d, 0x48, 0x61, 0x72, 0x64, 0x77, 0x61, 0x72, 0x65, 0x4b, 0x65, 0x79, 0x53, 0x6c, 0x6f, 0x74, - 0x4f, 0x76, 0x65, 0x72, 0x77, 0x72, 0x69, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x12, 0x28, 0x0a, 0x10, 0x72, 0x6f, 0x6f, 0x74, 0x5f, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, - 0x5f, 0x75, 0x72, 0x69, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x72, 0x6f, 0x6f, 0x74, - 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x55, 0x72, 0x69, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, - 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, - 0x73, 0x61, 0x67, 0x65, 0x22, 0x47, 0x0a, 0x27, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x72, 0x6d, 0x48, - 0x61, 0x72, 0x64, 0x77, 0x61, 0x72, 0x65, 0x4b, 0x65, 0x79, 0x53, 0x6c, 0x6f, 0x74, 0x4f, 0x76, - 0x65, 0x72, 0x77, 0x72, 0x69, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, - 0x1c, 0x0a, 0x09, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x72, 0x6d, 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x08, 0x52, 0x09, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x72, 0x6d, 0x65, 0x64, 0x22, 0x22, 0x0a, - 0x20, 0x47, 0x65, 0x74, 0x55, 0x73, 0x61, 0x67, 0x65, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x69, - 0x6e, 0x67, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x22, 0x8f, 0x01, 0x0a, 0x21, 0x47, 0x65, 0x74, 0x55, 0x73, 0x61, 0x67, 0x65, 0x52, 0x65, - 0x70, 0x6f, 0x72, 0x74, 0x69, 0x6e, 0x67, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x6a, 0x0a, 0x18, 0x75, 0x73, 0x61, 0x67, 0x65, - 0x5f, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x69, 0x6e, 0x67, 0x5f, 0x73, 0x65, 0x74, 0x74, 0x69, - 0x6e, 0x67, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x30, 0x2e, 0x74, 0x65, 0x6c, 0x65, - 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x6c, 0x69, 0x62, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x72, - 0x6d, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x73, 0x61, 0x67, 0x65, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, - 0x69, 0x6e, 0x67, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x52, 0x16, 0x75, 0x73, 0x61, - 0x67, 0x65, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x69, 0x6e, 0x67, 0x53, 0x65, 0x74, 0x74, 0x69, - 0x6e, 0x67, 0x73, 0x22, 0x32, 0x0a, 0x16, 0x55, 0x73, 0x61, 0x67, 0x65, 0x52, 0x65, 0x70, 0x6f, - 0x72, 0x74, 0x69, 0x6e, 0x67, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x12, 0x18, 0x0a, - 0x07, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, - 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x22, 0x3b, 0x0a, 0x23, 0x52, 0x65, 0x70, 0x6f, 0x72, - 0x74, 0x55, 0x6e, 0x65, 0x78, 0x70, 0x65, 0x63, 0x74, 0x65, 0x64, 0x56, 0x6e, 0x65, 0x74, 0x53, - 0x68, 0x75, 0x74, 0x64, 0x6f, 0x77, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x14, - 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, - 0x72, 0x72, 0x6f, 0x72, 0x22, 0x26, 0x0a, 0x24, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x55, 0x6e, - 0x65, 0x78, 0x70, 0x65, 0x63, 0x74, 0x65, 0x64, 0x56, 0x6e, 0x65, 0x74, 0x53, 0x68, 0x75, 0x74, - 0x64, 0x6f, 0x77, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x32, 0x93, 0x0b, 0x0a, - 0x11, 0x54, 0x73, 0x68, 0x64, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x53, 0x65, 0x72, 0x76, 0x69, - 0x63, 0x65, 0x12, 0x5e, 0x0a, 0x07, 0x52, 0x65, 0x6c, 0x6f, 0x67, 0x69, 0x6e, 0x12, 0x28, 0x2e, - 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x6c, 0x69, 0x62, 0x2e, 0x74, 0x65, 0x6c, - 0x65, 0x74, 0x65, 0x72, 0x6d, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x6c, 0x6f, 0x67, 0x69, 0x6e, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x29, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, - 0x72, 0x74, 0x2e, 0x6c, 0x69, 0x62, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x72, 0x6d, 0x2e, - 0x76, 0x31, 0x2e, 0x52, 0x65, 0x6c, 0x6f, 0x67, 0x69, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x12, 0x79, 0x0a, 0x10, 0x53, 0x65, 0x6e, 0x64, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x69, - 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x31, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, - 0x74, 0x2e, 0x6c, 0x69, 0x62, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x72, 0x6d, 0x2e, 0x76, - 0x31, 0x2e, 0x53, 0x65, 0x6e, 0x64, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x32, 0x2e, 0x74, 0x65, 0x6c, 0x65, - 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x6c, 0x69, 0x62, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x72, - 0x6d, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x65, 0x6e, 0x64, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x63, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0xac, 0x01, - 0x0a, 0x21, 0x53, 0x65, 0x6e, 0x64, 0x50, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x48, 0x65, 0x61, + 0x72, 0x72, 0x6f, 0x72, 0x12, 0x46, 0x0a, 0x0c, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x5f, 0x74, 0x6f, + 0x5f, 0x61, 0x70, 0x70, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x74, 0x65, 0x6c, + 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x6c, 0x69, 0x62, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x74, 0x65, + 0x72, 0x6d, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x54, 0x6f, 0x41, 0x70, 0x70, + 0x52, 0x0a, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x54, 0x6f, 0x41, 0x70, 0x70, 0x4a, 0x04, 0x08, 0x03, + 0x10, 0x04, 0x52, 0x0b, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x22, + 0x1a, 0x0a, 0x18, 0x53, 0x65, 0x6e, 0x64, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xdd, 0x01, 0x0a, 0x28, + 0x53, 0x65, 0x6e, 0x64, 0x50, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x48, 0x65, 0x61, 0x64, 0x6c, + 0x65, 0x73, 0x73, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x28, 0x0a, 0x10, 0x72, 0x6f, 0x6f, 0x74, + 0x5f, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x5f, 0x75, 0x72, 0x69, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x0e, 0x72, 0x6f, 0x6f, 0x74, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x55, + 0x72, 0x69, 0x12, 0x3c, 0x0a, 0x1a, 0x68, 0x65, 0x61, 0x64, 0x6c, 0x65, 0x73, 0x73, 0x5f, 0x61, + 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x18, 0x68, 0x65, 0x61, 0x64, 0x6c, 0x65, 0x73, 0x73, + 0x41, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, + 0x12, 0x49, 0x0a, 0x21, 0x68, 0x65, 0x61, 0x64, 0x6c, 0x65, 0x73, 0x73, 0x5f, 0x61, 0x75, 0x74, + 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x63, 0x6c, 0x69, 0x65, + 0x6e, 0x74, 0x5f, 0x69, 0x70, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x1e, 0x68, 0x65, 0x61, 0x64, 0x6c, 0x65, 0x73, 0x73, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x12, 0x42, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x6c, - 0x69, 0x62, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x72, 0x6d, 0x2e, 0x76, 0x31, 0x2e, 0x53, + 0x69, 0x6f, 0x6e, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x49, 0x70, 0x22, 0x2b, 0x0a, 0x29, 0x53, 0x65, 0x6e, 0x64, 0x50, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x48, 0x65, 0x61, 0x64, 0x6c, 0x65, 0x73, 0x73, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x43, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, - 0x72, 0x74, 0x2e, 0x6c, 0x69, 0x62, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x72, 0x6d, 0x2e, - 0x76, 0x31, 0x2e, 0x53, 0x65, 0x6e, 0x64, 0x50, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x48, 0x65, - 0x61, 0x64, 0x6c, 0x65, 0x73, 0x73, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x64, 0x0a, 0x09, - 0x50, 0x72, 0x6f, 0x6d, 0x70, 0x74, 0x4d, 0x46, 0x41, 0x12, 0x2a, 0x2e, 0x74, 0x65, 0x6c, 0x65, - 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x6c, 0x69, 0x62, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x72, - 0x6d, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x6d, 0x70, 0x74, 0x4d, 0x46, 0x41, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2b, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, - 0x2e, 0x6c, 0x69, 0x62, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x72, 0x6d, 0x2e, 0x76, 0x31, - 0x2e, 0x50, 0x72, 0x6f, 0x6d, 0x70, 0x74, 0x4d, 0x46, 0x41, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x12, 0x85, 0x01, 0x0a, 0x14, 0x50, 0x72, 0x6f, 0x6d, 0x70, 0x74, 0x48, 0x61, 0x72, - 0x64, 0x77, 0x61, 0x72, 0x65, 0x4b, 0x65, 0x79, 0x50, 0x49, 0x4e, 0x12, 0x35, 0x2e, 0x74, 0x65, - 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x6c, 0x69, 0x62, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x74, - 0x65, 0x72, 0x6d, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x6d, 0x70, 0x74, 0x48, 0x61, 0x72, - 0x64, 0x77, 0x61, 0x72, 0x65, 0x4b, 0x65, 0x79, 0x50, 0x49, 0x4e, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x1a, 0x36, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x6c, 0x69, - 0x62, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x72, 0x6d, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x72, - 0x6f, 0x6d, 0x70, 0x74, 0x48, 0x61, 0x72, 0x64, 0x77, 0x61, 0x72, 0x65, 0x4b, 0x65, 0x79, 0x50, - 0x49, 0x4e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x8b, 0x01, 0x0a, 0x16, 0x50, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xcd, 0x01, 0x0a, 0x10, 0x50, 0x72, 0x6f, + 0x6d, 0x70, 0x74, 0x4d, 0x46, 0x41, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x16, 0x0a, + 0x06, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x72, + 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x6f, 0x74, 0x70, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x08, 0x52, 0x04, 0x74, 0x6f, 0x74, 0x70, 0x12, 0x1a, 0x0a, 0x08, 0x77, 0x65, 0x62, + 0x61, 0x75, 0x74, 0x68, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x77, 0x65, 0x62, + 0x61, 0x75, 0x74, 0x68, 0x6e, 0x12, 0x1f, 0x0a, 0x0b, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, + 0x5f, 0x75, 0x72, 0x69, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x63, 0x6c, 0x75, 0x73, + 0x74, 0x65, 0x72, 0x55, 0x72, 0x69, 0x12, 0x38, 0x0a, 0x03, 0x73, 0x73, 0x6f, 0x18, 0x06, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x6c, + 0x69, 0x62, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x72, 0x6d, 0x2e, 0x76, 0x31, 0x2e, 0x53, + 0x53, 0x4f, 0x43, 0x68, 0x61, 0x6c, 0x6c, 0x65, 0x6e, 0x67, 0x65, 0x52, 0x03, 0x73, 0x73, 0x6f, + 0x4a, 0x04, 0x08, 0x01, 0x10, 0x02, 0x52, 0x10, 0x72, 0x6f, 0x6f, 0x74, 0x5f, 0x63, 0x6c, 0x75, + 0x73, 0x74, 0x65, 0x72, 0x5f, 0x75, 0x72, 0x69, 0x22, 0x9e, 0x01, 0x0a, 0x0c, 0x53, 0x53, 0x4f, + 0x43, 0x68, 0x61, 0x6c, 0x6c, 0x65, 0x6e, 0x67, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x63, 0x6f, 0x6e, + 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x0b, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x49, 0x64, 0x12, 0x25, 0x0a, 0x0e, + 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x54, + 0x79, 0x70, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x5f, 0x6e, + 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x69, 0x73, 0x70, 0x6c, + 0x61, 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x72, 0x65, 0x64, 0x69, 0x72, 0x65, + 0x63, 0x74, 0x5f, 0x75, 0x72, 0x6c, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x72, 0x65, + 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x55, 0x72, 0x6c, 0x22, 0x30, 0x0a, 0x11, 0x50, 0x72, 0x6f, + 0x6d, 0x70, 0x74, 0x4d, 0x46, 0x41, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1b, + 0x0a, 0x09, 0x74, 0x6f, 0x74, 0x70, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x08, 0x74, 0x6f, 0x74, 0x70, 0x43, 0x6f, 0x64, 0x65, 0x22, 0x6a, 0x0a, 0x1b, 0x50, 0x72, 0x6f, 0x6d, 0x70, 0x74, 0x48, 0x61, 0x72, 0x64, 0x77, 0x61, 0x72, 0x65, 0x4b, 0x65, 0x79, - 0x54, 0x6f, 0x75, 0x63, 0x68, 0x12, 0x37, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, + 0x50, 0x49, 0x4e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x28, 0x0a, 0x10, 0x72, 0x6f, + 0x6f, 0x74, 0x5f, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x5f, 0x75, 0x72, 0x69, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x72, 0x6f, 0x6f, 0x74, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, + 0x72, 0x55, 0x72, 0x69, 0x12, 0x21, 0x0a, 0x0c, 0x70, 0x69, 0x6e, 0x5f, 0x6f, 0x70, 0x74, 0x69, + 0x6f, 0x6e, 0x61, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x70, 0x69, 0x6e, 0x4f, + 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x22, 0x30, 0x0a, 0x1c, 0x50, 0x72, 0x6f, 0x6d, 0x70, + 0x74, 0x48, 0x61, 0x72, 0x64, 0x77, 0x61, 0x72, 0x65, 0x4b, 0x65, 0x79, 0x50, 0x49, 0x4e, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x70, 0x69, 0x6e, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x70, 0x69, 0x6e, 0x22, 0x49, 0x0a, 0x1d, 0x50, 0x72, 0x6f, + 0x6d, 0x70, 0x74, 0x48, 0x61, 0x72, 0x64, 0x77, 0x61, 0x72, 0x65, 0x4b, 0x65, 0x79, 0x54, 0x6f, + 0x75, 0x63, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x28, 0x0a, 0x10, 0x72, 0x6f, + 0x6f, 0x74, 0x5f, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x5f, 0x75, 0x72, 0x69, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x72, 0x6f, 0x6f, 0x74, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, + 0x72, 0x55, 0x72, 0x69, 0x22, 0x20, 0x0a, 0x1e, 0x50, 0x72, 0x6f, 0x6d, 0x70, 0x74, 0x48, 0x61, + 0x72, 0x64, 0x77, 0x61, 0x72, 0x65, 0x4b, 0x65, 0x79, 0x54, 0x6f, 0x75, 0x63, 0x68, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x4d, 0x0a, 0x21, 0x50, 0x72, 0x6f, 0x6d, 0x70, 0x74, + 0x48, 0x61, 0x72, 0x64, 0x77, 0x61, 0x72, 0x65, 0x4b, 0x65, 0x79, 0x50, 0x49, 0x4e, 0x43, 0x68, + 0x61, 0x6e, 0x67, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x28, 0x0a, 0x10, 0x72, + 0x6f, 0x6f, 0x74, 0x5f, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x5f, 0x75, 0x72, 0x69, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x72, 0x6f, 0x6f, 0x74, 0x43, 0x6c, 0x75, 0x73, 0x74, + 0x65, 0x72, 0x55, 0x72, 0x69, 0x22, 0x69, 0x0a, 0x22, 0x50, 0x72, 0x6f, 0x6d, 0x70, 0x74, 0x48, + 0x61, 0x72, 0x64, 0x77, 0x61, 0x72, 0x65, 0x4b, 0x65, 0x79, 0x50, 0x49, 0x4e, 0x43, 0x68, 0x61, + 0x6e, 0x67, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x70, + 0x69, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x70, 0x69, 0x6e, 0x12, 0x10, 0x0a, + 0x03, 0x70, 0x75, 0x6b, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x70, 0x75, 0x6b, 0x12, + 0x1f, 0x0a, 0x0b, 0x70, 0x75, 0x6b, 0x5f, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x70, 0x75, 0x6b, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, + 0x22, 0x6c, 0x0a, 0x26, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x72, 0x6d, 0x48, 0x61, 0x72, 0x64, 0x77, + 0x61, 0x72, 0x65, 0x4b, 0x65, 0x79, 0x53, 0x6c, 0x6f, 0x74, 0x4f, 0x76, 0x65, 0x72, 0x77, 0x72, + 0x69, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x28, 0x0a, 0x10, 0x72, 0x6f, + 0x6f, 0x74, 0x5f, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x5f, 0x75, 0x72, 0x69, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x72, 0x6f, 0x6f, 0x74, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, + 0x72, 0x55, 0x72, 0x69, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x47, + 0x0a, 0x27, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x72, 0x6d, 0x48, 0x61, 0x72, 0x64, 0x77, 0x61, 0x72, + 0x65, 0x4b, 0x65, 0x79, 0x53, 0x6c, 0x6f, 0x74, 0x4f, 0x76, 0x65, 0x72, 0x77, 0x72, 0x69, 0x74, + 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x63, 0x6f, 0x6e, + 0x66, 0x69, 0x72, 0x6d, 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x63, 0x6f, + 0x6e, 0x66, 0x69, 0x72, 0x6d, 0x65, 0x64, 0x22, 0x22, 0x0a, 0x20, 0x47, 0x65, 0x74, 0x55, 0x73, + 0x61, 0x67, 0x65, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x69, 0x6e, 0x67, 0x53, 0x65, 0x74, 0x74, + 0x69, 0x6e, 0x67, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x8f, 0x01, 0x0a, 0x21, + 0x47, 0x65, 0x74, 0x55, 0x73, 0x61, 0x67, 0x65, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x69, 0x6e, + 0x67, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x12, 0x6a, 0x0a, 0x18, 0x75, 0x73, 0x61, 0x67, 0x65, 0x5f, 0x72, 0x65, 0x70, 0x6f, 0x72, + 0x74, 0x69, 0x6e, 0x67, 0x5f, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x30, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x6c, + 0x69, 0x62, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x72, 0x6d, 0x2e, 0x76, 0x31, 0x2e, 0x55, + 0x73, 0x61, 0x67, 0x65, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x69, 0x6e, 0x67, 0x53, 0x65, 0x74, + 0x74, 0x69, 0x6e, 0x67, 0x73, 0x52, 0x16, 0x75, 0x73, 0x61, 0x67, 0x65, 0x52, 0x65, 0x70, 0x6f, + 0x72, 0x74, 0x69, 0x6e, 0x67, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x22, 0x32, 0x0a, + 0x16, 0x55, 0x73, 0x61, 0x67, 0x65, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x69, 0x6e, 0x67, 0x53, + 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x65, 0x6e, 0x61, 0x62, 0x6c, + 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, + 0x64, 0x22, 0x3b, 0x0a, 0x23, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x55, 0x6e, 0x65, 0x78, 0x70, + 0x65, 0x63, 0x74, 0x65, 0x64, 0x56, 0x6e, 0x65, 0x74, 0x53, 0x68, 0x75, 0x74, 0x64, 0x6f, 0x77, + 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, + 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x22, 0x26, + 0x0a, 0x24, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x55, 0x6e, 0x65, 0x78, 0x70, 0x65, 0x63, 0x74, + 0x65, 0x64, 0x56, 0x6e, 0x65, 0x74, 0x53, 0x68, 0x75, 0x74, 0x64, 0x6f, 0x77, 0x6e, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x32, 0x93, 0x0b, 0x0a, 0x11, 0x54, 0x73, 0x68, 0x64, 0x45, + 0x76, 0x65, 0x6e, 0x74, 0x73, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x5e, 0x0a, 0x07, + 0x52, 0x65, 0x6c, 0x6f, 0x67, 0x69, 0x6e, 0x12, 0x28, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, + 0x72, 0x74, 0x2e, 0x6c, 0x69, 0x62, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x72, 0x6d, 0x2e, + 0x76, 0x31, 0x2e, 0x52, 0x65, 0x6c, 0x6f, 0x67, 0x69, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x1a, 0x29, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x6c, 0x69, 0x62, + 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x72, 0x6d, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x6c, + 0x6f, 0x67, 0x69, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x79, 0x0a, 0x10, + 0x53, 0x65, 0x6e, 0x64, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x12, 0x31, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x6c, 0x69, 0x62, 0x2e, + 0x74, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x72, 0x6d, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x65, 0x6e, 0x64, + 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x32, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x6c, + 0x69, 0x62, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x72, 0x6d, 0x2e, 0x76, 0x31, 0x2e, 0x53, + 0x65, 0x6e, 0x64, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0xac, 0x01, 0x0a, 0x21, 0x53, 0x65, 0x6e, 0x64, + 0x50, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x48, 0x65, 0x61, 0x64, 0x6c, 0x65, 0x73, 0x73, 0x41, + 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x42, 0x2e, + 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x6c, 0x69, 0x62, 0x2e, 0x74, 0x65, 0x6c, + 0x65, 0x74, 0x65, 0x72, 0x6d, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x65, 0x6e, 0x64, 0x50, 0x65, 0x6e, + 0x64, 0x69, 0x6e, 0x67, 0x48, 0x65, 0x61, 0x64, 0x6c, 0x65, 0x73, 0x73, 0x41, 0x75, 0x74, 0x68, + 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x1a, 0x43, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x6c, 0x69, 0x62, + 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x72, 0x6d, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x65, 0x6e, + 0x64, 0x50, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x48, 0x65, 0x61, 0x64, 0x6c, 0x65, 0x73, 0x73, + 0x41, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x64, 0x0a, 0x09, 0x50, 0x72, 0x6f, 0x6d, 0x70, 0x74, + 0x4d, 0x46, 0x41, 0x12, 0x2a, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x6c, + 0x69, 0x62, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x72, 0x6d, 0x2e, 0x76, 0x31, 0x2e, 0x50, + 0x72, 0x6f, 0x6d, 0x70, 0x74, 0x4d, 0x46, 0x41, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x2b, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x6c, 0x69, 0x62, 0x2e, 0x74, + 0x65, 0x6c, 0x65, 0x74, 0x65, 0x72, 0x6d, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x6d, 0x70, + 0x74, 0x4d, 0x46, 0x41, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x85, 0x01, 0x0a, + 0x14, 0x50, 0x72, 0x6f, 0x6d, 0x70, 0x74, 0x48, 0x61, 0x72, 0x64, 0x77, 0x61, 0x72, 0x65, 0x4b, + 0x65, 0x79, 0x50, 0x49, 0x4e, 0x12, 0x35, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x6c, 0x69, 0x62, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x72, 0x6d, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x6d, 0x70, 0x74, 0x48, 0x61, 0x72, 0x64, 0x77, 0x61, 0x72, 0x65, 0x4b, - 0x65, 0x79, 0x54, 0x6f, 0x75, 0x63, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x38, + 0x65, 0x79, 0x50, 0x49, 0x4e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x36, 0x2e, 0x74, + 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x6c, 0x69, 0x62, 0x2e, 0x74, 0x65, 0x6c, 0x65, + 0x74, 0x65, 0x72, 0x6d, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x6d, 0x70, 0x74, 0x48, 0x61, + 0x72, 0x64, 0x77, 0x61, 0x72, 0x65, 0x4b, 0x65, 0x79, 0x50, 0x49, 0x4e, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x8b, 0x01, 0x0a, 0x16, 0x50, 0x72, 0x6f, 0x6d, 0x70, 0x74, 0x48, + 0x61, 0x72, 0x64, 0x77, 0x61, 0x72, 0x65, 0x4b, 0x65, 0x79, 0x54, 0x6f, 0x75, 0x63, 0x68, 0x12, + 0x37, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x6c, 0x69, 0x62, 0x2e, 0x74, + 0x65, 0x6c, 0x65, 0x74, 0x65, 0x72, 0x6d, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x6d, 0x70, + 0x74, 0x48, 0x61, 0x72, 0x64, 0x77, 0x61, 0x72, 0x65, 0x4b, 0x65, 0x79, 0x54, 0x6f, 0x75, 0x63, + 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x38, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, + 0x6f, 0x72, 0x74, 0x2e, 0x6c, 0x69, 0x62, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x72, 0x6d, + 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x6d, 0x70, 0x74, 0x48, 0x61, 0x72, 0x64, 0x77, 0x61, + 0x72, 0x65, 0x4b, 0x65, 0x79, 0x54, 0x6f, 0x75, 0x63, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x12, 0x97, 0x01, 0x0a, 0x1a, 0x50, 0x72, 0x6f, 0x6d, 0x70, 0x74, 0x48, 0x61, 0x72, + 0x64, 0x77, 0x61, 0x72, 0x65, 0x4b, 0x65, 0x79, 0x50, 0x49, 0x4e, 0x43, 0x68, 0x61, 0x6e, 0x67, + 0x65, 0x12, 0x3b, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x6c, 0x69, 0x62, + 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x72, 0x6d, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x72, 0x6f, + 0x6d, 0x70, 0x74, 0x48, 0x61, 0x72, 0x64, 0x77, 0x61, 0x72, 0x65, 0x4b, 0x65, 0x79, 0x50, 0x49, + 0x4e, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x3c, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x6c, 0x69, 0x62, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x72, 0x6d, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x6d, 0x70, 0x74, - 0x48, 0x61, 0x72, 0x64, 0x77, 0x61, 0x72, 0x65, 0x4b, 0x65, 0x79, 0x54, 0x6f, 0x75, 0x63, 0x68, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x97, 0x01, 0x0a, 0x1a, 0x50, 0x72, 0x6f, - 0x6d, 0x70, 0x74, 0x48, 0x61, 0x72, 0x64, 0x77, 0x61, 0x72, 0x65, 0x4b, 0x65, 0x79, 0x50, 0x49, - 0x4e, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x12, 0x3b, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, - 0x72, 0x74, 0x2e, 0x6c, 0x69, 0x62, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x72, 0x6d, 0x2e, - 0x76, 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x6d, 0x70, 0x74, 0x48, 0x61, 0x72, 0x64, 0x77, 0x61, 0x72, - 0x65, 0x4b, 0x65, 0x79, 0x50, 0x49, 0x4e, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x1a, 0x3c, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, - 0x6c, 0x69, 0x62, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x72, 0x6d, 0x2e, 0x76, 0x31, 0x2e, - 0x50, 0x72, 0x6f, 0x6d, 0x70, 0x74, 0x48, 0x61, 0x72, 0x64, 0x77, 0x61, 0x72, 0x65, 0x4b, 0x65, - 0x79, 0x50, 0x49, 0x4e, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x12, 0xa6, 0x01, 0x0a, 0x1f, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x72, 0x6d, 0x48, 0x61, - 0x72, 0x64, 0x77, 0x61, 0x72, 0x65, 0x4b, 0x65, 0x79, 0x53, 0x6c, 0x6f, 0x74, 0x4f, 0x76, 0x65, - 0x72, 0x77, 0x72, 0x69, 0x74, 0x65, 0x12, 0x40, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, - 0x74, 0x2e, 0x6c, 0x69, 0x62, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x72, 0x6d, 0x2e, 0x76, - 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x72, 0x6d, 0x48, 0x61, 0x72, 0x64, 0x77, 0x61, 0x72, - 0x65, 0x4b, 0x65, 0x79, 0x53, 0x6c, 0x6f, 0x74, 0x4f, 0x76, 0x65, 0x72, 0x77, 0x72, 0x69, 0x74, - 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x41, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, - 0x6f, 0x72, 0x74, 0x2e, 0x6c, 0x69, 0x62, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x72, 0x6d, - 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x72, 0x6d, 0x48, 0x61, 0x72, 0x64, 0x77, - 0x61, 0x72, 0x65, 0x4b, 0x65, 0x79, 0x53, 0x6c, 0x6f, 0x74, 0x4f, 0x76, 0x65, 0x72, 0x77, 0x72, - 0x69, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x94, 0x01, 0x0a, 0x19, - 0x47, 0x65, 0x74, 0x55, 0x73, 0x61, 0x67, 0x65, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x69, 0x6e, - 0x67, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x12, 0x3a, 0x2e, 0x74, 0x65, 0x6c, 0x65, - 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x6c, 0x69, 0x62, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x72, - 0x6d, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x55, 0x73, 0x61, 0x67, 0x65, 0x52, 0x65, 0x70, - 0x6f, 0x72, 0x74, 0x69, 0x6e, 0x67, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x3b, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, - 0x2e, 0x6c, 0x69, 0x62, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x72, 0x6d, 0x2e, 0x76, 0x31, - 0x2e, 0x47, 0x65, 0x74, 0x55, 0x73, 0x61, 0x67, 0x65, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x69, - 0x6e, 0x67, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x12, 0x9d, 0x01, 0x0a, 0x1c, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x55, 0x6e, 0x65, - 0x78, 0x70, 0x65, 0x63, 0x74, 0x65, 0x64, 0x56, 0x6e, 0x65, 0x74, 0x53, 0x68, 0x75, 0x74, 0x64, - 0x6f, 0x77, 0x6e, 0x12, 0x3d, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x6c, - 0x69, 0x62, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x72, 0x6d, 0x2e, 0x76, 0x31, 0x2e, 0x52, - 0x65, 0x70, 0x6f, 0x72, 0x74, 0x55, 0x6e, 0x65, 0x78, 0x70, 0x65, 0x63, 0x74, 0x65, 0x64, 0x56, - 0x6e, 0x65, 0x74, 0x53, 0x68, 0x75, 0x74, 0x64, 0x6f, 0x77, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x1a, 0x3e, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x6c, 0x69, - 0x62, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x72, 0x6d, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, - 0x70, 0x6f, 0x72, 0x74, 0x55, 0x6e, 0x65, 0x78, 0x70, 0x65, 0x63, 0x74, 0x65, 0x64, 0x56, 0x6e, - 0x65, 0x74, 0x53, 0x68, 0x75, 0x74, 0x64, 0x6f, 0x77, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x42, 0x54, 0x5a, 0x52, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, - 0x2f, 0x67, 0x72, 0x61, 0x76, 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x2f, 0x74, - 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x2f, 0x67, 0x6f, 0x2f, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x6c, 0x69, - 0x62, 0x2f, 0x74, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x72, 0x6d, 0x2f, 0x76, 0x31, 0x3b, 0x74, 0x65, - 0x6c, 0x65, 0x74, 0x65, 0x72, 0x6d, 0x76, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x48, 0x61, 0x72, 0x64, 0x77, 0x61, 0x72, 0x65, 0x4b, 0x65, 0x79, 0x50, 0x49, 0x4e, 0x43, 0x68, + 0x61, 0x6e, 0x67, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0xa6, 0x01, 0x0a, + 0x1f, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x72, 0x6d, 0x48, 0x61, 0x72, 0x64, 0x77, 0x61, 0x72, 0x65, + 0x4b, 0x65, 0x79, 0x53, 0x6c, 0x6f, 0x74, 0x4f, 0x76, 0x65, 0x72, 0x77, 0x72, 0x69, 0x74, 0x65, + 0x12, 0x40, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x6c, 0x69, 0x62, 0x2e, + 0x74, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x72, 0x6d, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x66, + 0x69, 0x72, 0x6d, 0x48, 0x61, 0x72, 0x64, 0x77, 0x61, 0x72, 0x65, 0x4b, 0x65, 0x79, 0x53, 0x6c, + 0x6f, 0x74, 0x4f, 0x76, 0x65, 0x72, 0x77, 0x72, 0x69, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x41, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x6c, 0x69, + 0x62, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x72, 0x6d, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, + 0x6e, 0x66, 0x69, 0x72, 0x6d, 0x48, 0x61, 0x72, 0x64, 0x77, 0x61, 0x72, 0x65, 0x4b, 0x65, 0x79, + 0x53, 0x6c, 0x6f, 0x74, 0x4f, 0x76, 0x65, 0x72, 0x77, 0x72, 0x69, 0x74, 0x65, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x94, 0x01, 0x0a, 0x19, 0x47, 0x65, 0x74, 0x55, 0x73, 0x61, + 0x67, 0x65, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x69, 0x6e, 0x67, 0x53, 0x65, 0x74, 0x74, 0x69, + 0x6e, 0x67, 0x73, 0x12, 0x3a, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x6c, + 0x69, 0x62, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x72, 0x6d, 0x2e, 0x76, 0x31, 0x2e, 0x47, + 0x65, 0x74, 0x55, 0x73, 0x61, 0x67, 0x65, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x69, 0x6e, 0x67, + 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x3b, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x6c, 0x69, 0x62, 0x2e, 0x74, + 0x65, 0x6c, 0x65, 0x74, 0x65, 0x72, 0x6d, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x55, 0x73, + 0x61, 0x67, 0x65, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x69, 0x6e, 0x67, 0x53, 0x65, 0x74, 0x74, + 0x69, 0x6e, 0x67, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x9d, 0x01, 0x0a, + 0x1c, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x55, 0x6e, 0x65, 0x78, 0x70, 0x65, 0x63, 0x74, 0x65, + 0x64, 0x56, 0x6e, 0x65, 0x74, 0x53, 0x68, 0x75, 0x74, 0x64, 0x6f, 0x77, 0x6e, 0x12, 0x3d, 0x2e, + 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x6c, 0x69, 0x62, 0x2e, 0x74, 0x65, 0x6c, + 0x65, 0x74, 0x65, 0x72, 0x6d, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x55, + 0x6e, 0x65, 0x78, 0x70, 0x65, 0x63, 0x74, 0x65, 0x64, 0x56, 0x6e, 0x65, 0x74, 0x53, 0x68, 0x75, + 0x74, 0x64, 0x6f, 0x77, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x3e, 0x2e, 0x74, + 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x6c, 0x69, 0x62, 0x2e, 0x74, 0x65, 0x6c, 0x65, + 0x74, 0x65, 0x72, 0x6d, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x55, 0x6e, + 0x65, 0x78, 0x70, 0x65, 0x63, 0x74, 0x65, 0x64, 0x56, 0x6e, 0x65, 0x74, 0x53, 0x68, 0x75, 0x74, + 0x64, 0x6f, 0x77, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x54, 0x5a, 0x52, + 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x72, 0x61, 0x76, 0x69, + 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x2f, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, + 0x74, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x6f, 0x2f, 0x74, + 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x6c, 0x69, 0x62, 0x2f, 0x74, 0x65, 0x6c, 0x65, + 0x74, 0x65, 0x72, 0x6d, 0x2f, 0x76, 0x31, 0x3b, 0x74, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x72, 0x6d, + 0x76, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -1745,39 +1755,42 @@ var file_teleport_lib_teleterm_v1_tshd_events_service_proto_goTypes = []any{ (*UsageReportingSettings)(nil), // 23: teleport.lib.teleterm.v1.UsageReportingSettings (*ReportUnexpectedVnetShutdownRequest)(nil), // 24: teleport.lib.teleterm.v1.ReportUnexpectedVnetShutdownRequest (*ReportUnexpectedVnetShutdownResponse)(nil), // 25: teleport.lib.teleterm.v1.ReportUnexpectedVnetShutdownResponse + (*RouteToApp)(nil), // 26: teleport.lib.teleterm.v1.RouteToApp } var file_teleport_lib_teleterm_v1_tshd_events_service_proto_depIdxs = []int32{ 1, // 0: teleport.lib.teleterm.v1.ReloginRequest.gateway_cert_expired:type_name -> teleport.lib.teleterm.v1.GatewayCertExpired 2, // 1: teleport.lib.teleterm.v1.ReloginRequest.vnet_cert_expired:type_name -> teleport.lib.teleterm.v1.VnetCertExpired - 5, // 2: teleport.lib.teleterm.v1.SendNotificationRequest.cannot_proxy_gateway_connection:type_name -> teleport.lib.teleterm.v1.CannotProxyGatewayConnection - 6, // 3: teleport.lib.teleterm.v1.SendNotificationRequest.cannot_proxy_vnet_connection:type_name -> teleport.lib.teleterm.v1.CannotProxyVnetConnection - 11, // 4: teleport.lib.teleterm.v1.PromptMFARequest.sso:type_name -> teleport.lib.teleterm.v1.SSOChallenge - 23, // 5: teleport.lib.teleterm.v1.GetUsageReportingSettingsResponse.usage_reporting_settings:type_name -> teleport.lib.teleterm.v1.UsageReportingSettings - 0, // 6: teleport.lib.teleterm.v1.TshdEventsService.Relogin:input_type -> teleport.lib.teleterm.v1.ReloginRequest - 4, // 7: teleport.lib.teleterm.v1.TshdEventsService.SendNotification:input_type -> teleport.lib.teleterm.v1.SendNotificationRequest - 8, // 8: teleport.lib.teleterm.v1.TshdEventsService.SendPendingHeadlessAuthentication:input_type -> teleport.lib.teleterm.v1.SendPendingHeadlessAuthenticationRequest - 10, // 9: teleport.lib.teleterm.v1.TshdEventsService.PromptMFA:input_type -> teleport.lib.teleterm.v1.PromptMFARequest - 13, // 10: teleport.lib.teleterm.v1.TshdEventsService.PromptHardwareKeyPIN:input_type -> teleport.lib.teleterm.v1.PromptHardwareKeyPINRequest - 15, // 11: teleport.lib.teleterm.v1.TshdEventsService.PromptHardwareKeyTouch:input_type -> teleport.lib.teleterm.v1.PromptHardwareKeyTouchRequest - 17, // 12: teleport.lib.teleterm.v1.TshdEventsService.PromptHardwareKeyPINChange:input_type -> teleport.lib.teleterm.v1.PromptHardwareKeyPINChangeRequest - 19, // 13: teleport.lib.teleterm.v1.TshdEventsService.ConfirmHardwareKeySlotOverwrite:input_type -> teleport.lib.teleterm.v1.ConfirmHardwareKeySlotOverwriteRequest - 21, // 14: teleport.lib.teleterm.v1.TshdEventsService.GetUsageReportingSettings:input_type -> teleport.lib.teleterm.v1.GetUsageReportingSettingsRequest - 24, // 15: teleport.lib.teleterm.v1.TshdEventsService.ReportUnexpectedVnetShutdown:input_type -> teleport.lib.teleterm.v1.ReportUnexpectedVnetShutdownRequest - 3, // 16: teleport.lib.teleterm.v1.TshdEventsService.Relogin:output_type -> teleport.lib.teleterm.v1.ReloginResponse - 7, // 17: teleport.lib.teleterm.v1.TshdEventsService.SendNotification:output_type -> teleport.lib.teleterm.v1.SendNotificationResponse - 9, // 18: teleport.lib.teleterm.v1.TshdEventsService.SendPendingHeadlessAuthentication:output_type -> teleport.lib.teleterm.v1.SendPendingHeadlessAuthenticationResponse - 12, // 19: teleport.lib.teleterm.v1.TshdEventsService.PromptMFA:output_type -> teleport.lib.teleterm.v1.PromptMFAResponse - 14, // 20: teleport.lib.teleterm.v1.TshdEventsService.PromptHardwareKeyPIN:output_type -> teleport.lib.teleterm.v1.PromptHardwareKeyPINResponse - 16, // 21: teleport.lib.teleterm.v1.TshdEventsService.PromptHardwareKeyTouch:output_type -> teleport.lib.teleterm.v1.PromptHardwareKeyTouchResponse - 18, // 22: teleport.lib.teleterm.v1.TshdEventsService.PromptHardwareKeyPINChange:output_type -> teleport.lib.teleterm.v1.PromptHardwareKeyPINChangeResponse - 20, // 23: teleport.lib.teleterm.v1.TshdEventsService.ConfirmHardwareKeySlotOverwrite:output_type -> teleport.lib.teleterm.v1.ConfirmHardwareKeySlotOverwriteResponse - 22, // 24: teleport.lib.teleterm.v1.TshdEventsService.GetUsageReportingSettings:output_type -> teleport.lib.teleterm.v1.GetUsageReportingSettingsResponse - 25, // 25: teleport.lib.teleterm.v1.TshdEventsService.ReportUnexpectedVnetShutdown:output_type -> teleport.lib.teleterm.v1.ReportUnexpectedVnetShutdownResponse - 16, // [16:26] is the sub-list for method output_type - 6, // [6:16] is the sub-list for method input_type - 6, // [6:6] is the sub-list for extension type_name - 6, // [6:6] is the sub-list for extension extendee - 0, // [0:6] is the sub-list for field type_name + 26, // 2: teleport.lib.teleterm.v1.VnetCertExpired.route_to_app:type_name -> teleport.lib.teleterm.v1.RouteToApp + 5, // 3: teleport.lib.teleterm.v1.SendNotificationRequest.cannot_proxy_gateway_connection:type_name -> teleport.lib.teleterm.v1.CannotProxyGatewayConnection + 6, // 4: teleport.lib.teleterm.v1.SendNotificationRequest.cannot_proxy_vnet_connection:type_name -> teleport.lib.teleterm.v1.CannotProxyVnetConnection + 26, // 5: teleport.lib.teleterm.v1.CannotProxyVnetConnection.route_to_app:type_name -> teleport.lib.teleterm.v1.RouteToApp + 11, // 6: teleport.lib.teleterm.v1.PromptMFARequest.sso:type_name -> teleport.lib.teleterm.v1.SSOChallenge + 23, // 7: teleport.lib.teleterm.v1.GetUsageReportingSettingsResponse.usage_reporting_settings:type_name -> teleport.lib.teleterm.v1.UsageReportingSettings + 0, // 8: teleport.lib.teleterm.v1.TshdEventsService.Relogin:input_type -> teleport.lib.teleterm.v1.ReloginRequest + 4, // 9: teleport.lib.teleterm.v1.TshdEventsService.SendNotification:input_type -> teleport.lib.teleterm.v1.SendNotificationRequest + 8, // 10: teleport.lib.teleterm.v1.TshdEventsService.SendPendingHeadlessAuthentication:input_type -> teleport.lib.teleterm.v1.SendPendingHeadlessAuthenticationRequest + 10, // 11: teleport.lib.teleterm.v1.TshdEventsService.PromptMFA:input_type -> teleport.lib.teleterm.v1.PromptMFARequest + 13, // 12: teleport.lib.teleterm.v1.TshdEventsService.PromptHardwareKeyPIN:input_type -> teleport.lib.teleterm.v1.PromptHardwareKeyPINRequest + 15, // 13: teleport.lib.teleterm.v1.TshdEventsService.PromptHardwareKeyTouch:input_type -> teleport.lib.teleterm.v1.PromptHardwareKeyTouchRequest + 17, // 14: teleport.lib.teleterm.v1.TshdEventsService.PromptHardwareKeyPINChange:input_type -> teleport.lib.teleterm.v1.PromptHardwareKeyPINChangeRequest + 19, // 15: teleport.lib.teleterm.v1.TshdEventsService.ConfirmHardwareKeySlotOverwrite:input_type -> teleport.lib.teleterm.v1.ConfirmHardwareKeySlotOverwriteRequest + 21, // 16: teleport.lib.teleterm.v1.TshdEventsService.GetUsageReportingSettings:input_type -> teleport.lib.teleterm.v1.GetUsageReportingSettingsRequest + 24, // 17: teleport.lib.teleterm.v1.TshdEventsService.ReportUnexpectedVnetShutdown:input_type -> teleport.lib.teleterm.v1.ReportUnexpectedVnetShutdownRequest + 3, // 18: teleport.lib.teleterm.v1.TshdEventsService.Relogin:output_type -> teleport.lib.teleterm.v1.ReloginResponse + 7, // 19: teleport.lib.teleterm.v1.TshdEventsService.SendNotification:output_type -> teleport.lib.teleterm.v1.SendNotificationResponse + 9, // 20: teleport.lib.teleterm.v1.TshdEventsService.SendPendingHeadlessAuthentication:output_type -> teleport.lib.teleterm.v1.SendPendingHeadlessAuthenticationResponse + 12, // 21: teleport.lib.teleterm.v1.TshdEventsService.PromptMFA:output_type -> teleport.lib.teleterm.v1.PromptMFAResponse + 14, // 22: teleport.lib.teleterm.v1.TshdEventsService.PromptHardwareKeyPIN:output_type -> teleport.lib.teleterm.v1.PromptHardwareKeyPINResponse + 16, // 23: teleport.lib.teleterm.v1.TshdEventsService.PromptHardwareKeyTouch:output_type -> teleport.lib.teleterm.v1.PromptHardwareKeyTouchResponse + 18, // 24: teleport.lib.teleterm.v1.TshdEventsService.PromptHardwareKeyPINChange:output_type -> teleport.lib.teleterm.v1.PromptHardwareKeyPINChangeResponse + 20, // 25: teleport.lib.teleterm.v1.TshdEventsService.ConfirmHardwareKeySlotOverwrite:output_type -> teleport.lib.teleterm.v1.ConfirmHardwareKeySlotOverwriteResponse + 22, // 26: teleport.lib.teleterm.v1.TshdEventsService.GetUsageReportingSettings:output_type -> teleport.lib.teleterm.v1.GetUsageReportingSettingsResponse + 25, // 27: teleport.lib.teleterm.v1.TshdEventsService.ReportUnexpectedVnetShutdown:output_type -> teleport.lib.teleterm.v1.ReportUnexpectedVnetShutdownResponse + 18, // [18:28] is the sub-list for method output_type + 8, // [8:18] is the sub-list for method input_type + 8, // [8:8] is the sub-list for extension type_name + 8, // [8:8] is the sub-list for extension extendee + 0, // [0:8] is the sub-list for field type_name } func init() { file_teleport_lib_teleterm_v1_tshd_events_service_proto_init() } @@ -1785,6 +1798,7 @@ func file_teleport_lib_teleterm_v1_tshd_events_service_proto_init() { if File_teleport_lib_teleterm_v1_tshd_events_service_proto != nil { return } + file_teleport_lib_teleterm_v1_app_proto_init() file_teleport_lib_teleterm_v1_tshd_events_service_proto_msgTypes[0].OneofWrappers = []any{ (*ReloginRequest_GatewayCertExpired)(nil), (*ReloginRequest_VnetCertExpired)(nil), diff --git a/gen/proto/ts/teleport/lib/teleterm/v1/app_pb.ts b/gen/proto/ts/teleport/lib/teleterm/v1/app_pb.ts index 56fbe74bd0266..5764dffcd6ab8 100644 --- a/gen/proto/ts/teleport/lib/teleterm/v1/app_pb.ts +++ b/gen/proto/ts/teleport/lib/teleterm/v1/app_pb.ts @@ -134,6 +134,15 @@ export interface App { * @generated from protobuf field: repeated teleport.lib.teleterm.v1.AWSRole aws_roles = 11; */ awsRoles: AWSRole[]; + /** + * TCPPorts is a list of ports and port ranges that an app agent can forward connections to. + * Only applicable to TCP App Access. + * If this field is not empty, URI is expected to contain no port number and start with the tcp + * protocol. + * + * @generated from protobuf field: repeated teleport.lib.teleterm.v1.PortRange tcp_ports = 12; + */ + tcpPorts: PortRange[]; } /** * AwsRole describes AWS IAM role. @@ -166,6 +175,72 @@ export interface AWSRole { */ accountId: string; } +/** + * PortRange describes a port range for TCP apps. The range starts with Port and ends with EndPort. + * PortRange can be used to describe a single port in which case the Port field is the port and the + * EndPort field is 0. + * + * @generated from protobuf message teleport.lib.teleterm.v1.PortRange + */ +export interface PortRange { + /** + * Port describes the start of the range. It must be between 1 and 65535. + * + * @generated from protobuf field: uint32 port = 1; + */ + port: number; + /** + * EndPort describes the end of the range, inclusive. If set, it must be between 2 and 65535 and + * be greater than Port when describing a port range. When omitted or set to zero, it signifies + * that the port range defines a single port. + * + * @generated from protobuf field: uint32 end_port = 2; + */ + endPort: number; +} +/** + * RouteToApp is used by the auth service and the app service during cert generation and routing. + * It's purpose is to point to a specific app within a root cluster. Kind of like an app URI in + * Connect, but with extra data attached. + * + * @generated from protobuf message teleport.lib.teleterm.v1.RouteToApp + */ +export interface RouteToApp { + /** + * name is the name of the app within a cluster. + * + * @generated from protobuf field: string name = 1; + */ + name: string; + /** + * public_addr is the address under which the app can be reached. It's just the hostname, it does + * not include the schema or the port number. See the docs for public_addr of + * the App message for a more thorough description. + * + * @generated from protobuf field: string public_addr = 2; + */ + publicAddr: string; + /** + * cluster_name is the name of the cluster that the app belongs to. In the case of the root + * cluster, it's not guaranteed to be equal to the proxy hostname – the root cluster might have a + * distinct name set. + * + * @generated from protobuf field: string cluster_name = 3; + */ + clusterName: string; + /** + * uri is the URI which the app service is going to proxy requests to. + * + * @generated from protobuf field: string uri = 4; + */ + uri: string; + /** + * target_port is the port of a multi-port TCP app that the connection is going to be proxied to. + * + * @generated from protobuf field: uint32 target_port = 5; + */ + targetPort: number; +} // @generated message type with reflection information, may provide speed optimized methods class App$Type extends MessageType { constructor() { @@ -180,7 +255,8 @@ class App$Type extends MessageType { { no: 8, name: "saml_app", kind: "scalar", T: 8 /*ScalarType.BOOL*/ }, { no: 9, name: "labels", kind: "message", repeat: 1 /*RepeatType.PACKED*/, T: () => Label }, { no: 10, name: "fqdn", kind: "scalar", T: 9 /*ScalarType.STRING*/ }, - { no: 11, name: "aws_roles", kind: "message", repeat: 1 /*RepeatType.PACKED*/, T: () => AWSRole } + { no: 11, name: "aws_roles", kind: "message", repeat: 1 /*RepeatType.PACKED*/, T: () => AWSRole }, + { no: 12, name: "tcp_ports", kind: "message", repeat: 1 /*RepeatType.PACKED*/, T: () => PortRange } ]); } create(value?: PartialMessage): App { @@ -196,6 +272,7 @@ class App$Type extends MessageType { message.labels = []; message.fqdn = ""; message.awsRoles = []; + message.tcpPorts = []; if (value !== undefined) reflectionMergePartial(this, message, value); return message; @@ -238,6 +315,9 @@ class App$Type extends MessageType { case /* repeated teleport.lib.teleterm.v1.AWSRole aws_roles */ 11: message.awsRoles.push(AWSRole.internalBinaryRead(reader, reader.uint32(), options)); break; + case /* repeated teleport.lib.teleterm.v1.PortRange tcp_ports */ 12: + message.tcpPorts.push(PortRange.internalBinaryRead(reader, reader.uint32(), options)); + break; default: let u = options.readUnknownField; if (u === "throw") @@ -283,6 +363,9 @@ class App$Type extends MessageType { /* repeated teleport.lib.teleterm.v1.AWSRole aws_roles = 11; */ for (let i = 0; i < message.awsRoles.length; i++) AWSRole.internalBinaryWrite(message.awsRoles[i], writer.tag(11, WireType.LengthDelimited).fork(), options).join(); + /* repeated teleport.lib.teleterm.v1.PortRange tcp_ports = 12; */ + for (let i = 0; i < message.tcpPorts.length; i++) + PortRange.internalBinaryWrite(message.tcpPorts[i], writer.tag(12, WireType.LengthDelimited).fork(), options).join(); let u = options.writeUnknownFields; if (u !== false) (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); @@ -364,3 +447,137 @@ class AWSRole$Type extends MessageType { * @generated MessageType for protobuf message teleport.lib.teleterm.v1.AWSRole */ export const AWSRole = new AWSRole$Type(); +// @generated message type with reflection information, may provide speed optimized methods +class PortRange$Type extends MessageType { + constructor() { + super("teleport.lib.teleterm.v1.PortRange", [ + { no: 1, name: "port", kind: "scalar", T: 13 /*ScalarType.UINT32*/ }, + { no: 2, name: "end_port", kind: "scalar", T: 13 /*ScalarType.UINT32*/ } + ]); + } + create(value?: PartialMessage): PortRange { + const message = globalThis.Object.create((this.messagePrototype!)); + message.port = 0; + message.endPort = 0; + if (value !== undefined) + reflectionMergePartial(this, message, value); + return message; + } + internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: PortRange): PortRange { + let message = target ?? this.create(), end = reader.pos + length; + while (reader.pos < end) { + let [fieldNo, wireType] = reader.tag(); + switch (fieldNo) { + case /* uint32 port */ 1: + message.port = reader.uint32(); + break; + case /* uint32 end_port */ 2: + message.endPort = reader.uint32(); + break; + default: + let u = options.readUnknownField; + if (u === "throw") + throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`); + let d = reader.skip(wireType); + if (u !== false) + (u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d); + } + } + return message; + } + internalBinaryWrite(message: PortRange, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter { + /* uint32 port = 1; */ + if (message.port !== 0) + writer.tag(1, WireType.Varint).uint32(message.port); + /* uint32 end_port = 2; */ + if (message.endPort !== 0) + writer.tag(2, WireType.Varint).uint32(message.endPort); + let u = options.writeUnknownFields; + if (u !== false) + (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); + return writer; + } +} +/** + * @generated MessageType for protobuf message teleport.lib.teleterm.v1.PortRange + */ +export const PortRange = new PortRange$Type(); +// @generated message type with reflection information, may provide speed optimized methods +class RouteToApp$Type extends MessageType { + constructor() { + super("teleport.lib.teleterm.v1.RouteToApp", [ + { no: 1, name: "name", kind: "scalar", T: 9 /*ScalarType.STRING*/ }, + { no: 2, name: "public_addr", kind: "scalar", T: 9 /*ScalarType.STRING*/ }, + { no: 3, name: "cluster_name", kind: "scalar", T: 9 /*ScalarType.STRING*/ }, + { no: 4, name: "uri", kind: "scalar", T: 9 /*ScalarType.STRING*/ }, + { no: 5, name: "target_port", kind: "scalar", T: 13 /*ScalarType.UINT32*/ } + ]); + } + create(value?: PartialMessage): RouteToApp { + const message = globalThis.Object.create((this.messagePrototype!)); + message.name = ""; + message.publicAddr = ""; + message.clusterName = ""; + message.uri = ""; + message.targetPort = 0; + if (value !== undefined) + reflectionMergePartial(this, message, value); + return message; + } + internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: RouteToApp): RouteToApp { + let message = target ?? this.create(), end = reader.pos + length; + while (reader.pos < end) { + let [fieldNo, wireType] = reader.tag(); + switch (fieldNo) { + case /* string name */ 1: + message.name = reader.string(); + break; + case /* string public_addr */ 2: + message.publicAddr = reader.string(); + break; + case /* string cluster_name */ 3: + message.clusterName = reader.string(); + break; + case /* string uri */ 4: + message.uri = reader.string(); + break; + case /* uint32 target_port */ 5: + message.targetPort = reader.uint32(); + break; + default: + let u = options.readUnknownField; + if (u === "throw") + throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`); + let d = reader.skip(wireType); + if (u !== false) + (u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d); + } + } + return message; + } + internalBinaryWrite(message: RouteToApp, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter { + /* string name = 1; */ + if (message.name !== "") + writer.tag(1, WireType.LengthDelimited).string(message.name); + /* string public_addr = 2; */ + if (message.publicAddr !== "") + writer.tag(2, WireType.LengthDelimited).string(message.publicAddr); + /* string cluster_name = 3; */ + if (message.clusterName !== "") + writer.tag(3, WireType.LengthDelimited).string(message.clusterName); + /* string uri = 4; */ + if (message.uri !== "") + writer.tag(4, WireType.LengthDelimited).string(message.uri); + /* uint32 target_port = 5; */ + if (message.targetPort !== 0) + writer.tag(5, WireType.Varint).uint32(message.targetPort); + let u = options.writeUnknownFields; + if (u !== false) + (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); + return writer; + } +} +/** + * @generated MessageType for protobuf message teleport.lib.teleterm.v1.RouteToApp + */ +export const RouteToApp = new RouteToApp$Type(); diff --git a/gen/proto/ts/teleport/lib/teleterm/v1/cluster_pb.ts b/gen/proto/ts/teleport/lib/teleterm/v1/cluster_pb.ts index 297e11f43715d..35c3ae9dcae0b 100644 --- a/gen/proto/ts/teleport/lib/teleterm/v1/cluster_pb.ts +++ b/gen/proto/ts/teleport/lib/teleterm/v1/cluster_pb.ts @@ -300,6 +300,12 @@ export interface ACL { * @generated from protobuf field: teleport.lib.teleterm.v1.ResourceAccess active_sessions = 14; */ activeSessions?: ResourceAccess; + /** + * review_requests defines the ability to review requests + * + * @generated from protobuf field: bool review_requests = 15; + */ + reviewRequests: boolean; } /** * ResourceAccess describes access verbs @@ -649,11 +655,13 @@ class ACL$Type extends MessageType { { no: 11, name: "kubeservers", kind: "message", T: () => ResourceAccess }, { no: 12, name: "access_requests", kind: "message", T: () => ResourceAccess }, { no: 13, name: "recorded_sessions", kind: "message", T: () => ResourceAccess }, - { no: 14, name: "active_sessions", kind: "message", T: () => ResourceAccess } + { no: 14, name: "active_sessions", kind: "message", T: () => ResourceAccess }, + { no: 15, name: "review_requests", kind: "scalar", T: 8 /*ScalarType.BOOL*/ } ]); } create(value?: PartialMessage): ACL { const message = globalThis.Object.create((this.messagePrototype!)); + message.reviewRequests = false; if (value !== undefined) reflectionMergePartial(this, message, value); return message; @@ -702,6 +710,9 @@ class ACL$Type extends MessageType { case /* teleport.lib.teleterm.v1.ResourceAccess active_sessions */ 14: message.activeSessions = ResourceAccess.internalBinaryRead(reader, reader.uint32(), options, message.activeSessions); break; + case /* bool review_requests */ 15: + message.reviewRequests = reader.bool(); + break; default: let u = options.readUnknownField; if (u === "throw") @@ -753,6 +764,9 @@ class ACL$Type extends MessageType { /* teleport.lib.teleterm.v1.ResourceAccess active_sessions = 14; */ if (message.activeSessions) ResourceAccess.internalBinaryWrite(message.activeSessions, writer.tag(14, WireType.LengthDelimited).fork(), options).join(); + /* bool review_requests = 15; */ + if (message.reviewRequests !== false) + writer.tag(15, WireType.Varint).bool(message.reviewRequests); let u = options.writeUnknownFields; if (u !== false) (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); diff --git a/gen/proto/ts/teleport/lib/teleterm/v1/tshd_events_service_pb.ts b/gen/proto/ts/teleport/lib/teleterm/v1/tshd_events_service_pb.ts index 66b3f05bdb2d2..ac021c705e893 100644 --- a/gen/proto/ts/teleport/lib/teleterm/v1/tshd_events_service_pb.ts +++ b/gen/proto/ts/teleport/lib/teleterm/v1/tshd_events_service_pb.ts @@ -31,6 +31,7 @@ import { UnknownFieldHandler } from "@protobuf-ts/runtime"; import type { PartialMessage } from "@protobuf-ts/runtime"; import { reflectionMergePartial } from "@protobuf-ts/runtime"; import { MessageType } from "@protobuf-ts/runtime"; +import { RouteToApp } from "./app_pb"; /** * Request for Relogin. * @@ -93,11 +94,11 @@ export interface VnetCertExpired { */ targetUri: string; /** - * public_addr is the public address of the app that the user tried to access. + * route_to_app is the metadata associated with the app that the user was trying to reach. * - * @generated from protobuf field: string public_addr = 2; + * @generated from protobuf field: teleport.lib.teleterm.v1.RouteToApp route_to_app = 3; */ - publicAddr: string; + routeToApp?: RouteToApp; } /** * Response for Relogin. @@ -173,11 +174,11 @@ export interface CannotProxyVnetConnection { */ error: string; /** - * public_addr is the public address of the app that the user tried to access. + * route_to_app is the metadata associated with the app that the user was trying to reach. * - * @generated from protobuf field: string public_addr = 3; + * @generated from protobuf field: teleport.lib.teleterm.v1.RouteToApp route_to_app = 4; */ - publicAddr: string; + routeToApp?: RouteToApp; } /** * Response for SendNotification. @@ -567,13 +568,12 @@ class VnetCertExpired$Type extends MessageType { constructor() { super("teleport.lib.teleterm.v1.VnetCertExpired", [ { no: 1, name: "target_uri", kind: "scalar", T: 9 /*ScalarType.STRING*/ }, - { no: 2, name: "public_addr", kind: "scalar", T: 9 /*ScalarType.STRING*/ } + { no: 3, name: "route_to_app", kind: "message", T: () => RouteToApp } ]); } create(value?: PartialMessage): VnetCertExpired { const message = globalThis.Object.create((this.messagePrototype!)); message.targetUri = ""; - message.publicAddr = ""; if (value !== undefined) reflectionMergePartial(this, message, value); return message; @@ -586,8 +586,8 @@ class VnetCertExpired$Type extends MessageType { case /* string target_uri */ 1: message.targetUri = reader.string(); break; - case /* string public_addr */ 2: - message.publicAddr = reader.string(); + case /* teleport.lib.teleterm.v1.RouteToApp route_to_app */ 3: + message.routeToApp = RouteToApp.internalBinaryRead(reader, reader.uint32(), options, message.routeToApp); break; default: let u = options.readUnknownField; @@ -604,9 +604,9 @@ class VnetCertExpired$Type extends MessageType { /* string target_uri = 1; */ if (message.targetUri !== "") writer.tag(1, WireType.LengthDelimited).string(message.targetUri); - /* string public_addr = 2; */ - if (message.publicAddr !== "") - writer.tag(2, WireType.LengthDelimited).string(message.publicAddr); + /* teleport.lib.teleterm.v1.RouteToApp route_to_app = 3; */ + if (message.routeToApp) + RouteToApp.internalBinaryWrite(message.routeToApp, writer.tag(3, WireType.LengthDelimited).fork(), options).join(); let u = options.writeUnknownFields; if (u !== false) (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); @@ -771,14 +771,13 @@ class CannotProxyVnetConnection$Type extends MessageType RouteToApp } ]); } create(value?: PartialMessage): CannotProxyVnetConnection { const message = globalThis.Object.create((this.messagePrototype!)); message.targetUri = ""; message.error = ""; - message.publicAddr = ""; if (value !== undefined) reflectionMergePartial(this, message, value); return message; @@ -794,8 +793,8 @@ class CannotProxyVnetConnection$Type extends MessageType. + */ + +package maintenance + +import ( + "context" + + "github.com/gravitational/trace" + "sigs.k8s.io/controller-runtime/pkg/client" + + "github.com/gravitational/teleport/api/client/webclient" + "github.com/gravitational/teleport/lib/automaticupgrades/cache" + "github.com/gravitational/teleport/lib/automaticupgrades/constants" +) + +type proxyMaintenanceClient struct { + client *webclient.ReusableClient +} + +// Get does the HTTPS call to the Teleport Proxy sevrice to check if the update should happen now. +// If the proxy response does not contain the auto_update.agent_version field, +// this means the proxy does not support autoupdates. In this case we return trace.NotImplementedErr. +func (b *proxyMaintenanceClient) Get(ctx context.Context) (bool, error) { + resp, err := b.client.Find() + if err != nil { + return false, trace.Wrap(err) + } + // We check if a version is advertised to know if the proxy implements RFD-184 or not. + if resp.AutoUpdate.AgentVersion == "" { + return false, trace.NotImplemented("proxy does not seem to implement RFD-184") + } + return resp.AutoUpdate.AgentAutoUpdate, nil +} + +// ProxyMaintenanceTrigger checks if the maintenance should be triggered from the Teleport Proxy service /find endpoint, +// as specified in the RFD-184: https://github.com/gravitational/teleport/blob/master/rfd/0184-agent-auto-updates.md +// The Trigger returns trace.NotImplementedErr when running against a proxy that does not seem to +// expose automatic update instructions over the /find endpoint (proxy too old). +type ProxyMaintenanceTrigger struct { + name string + cachedGetter func(context.Context) (bool, error) +} + +// Name implements maintenance.Trigger returns the trigger name for logging +// and debugging purposes. +func (g ProxyMaintenanceTrigger) Name() string { + return g.name +} + +// Default implements maintenance.Trigger and returns what to do if the trigger can't be evaluated. +// ProxyMaintenanceTrigger should fail open, so the function returns true. +func (g ProxyMaintenanceTrigger) Default() bool { + return false +} + +// CanStart implements maintenance.Trigger. +func (g ProxyMaintenanceTrigger) CanStart(ctx context.Context, _ client.Object) (bool, error) { + result, err := g.cachedGetter(ctx) + return result, trace.Wrap(err) +} + +// NewProxyMaintenanceTrigger builds and return a Trigger checking a public HTTP endpoint. +func NewProxyMaintenanceTrigger(name string, clt *webclient.ReusableClient) Trigger { + maintenanceClient := &proxyMaintenanceClient{ + client: clt, + } + + return ProxyMaintenanceTrigger{name, cache.NewTimedMemoize[bool](maintenanceClient.Get, constants.CacheDuration).Get} +} diff --git a/lib/automaticupgrades/maintenance/trigger.go b/lib/automaticupgrades/maintenance/trigger.go index 53e12b26cdd4a..5d9449d7ad864 100644 --- a/lib/automaticupgrades/maintenance/trigger.go +++ b/lib/automaticupgrades/maintenance/trigger.go @@ -20,7 +20,9 @@ package maintenance import ( "context" + "strings" + "github.com/gravitational/trace" "sigs.k8s.io/controller-runtime/pkg/client" ctrllog "sigs.k8s.io/controller-runtime/pkg/log" ) @@ -51,7 +53,10 @@ func (t Triggers) CanStart(ctx context.Context, object client.Object) bool { start, err := trigger.CanStart(ctx, object) if err != nil { start = trigger.Default() - log.Error(err, "trigger failed to evaluate, using its default value", "trigger", trigger.Name(), "defaultValue", start) + log.Error( + err, "trigger failed to evaluate, using its default value", "trigger", trigger.Name(), "defaultValue", + start, + ) } else { log.Info("trigger evaluated", "trigger", trigger.Name(), "result", start) } @@ -62,3 +67,48 @@ func (t Triggers) CanStart(ctx context.Context, object client.Object) bool { } return false } + +// FailoverTrigger wraps multiple Triggers and tries them sequentially. +// Any error is considered fatal, except for the trace.NotImplementedErr +// which indicates the trigger is not supported yet and we should +// failover to the next trigger. +type FailoverTrigger []Trigger + +// Name implements Trigger +func (f FailoverTrigger) Name() string { + names := make([]string, len(f)) + for i, t := range f { + names[i] = t.Name() + } + + return strings.Join(names, ", failover ") +} + +// CanStart implements Trigger +// Triggers are evaluated sequentially, the result of the first trigger not returning +// trace.NotImplementedErr is used. +func (f FailoverTrigger) CanStart(ctx context.Context, object client.Object) (bool, error) { + for _, trigger := range f { + canStart, err := trigger.CanStart(ctx, object) + switch { + case err == nil: + return canStart, nil + case trace.IsNotImplemented(err): + continue + default: + return false, trace.Wrap(err) + } + } + return false, trace.NotFound("every trigger returned NotImplemented") +} + +// Default implements Trigger. +// The default is the logical OR of every Trigger.Default. +func (f FailoverTrigger) Default() bool { + for _, trigger := range f { + if trigger.Default() { + return true + } + } + return false +} diff --git a/lib/automaticupgrades/maintenance/trigger_test.go b/lib/automaticupgrades/maintenance/trigger_test.go new file mode 100644 index 0000000000000..435b73f0f9bc4 --- /dev/null +++ b/lib/automaticupgrades/maintenance/trigger_test.go @@ -0,0 +1,169 @@ +/* + * Teleport + * Copyright (C) 2024 Gravitational, Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package maintenance + +import ( + "context" + "testing" + + "github.com/gravitational/trace" + "github.com/stretchr/testify/require" +) + +// checkTraceError is a test helper that converts trace.IsXXXError into a require.ErrorAssertionFunc +func checkTraceError(check func(error) bool) require.ErrorAssertionFunc { + return func(t require.TestingT, err error, i ...interface{}) { + require.True(t, check(err), i...) + } +} + +func TestFailoverTrigger_CanStart(t *testing.T) { + t.Parallel() + + // Test setup + ctx := context.Background() + tests := []struct { + name string + triggers []Trigger + expectResult bool + expectErr require.ErrorAssertionFunc + }{ + { + name: "nil", + triggers: nil, + expectResult: false, + expectErr: checkTraceError(trace.IsNotFound), + }, + { + name: "empty", + triggers: []Trigger{}, + expectResult: false, + expectErr: checkTraceError(trace.IsNotFound), + }, + { + name: "first trigger success firing", + triggers: []Trigger{ + StaticTrigger{canStart: true}, + StaticTrigger{canStart: false}, + }, + expectResult: true, + expectErr: require.NoError, + }, + { + name: "first trigger success not firing", + triggers: []Trigger{ + StaticTrigger{canStart: false}, + StaticTrigger{canStart: true}, + }, + expectResult: false, + expectErr: require.NoError, + }, + { + name: "first trigger failure", + triggers: []Trigger{ + StaticTrigger{err: trace.LimitExceeded("got rate-limited")}, + StaticTrigger{canStart: true}, + }, + expectResult: false, + expectErr: checkTraceError(trace.IsLimitExceeded), + }, + { + name: "first trigger skipped, second getter success", + triggers: []Trigger{ + StaticTrigger{err: trace.NotImplemented("proxy does not seem to implement RFD-184")}, + StaticTrigger{canStart: true}, + }, + expectResult: true, + expectErr: require.NoError, + }, + { + name: "first trigger skipped, second getter failure", + triggers: []Trigger{ + StaticTrigger{err: trace.NotImplemented("proxy does not seem to implement RFD-184")}, + StaticTrigger{err: trace.LimitExceeded("got rate-limited")}, + }, + expectResult: false, + expectErr: checkTraceError(trace.IsLimitExceeded), + }, + { + name: "first trigger skipped, second getter skipped", + triggers: []Trigger{ + StaticTrigger{err: trace.NotImplemented("proxy does not seem to implement RFD-184")}, + StaticTrigger{err: trace.NotImplemented("proxy does not seem to implement RFD-184")}, + }, + expectResult: false, + expectErr: checkTraceError(trace.IsNotFound), + }, + } + for _, tt := range tests { + t.Run( + tt.name, func(t *testing.T) { + // Test execution + trigger := FailoverTrigger(tt.triggers) + result, err := trigger.CanStart(ctx, nil) + require.Equal(t, tt.expectResult, result) + tt.expectErr(t, err) + }, + ) + } +} + +func TestFailoverTrigger_Name(t *testing.T) { + tests := []struct { + name string + triggers []Trigger + expectResult string + }{ + { + name: "nil", + triggers: nil, + expectResult: "", + }, + { + name: "empty", + triggers: []Trigger{}, + expectResult: "", + }, + { + name: "one trigger", + triggers: []Trigger{ + StaticTrigger{name: "proxy"}, + }, + expectResult: "proxy", + }, + { + name: "two triggers", + triggers: []Trigger{ + StaticTrigger{name: "proxy"}, + StaticTrigger{name: "version-server"}, + }, + expectResult: "proxy, failover version-server", + }, + } + for _, tt := range tests { + t.Run( + tt.name, func(t *testing.T) { + // Test execution + trigger := FailoverTrigger(tt.triggers) + result := trigger.Name() + require.Equal(t, tt.expectResult, result) + }, + ) + } +} diff --git a/lib/automaticupgrades/version/proxy.go b/lib/automaticupgrades/version/proxy.go new file mode 100644 index 0000000000000..db55123dd529e --- /dev/null +++ b/lib/automaticupgrades/version/proxy.go @@ -0,0 +1,75 @@ +/* + * Teleport + * Copyright (C) 2023 Gravitational, Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package version + +import ( + "context" + + "github.com/gravitational/trace" + + "github.com/gravitational/teleport/api/client/webclient" + "github.com/gravitational/teleport/lib/automaticupgrades/cache" + "github.com/gravitational/teleport/lib/automaticupgrades/constants" +) + +type proxyVersionClient struct { + client *webclient.ReusableClient +} + +func (b *proxyVersionClient) Get(ctx context.Context) (string, error) { + resp, err := b.client.Find() + if err != nil { + return "", trace.Wrap(err) + } + // We check if a version is advertised to know if the proxy implements RFD-184 or not. + if resp.AutoUpdate.AgentVersion == "" { + return "", trace.NotImplemented("proxy does not seem to implement RFD-184") + } + return resp.AutoUpdate.AgentVersion, nil +} + +// ProxyVersionGetter gets the target version from the Teleport Proxy Service /find endpoint, as +// specified in the RFD-184: https://github.com/gravitational/teleport/blob/master/rfd/0184-agent-auto-updates.md +// The Getter returns trace.NotImplementedErr when running against a proxy that does not seem to +// expose automatic update instructions over the /find endpoint (proxy too old). +type ProxyVersionGetter struct { + name string + cachedGetter func(context.Context) (string, error) +} + +// Name implements Getter +func (g ProxyVersionGetter) Name() string { + return g.name +} + +// GetVersion implements Getter +func (g ProxyVersionGetter) GetVersion(ctx context.Context) (string, error) { + result, err := g.cachedGetter(ctx) + return result, trace.Wrap(err) +} + +// NewProxyVersionGetter creates a ProxyVersionGetter from a webclient. +// The answer is cached for a minute. +func NewProxyVersionGetter(name string, clt *webclient.ReusableClient) Getter { + versionClient := &proxyVersionClient{ + client: clt, + } + + return ProxyVersionGetter{name, cache.NewTimedMemoize[string](versionClient.Get, constants.CacheDuration).Get} +} diff --git a/lib/automaticupgrades/version/versionget.go b/lib/automaticupgrades/version/versionget.go index f1e7723a9a320..e2a1a893e5270 100644 --- a/lib/automaticupgrades/version/versionget.go +++ b/lib/automaticupgrades/version/versionget.go @@ -1,6 +1,6 @@ /* * Teleport - * Copyright (C) 2023 Gravitational, Inc. + * Copyright (C) 2024 Gravitational, Inc. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by @@ -36,13 +36,42 @@ type Getter interface { GetVersion(context.Context) (string, error) } +// FailoverGetter wraps multiple Getters and tries them sequentially. +// Any error is considered fatal, except for the trace.NotImplementedErr +// which indicates the version getter is not supported yet and we should +// failover to the next version getter. +type FailoverGetter []Getter + +// GetVersion implements Getter +// Getters are evaluated sequentially, the result of the first getter not returning +// trace.NotImplementedErr is used. +func (f FailoverGetter) GetVersion(ctx context.Context) (string, error) { + for _, getter := range f { + version, err := getter.GetVersion(ctx) + switch { + case err == nil: + return version, nil + case trace.IsNotImplemented(err): + continue + default: + return "", trace.Wrap(err) + } + } + return "", trace.NotFound("every versionGetter returned NotImplemented") +} + // ValidVersionChange receives the current version and the candidate next version // and evaluates if the version transition is valid. func ValidVersionChange(ctx context.Context, current, next string) bool { log := ctrllog.FromContext(ctx).V(1) // Cannot upgrade to a non-valid version if !semver.IsValid(next) { - log.Error(trace.BadParameter("next version is not following semver"), "version change is invalid", "nextVersion", next) + log.Error( + trace.BadParameter("next version is not following semver"), + "version change is invalid", + "current_version", current, + "next_version", next, + ) return false } switch semver.Compare(next, current) { diff --git a/lib/automaticupgrades/version/versionget_test.go b/lib/automaticupgrades/version/versionget_test.go index 80c2ec767b8fb..78f4940db229a 100644 --- a/lib/automaticupgrades/version/versionget_test.go +++ b/lib/automaticupgrades/version/versionget_test.go @@ -22,6 +22,7 @@ import ( "context" "testing" + "github.com/gravitational/trace" "github.com/stretchr/testify/require" ) @@ -66,8 +67,99 @@ func TestValidVersionChange(t *testing.T) { }, } for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - require.Equal(t, tt.want, ValidVersionChange(ctx, tt.current, tt.next)) - }) + t.Run( + tt.name, func(t *testing.T) { + require.Equal(t, tt.want, ValidVersionChange(ctx, tt.current, tt.next)) + }, + ) + } +} + +// checkTraceError is a test helper that converts trace.IsXXXError into a require.ErrorAssertionFunc +func checkTraceError(check func(error) bool) require.ErrorAssertionFunc { + return func(t require.TestingT, err error, i ...interface{}) { + require.True(t, check(err), i...) + } +} + +func TestFailoverGetter_GetVersion(t *testing.T) { + t.Parallel() + + // Test setup + ctx := context.Background() + tests := []struct { + name string + getters []Getter + expectResult string + expectErr require.ErrorAssertionFunc + }{ + { + name: "nil", + getters: nil, + expectResult: "", + expectErr: checkTraceError(trace.IsNotFound), + }, + { + name: "empty", + getters: []Getter{}, + expectResult: "", + expectErr: checkTraceError(trace.IsNotFound), + }, + { + name: "first getter success", + getters: []Getter{ + StaticGetter{version: semverMid}, + StaticGetter{version: semverHigh}, + }, + expectResult: semverMid, + expectErr: require.NoError, + }, + { + name: "first getter failure", + getters: []Getter{ + StaticGetter{err: trace.LimitExceeded("got rate-limited")}, + StaticGetter{version: semverHigh}, + }, + expectResult: "", + expectErr: checkTraceError(trace.IsLimitExceeded), + }, + { + name: "first getter skipped, second getter success", + getters: []Getter{ + StaticGetter{err: trace.NotImplemented("proxy does not seem to implement RFD-184")}, + StaticGetter{version: semverHigh}, + }, + expectResult: semverHigh, + expectErr: require.NoError, + }, + { + name: "first getter skipped, second getter failure", + getters: []Getter{ + StaticGetter{err: trace.NotImplemented("proxy does not seem to implement RFD-184")}, + StaticGetter{err: trace.LimitExceeded("got rate-limited")}, + }, + expectResult: "", + expectErr: checkTraceError(trace.IsLimitExceeded), + }, + { + name: "first getter skipped, second getter skipped", + getters: []Getter{ + StaticGetter{err: trace.NotImplemented("proxy does not seem to implement RFD-184")}, + StaticGetter{err: trace.NotImplemented("proxy does not seem to implement RFD-184")}, + }, + expectResult: "", + expectErr: checkTraceError(trace.IsNotFound), + }, + } + for _, tt := range tests { + t.Run( + tt.name, func(t *testing.T) { + // Test execution + getter := FailoverGetter(tt.getters) + result, err := getter.GetVersion(ctx) + require.Equal(t, tt.expectResult, result) + tt.expectErr(t, err) + }, + ) } } diff --git a/lib/autoupdate/agent/installer.go b/lib/autoupdate/agent/installer.go index 6de16e17cb4c6..f62da824c7c5b 100644 --- a/lib/autoupdate/agent/installer.go +++ b/lib/autoupdate/agent/installer.go @@ -86,6 +86,9 @@ type LocalInstaller struct { ReservedFreeInstallDisk uint64 // TransformService transforms the systemd service during copying. TransformService func([]byte) []byte + // ValidateBinary returns true if a file is a linkable binary, or + // false if a file should not be linked. + ValidateBinary func(ctx context.Context, path string) (bool, error) } // Remove a Teleport version directory from InstallDir. @@ -307,6 +310,7 @@ func (li *LocalInstaller) download(ctx context.Context, w io.Writer, max int64, if err != nil { return nil, trace.Wrap(err) } + startTime := time.Now() resp, err := li.HTTP.Do(req) if err != nil { return nil, trace.Wrap(err) @@ -330,13 +334,23 @@ func (li *LocalInstaller) download(ctx context.Context, w io.Writer, max int64, } // Calculate checksum concurrently with download. shaReader := sha256.New() - n, err := io.CopyN(w, io.TeeReader(resp.Body, shaReader), size) + tee := io.TeeReader(resp.Body, shaReader) + tee = io.TeeReader(tee, &progressLogger{ + ctx: ctx, + log: li.Log, + level: slog.LevelInfo, + name: path.Base(resp.Request.URL.Path), + max: int(resp.ContentLength), + lines: 5, + }) + n, err := io.CopyN(w, tee, size) if err != nil { return nil, trace.Wrap(err) } if resp.ContentLength >= 0 && n != resp.ContentLength { return nil, trace.Errorf("mismatch in Teleport download size") } + li.Log.InfoContext(ctx, "Download complete.", "duration", time.Since(startTime), "size", n) return shaReader.Sum(nil), nil } @@ -564,9 +578,16 @@ func (li *LocalInstaller) forceLinks(ctx context.Context, binDir, svcPath string } oldname := filepath.Join(binDir, entry.Name()) newname := filepath.Join(li.LinkBinDir, entry.Name()) + exec, err := li.ValidateBinary(ctx, oldname) + if err != nil { + return revert, trace.Wrap(err) + } + if !exec { + continue + } orig, err := forceLink(oldname, newname) if err != nil && !errors.Is(err, os.ErrExist) { - return revert, trace.Wrap(err, "failed to create symlink for %s", filepath.Base(oldname)) + return revert, trace.Wrap(err, "failed to create symlink for %s", entry.Name()) } if orig != "" { revertLinks = append(revertLinks, symlink{ @@ -596,7 +617,7 @@ func (li *LocalInstaller) forceLinks(ctx context.Context, binDir, svcPath string // The contents of both src and dst must be smaller than n. // See forceCopy for more details. func (li *LocalInstaller) forceCopyService(dst, src string, n int64) (orig *smallFile, err error) { - srcData, err := readFileN(src, n) + srcData, err := readFileAtMost(src, n) if err != nil { return nil, trace.Wrap(err) } @@ -607,13 +628,6 @@ func (li *LocalInstaller) forceCopyService(dst, src string, n int64) (orig *smal // If a non-symlink file or directory exists in newname already, forceLink errors. // If the link is already present with the desired oldname, forceLink returns os.ErrExist. func forceLink(oldname, newname string) (orig string, err error) { - exec, err := isExecutable(oldname) - if err != nil { - return "", trace.Wrap(err) - } - if !exec { - return "", trace.Errorf("%s is not a regular executable file", oldname) - } orig, err = os.Readlink(newname) if errors.Is(err, os.ErrInvalid) || errors.Is(err, syscall.EINVAL) { // workaround missing ErrInvalid wrapper @@ -633,17 +647,6 @@ func forceLink(oldname, newname string) (orig string, err error) { return orig, nil } -// isExecutable returns true for regular files that are executable by all users (0111). -func isExecutable(path string) (bool, error) { - fi, err := os.Lstat(path) - if err != nil { - return false, trace.Wrap(err) - } - // TODO(sclevine): verify path is valid binary - return fi.Mode().IsRegular() && - fi.Mode()&0111 == 0111, nil -} - // forceCopy atomically copies a file from srcData to dst, replacing an existing file at dst if needed. // The contents of dst must be smaller than n. // forceCopy returns the original file path, mode, and contents as orig. @@ -662,7 +665,7 @@ func forceCopy(dst string, srcData []byte, n int64) (orig *smallFile, err error) if !orig.mode.IsRegular() { return nil, trace.Errorf("refusing to replace irregular file at %s", dst) } - orig.data, err = readFileN(dst, n) + orig.data, err = readFileAtMost(dst, n) if err != nil { return nil, trace.Wrap(err) } @@ -677,8 +680,8 @@ func forceCopy(dst string, srcData []byte, n int64) (orig *smallFile, err error) return orig, nil } -// readFileN reads a file up to n, or errors if it is too large. -func readFileN(name string, n int64) ([]byte, error) { +// readFileAtMost reads a file up to n, or errors if it is too large. +func readFileAtMost(name string, n int64) ([]byte, error) { f, err := os.Open(name) if err != nil { return nil, err @@ -727,11 +730,11 @@ func (li *LocalInstaller) removeLinks(ctx context.Context, binDir, svcPath strin li.Log.DebugContext(ctx, "Teleport binary not unlinked. Skipping removal of teleport.service.") return nil } - srcBytes, err := readFileN(svcPath, maxServiceFileSize) + srcBytes, err := readFileAtMost(svcPath, maxServiceFileSize) if err != nil { return trace.Wrap(err) } - dstBytes, err := readFileN(li.CopyServiceFile, maxServiceFileSize) + dstBytes, err := readFileAtMost(li.CopyServiceFile, maxServiceFileSize) if errors.Is(err, os.ErrNotExist) { li.Log.DebugContext(ctx, "Service not present.", "path", li.CopyServiceFile) return nil @@ -778,6 +781,13 @@ func (li *LocalInstaller) tryLinks(ctx context.Context, binDir, svcPath string) } oldname := filepath.Join(binDir, entry.Name()) newname := filepath.Join(li.LinkBinDir, entry.Name()) + exec, err := li.ValidateBinary(ctx, oldname) + if err != nil { + return trace.Wrap(err) + } + if !exec { + continue + } ok, err := needsLink(oldname, newname) if err != nil { return trace.Wrap(err, "error evaluating link for %s", filepath.Base(oldname)) @@ -812,13 +822,6 @@ func (li *LocalInstaller) tryLinks(ctx context.Context, binDir, svcPath string) // If a non-symlink file or directory exists at newname, needsLink errors. // If a symlink to a different location exists, needsLink errors with ErrLinked. func needsLink(oldname, newname string) (ok bool, err error) { - exec, err := isExecutable(oldname) - if err != nil { - return false, trace.Wrap(err) - } - if !exec { - return false, trace.Errorf("%s is not a regular executable file", oldname) - } orig, err := os.Readlink(newname) if errors.Is(err, os.ErrInvalid) || errors.Is(err, syscall.EINVAL) { // workaround missing ErrInvalid wrapper diff --git a/lib/autoupdate/agent/installer_test.go b/lib/autoupdate/agent/installer_test.go index 576e2ddacc9af..01dad06750cc6 100644 --- a/lib/autoupdate/agent/installer_test.go +++ b/lib/autoupdate/agent/installer_test.go @@ -255,7 +255,7 @@ func TestLocalInstaller_Link(t *testing.T) { }, installFileMode: 0644, - errMatch: "executable", + errMatch: "no binaries", }, { name: "present with existing links", @@ -396,6 +396,7 @@ func TestLocalInstaller_Link(t *testing.T) { require.NoError(t, err) } + validator := Validator{Log: slog.Default()} installer := &LocalInstaller{ InstallDir: versionsDir, LinkBinDir: filepath.Join(linkDir, "bin"), @@ -404,6 +405,7 @@ func TestLocalInstaller_Link(t *testing.T) { TransformService: func(b []byte) []byte { return []byte("[transform]" + string(b)) }, + ValidateBinary: validator.IsExecutable, } ctx := context.Background() revert, err := installer.Link(ctx, NewRevision(version, 0)) @@ -523,7 +525,7 @@ func TestLocalInstaller_TryLink(t *testing.T) { }, installFileMode: 0644, - errMatch: "executable", + errMatch: "no binaries", }, { name: "present with existing links", @@ -649,6 +651,7 @@ func TestLocalInstaller_TryLink(t *testing.T) { require.NoError(t, err) } + validator := Validator{Log: slog.Default()} installer := &LocalInstaller{ InstallDir: versionsDir, LinkBinDir: filepath.Join(linkDir, "bin"), @@ -657,6 +660,7 @@ func TestLocalInstaller_TryLink(t *testing.T) { TransformService: func(b []byte) []byte { return []byte("[transform]" + string(b)) }, + ValidateBinary: validator.IsExecutable, } ctx := context.Background() err = installer.TryLink(ctx, NewRevision(version, 0)) @@ -797,6 +801,7 @@ func TestLocalInstaller_Remove(t *testing.T) { linkDir := t.TempDir() + validator := Validator{Log: slog.Default()} installer := &LocalInstaller{ InstallDir: versionsDir, LinkBinDir: filepath.Join(linkDir, "bin"), @@ -805,6 +810,7 @@ func TestLocalInstaller_Remove(t *testing.T) { TransformService: func(b []byte) []byte { return []byte("[transform]" + string(b)) }, + ValidateBinary: validator.IsExecutable, } ctx := context.Background() diff --git a/lib/autoupdate/agent/logger.go b/lib/autoupdate/agent/logger.go new file mode 100644 index 0000000000000..bd50ee50859a4 --- /dev/null +++ b/lib/autoupdate/agent/logger.go @@ -0,0 +1,108 @@ +/* + * Teleport + * Copyright (C) 2024 Gravitational, Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package agent + +import ( + "bytes" + "context" + "fmt" + "log/slog" + + "github.com/gravitational/trace" +) + +// progressLogger logs progress of any data written as it approaches max. +// max(lines, call_count(Write)) lines are written for each multiple of max. +// progressLogger uses the variability of chunk size as a proxy for speed, and avoids +// logging extraneous lines that do not improve UX for waiting humans. +type progressLogger struct { + ctx context.Context + log *slog.Logger + level slog.Level + name string + max int + lines int + + l int + n int +} + +func (w *progressLogger) Write(p []byte) (n int, err error) { + w.n += len(p) + if w.n >= w.max*(w.l+1)/w.lines { + w.log.Log(w.ctx, w.level, "Downloading", + "file", w.name, + "progress", fmt.Sprintf("%d%%", w.n*100/w.max), + ) + w.l++ + } + return len(p), nil +} + +// lineLogger logs each line written to it. +type lineLogger struct { + ctx context.Context + log *slog.Logger + level slog.Level + prefix string + + last bytes.Buffer +} + +func (w *lineLogger) out(s string) { + w.log.Log(w.ctx, w.level, w.prefix+s) //nolint:sloglint // msg cannot be constant +} + +func (w *lineLogger) Write(p []byte) (n int, err error) { + lines := bytes.Split(p, []byte("\n")) + // Finish writing line + if len(lines) > 0 { + n, err = w.last.Write(lines[0]) + lines = lines[1:] + } + // Quit if no newline + if len(lines) == 0 || err != nil { + return n, trace.Wrap(err) + } + + // Newline found, log line + w.out(w.last.String()) + n += 1 + w.last.Reset() + + // Log lines that are already newline-terminated + for _, line := range lines[:len(lines)-1] { + w.out(string(line)) + n += len(line) + 1 + } + + // Store remaining line non-newline-terminated line. + n2, err := w.last.Write(lines[len(lines)-1]) + n += n2 + return n, trace.Wrap(err) +} + +// Flush logs any trailing bytes that were never terminated with a newline. +func (w *lineLogger) Flush() { + if w.last.Len() == 0 { + return + } + w.out(w.last.String()) + w.last.Reset() +} diff --git a/lib/autoupdate/agent/logger_test.go b/lib/autoupdate/agent/logger_test.go new file mode 100644 index 0000000000000..2a8430ef8cf44 --- /dev/null +++ b/lib/autoupdate/agent/logger_test.go @@ -0,0 +1,186 @@ +/* + * Teleport + * Copyright (C) 2024 Gravitational, Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package agent + +import ( + "bytes" + "context" + "fmt" + "io" + "log/slog" + "testing" + + "github.com/stretchr/testify/require" +) + +func TestLineLogger(t *testing.T) { + t.Parallel() + + out := &bytes.Buffer{} + ll := lineLogger{ + ctx: context.Background(), + log: slog.New(slog.NewTextHandler(out, + &slog.HandlerOptions{ReplaceAttr: msgOnly}, + )), + } + + for _, e := range []struct { + v string + n int + }{ + {v: "", n: 0}, + {v: "a", n: 1}, + {v: "b\n", n: 2}, + {v: "c\nd", n: 3}, + {v: "e\nf\ng", n: 5}, + {v: "h", n: 1}, + {v: "", n: 0}, + {v: "\n", n: 1}, + {v: "i\n", n: 2}, + {v: "j", n: 1}, + } { + n, err := ll.Write([]byte(e.v)) + require.NoError(t, err) + require.Equal(t, e.n, n) + } + require.Equal(t, "msg=ab\nmsg=c\nmsg=de\nmsg=f\nmsg=gh\nmsg=i\n", out.String()) + ll.Flush() + require.Equal(t, "msg=ab\nmsg=c\nmsg=de\nmsg=f\nmsg=gh\nmsg=i\nmsg=j\n", out.String()) +} + +func msgOnly(_ []string, a slog.Attr) slog.Attr { + switch a.Key { + case "time", "level": + return slog.Attr{} + } + return slog.Attr{Key: a.Key, Value: a.Value} +} + +func TestProgressLogger(t *testing.T) { + t.Parallel() + + type write struct { + n int + out string + } + for _, tt := range []struct { + name string + max, lines int + writes []write + }{ + { + name: "even", + max: 100, + lines: 5, + writes: []write{ + {n: 10}, + {n: 10, out: "20%"}, + {n: 10}, + {n: 10, out: "40%"}, + {n: 10}, + {n: 10, out: "60%"}, + {n: 10}, + {n: 10, out: "80%"}, + {n: 10}, + {n: 10, out: "100%"}, + {n: 10}, + {n: 10, out: "120%"}, + }, + }, + { + name: "fast", + max: 100, + lines: 5, + writes: []write{ + {n: 100, out: "100%"}, + {n: 100, out: "200%"}, + }, + }, + { + name: "over fast", + max: 100, + lines: 5, + writes: []write{ + {n: 200, out: "200%"}, + }, + }, + { + name: "slow down when uneven", + max: 100, + lines: 5, + writes: []write{ + {n: 50, out: "50%"}, + {n: 10, out: "60%"}, + {n: 10, out: "70%"}, + {n: 10, out: "80%"}, + {n: 10}, + {n: 10, out: "100%"}, + {n: 10}, + {n: 10, out: "120%"}, + }, + }, + { + name: "slow down when very uneven", + max: 100, + lines: 5, + writes: []write{ + {n: 50, out: "50%"}, + {n: 1, out: "51%"}, + {n: 1}, + {n: 20, out: "72%"}, + {n: 10, out: "82%"}, + {n: 10}, + {n: 10, out: "102%"}, + }, + }, + { + name: "close", + max: 1000, + lines: 5, + writes: []write{ + {n: 999, out: "99%"}, + {n: 1, out: "100%"}, + }, + }, + } { + t.Run(tt.name, func(t *testing.T) { + out := &bytes.Buffer{} + ll := progressLogger{ + ctx: context.Background(), + log: slog.New(slog.NewTextHandler(out, + &slog.HandlerOptions{ReplaceAttr: msgOnly}, + )), + name: "test", + max: tt.max, + lines: tt.lines, + } + for _, e := range tt.writes { + n, err := ll.Write(make([]byte, e.n)) + require.NoError(t, err) + require.Equal(t, e.n, n) + v, err := io.ReadAll(out) + require.NoError(t, err) + if len(v) > 0 { + e.out = fmt.Sprintf(`msg=Downloading file=test progress=%s`+"\n", e.out) + } + require.Equal(t, e.out, string(v)) + } + }) + } +} diff --git a/lib/autoupdate/agent/process.go b/lib/autoupdate/agent/process.go index d2b2b081ad7fe..6a13d2e0687bf 100644 --- a/lib/autoupdate/agent/process.go +++ b/lib/autoupdate/agent/process.go @@ -210,7 +210,7 @@ func (s SystemdService) waitForStablePID(ctx context.Context, minStable, maxCras // readInt reads an integer from a file. func readInt(path string) (int, error) { - p, err := readFileN(path, 32) + p, err := readFileAtMost(path, 32) if err != nil { return 0, trace.Wrap(err) } @@ -368,64 +368,5 @@ func (c *localExec) Run(ctx context.Context, name string, args ...string) (int, stderr.Flush() stdout.Flush() code := cmd.ProcessState.ExitCode() - - // Treat out-of-range exit code (255) as an error executing the command. - // This allows callers to treat codes that are more likely OS-related as execution errors - // instead of intentionally returned error codes. - if code == 255 { - code = -1 - } return code, trace.Wrap(err) } - -// lineLogger logs each line written to it. -type lineLogger struct { - ctx context.Context - log *slog.Logger - level slog.Level - prefix string - - last bytes.Buffer -} - -func (w *lineLogger) out(s string) { - w.log.Log(w.ctx, w.level, w.prefix+s) //nolint:sloglint // msg cannot be constant -} - -func (w *lineLogger) Write(p []byte) (n int, err error) { - lines := bytes.Split(p, []byte("\n")) - // Finish writing line - if len(lines) > 0 { - n, err = w.last.Write(lines[0]) - lines = lines[1:] - } - // Quit if no newline - if len(lines) == 0 || err != nil { - return n, trace.Wrap(err) - } - - // Newline found, log line - w.out(w.last.String()) - n += 1 - w.last.Reset() - - // Log lines that are already newline-terminated - for _, line := range lines[:len(lines)-1] { - w.out(string(line)) - n += len(line) + 1 - } - - // Store remaining line non-newline-terminated line. - n2, err := w.last.Write(lines[len(lines)-1]) - n += n2 - return n, trace.Wrap(err) -} - -// Flush logs any trailing bytes that were never terminated with a newline. -func (w *lineLogger) Flush() { - if w.last.Len() == 0 { - return - } - w.out(w.last.String()) - w.last.Reset() -} diff --git a/lib/autoupdate/agent/process_test.go b/lib/autoupdate/agent/process_test.go index c558a7539831a..e3d3d00ff085b 100644 --- a/lib/autoupdate/agent/process_test.go +++ b/lib/autoupdate/agent/process_test.go @@ -19,7 +19,6 @@ package agent import ( - "bytes" "context" "errors" "fmt" @@ -32,49 +31,6 @@ import ( "github.com/stretchr/testify/require" ) -func TestLineLogger(t *testing.T) { - t.Parallel() - - out := &bytes.Buffer{} - ll := lineLogger{ - ctx: context.Background(), - log: slog.New(slog.NewTextHandler(out, - &slog.HandlerOptions{ReplaceAttr: msgOnly}, - )), - } - - for _, e := range []struct { - v string - n int - }{ - {v: "", n: 0}, - {v: "a", n: 1}, - {v: "b\n", n: 2}, - {v: "c\nd", n: 3}, - {v: "e\nf\ng", n: 5}, - {v: "h", n: 1}, - {v: "", n: 0}, - {v: "\n", n: 1}, - {v: "i\n", n: 2}, - {v: "j", n: 1}, - } { - n, err := ll.Write([]byte(e.v)) - require.NoError(t, err) - require.Equal(t, e.n, n) - } - require.Equal(t, "msg=ab\nmsg=c\nmsg=de\nmsg=f\nmsg=gh\nmsg=i\n", out.String()) - ll.Flush() - require.Equal(t, "msg=ab\nmsg=c\nmsg=de\nmsg=f\nmsg=gh\nmsg=i\nmsg=j\n", out.String()) -} - -func msgOnly(_ []string, a slog.Attr) slog.Attr { - switch a.Key { - case "time", "level": - return slog.Attr{} - } - return slog.Attr{Key: a.Key, Value: a.Value} -} - func TestWaitForStablePID(t *testing.T) { t.Parallel() diff --git a/lib/autoupdate/agent/testdata/TestUpdater_Update/updates_enabled_now.golden b/lib/autoupdate/agent/testdata/TestUpdater_Update/updates_enabled_now.golden new file mode 100644 index 0000000000000..66e2695c2fd3a --- /dev/null +++ b/lib/autoupdate/agent/testdata/TestUpdater_Update/updates_enabled_now.golden @@ -0,0 +1,13 @@ +version: v1 +kind: update_config +spec: + proxy: localhost + group: group + url_template: https://example.com + enabled: true + pinned: false +status: + active: + version: 16.3.0 + backup: + version: old-version diff --git a/lib/autoupdate/agent/updater.go b/lib/autoupdate/agent/updater.go index f9053da822511..cc95048b11b50 100644 --- a/lib/autoupdate/agent/updater.go +++ b/lib/autoupdate/agent/updater.go @@ -94,6 +94,7 @@ func NewLocalUpdater(cfg LocalUpdaterConfig, ns *Namespace) (*Updater, error) { if cfg.SystemDir == "" { cfg.SystemDir = defaultSystemDir } + validator := Validator{Log: cfg.Log} return &Updater{ Log: cfg.Log, Pool: certPool, @@ -110,6 +111,7 @@ func NewLocalUpdater(cfg LocalUpdaterConfig, ns *Namespace) (*Updater, error) { ReservedFreeTmpDisk: reservedFreeDisk, ReservedFreeInstallDisk: reservedFreeDisk, TransformService: ns.replaceTeleportService, + ValidateBinary: validator.IsBinary, }, Process: &SystemdService{ ServiceName: filepath.Base(ns.serviceFile), @@ -501,7 +503,7 @@ func (u *Updater) Unpin(ctx context.Context) error { // Otherwise, the auto-updates configuration is not changed. // Unlike Enable, Update will not validate or repair the current version. // This function is idempotent. -func (u *Updater) Update(ctx context.Context) error { +func (u *Updater) Update(ctx context.Context, now bool) error { // Read configuration from update.yaml and override any new values passed as flags. cfg, err := readConfig(u.ConfigPath) if err != nil { @@ -536,7 +538,7 @@ func (u *Updater) Update(ctx context.Context) error { // If a version fails and is marked skip, we ignore any edition changes as well. // If a cluster is broadcasting a version that failed to start, changing ent/fips is unlikely to fix the issue. - if !resp.InWindow { + if !resp.InWindow && !now { switch { case target.Version == "": u.Log.WarnContext(ctx, "Cannot determine target agent version. Waiting for both version and update window.") @@ -552,18 +554,26 @@ func (u *Updater) Update(ctx context.Context) error { switch { case target.Version == "": - u.Log.ErrorContext(ctx, "Update window is active, but target version is not available.", activeKey, active) + if resp.InWindow { + u.Log.ErrorContext(ctx, "Update window is active, but target version is not available.", activeKey, active) + } return trace.Errorf("target version missing") case target == active: - u.Log.InfoContext(ctx, "Teleport is up-to-date. Update window is active, but no action is needed.", activeKey, active) + if resp.InWindow { + u.Log.InfoContext(ctx, "Teleport is up-to-date. Update window is active, but no action is needed.", activeKey, active) + } else { + u.Log.InfoContext(ctx, "Teleport is up-to-date. No action is needed.", activeKey, active) + } return nil case target.Version == skip.Version: - u.Log.InfoContext(ctx, "Update available, but the new version is marked as broken. Skipping update during the update window.", targetKey, target, activeKey, active) + u.Log.InfoContext(ctx, "Update available, but the new version is marked as broken. Skipping update.", targetKey, target, activeKey, active) return nil default: u.Log.InfoContext(ctx, "Update available. Initiating update.", targetKey, target, activeKey, active) } - time.Sleep(resp.Jitter) + if !now { + time.Sleep(resp.Jitter) + } updateErr := u.update(ctx, cfg, target) writeErr := writeConfig(u.ConfigPath, cfg) diff --git a/lib/autoupdate/agent/updater_test.go b/lib/autoupdate/agent/updater_test.go index db6ffdd930c64..c52117ea44985 100644 --- a/lib/autoupdate/agent/updater_test.go +++ b/lib/autoupdate/agent/updater_test.go @@ -223,6 +223,7 @@ func TestUpdater_Update(t *testing.T) { cfg *UpdateConfig // nil -> file not present flags InstallFlags inWindow bool + now bool installErr error setupErr error reloadErr error @@ -261,6 +262,30 @@ func TestUpdater_Update(t *testing.T) { reloadCalls: 1, setupCalls: 1, }, + { + name: "updates enabled now", + cfg: &UpdateConfig{ + Version: updateConfigVersion, + Kind: updateConfigKind, + Spec: UpdateSpec{ + Group: "group", + URLTemplate: "https://example.com", + Enabled: true, + }, + Status: UpdateStatus{ + Active: NewRevision("old-version", 0), + }, + }, + now: true, + + removedRevisions: []Revision{NewRevision("unknown-version", 0)}, + installedRevision: NewRevision("16.3.0", 0), + installedTemplate: "https://example.com", + linkedRevision: NewRevision("16.3.0", 0), + requestGroup: "group", + reloadCalls: 1, + setupCalls: 1, + }, { name: "updates disabled during window", cfg: &UpdateConfig{ @@ -627,7 +652,7 @@ func TestUpdater_Update(t *testing.T) { } ctx := context.Background() - err = updater.Update(ctx) + err = updater.Update(ctx, tt.now) if tt.errMatch != "" { require.Error(t, err) assert.Contains(t, err.Error(), tt.errMatch) diff --git a/lib/autoupdate/agent/validate.go b/lib/autoupdate/agent/validate.go new file mode 100644 index 0000000000000..8ce1732d3d5d1 --- /dev/null +++ b/lib/autoupdate/agent/validate.go @@ -0,0 +1,130 @@ +/* + * Teleport + * Copyright (C) 2024 Gravitational, Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package agent + +import ( + "bytes" + "context" + "io" + "log/slog" + "os" + "path/filepath" + "unicode" + + "github.com/gravitational/trace" +) + +const ( + // fileHeaderSniffBytes is the max size to read to determine a file's MIME type + fileHeaderSniffBytes = 512 // MIME standard size + // execModeMask is the minimum required set of bits to consider a file executable. + execModeMask = 0111 +) + +// Validator validates filesystem paths. +type Validator struct { + Log *slog.Logger +} + +// IsBinary returns true for working binaries that are executable by all users. +// If the file is irregular, non-executable, or a shell script, IsBinary returns false and logs a warning. +// IsBinary errors if lstat fails, a regular file is unreadable, or an executable file does not execute. +func (v *Validator) IsBinary(ctx context.Context, path string) (bool, error) { + // The behavior of this method is intended to protect against executable files + // being adding to the Teleport tgz that should not be made available on PATH, + // and additionally, should not cause installation to fail. + // While known copies of these files (e.g., "install") are excluded during extraction, + // it is safer to assume others could be present in past or future tgzs. + + if exec, err := v.IsExecutable(ctx, path); err != nil || !exec { + return exec, trace.Wrap(err) + } + name := filepath.Base(path) + d, err := readFileLimit(path, fileHeaderSniffBytes) + if err != nil { + return false, trace.Wrap(err) + } + // Refuse to test or link shell scripts + if isTextScript(d) { + v.Log.WarnContext(ctx, "Found unexpected shell script", "name", name) + return false, nil + } + v.Log.InfoContext(ctx, "Validating binary", "name", name) + r := localExec{ + Log: v.Log, + ErrLevel: slog.LevelDebug, + OutLevel: slog.LevelInfo, // always show version + } + code, err := r.Run(ctx, path, "version") + if code < 0 { + return false, trace.Wrap(err, "error validating binary %s", name) + } + if code > 0 { + v.Log.InfoContext(ctx, "Binary does not support version command", "name", name) + } + return true, nil +} + +// IsExecutable returns true for regular, executable files. +func (v *Validator) IsExecutable(ctx context.Context, path string) (bool, error) { + name := filepath.Base(path) + fi, err := os.Lstat(path) + if err != nil { + return false, trace.Wrap(err) + } + if !fi.Mode().IsRegular() { + v.Log.WarnContext(ctx, "Found unexpected irregular file", "name", name) + return false, nil + } + if fi.Mode()&execModeMask != execModeMask { + v.Log.WarnContext(ctx, "Found unexpected non-executable file", "name", name) + return false, nil + } + return true, nil +} + +func isTextScript(data []byte) bool { + data = bytes.TrimLeftFunc(data, unicode.IsSpace) + if !bytes.HasPrefix(data, []byte("#!")) { + return false + } + // Assume presence of MIME binary data bytes means binary: + // https://mimesniff.spec.whatwg.org/#terminology + for _, b := range data { + switch { + case b <= 0x08, b == 0x0B, + 0x0E <= b && b <= 0x1A, + 0x1C <= b && b <= 0x1F: + return false + } + } + return true +} + +// readFileLimit the first n bytes of a file. +func readFileLimit(name string, n int64) ([]byte, error) { + f, err := os.Open(name) + if err != nil { + return nil, err + } + defer f.Close() + var buf bytes.Buffer + _, err = io.Copy(&buf, io.LimitReader(f, n)) + return buf.Bytes(), trace.Wrap(err) +} diff --git a/lib/autoupdate/agent/validate_test.go b/lib/autoupdate/agent/validate_test.go new file mode 100644 index 0000000000000..71b979016f8fc --- /dev/null +++ b/lib/autoupdate/agent/validate_test.go @@ -0,0 +1,102 @@ +/* + * Teleport + * Copyright (C) 2024 Gravitational, Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package agent + +import ( + "bytes" + "context" + "log/slog" + "os" + "path/filepath" + "testing" + + "github.com/stretchr/testify/require" +) + +func TestValidator_IsBinary(t *testing.T) { + for _, tt := range []struct { + name string + mode os.FileMode + contents string + + valid bool + errMatch string + logMatch string + }{ + { + name: "missing", + errMatch: "no such", + }, + { + name: "non-executable", + contents: "test", + mode: 0666, + logMatch: "non-executable", + }, + { + name: "shell script", + contents: " #!bash ", + mode: 0777, + logMatch: "unexpected shell", + }, + { + name: "unqualified shell script", + contents: " #!bash" + string([]byte{0x0B}), + mode: 0777, + errMatch: "validating binary", + }, + { + name: "exit 0", + contents: "#!/bin/sh\nexit 0\n" + string([]byte{0x0B}), + mode: 0777, + valid: true, + }, + { + name: "exit 1", + contents: "#!/bin/sh\nexit 1\n" + string([]byte{0x0B}), + mode: 0777, + valid: true, + logMatch: "version command", + }, + } { + t.Run(tt.name, func(t *testing.T) { + var buf bytes.Buffer + opts := &slog.HandlerOptions{AddSource: true} + log := slog.New(slog.NewTextHandler(&buf, opts)) + v := Validator{Log: log} + ctx := context.Background() + path := filepath.Join(t.TempDir(), "file") + if tt.contents != "" { + os.WriteFile(path, []byte(tt.contents), tt.mode) + } + val, err := v.IsBinary(ctx, path) + if tt.logMatch != "" { + require.Contains(t, buf.String(), tt.logMatch) + } + if tt.errMatch != "" { + require.Error(t, err) + require.False(t, val) + require.Contains(t, err.Error(), tt.errMatch) + return + } + require.Equal(t, tt.valid, val) + require.NoError(t, err) + }) + } +} diff --git a/lib/autoupdate/rollout/controller.go b/lib/autoupdate/rollout/controller.go index 53a3741f8050a..667a2c557ca32 100644 --- a/lib/autoupdate/rollout/controller.go +++ b/lib/autoupdate/rollout/controller.go @@ -56,12 +56,16 @@ func NewController(client Client, log *slog.Logger, clock clockwork.Clock) (*Con if clock == nil { return nil, trace.BadParameter("missing clock") } + return &Controller{ clock: clock, log: log, reconciler: reconciler{ - clt: client, - log: log, + clt: client, + log: log, + rolloutStrategies: []rolloutStrategy{ + // TODO(hugoShaka): add the strategies here as we implement them + }, }, }, nil } diff --git a/lib/autoupdate/rollout/reconciler.go b/lib/autoupdate/rollout/reconciler.go index 2fc04634c72f9..80848dfd920b4 100644 --- a/lib/autoupdate/rollout/reconciler.go +++ b/lib/autoupdate/rollout/reconciler.go @@ -25,9 +25,13 @@ import ( "time" "github.com/gravitational/trace" + "github.com/jonboulle/clockwork" + "google.golang.org/protobuf/proto" + "google.golang.org/protobuf/types/known/timestamppb" "github.com/gravitational/teleport/api/gen/proto/go/teleport/autoupdate/v1" update "github.com/gravitational/teleport/api/types/autoupdate" + "github.com/gravitational/teleport/api/utils" ) const ( @@ -35,6 +39,13 @@ const ( defaultConfigMode = update.AgentsUpdateModeEnabled defaultStrategy = update.AgentsStrategyHaltOnError maxConflictRetry = 3 + + defaultGroupName = "default" + defaultStartHour = 12 +) + +var ( + defaultUpdateDays = []string{"Mon", "Tue", "Wed", "Thu"} ) // reconciler reconciles the AutoUpdateAgentRollout singleton based on the content of the AutoUpdateVersion and @@ -42,8 +53,11 @@ const ( // - we reconcile 2 resources with one // - both input and output are singletons, we don't need the multi resource logic nor stream/paginated APIs type reconciler struct { - clt Client - log *slog.Logger + clt Client + log *slog.Logger + clock clockwork.Clock + + rolloutStrategies []rolloutStrategy // mutex ensures we only run one reconciliation at a time mutex sync.Mutex @@ -131,10 +145,26 @@ func (r *reconciler) tryReconcile(ctx context.Context) error { if err != nil { return trace.Wrap(err, "mutating rollout") } + newStatus, err := r.computeStatus(ctx, existingRollout, newSpec, config.GetSpec().GetAgents().GetSchedules()) + if err != nil { + return trace.Wrap(err, "computing rollout status") + } - // if there are no existing rollout, we create a new one + // there was an existing rollout, we must figure if something changed + specChanged := !proto.Equal(existingRollout.GetSpec(), newSpec) + statusChanged := !proto.Equal(existingRollout.GetStatus(), newStatus) + rolloutChanged := specChanged || statusChanged + + // if nothing changed, no need to update the resource + if !rolloutChanged { + r.log.DebugContext(ctx, "rollout unchanged") + return nil + } + + // if there are no existing rollout, we create a new one and set the status if !rolloutExists { rollout, err := update.NewAutoUpdateAgentRollout(newSpec) + rollout.Status = newStatus if err != nil { return trace.Wrap(err, "validating new rollout") } @@ -142,27 +172,10 @@ func (r *reconciler) tryReconcile(ctx context.Context) error { return trace.Wrap(err, "creating rollout") } - // there was an existing rollout, we must figure if something changed - specChanged := existingRollout.GetSpec().GetStartVersion() != newSpec.GetStartVersion() || - existingRollout.GetSpec().GetTargetVersion() != newSpec.GetTargetVersion() || - existingRollout.GetSpec().GetAutoupdateMode() != newSpec.GetAutoupdateMode() || - existingRollout.GetSpec().GetStrategy() != newSpec.GetStrategy() || - existingRollout.GetSpec().GetSchedule() != newSpec.GetSchedule() - - // TODO: reconcile the status here when we'll add group support. - // Even if the spec does not change, we might still have to update the status: - // - sync groups with the ones from the user config - // - progress the rollout across groups - - // if nothing changed, no need to update the resource - if !specChanged { - r.log.DebugContext(ctx, "rollout unchanged") - return nil - } - - // something changed, we replace the old spec with the new one, validate and update the resource - // we don't create a new resource to keep the revision ID and + // If there was a previous rollout, we update its spec and status and do an update. + // We don't create a new resource to keep the metadata containing the revision ID. existingRollout.Spec = newSpec + existingRollout.Status = newStatus err = update.ValidateAutoUpdateAgentRollout(existingRollout) if err != nil { return trace.Wrap(err, "validating mutated rollout") @@ -233,3 +246,122 @@ func getMode(configMode, versionMode string) (string, error) { } return codeToAgentMode[versionCode], nil } + +// computeStatus computes the new rollout status based on the existing rollout, +// new rollout spec, and autoupdate_config. existingRollout might be nil if this +// is a new rollout. +// Even if the returned new status might be derived from the existing rollout +// status, it is a new deep-cloned structure. +func (r *reconciler) computeStatus( + ctx context.Context, + existingRollout *autoupdate.AutoUpdateAgentRollout, + newSpec *autoupdate.AutoUpdateAgentRolloutSpec, + configSchedules *autoupdate.AgentAutoUpdateSchedules, +) (*autoupdate.AutoUpdateAgentRolloutStatus, error) { + + var status *autoupdate.AutoUpdateAgentRolloutStatus + + // First, we check if a major spec change happened and we should reset the rollout status + shouldResetRollout := existingRollout.GetSpec().GetStartVersion() != newSpec.GetStartVersion() || + existingRollout.GetSpec().GetTargetVersion() != newSpec.GetTargetVersion() || + existingRollout.GetSpec().GetSchedule() != newSpec.GetSchedule() || + existingRollout.GetSpec().GetStrategy() != newSpec.GetStrategy() + + // We create a new status if the rollout should be reset or the previous status was nil + if shouldResetRollout || existingRollout.GetStatus() == nil { + status = new(autoupdate.AutoUpdateAgentRolloutStatus) + } else { + status = utils.CloneProtoMsg(existingRollout.GetStatus()) + } + + // Then, we check if the selected schedule uses groups + switch newSpec.GetSchedule() { + case update.AgentsScheduleImmediate: + // There are no groups with the immediate schedule, we must clean them + status.Groups = nil + return status, nil + case update.AgentsScheduleRegular: + // Regular schedule has groups, we will compute them after + default: + return nil, trace.BadParameter("unsupported agent schedule type %q", newSpec.GetSchedule()) + } + + // capture the current time to put it in the status update timestamps and to + // compute the group state changes + now := r.clock.Now() + + // If this is a new rollout or the rollout has been reset, we create groups from the config + groups := status.GetGroups() + var err error + if len(groups) == 0 { + groups, err = makeGroupsStatus(configSchedules, now) + if err != nil { + return nil, trace.Wrap(err, "creating groups status") + } + } + + err = r.progressRollout(ctx, newSpec.GetStrategy(), groups) + // Failing to progress the update is not a hard failure. + // We expected to update the status even if something went wrong to surface the failed reconciliation and potential errors to the user. + if err != nil { + r.log.ErrorContext(ctx, "Errors encountered during rollout progress. Some groups might not get updated properly.", + "error", err) + } + + status.Groups = groups + return status, nil +} + +// progressRollout picks the right rollout strategy and updates groups to progress the rollout. +// groups are updated in place. +// If an error is returned, the groups should still be upserted, depending on the strategy, +// failing to update a group might not be fatal (other groups can still progress independently). +func (r *reconciler) progressRollout(ctx context.Context, strategyName string, groups []*autoupdate.AutoUpdateAgentRolloutStatusGroup) error { + for _, strategy := range r.rolloutStrategies { + if strategy.name() == strategyName { + return strategy.progressRollout(ctx, groups) + } + } + return trace.NotImplemented("rollout strategy %q not implemented", strategyName) +} + +// makeGroupStatus creates the autoupdate_agent_rollout.status.groups based on the autoupdate_config. +// This should be called if the status groups have not been initialized or must be reset. +func makeGroupsStatus(schedules *autoupdate.AgentAutoUpdateSchedules, now time.Time) ([]*autoupdate.AutoUpdateAgentRolloutStatusGroup, error) { + configGroups := schedules.GetRegular() + if len(configGroups) == 0 { + defaultGroup, err := defaultConfigGroup() + if err != nil { + return nil, trace.Wrap(err, "retrieving default group") + } + configGroups = []*autoupdate.AgentAutoUpdateGroup{defaultGroup} + } + + groups := make([]*autoupdate.AutoUpdateAgentRolloutStatusGroup, len(configGroups)) + for i, group := range configGroups { + groups[i] = &autoupdate.AutoUpdateAgentRolloutStatusGroup{ + Name: group.Name, + StartTime: nil, + State: autoupdate.AutoUpdateAgentGroupState_AUTO_UPDATE_AGENT_GROUP_STATE_UNSTARTED, + LastUpdateTime: timestamppb.New(now), + LastUpdateReason: updateReasonCreated, + ConfigDays: group.Days, + ConfigStartHour: group.StartHour, + ConfigWaitDays: group.WaitDays, + } + } + return groups, nil +} + +// defaultConfigGroup returns the default group in case of missing autoupdate_config resource. +// This is a function and not a variable because we will need to add more logic there in the future +// lookup maintenance information from RFD 109's cluster_maintenance_config. +func defaultConfigGroup() (*autoupdate.AgentAutoUpdateGroup, error) { + // TODO: get group from CMC if possible + return &autoupdate.AgentAutoUpdateGroup{ + Name: defaultGroupName, + Days: defaultUpdateDays, + StartHour: defaultStartHour, + WaitDays: 0, + }, nil +} diff --git a/lib/autoupdate/rollout/reconciler_test.go b/lib/autoupdate/rollout/reconciler_test.go index 4d24563f7b32f..388c7bceb8492 100644 --- a/lib/autoupdate/rollout/reconciler_test.go +++ b/lib/autoupdate/rollout/reconciler_test.go @@ -20,13 +20,17 @@ package rollout import ( "context" + "sync" "testing" + "time" "github.com/google/go-cmp/cmp" "github.com/google/uuid" "github.com/gravitational/trace" + "github.com/jonboulle/clockwork" "github.com/stretchr/testify/require" "google.golang.org/protobuf/testing/protocmp" + "google.golang.org/protobuf/types/known/timestamppb" "github.com/gravitational/teleport/api/gen/proto/go/teleport/autoupdate/v1" update "github.com/gravitational/teleport/api/types/autoupdate" @@ -39,7 +43,7 @@ import ( // The comparison does not take into account the proto internal state. func rolloutEquals(expected *autoupdate.AutoUpdateAgentRollout) require.ValueAssertionFunc { return func(t require.TestingT, i interface{}, _ ...interface{}) { - require.IsType(t, &autoupdate.AutoUpdateAgentRollout{}, i) + require.IsType(t, &autoupdate.AutoUpdateAgentRollout{}, i, "resource should be an autoupdate_agent_rollout") actual := i.(*autoupdate.AutoUpdateAgentRollout) require.Empty(t, cmp.Diff(expected, actual, protocmp.Transform())) } @@ -181,6 +185,7 @@ func TestTryReconcile(t *testing.T) { Strategy: update.AgentsStrategyHaltOnError, }) require.NoError(t, err) + upToDateRollout.Status = &autoupdate.AutoUpdateAgentRolloutStatus{} outOfDateRollout, err := update.NewAutoUpdateAgentRollout(&autoupdate.AutoUpdateAgentRolloutSpec{ StartVersion: "1.2.2", @@ -190,6 +195,7 @@ func TestTryReconcile(t *testing.T) { Strategy: update.AgentsStrategyHaltOnError, }) require.NoError(t, err) + outOfDateRollout.Status = &autoupdate.AutoUpdateAgentRolloutStatus{} tests := []struct { name string @@ -354,6 +360,7 @@ func TestReconciler_Reconcile(t *testing.T) { Strategy: update.AgentsStrategyHaltOnError, }) require.NoError(t, err) + upToDateRollout.Status = &autoupdate.AutoUpdateAgentRolloutStatus{} outOfDateRollout, err := update.NewAutoUpdateAgentRollout(&autoupdate.AutoUpdateAgentRolloutSpec{ StartVersion: "1.2.2", @@ -363,6 +370,7 @@ func TestReconciler_Reconcile(t *testing.T) { Strategy: update.AgentsStrategyHaltOnError, }) require.NoError(t, err) + outOfDateRollout.Status = &autoupdate.AutoUpdateAgentRolloutStatus{} // Those tests are not written in table format because the fixture setup it too complex and this would harm // readability. @@ -565,3 +573,290 @@ func TestReconciler_Reconcile(t *testing.T) { client.checkIfEmpty(t) }) } + +func Test_makeGroupsStatus(t *testing.T) { + now := time.Now() + + tests := []struct { + name string + schedules *autoupdate.AgentAutoUpdateSchedules + expected []*autoupdate.AutoUpdateAgentRolloutStatusGroup + }{ + { + name: "nil schedules", + schedules: nil, + expected: []*autoupdate.AutoUpdateAgentRolloutStatusGroup{ + { + Name: defaultGroupName, + StartTime: nil, + State: autoupdate.AutoUpdateAgentGroupState_AUTO_UPDATE_AGENT_GROUP_STATE_UNSTARTED, + LastUpdateTime: timestamppb.New(now), + LastUpdateReason: updateReasonCreated, + ConfigDays: defaultUpdateDays, + ConfigStartHour: defaultStartHour, + ConfigWaitDays: 0, + }, + }, + }, + { + name: "no groups in schedule", + schedules: &autoupdate.AgentAutoUpdateSchedules{Regular: make([]*autoupdate.AgentAutoUpdateGroup, 0)}, + expected: []*autoupdate.AutoUpdateAgentRolloutStatusGroup{ + { + Name: defaultGroupName, + StartTime: nil, + State: autoupdate.AutoUpdateAgentGroupState_AUTO_UPDATE_AGENT_GROUP_STATE_UNSTARTED, + LastUpdateTime: timestamppb.New(now), + LastUpdateReason: updateReasonCreated, + ConfigDays: defaultUpdateDays, + ConfigStartHour: defaultStartHour, + ConfigWaitDays: 0, + }, + }, + }, + { + name: "one group in schedule", + schedules: &autoupdate.AgentAutoUpdateSchedules{ + Regular: []*autoupdate.AgentAutoUpdateGroup{ + { + Name: "group1", + Days: everyWeekday, + StartHour: matchingStartHour, + WaitDays: 0, + }, + }, + }, + expected: []*autoupdate.AutoUpdateAgentRolloutStatusGroup{ + { + Name: "group1", + State: autoupdate.AutoUpdateAgentGroupState_AUTO_UPDATE_AGENT_GROUP_STATE_UNSTARTED, + LastUpdateTime: timestamppb.New(now), + LastUpdateReason: updateReasonCreated, + ConfigDays: everyWeekday, + ConfigStartHour: matchingStartHour, + ConfigWaitDays: 0, + }, + }, + }, + { + name: "multiple groups in schedule", + schedules: &autoupdate.AgentAutoUpdateSchedules{ + Regular: []*autoupdate.AgentAutoUpdateGroup{ + { + Name: "group1", + Days: everyWeekday, + StartHour: matchingStartHour, + WaitDays: 0, + }, + { + Name: "group2", + Days: everyWeekdayButSunday, + StartHour: nonMatchingStartHour, + WaitDays: 1, + }, + }, + }, + expected: []*autoupdate.AutoUpdateAgentRolloutStatusGroup{ + { + Name: "group1", + State: autoupdate.AutoUpdateAgentGroupState_AUTO_UPDATE_AGENT_GROUP_STATE_UNSTARTED, + LastUpdateTime: timestamppb.New(now), + LastUpdateReason: updateReasonCreated, + ConfigDays: everyWeekday, + ConfigStartHour: matchingStartHour, + ConfigWaitDays: 0, + }, + { + Name: "group2", + State: autoupdate.AutoUpdateAgentGroupState_AUTO_UPDATE_AGENT_GROUP_STATE_UNSTARTED, + LastUpdateTime: timestamppb.New(now), + LastUpdateReason: updateReasonCreated, + ConfigDays: everyWeekdayButSunday, + ConfigStartHour: nonMatchingStartHour, + ConfigWaitDays: 1, + }, + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + result, err := makeGroupsStatus(tt.schedules, now) + require.NoError(t, err) + require.Equal(t, tt.expected, result) + }) + } +} + +const fakeRolloutStrategyName = "fake" + +type fakeRolloutStrategy struct { + strategyName string + // calls counts how many times the fake rollout strategy was called. + // This is not thread safe. + calls int +} + +func (f *fakeRolloutStrategy) name() string { + return f.strategyName +} + +func (f *fakeRolloutStrategy) progressRollout(ctx context.Context, groups []*autoupdate.AutoUpdateAgentRolloutStatusGroup) error { + f.calls++ + return nil +} + +func Test_reconciler_computeStatus(t *testing.T) { + log := utils.NewSlogLoggerForTests() + clock := clockwork.NewFakeClock() + ctx := context.Background() + + oldStatus := &autoupdate.AutoUpdateAgentRolloutStatus{ + Groups: []*autoupdate.AutoUpdateAgentRolloutStatusGroup{ + { + Name: "old group", + }, + }, + } + oldSpec := &autoupdate.AutoUpdateAgentRolloutSpec{ + StartVersion: "1.2.3", + TargetVersion: "1.2.4", + Schedule: update.AgentsScheduleRegular, + AutoupdateMode: update.AgentsUpdateModeEnabled, + Strategy: fakeRolloutStrategyName, + } + schedules := &autoupdate.AgentAutoUpdateSchedules{ + Regular: []*autoupdate.AgentAutoUpdateGroup{ + { + Name: "new group", + Days: everyWeekday, + }, + }, + } + newGroups, err := makeGroupsStatus(schedules, clock.Now()) + require.NoError(t, err) + newStatus := &autoupdate.AutoUpdateAgentRolloutStatus{ + Groups: newGroups, + } + + tests := []struct { + name string + existingRollout *autoupdate.AutoUpdateAgentRollout + newSpec *autoupdate.AutoUpdateAgentRolloutSpec + expectedStatus *autoupdate.AutoUpdateAgentRolloutStatus + expectedStrategyCalls int + }{ + { + name: "status is reset if start version changes", + existingRollout: &autoupdate.AutoUpdateAgentRollout{ + Spec: oldSpec, + Status: oldStatus, + }, + newSpec: &autoupdate.AutoUpdateAgentRolloutSpec{ + StartVersion: "1.2.2", + TargetVersion: "1.2.4", + Schedule: update.AgentsScheduleRegular, + AutoupdateMode: update.AgentsUpdateModeEnabled, + Strategy: fakeRolloutStrategyName, + }, + // status should have been reset and is now the new status + expectedStatus: newStatus, + expectedStrategyCalls: 1, + }, + { + name: "status is reset if target version changes", + existingRollout: &autoupdate.AutoUpdateAgentRollout{ + Spec: oldSpec, + Status: oldStatus, + }, + newSpec: &autoupdate.AutoUpdateAgentRolloutSpec{ + StartVersion: "1.2.3", + TargetVersion: "1.2.5", + Schedule: update.AgentsScheduleRegular, + AutoupdateMode: update.AgentsUpdateModeEnabled, + Strategy: fakeRolloutStrategyName, + }, + // status should have been reset and is now the new status + expectedStatus: newStatus, + expectedStrategyCalls: 1, + }, + { + name: "status is reset if strategy changes", + existingRollout: &autoupdate.AutoUpdateAgentRollout{ + Spec: oldSpec, + Status: oldStatus, + }, + newSpec: &autoupdate.AutoUpdateAgentRolloutSpec{ + StartVersion: "1.2.3", + TargetVersion: "1.2.4", + Schedule: update.AgentsScheduleRegular, + AutoupdateMode: update.AgentsUpdateModeEnabled, + Strategy: fakeRolloutStrategyName + "2", + }, + // status should have been reset and is now the new status + expectedStatus: newStatus, + expectedStrategyCalls: 1, + }, + { + name: "status is not reset if mode changes", + existingRollout: &autoupdate.AutoUpdateAgentRollout{ + Spec: oldSpec, + Status: oldStatus, + }, + newSpec: &autoupdate.AutoUpdateAgentRolloutSpec{ + StartVersion: "1.2.3", + TargetVersion: "1.2.4", + Schedule: update.AgentsScheduleRegular, + AutoupdateMode: update.AgentsUpdateModeSuspended, + Strategy: fakeRolloutStrategyName, + }, + // status should NOT have been reset and still contain the old groups + expectedStatus: oldStatus, + expectedStrategyCalls: 1, + }, + { + name: "groups are unset if schedule is immediate", + existingRollout: &autoupdate.AutoUpdateAgentRollout{ + Spec: oldSpec, + Status: oldStatus, + }, + newSpec: &autoupdate.AutoUpdateAgentRolloutSpec{ + StartVersion: "1.2.3", + TargetVersion: "1.2.4", + Schedule: update.AgentsScheduleImmediate, + AutoupdateMode: update.AgentsUpdateModeEnabled, + Strategy: fakeRolloutStrategyName, + }, + // groups should be unset + expectedStatus: &autoupdate.AutoUpdateAgentRolloutStatus{}, + expectedStrategyCalls: 0, + }, + { + name: "new groups are populated if previous ones were empty", + existingRollout: &autoupdate.AutoUpdateAgentRollout{ + Spec: oldSpec, + // old groups were empty + Status: &autoupdate.AutoUpdateAgentRolloutStatus{}, + }, + // no spec change + newSpec: oldSpec, + // still, we have the new groups set + expectedStatus: newStatus, + expectedStrategyCalls: 1, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + strategy := &fakeRolloutStrategy{strategyName: tt.newSpec.Strategy} + r := &reconciler{ + log: log, + clock: clock, + rolloutStrategies: []rolloutStrategy{strategy}, + mutex: sync.Mutex{}, + } + result, err := r.computeStatus(ctx, tt.existingRollout, tt.newSpec, schedules) + require.NoError(t, err) + require.Empty(t, cmp.Diff(tt.expectedStatus, result, protocmp.Transform())) + require.Equal(t, tt.expectedStrategyCalls, strategy.calls) + }) + } +} diff --git a/lib/autoupdate/rollout/strategy.go b/lib/autoupdate/rollout/strategy.go new file mode 100644 index 0000000000000..339789c4e3028 --- /dev/null +++ b/lib/autoupdate/rollout/strategy.go @@ -0,0 +1,96 @@ +/* + * Teleport + * Copyright (C) 2024 Gravitational, Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package rollout + +import ( + "context" + "time" + + "github.com/gravitational/trace" + "google.golang.org/protobuf/types/known/timestamppb" + + "github.com/gravitational/teleport/api/gen/proto/go/teleport/autoupdate/v1" + "github.com/gravitational/teleport/api/types" +) + +const ( + // Common update reasons + updateReasonCreated = "created" + updateReasonReconcilerError = "reconciler_error" +) + +// rolloutStrategy is responsible for rolling out the update across groups. +// This interface allows us to inject dummy strategies for simpler testing. +type rolloutStrategy interface { + name() string + progressRollout(context.Context, []*autoupdate.AutoUpdateAgentRolloutStatusGroup) error +} + +func inWindow(group *autoupdate.AutoUpdateAgentRolloutStatusGroup, now time.Time) (bool, error) { + dayOK, err := canUpdateToday(group.ConfigDays, now) + if err != nil { + return false, trace.Wrap(err, "checking the day of the week") + } + if !dayOK { + return false, nil + } + return int(group.ConfigStartHour) == now.Hour(), nil +} + +func canUpdateToday(allowedDays []string, now time.Time) (bool, error) { + for _, allowedDay := range allowedDays { + if allowedDay == types.Wildcard { + return true, nil + } + weekday, ok := types.ParseWeekday(allowedDay) + if !ok { + return false, trace.BadParameter("failed to parse weekday %q", allowedDay) + } + if weekday == now.Weekday() { + return true, nil + } + } + return false, nil +} + +func setGroupState(group *autoupdate.AutoUpdateAgentRolloutStatusGroup, newState autoupdate.AutoUpdateAgentGroupState, reason string, now time.Time) { + changed := false + previousState := group.State + + // Check if there is a state transition + if previousState != newState { + group.State = newState + changed = true + // If we just started the group, also update the start time + if newState == autoupdate.AutoUpdateAgentGroupState_AUTO_UPDATE_AGENT_GROUP_STATE_ACTIVE { + group.StartTime = timestamppb.New(now) + } + } + + // Check if there is a reason change. Even if the state did not change, we + // might expected to explain why. + if group.LastUpdateReason != reason { + group.LastUpdateReason = reason + changed = true + } + + if changed { + group.LastUpdateTime = timestamppb.New(now) + } +} diff --git a/lib/autoupdate/rollout/strategy_test.go b/lib/autoupdate/rollout/strategy_test.go new file mode 100644 index 0000000000000..ba9251a9c023a --- /dev/null +++ b/lib/autoupdate/rollout/strategy_test.go @@ -0,0 +1,310 @@ +/* + * Teleport + * Copyright (C) 2024 Gravitational, Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package rollout + +import ( + "testing" + "time" + + "github.com/jonboulle/clockwork" + "github.com/stretchr/testify/require" + "google.golang.org/protobuf/types/known/timestamppb" + + "github.com/gravitational/teleport/api/gen/proto/go/teleport/autoupdate/v1" +) + +var ( + // TODO(hugoShaka) uncomment in the next PRs when this value will become useful + // 2024-11-30 is a Saturday + // testSaturday = time.Date(2024, 11, 30, 15, 30, 0, 0, time.UTC) + // 2024-12-01 is a Sunday + testSunday = time.Date(2024, 12, 1, 12, 30, 0, 0, time.UTC) + matchingStartHour = int32(12) + nonMatchingStartHour = int32(15) + everyWeekday = []string{"Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"} + everyWeekdayButSunday = []string{"Mon", "Tue", "Wed", "Thu", "Fri", "Sat"} +) + +func Test_canUpdateToday(t *testing.T) { + tests := []struct { + name string + allowedDays []string + now time.Time + want bool + wantErr require.ErrorAssertionFunc + }{ + { + name: "Empty list", + allowedDays: []string{}, + now: time.Now(), + want: false, + wantErr: require.NoError, + }, + { + name: "Wildcard", + allowedDays: []string{"*"}, + now: time.Now(), + want: true, + wantErr: require.NoError, + }, + { + name: "Matching day", + allowedDays: everyWeekday, + now: testSunday, + want: true, + wantErr: require.NoError, + }, + { + name: "No matching day", + allowedDays: everyWeekdayButSunday, + now: testSunday, + want: false, + wantErr: require.NoError, + }, + { + name: "Malformed day", + allowedDays: []string{"Mon", "Tue", "HelloThereGeneralKenobi"}, + now: testSunday, + want: false, + wantErr: require.Error, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := canUpdateToday(tt.allowedDays, tt.now) + tt.wantErr(t, err) + require.Equal(t, tt.want, got) + }) + } +} + +func Test_inWindow(t *testing.T) { + tests := []struct { + name string + group *autoupdate.AutoUpdateAgentRolloutStatusGroup + now time.Time + want bool + wantErr require.ErrorAssertionFunc + }{ + { + name: "out of window", + group: &autoupdate.AutoUpdateAgentRolloutStatusGroup{ + ConfigDays: everyWeekdayButSunday, + ConfigStartHour: matchingStartHour, + }, + now: testSunday, + want: false, + wantErr: require.NoError, + }, + { + name: "inside window, wrong hour", + group: &autoupdate.AutoUpdateAgentRolloutStatusGroup{ + ConfigDays: everyWeekday, + ConfigStartHour: nonMatchingStartHour, + }, + now: testSunday, + want: false, + wantErr: require.NoError, + }, + { + name: "inside window, correct hour", + group: &autoupdate.AutoUpdateAgentRolloutStatusGroup{ + ConfigDays: everyWeekday, + ConfigStartHour: matchingStartHour, + }, + now: testSunday, + want: true, + wantErr: require.NoError, + }, + { + name: "invalid weekdays", + group: &autoupdate.AutoUpdateAgentRolloutStatusGroup{ + ConfigDays: []string{"HelloThereGeneralKenobi"}, + ConfigStartHour: matchingStartHour, + }, + now: testSunday, + want: false, + wantErr: require.Error, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := inWindow(tt.group, tt.now) + tt.wantErr(t, err) + require.Equal(t, tt.want, got) + }) + } +} + +func Test_setGroupState(t *testing.T) { + groupName := "test-group" + + // TODO(hugoShaka) remove those two variables once the strategies are merged and the constants are defined. + updateReasonCanStart := "can_start" + updateReasonCannotStart := "cannot_start" + + clock := clockwork.NewFakeClock() + // oldUpdateTime is 5 minutes in the past + oldUpdateTime := clock.Now() + clock.Advance(5 * time.Minute) + + tests := []struct { + name string + group *autoupdate.AutoUpdateAgentRolloutStatusGroup + newState autoupdate.AutoUpdateAgentGroupState + reason string + now time.Time + expected *autoupdate.AutoUpdateAgentRolloutStatusGroup + }{ + { + name: "same state, no change", + group: &autoupdate.AutoUpdateAgentRolloutStatusGroup{ + Name: groupName, + StartTime: nil, + State: autoupdate.AutoUpdateAgentGroupState_AUTO_UPDATE_AGENT_GROUP_STATE_UNSTARTED, + LastUpdateTime: timestamppb.New(oldUpdateTime), + LastUpdateReason: updateReasonCannotStart, + }, + newState: autoupdate.AutoUpdateAgentGroupState_AUTO_UPDATE_AGENT_GROUP_STATE_UNSTARTED, + reason: updateReasonCannotStart, + now: clock.Now(), + expected: &autoupdate.AutoUpdateAgentRolloutStatusGroup{ + Name: groupName, + StartTime: nil, + State: autoupdate.AutoUpdateAgentGroupState_AUTO_UPDATE_AGENT_GROUP_STATE_UNSTARTED, + // update time has not been bumped as nothing changed + LastUpdateTime: timestamppb.New(oldUpdateTime), + LastUpdateReason: updateReasonCannotStart, + }, + }, + { + name: "same state, reason change", + group: &autoupdate.AutoUpdateAgentRolloutStatusGroup{ + Name: groupName, + StartTime: nil, + State: autoupdate.AutoUpdateAgentGroupState_AUTO_UPDATE_AGENT_GROUP_STATE_UNSTARTED, + LastUpdateTime: timestamppb.New(oldUpdateTime), + LastUpdateReason: updateReasonCannotStart, + }, + newState: autoupdate.AutoUpdateAgentGroupState_AUTO_UPDATE_AGENT_GROUP_STATE_UNSTARTED, + reason: updateReasonReconcilerError, + now: clock.Now(), + expected: &autoupdate.AutoUpdateAgentRolloutStatusGroup{ + Name: groupName, + StartTime: nil, + State: autoupdate.AutoUpdateAgentGroupState_AUTO_UPDATE_AGENT_GROUP_STATE_UNSTARTED, + // update time has been bumped because reason changed + LastUpdateTime: timestamppb.New(clock.Now()), + LastUpdateReason: updateReasonReconcilerError, + }, + }, + { + name: "new state, no reason change", + group: &autoupdate.AutoUpdateAgentRolloutStatusGroup{ + Name: groupName, + StartTime: nil, + State: autoupdate.AutoUpdateAgentGroupState_AUTO_UPDATE_AGENT_GROUP_STATE_UNSTARTED, + LastUpdateTime: timestamppb.New(oldUpdateTime), + LastUpdateReason: updateReasonCannotStart, + }, + newState: autoupdate.AutoUpdateAgentGroupState_AUTO_UPDATE_AGENT_GROUP_STATE_ROLLEDBACK, + reason: updateReasonCannotStart, + now: clock.Now(), + expected: &autoupdate.AutoUpdateAgentRolloutStatusGroup{ + Name: groupName, + StartTime: nil, + State: autoupdate.AutoUpdateAgentGroupState_AUTO_UPDATE_AGENT_GROUP_STATE_ROLLEDBACK, + // update time has been bumped because state changed + LastUpdateTime: timestamppb.New(clock.Now()), + LastUpdateReason: updateReasonCannotStart, + }, + }, + { + name: "new state, reason change", + group: &autoupdate.AutoUpdateAgentRolloutStatusGroup{ + Name: groupName, + StartTime: nil, + State: autoupdate.AutoUpdateAgentGroupState_AUTO_UPDATE_AGENT_GROUP_STATE_UNSTARTED, + LastUpdateTime: timestamppb.New(oldUpdateTime), + LastUpdateReason: updateReasonCannotStart, + }, + newState: autoupdate.AutoUpdateAgentGroupState_AUTO_UPDATE_AGENT_GROUP_STATE_ROLLEDBACK, + reason: updateReasonReconcilerError, + now: clock.Now(), + expected: &autoupdate.AutoUpdateAgentRolloutStatusGroup{ + Name: groupName, + StartTime: nil, + State: autoupdate.AutoUpdateAgentGroupState_AUTO_UPDATE_AGENT_GROUP_STATE_ROLLEDBACK, + // update time has been bumped because state and reason changed + LastUpdateTime: timestamppb.New(clock.Now()), + LastUpdateReason: updateReasonReconcilerError, + }, + }, + { + name: "new state, transition to active", + group: &autoupdate.AutoUpdateAgentRolloutStatusGroup{ + Name: groupName, + StartTime: nil, + State: autoupdate.AutoUpdateAgentGroupState_AUTO_UPDATE_AGENT_GROUP_STATE_UNSTARTED, + LastUpdateTime: timestamppb.New(oldUpdateTime), + LastUpdateReason: updateReasonCannotStart, + }, + newState: autoupdate.AutoUpdateAgentGroupState_AUTO_UPDATE_AGENT_GROUP_STATE_ACTIVE, + reason: updateReasonCanStart, + now: clock.Now(), + expected: &autoupdate.AutoUpdateAgentRolloutStatusGroup{ + Name: groupName, + // We set start time during the transition + StartTime: timestamppb.New(clock.Now()), + State: autoupdate.AutoUpdateAgentGroupState_AUTO_UPDATE_AGENT_GROUP_STATE_ACTIVE, + // update time has been bumped because state and reason changed + LastUpdateTime: timestamppb.New(clock.Now()), + LastUpdateReason: updateReasonCanStart, + }, + }, + { + name: "same state, transition from active to active", + group: &autoupdate.AutoUpdateAgentRolloutStatusGroup{ + Name: groupName, + StartTime: timestamppb.New(oldUpdateTime), + State: autoupdate.AutoUpdateAgentGroupState_AUTO_UPDATE_AGENT_GROUP_STATE_ACTIVE, + LastUpdateTime: timestamppb.New(oldUpdateTime), + LastUpdateReason: updateReasonCanStart, + }, + newState: autoupdate.AutoUpdateAgentGroupState_AUTO_UPDATE_AGENT_GROUP_STATE_ACTIVE, + reason: updateReasonReconcilerError, + now: clock.Now(), + expected: &autoupdate.AutoUpdateAgentRolloutStatusGroup{ + Name: groupName, + // As the state was already active, the start time should not be refreshed + StartTime: timestamppb.New(oldUpdateTime), + State: autoupdate.AutoUpdateAgentGroupState_AUTO_UPDATE_AGENT_GROUP_STATE_ACTIVE, + // update time has been bumped because reason changed + LastUpdateTime: timestamppb.New(clock.Now()), + LastUpdateReason: updateReasonReconcilerError, + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + setGroupState(tt.group, tt.newState, tt.reason, tt.now) + require.Equal(t, tt.expected, tt.group) + }) + } +} diff --git a/lib/backend/dynamo/dynamodbbk.go b/lib/backend/dynamo/dynamodbbk.go index 44f9774584b7e..556366959e905 100644 --- a/lib/backend/dynamo/dynamodbbk.go +++ b/lib/backend/dynamo/dynamodbbk.go @@ -38,9 +38,10 @@ import ( "github.com/aws/aws-sdk-go-v2/service/dynamodb/types" "github.com/aws/aws-sdk-go-v2/service/dynamodbstreams" streamtypes "github.com/aws/aws-sdk-go-v2/service/dynamodbstreams/types" + "github.com/aws/smithy-go/tracing/smithyoteltracing" "github.com/gravitational/trace" "github.com/jonboulle/clockwork" - "go.opentelemetry.io/contrib/instrumentation/github.com/aws/aws-sdk-go-v2/otelaws" + "go.opentelemetry.io/otel" "github.com/gravitational/teleport" "github.com/gravitational/teleport/api/utils" @@ -282,7 +283,12 @@ func New(ctx context.Context, params backend.Params) (*Backend, error) { return nil, trace.Wrap(err) } - dynamoOpts := []func(*dynamodb.Options){dynamodb.WithEndpointResolverV2(dynamoResolver)} + dynamoOpts := []func(*dynamodb.Options){ + dynamodb.WithEndpointResolverV2(dynamoResolver), + func(o *dynamodb.Options) { + o.TracerProvider = smithyoteltracing.Adapt(otel.GetTracerProvider()) + }, + } // FIPS settings are applied on the individual service instead of the aws config, // as DynamoDB Streams and Application Auto Scaling do not yet have FIPS endpoints in non-GovCloud. @@ -293,8 +299,6 @@ func New(ctx context.Context, params backend.Params) (*Backend, error) { }) } - otelaws.AppendMiddlewares(&awsConfig.APIOptions, otelaws.WithAttributeSetter(otelaws.DynamoDBAttributeSetter)) - dynamoClient := dynamodb.NewFromConfig(awsConfig, dynamoOpts...) streamsResolver, err := endpoint.NewLoggingResolver( diff --git a/lib/cache/cache.go b/lib/cache/cache.go index de46c13323831..fcb2a3bf7da5f 100644 --- a/lib/cache/cache.go +++ b/lib/cache/cache.go @@ -103,6 +103,7 @@ var highVolumeResources = map[string]struct{}{ types.KindWindowsDesktopService: {}, types.KindKubeServer: {}, types.KindDatabaseObject: {}, + types.KindGitServer: {}, } func isHighVolumeResource(kind string) bool { @@ -199,6 +200,7 @@ func ForAuth(cfg Config) Config { {Kind: types.KindIdentityCenterPrincipalAssignment}, {Kind: types.KindIdentityCenterAccountAssignment}, {Kind: types.KindPluginStaticCredentials}, + {Kind: types.KindGitServer}, } cfg.QueueSize = defaults.AuthQueueSize // We don't want to enable partial health for auth cache because auth uses an event stream @@ -256,6 +258,7 @@ func ForProxy(cfg Config) Config { {Kind: types.KindAutoUpdateVersion}, {Kind: types.KindAutoUpdateAgentRollout}, {Kind: types.KindUserTask}, + {Kind: types.KindGitServer}, } cfg.QueueSize = defaults.ProxyQueueSize return cfg @@ -552,6 +555,7 @@ type Cache struct { provisioningStatesCache *local.ProvisioningStateService identityCenterCache *local.IdentityCenterService pluginStaticCredentialsCache *local.PluginStaticCredentialsService + gitServersCache *local.GitServerService // closed indicates that the cache has been closed closed atomic.Bool @@ -788,6 +792,8 @@ type Config struct { IdentityCenter services.IdentityCenter // PluginStaticCredentials is the plugin static credentials services PluginStaticCredentials services.PluginStaticCredentials + // GitServers is the Git server service. + GitServers services.GitServerGetter } // CheckAndSetDefaults checks parameters and sets default values @@ -1033,6 +1039,12 @@ func New(config Config) (*Cache, error) { return nil, trace.Wrap(err) } + gitServersCache, err := local.NewGitServerService(config.Backend) + if err != nil { + cancel() + return nil, trace.Wrap(err) + } + cs := &Cache{ ctx: ctx, cancel: cancel, @@ -1081,6 +1093,7 @@ func New(config Config) (*Cache, error) { provisioningStatesCache: provisioningStatesCache, identityCenterCache: identityCenterCache, pluginStaticCredentialsCache: pluginStaticCredentialsCache, + gitServersCache: gitServersCache, Logger: log.WithFields(log.Fields{ teleport.ComponentKey: config.Component, }), diff --git a/lib/cache/cache_test.go b/lib/cache/cache_test.go index e49baa304aad8..af4b4d195bce4 100644 --- a/lib/cache/cache_test.go +++ b/lib/cache/cache_test.go @@ -142,6 +142,7 @@ type testPack struct { provisioningStates services.ProvisioningStates identityCenter services.IdentityCenter pluginStaticCredentials *local.PluginStaticCredentialsService + gitServers services.GitServers } // testFuncs are functions to support testing an object in a cache. @@ -409,6 +410,11 @@ func newPackWithoutCache(dir string, opts ...packOption) (*testPack, error) { return nil, trace.Wrap(err) } + p.gitServers, err = local.NewGitServerService(p.backend) + if err != nil { + return nil, trace.Wrap(err) + } + return p, nil } @@ -463,6 +469,7 @@ func newPack(dir string, setupConfig func(c Config) Config, opts ...packOption) ProvisioningStates: p.provisioningStates, IdentityCenter: p.identityCenter, PluginStaticCredentials: p.pluginStaticCredentials, + GitServers: p.gitServers, MaxRetryPeriod: 200 * time.Millisecond, EventsC: p.eventsC, })) @@ -878,6 +885,7 @@ func TestCompletenessInit(t *testing.T) { IdentityCenter: p.identityCenter, PluginStaticCredentials: p.pluginStaticCredentials, EventsC: p.eventsC, + GitServers: p.gitServers, })) require.NoError(t, err) @@ -963,6 +971,7 @@ func TestCompletenessReset(t *testing.T) { PluginStaticCredentials: p.pluginStaticCredentials, MaxRetryPeriod: 200 * time.Millisecond, EventsC: p.eventsC, + GitServers: p.gitServers, })) require.NoError(t, err) @@ -1175,6 +1184,7 @@ func TestListResources_NodesTTLVariant(t *testing.T) { MaxRetryPeriod: 200 * time.Millisecond, EventsC: p.eventsC, neverOK: true, // ensure reads are never healthy + GitServers: p.gitServers, })) require.NoError(t, err) @@ -1270,6 +1280,7 @@ func initStrategy(t *testing.T) { PluginStaticCredentials: p.pluginStaticCredentials, MaxRetryPeriod: 200 * time.Millisecond, EventsC: p.eventsC, + GitServers: p.gitServers, })) require.NoError(t, err) @@ -3544,6 +3555,7 @@ func TestCacheWatchKindExistsInEvents(t *testing.T) { types.KindIdentityCenterAccountAssignment: types.Resource153ToLegacy(newIdentityCenterAccountAssignment("some_account_assignment")), types.KindIdentityCenterPrincipalAssignment: types.Resource153ToLegacy(newIdentityCenterPrincipalAssignment("some_principal_assignment")), types.KindPluginStaticCredentials: &types.PluginStaticCredentialsV1{}, + types.KindGitServer: &types.ServerV2{}, } for name, cfg := range cases { diff --git a/lib/cache/collections.go b/lib/cache/collections.go index 36aaefebf5398..2635a0d71ea04 100644 --- a/lib/cache/collections.go +++ b/lib/cache/collections.go @@ -177,6 +177,7 @@ type cacheCollections struct { identityCenterPrincipalAssignments collectionReader[identityCenterPrincipalAssignmentGetter] identityCenterAccountAssignments collectionReader[identityCenterAccountAssignmentGetter] pluginStaticCredentials collectionReader[pluginStaticCredentialsGetter] + gitServers collectionReader[services.GitServerGetter] } // setupCollections returns a registry of collections. @@ -799,6 +800,19 @@ func setupCollections(c *Cache, watches []types.WatchKind) (*cacheCollections, e } collections.byKind[resourceKind] = collections.pluginStaticCredentials + case types.KindGitServer: + if c.GitServers == nil { + return nil, trace.BadParameter("missing parameter GitServers") + } + collections.gitServers = &genericCollection[ + types.Server, + services.GitServerGetter, + gitServerExecutor, + ]{ + cache: c, + watch: watch, + } + collections.byKind[resourceKind] = collections.gitServers default: return nil, trace.BadParameter("resource %q is not supported", watch.Kind) } diff --git a/lib/cache/git_server.go b/lib/cache/git_server.go new file mode 100644 index 0000000000000..849a160757eee --- /dev/null +++ b/lib/cache/git_server.go @@ -0,0 +1,95 @@ +/* + * Teleport + * Copyright (C) 2024 Gravitational, Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package cache + +import ( + "context" + + "github.com/gravitational/trace" + + apidefaults "github.com/gravitational/teleport/api/defaults" + "github.com/gravitational/teleport/api/types" + "github.com/gravitational/teleport/lib/services" +) + +func (c *Cache) GetGitServer(ctx context.Context, name string) (types.Server, error) { + ctx, span := c.Tracer.Start(ctx, "cache/GetGitServer") + defer span.End() + + rg, err := readCollectionCache(c, c.collections.gitServers) + if err != nil { + return nil, trace.Wrap(err) + } + defer rg.Release() + return rg.reader.GetGitServer(ctx, name) +} + +func (c *Cache) ListGitServers(ctx context.Context, pageSize int, pageToken string) ([]types.Server, string, error) { + ctx, span := c.Tracer.Start(ctx, "cache/ListGitServers") + defer span.End() + + rg, err := readCollectionCache(c, c.collections.gitServers) + if err != nil { + return nil, "", trace.Wrap(err) + } + defer rg.Release() + return rg.reader.ListGitServers(ctx, pageSize, pageToken) +} + +type gitServerExecutor struct{} + +func (gitServerExecutor) getAll(ctx context.Context, cache *Cache, loadSecrets bool) (all []types.Server, err error) { + var page []types.Server + var nextToken string + for { + page, nextToken, err = cache.GitServers.ListGitServers(ctx, apidefaults.DefaultChunkSize, nextToken) + if err != nil { + return nil, trace.Wrap(err) + } + all = append(all, page...) + if nextToken == "" { + break + } + } + return all, nil +} + +func (gitServerExecutor) upsert(ctx context.Context, cache *Cache, resource types.Server) error { + _, err := cache.gitServersCache.UpsertGitServer(ctx, resource) + return trace.Wrap(err) +} + +func (gitServerExecutor) deleteAll(ctx context.Context, cache *Cache) error { + return cache.gitServersCache.DeleteAllGitServers(ctx) +} + +func (gitServerExecutor) delete(ctx context.Context, cache *Cache, resource types.Resource) error { + return cache.gitServersCache.DeleteGitServer(ctx, resource.GetName()) +} + +func (gitServerExecutor) isSingleton() bool { return false } + +func (gitServerExecutor) getReader(cache *Cache, cacheOK bool) services.GitServerGetter { + if cacheOK { + return cache.gitServersCache + } + return cache.Config.GitServers +} + +var _ executor[types.Server, services.GitServerGetter] = gitServerExecutor{} diff --git a/lib/cache/git_server_test.go b/lib/cache/git_server_test.go new file mode 100644 index 0000000000000..35ce40941a53b --- /dev/null +++ b/lib/cache/git_server_test.go @@ -0,0 +1,65 @@ +/* + * Teleport + * Copyright (C) 2024 Gravitational, Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package cache + +import ( + "context" + "testing" + + "github.com/gravitational/trace" + "github.com/stretchr/testify/require" + + "github.com/gravitational/teleport/api/types" +) + +func TestGitServers(t *testing.T) { + t.Parallel() + + p, err := newPack(t.TempDir(), ForAuth) + require.NoError(t, err) + t.Cleanup(p.Close) + + testResources(t, p, testFuncs[types.Server]{ + newResource: func(name string) (types.Server, error) { + return types.NewGitHubServer( + types.GitHubServerMetadata{ + Integration: name, + Organization: name, + }) + }, + create: func(ctx context.Context, server types.Server) error { + _, err := p.gitServers.CreateGitServer(ctx, server) + return trace.Wrap(err) + }, + list: func(ctx context.Context) ([]types.Server, error) { + servers, _, err := p.gitServers.ListGitServers(ctx, 0, "") + return servers, trace.Wrap(err) + }, + update: func(ctx context.Context, server types.Server) error { + _, err := p.gitServers.UpdateGitServer(ctx, server) + return trace.Wrap(err) + }, + deleteAll: p.gitServers.DeleteAllGitServers, + cacheList: func(ctx context.Context) ([]types.Server, error) { + servers, _, err := p.cache.ListGitServers(ctx, 0, "") + return servers, trace.Wrap(err) + }, + cacheGet: p.cache.GetGitServer, + }) +} diff --git a/lib/cloud/aws/config/config.go b/lib/cloud/aws/config/config.go index 815ebea3d0230..13e032bf3fe65 100644 --- a/lib/cloud/aws/config/config.go +++ b/lib/cloud/aws/config/config.go @@ -24,7 +24,9 @@ import ( "github.com/aws/aws-sdk-go-v2/config" "github.com/aws/aws-sdk-go-v2/credentials/stscreds" "github.com/aws/aws-sdk-go-v2/service/sts" + "github.com/aws/smithy-go/tracing/smithyoteltracing" "github.com/gravitational/trace" + "go.opentelemetry.io/otel" "github.com/gravitational/teleport/lib/modules" ) @@ -221,7 +223,9 @@ func getAWSConfigForRole(ctx context.Context, region string, options awsOptions) return aws.Config{}, trace.Wrap(err) } - stsClient := sts.NewFromConfig(*options.baseConfig) + stsClient := sts.NewFromConfig(*options.baseConfig, func(o *sts.Options) { + o.TracerProvider = smithyoteltracing.Adapt(otel.GetTracerProvider()) + }) cred := stscreds.NewAssumeRoleProvider(stsClient, options.assumeRoleARN, func(aro *stscreds.AssumeRoleOptions) { if options.assumeRoleExternalID != "" { aro.ExternalID = aws.String(options.assumeRoleExternalID) diff --git a/lib/cloud/clients.go b/lib/cloud/clients.go index 328ee76bcee0e..3cce15285593a 100644 --- a/lib/cloud/clients.go +++ b/lib/cloud/clients.go @@ -60,8 +60,6 @@ import ( "github.com/aws/aws-sdk-go/service/s3/s3iface" "github.com/aws/aws-sdk-go/service/secretsmanager" "github.com/aws/aws-sdk-go/service/secretsmanager/secretsmanageriface" - "github.com/aws/aws-sdk-go/service/ssm" - "github.com/aws/aws-sdk-go/service/ssm/ssmiface" "github.com/aws/aws-sdk-go/service/sts" "github.com/aws/aws-sdk-go/service/sts/stsiface" "github.com/gravitational/trace" @@ -133,8 +131,6 @@ type AWSClients interface { GetAWSIAMClient(ctx context.Context, region string, opts ...AWSOptionsFn) (iamiface.IAMAPI, error) // GetAWSSTSClient returns AWS STS client for the specified region. GetAWSSTSClient(ctx context.Context, region string, opts ...AWSOptionsFn) (stsiface.STSAPI, error) - // GetAWSSSMClient returns AWS SSM client for the specified region. - GetAWSSSMClient(ctx context.Context, region string, opts ...AWSOptionsFn) (ssmiface.SSMAPI, error) // GetAWSEKSClient returns AWS EKS client for the specified region. GetAWSEKSClient(ctx context.Context, region string, opts ...AWSOptionsFn) (eksiface.EKSAPI, error) // GetAWSKMSClient returns AWS KMS client for the specified region. @@ -592,15 +588,6 @@ func (c *cloudClients) GetAWSSTSClient(ctx context.Context, region string, opts return sts.New(session), nil } -// GetAWSSSMClient returns AWS SSM client for the specified region. -func (c *cloudClients) GetAWSSSMClient(ctx context.Context, region string, opts ...AWSOptionsFn) (ssmiface.SSMAPI, error) { - session, err := c.GetAWSSession(ctx, region, opts...) - if err != nil { - return nil, trace.Wrap(err) - } - return ssm.New(session), nil -} - // GetAWSEKSClient returns AWS EKS client for the specified region. func (c *cloudClients) GetAWSEKSClient(ctx context.Context, region string, opts ...AWSOptionsFn) (eksiface.EKSAPI, error) { session, err := c.GetAWSSession(ctx, region, opts...) @@ -1021,7 +1008,6 @@ type TestCloudClients struct { GCPGKE gcp.GKEClient GCPProjects gcp.ProjectsClient GCPInstances gcp.InstancesClient - SSM ssmiface.SSMAPI InstanceMetadata imds.Client EKS eksiface.EKSAPI KMS kmsiface.KMSAPI @@ -1191,15 +1177,6 @@ func (c *TestCloudClients) GetAWSKMSClient(ctx context.Context, region string, o return c.KMS, nil } -// GetAWSSSMClient returns an AWS SSM client -func (c *TestCloudClients) GetAWSSSMClient(ctx context.Context, region string, opts ...AWSOptionsFn) (ssmiface.SSMAPI, error) { - _, err := c.GetAWSSession(ctx, region, opts...) - if err != nil { - return nil, trace.Wrap(err) - } - return c.SSM, nil -} - // GetGCPIAMClient returns GCP IAM client. func (c *TestCloudClients) GetGCPIAMClient(ctx context.Context) (*gcpcredentials.IamCredentialsClient, error) { return gcpcredentials.NewIamCredentialsClient(ctx, diff --git a/lib/configurators/aws/aws.go b/lib/configurators/aws/aws.go index 839bf08de2df1..6673b1fbe8519 100644 --- a/lib/configurators/aws/aws.go +++ b/lib/configurators/aws/aws.go @@ -34,7 +34,9 @@ import ( "github.com/aws/aws-sdk-go-v2/service/ssm" ssmtypes "github.com/aws/aws-sdk-go-v2/service/ssm/types" "github.com/aws/aws-sdk-go-v2/service/sts" + "github.com/aws/smithy-go/tracing/smithyoteltracing" "github.com/gravitational/trace" + "go.opentelemetry.io/otel" "github.com/gravitational/teleport/api/types" apiutils "github.com/gravitational/teleport/api/utils" @@ -388,10 +390,14 @@ func (c *ConfiguratorConfig) CheckAndSetDefaults() error { } if c.stsClient == nil { - c.stsClient = sts.NewFromConfig(*c.awsCfg) + c.stsClient = sts.NewFromConfig(*c.awsCfg, func(o *sts.Options) { + o.TracerProvider = smithyoteltracing.Adapt(otel.GetTracerProvider()) + }) } if c.iamClient == nil { - c.iamClient = iam.NewFromConfig(*c.awsCfg) + c.iamClient = iam.NewFromConfig(*c.awsCfg, func(o *iam.Options) { + o.TracerProvider = smithyoteltracing.Adapt(otel.GetTracerProvider()) + }) } if c.Identity == nil { c.Identity, err = awslib.GetIdentityWithClientV2(context.Background(), c.stsClient) @@ -413,7 +419,9 @@ func (c *ConfiguratorConfig) CheckAndSetDefaults() error { withRegion := func(o *ssm.Options) { o.Region = region } - c.ssmClients[region] = ssm.NewFromConfig(*c.awsCfg, withRegion) + c.ssmClients[region] = ssm.NewFromConfig(*c.awsCfg, withRegion, func(o *ssm.Options) { + o.TracerProvider = smithyoteltracing.Adapt(otel.GetTracerProvider()) + }) } } @@ -422,7 +430,9 @@ func (c *ConfiguratorConfig) CheckAndSetDefaults() error { if c.Policies == nil { partition := c.Identity.GetPartition() accountID := c.Identity.GetAccountID() - iamClient := iam.NewFromConfig(*c.awsCfg) + iamClient := iam.NewFromConfig(*c.awsCfg, func(o *iam.Options) { + o.TracerProvider = smithyoteltracing.Adapt(otel.GetTracerProvider()) + }) c.Policies = awslib.NewPolicies(partition, accountID, iamClient) } } diff --git a/lib/events/api.go b/lib/events/api.go index 20b72ddd2e5f9..8825577865dc0 100644 --- a/lib/events/api.go +++ b/lib/events/api.go @@ -792,35 +792,35 @@ const ( // IntegrationCreateEvent is emitted when an integration resource is created. IntegrationCreateEvent = "integration.create" - //IntegrationUpdateEvent is emitted when an integration resource is updated. + // IntegrationUpdateEvent is emitted when an integration resource is updated. IntegrationUpdateEvent = "integration.update" // IntegrationDeleteEvent is emitted when an integration resource is deleted. IntegrationDeleteEvent = "integration.delete" // PluginCreateEvent is emitted when a plugin resource is created. PluginCreateEvent = "plugin.create" - //PluginUpdateEvent is emitted when a plugin resource is updated. + // PluginUpdateEvent is emitted when a plugin resource is updated. PluginUpdateEvent = "plugin.update" // PluginDeleteEvent is emitted when a plugin resource is deleted. PluginDeleteEvent = "plugin.delete" // StaticHostUserCreateEvent is emitted when a static host user resource is created. StaticHostUserCreateEvent = "static_host_user.create" - //StaticHostUserUpdateEvent is emitted when a static host user resource is updated. + // StaticHostUserUpdateEvent is emitted when a static host user resource is updated. StaticHostUserUpdateEvent = "static_host_user.update" // StaticHostUserDeleteEvent is emitted when a static host user resource is deleted. StaticHostUserDeleteEvent = "static_host_user.delete" // CrownJewelCreateEvent is emitted when a crown jewel resource is created. CrownJewelCreateEvent = "access_graph.crown_jewel.create" - //CrownJewelUpdateEvent is emitted when a crown jewel resource is updated. + // CrownJewelUpdateEvent is emitted when a crown jewel resource is updated. CrownJewelUpdateEvent = "access_graph.crown_jewel.update" // CrownJewelDeleteEvent is emitted when a crown jewel resource is deleted. CrownJewelDeleteEvent = "access_graph.crown_jewel.delete" // UserTaskCreateEvent is emitted when a user task resource is created. UserTaskCreateEvent = "user_task.create" - //UserTaskUpdateEvent is emitted when a user task resource is updated. + // UserTaskUpdateEvent is emitted when a user task resource is updated. UserTaskUpdateEvent = "user_task.update" // UserTaskDeleteEvent is emitted when a user task resource is deleted. UserTaskDeleteEvent = "user_task.delete" @@ -838,6 +838,18 @@ const ( AutoUpdateVersionUpdateEvent = "auto_update_version.update" // AutoUpdateVersionDeleteEvent is emitted when a AutoUpdateVersion resource is deleted. AutoUpdateVersionDeleteEvent = "auto_update_version.delete" + + // ContactCreateEvent is emitted when a Contact resource is created. + ContactCreateEvent = "contact.create" + // ContactDeleteEvent is emitted when a Contact resource is deleted. + ContactDeleteEvent = "contact.delete" + + // WorkloadIdentityCreateEvent is emitted when a WorkloadIdentity resource is created. + WorkloadIdentityCreateEvent = "workload_identity.create" + // WorkloadIdentityUpdateEvent is emitted when a WorkloadIdentity resource is updated. + WorkloadIdentityUpdateEvent = "workload_identity.update" + // WorkloadIdentityDeleteEvent is emitted when a WorkloadIdentity resource is deleted. + WorkloadIdentityDeleteEvent = "workload_identity.delete" ) // Add an entry to eventsMap in lib/events/events_test.go when you add @@ -856,15 +868,13 @@ const ( V3 = 3 ) -var ( - // SessionRecordingEvents is a list of events that are related to session - // recorings. - SessionRecordingEvents = []string{ - SessionEndEvent, - WindowsDesktopSessionEndEvent, - DatabaseSessionEndEvent, - } -) +// SessionRecordingEvents is a list of events that are related to session +// recorings. +var SessionRecordingEvents = []string{ + SessionEndEvent, + WindowsDesktopSessionEndEvent, + DatabaseSessionEndEvent, +} // ServerMetadataGetter represents interface // that provides information about its server id diff --git a/lib/events/athena/athena.go b/lib/events/athena/athena.go index 0fa5416a5e1cb..7541523ea01bd 100644 --- a/lib/events/athena/athena.go +++ b/lib/events/athena/athena.go @@ -33,7 +33,6 @@ import ( "github.com/gravitational/trace" "github.com/jonboulle/clockwork" "github.com/prometheus/client_golang/prometheus" - "go.opentelemetry.io/contrib/instrumentation/github.com/aws/aws-sdk-go-v2/otelaws" oteltrace "go.opentelemetry.io/otel/trace" "github.com/gravitational/teleport" @@ -296,7 +295,6 @@ func (cfg *Config) CheckAndSetDefaults(ctx context.Context) error { if cfg.Region != "" { awsCfg.Region = cfg.Region } - otelaws.AppendMiddlewares(&awsCfg.APIOptions) cfg.PublisherConsumerAWSConfig = &awsCfg } @@ -452,7 +450,6 @@ func (cfg *Config) UpdateForExternalAuditStorage(ctx context.Context, externalAu if err != nil { return trace.Wrap(err) } - otelaws.AppendMiddlewares(&awsCfg.APIOptions) cfg.StorerQuerierAWSConfig = &awsCfg cfg.ObserveWriteEventsError = externalAuditStorage.ErrorCounter.ObserveEmitError diff --git a/lib/events/athena/consumer.go b/lib/events/athena/consumer.go index 0b9655c90beb2..4c51ec53f0fa8 100644 --- a/lib/events/athena/consumer.go +++ b/lib/events/athena/consumer.go @@ -38,9 +38,11 @@ import ( s3Types "github.com/aws/aws-sdk-go-v2/service/s3/types" "github.com/aws/aws-sdk-go-v2/service/sqs" sqsTypes "github.com/aws/aws-sdk-go-v2/service/sqs/types" + "github.com/aws/smithy-go/tracing/smithyoteltracing" "github.com/google/uuid" "github.com/gravitational/trace" "github.com/parquet-go/parquet-go" + "go.opentelemetry.io/otel" "github.com/gravitational/teleport" apievents "github.com/gravitational/teleport/api/types/events" @@ -121,14 +123,26 @@ func newConsumer(cfg Config, cancelFn context.CancelFunc) (*consumer, error) { t.MaxIdleConns = defaults.HTTPMaxIdleConns t.MaxIdleConnsPerHost = defaults.HTTPMaxIdleConnsPerHost }) - sqsClient := sqs.NewFromConfig(*cfg.PublisherConsumerAWSConfig, func(o *sqs.Options) { o.HTTPClient = sqsHTTPClient }) + sqsClient := sqs.NewFromConfig(*cfg.PublisherConsumerAWSConfig, + func(o *sqs.Options) { + o.HTTPClient = sqsHTTPClient + o.TracerProvider = smithyoteltracing.Adapt(otel.GetTracerProvider()) + }) s3HTTPClient := awshttp.NewBuildableClient().WithTransportOptions(func(t *http.Transport) { t.MaxIdleConns = defaults.HTTPMaxIdleConns t.MaxIdleConnsPerHost = defaults.HTTPMaxIdleConnsPerHost }) - publisherS3Client := s3.NewFromConfig(*cfg.PublisherConsumerAWSConfig, func(o *s3.Options) { o.HTTPClient = s3HTTPClient }) - storerS3Client := s3.NewFromConfig(*cfg.StorerQuerierAWSConfig, func(o *s3.Options) { o.HTTPClient = s3HTTPClient }) + publisherS3Client := s3.NewFromConfig(*cfg.PublisherConsumerAWSConfig, + func(o *s3.Options) { + o.HTTPClient = s3HTTPClient + o.TracerProvider = smithyoteltracing.Adapt(otel.GetTracerProvider()) + }) + storerS3Client := s3.NewFromConfig(*cfg.StorerQuerierAWSConfig, + func(o *s3.Options) { + o.HTTPClient = s3HTTPClient + o.TracerProvider = smithyoteltracing.Adapt(otel.GetTracerProvider()) + }) collectCfg := sqsCollectConfig{ sqsReceiver: sqsClient, diff --git a/lib/events/athena/publisher.go b/lib/events/athena/publisher.go index 1c9fed79107f4..4f5d541c1fd8a 100644 --- a/lib/events/athena/publisher.go +++ b/lib/events/athena/publisher.go @@ -36,8 +36,10 @@ import ( snstypes "github.com/aws/aws-sdk-go-v2/service/sns/types" "github.com/aws/aws-sdk-go-v2/service/sqs" sqstypes "github.com/aws/aws-sdk-go-v2/service/sqs/types" + "github.com/aws/smithy-go/tracing/smithyoteltracing" "github.com/google/uuid" "github.com/gravitational/trace" + "go.opentelemetry.io/otel" apievents "github.com/gravitational/teleport/api/types/events" "github.com/gravitational/teleport/lib/defaults" @@ -183,18 +185,21 @@ func newPublisherFromAthenaConfig(cfg Config) *publisher { messagePublisher = SQSPublisherFunc(cfg.QueueURL, sqs.NewFromConfig(*cfg.PublisherConsumerAWSConfig, func(o *sqs.Options) { o.Retryer = r o.HTTPClient = hc + o.TracerProvider = smithyoteltracing.Adapt(otel.GetTracerProvider()) })) } else { messagePublisher = SNSPublisherFunc(cfg.TopicARN, sns.NewFromConfig(*cfg.PublisherConsumerAWSConfig, func(o *sns.Options) { o.Retryer = r o.HTTPClient = hc + o.TracerProvider = smithyoteltracing.Adapt(otel.GetTracerProvider()) })) } return NewPublisher(PublisherConfig{ MessagePublisher: messagePublisher, - // TODO(tobiaszheller): consider reworking lib/observability to work also on s3 sdk-v2. - Uploader: s3manager.NewUploader(s3.NewFromConfig(*cfg.PublisherConsumerAWSConfig)), + Uploader: s3manager.NewUploader(s3.NewFromConfig(*cfg.PublisherConsumerAWSConfig, func(o *s3.Options) { + o.TracerProvider = smithyoteltracing.Adapt(otel.GetTracerProvider()) + })), PayloadBucket: cfg.largeEventsBucket, PayloadPrefix: cfg.largeEventsPrefix, }) diff --git a/lib/events/athena/querier.go b/lib/events/athena/querier.go index 9b22920e5cc99..b2d36040d0014 100644 --- a/lib/events/athena/querier.go +++ b/lib/events/athena/querier.go @@ -36,11 +36,13 @@ import ( athenaTypes "github.com/aws/aws-sdk-go-v2/service/athena/types" "github.com/aws/aws-sdk-go-v2/service/s3" s3types "github.com/aws/aws-sdk-go-v2/service/s3/types" + "github.com/aws/smithy-go/tracing/smithyoteltracing" "github.com/dustin/go-humanize" "github.com/google/uuid" "github.com/gravitational/trace" "github.com/jonboulle/clockwork" "github.com/parquet-go/parquet-go" + "go.opentelemetry.io/otel" "go.opentelemetry.io/otel/attribute" oteltrace "go.opentelemetry.io/otel/trace" @@ -148,8 +150,12 @@ func newQuerier(cfg querierConfig) (*querier, error) { return nil, trace.Wrap(err) } return &querier{ - athenaClient: athena.NewFromConfig(*cfg.awsCfg), - s3Getter: s3.NewFromConfig(*cfg.awsCfg), + athenaClient: athena.NewFromConfig(*cfg.awsCfg, func(o *athena.Options) { + o.TracerProvider = smithyoteltracing.Adapt(otel.GetTracerProvider()) + }), + s3Getter: s3.NewFromConfig(*cfg.awsCfg, func(o *s3.Options) { + o.TracerProvider = smithyoteltracing.Adapt(otel.GetTracerProvider()) + }), querierConfig: cfg, }, nil } diff --git a/lib/events/codes.go b/lib/events/codes.go index fa8c284fe925b..fa86db2bb32bd 100644 --- a/lib/events/codes.go +++ b/lib/events/codes.go @@ -286,6 +286,8 @@ const ( ExecFailureCode = "T3002E" // PortForwardCode is the port forward event code. PortForwardCode = "T3003I" + // PortForwardStopCode is the port forward stop event code. + PortForwardStopCode = "T3003S" // PortForwardFailureCode is the port forward failure event code. PortForwardFailureCode = "T3003E" // SCPDownloadCode is the file download event code. @@ -669,6 +671,18 @@ const ( // AutoUpdateVersionDeleteCode is the auto update version delete event code. AutoUpdateVersionDeleteCode = "AUV003I" + // ContactCreateCode is the auto update version create event code. + ContactCreateCode = "TCTC001I" + // ContactDeleteCode is the auto update version delete event code. + ContactDeleteCode = "TCTC002I" + + // WorkloadIdentityCreateCode is the workload identity create event code. + WorkloadIdentityCreateCode = "WID001I" + // WorkloadIdentityUpdateCode is the workload identity update event code. + WorkloadIdentityUpdateCode = "WID002I" + // WorkloadIdentityDeleteCode is the workload identity delete event code. + WorkloadIdentityDeleteCode = "WID003I" + // UnknownCode is used when an event of unknown type is encountered. UnknownCode = apievents.UnknownCode ) diff --git a/lib/events/dynamic.go b/lib/events/dynamic.go index 476528255e5ba..f695855bad233 100644 --- a/lib/events/dynamic.go +++ b/lib/events/dynamic.go @@ -462,6 +462,19 @@ func FromEventFields(fields EventFields) (events.AuditEvent, error) { e = &events.AutoUpdateVersionUpdate{} case AutoUpdateVersionDeleteEvent: e = &events.AutoUpdateVersionDelete{} + + case ContactCreateEvent: + e = &events.ContactCreate{} + case ContactDeleteEvent: + e = &events.ContactDelete{} + + case WorkloadIdentityCreateEvent: + e = &events.WorkloadIdentityCreate{} + case WorkloadIdentityUpdateEvent: + e = &events.WorkloadIdentityUpdate{} + case WorkloadIdentityDeleteEvent: + e = &events.WorkloadIdentityDelete{} + default: slog.ErrorContext(context.Background(), "Attempted to convert dynamic event of unknown type into protobuf event.", "event_type", eventType) unknown := &events.Unknown{} diff --git a/lib/events/dynamoevents/dynamoevents.go b/lib/events/dynamoevents/dynamoevents.go index 1504d987b7fcc..3f3c46ac874b6 100644 --- a/lib/events/dynamoevents/dynamoevents.go +++ b/lib/events/dynamoevents/dynamoevents.go @@ -43,10 +43,11 @@ import ( "github.com/aws/aws-sdk-go-v2/service/dynamodb" dynamodbtypes "github.com/aws/aws-sdk-go-v2/service/dynamodb/types" "github.com/aws/smithy-go" + "github.com/aws/smithy-go/tracing/smithyoteltracing" "github.com/google/uuid" "github.com/gravitational/trace" "github.com/jonboulle/clockwork" - "go.opentelemetry.io/contrib/instrumentation/github.com/aws/aws-sdk-go-v2/otelaws" + "go.opentelemetry.io/otel" "github.com/gravitational/teleport" apidefaults "github.com/gravitational/teleport/api/defaults" @@ -307,7 +308,12 @@ func New(ctx context.Context, cfg Config) (*Log, error) { return nil, trace.Wrap(err) } - dynamoOpts := []func(*dynamodb.Options){dynamodb.WithEndpointResolverV2(resolver)} + dynamoOpts := []func(*dynamodb.Options){ + dynamodb.WithEndpointResolverV2(resolver), + func(o *dynamodb.Options) { + o.TracerProvider = smithyoteltracing.Adapt(otel.GetTracerProvider()) + }, + } // Override the service endpoint using the "endpoint" query parameter from // "audit_events_uri". This is for non-AWS DynamoDB-compatible backends. @@ -333,8 +339,6 @@ func New(ctx context.Context, cfg Config) (*Log, error) { return nil, trace.Wrap(err) } - otelaws.AppendMiddlewares(&awsConfig.APIOptions, otelaws.WithAttributeSetter(otelaws.DynamoDBAttributeSetter)) - client := dynamodb.NewFromConfig(awsConfig, dynamoOpts...) b := &Log{ logger: l, diff --git a/lib/events/events_test.go b/lib/events/events_test.go index d304a65ddd4bc..b97c8064f3b62 100644 --- a/lib/events/events_test.go +++ b/lib/events/events_test.go @@ -242,6 +242,11 @@ var eventsMap = map[string]apievents.AuditEvent{ AutoUpdateVersionCreateEvent: &apievents.AutoUpdateVersionCreate{}, AutoUpdateVersionUpdateEvent: &apievents.AutoUpdateVersionUpdate{}, AutoUpdateVersionDeleteEvent: &apievents.AutoUpdateVersionDelete{}, + ContactCreateEvent: &apievents.ContactCreate{}, + ContactDeleteEvent: &apievents.ContactDelete{}, + WorkloadIdentityCreateEvent: &apievents.WorkloadIdentityCreate{}, + WorkloadIdentityUpdateEvent: &apievents.WorkloadIdentityUpdate{}, + WorkloadIdentityDeleteEvent: &apievents.WorkloadIdentityDelete{}, } // TestJSON tests JSON marshal events diff --git a/lib/events/s3sessions/s3handler.go b/lib/events/s3sessions/s3handler.go index 8b8487bd26a3f..f4492d27337a9 100644 --- a/lib/events/s3sessions/s3handler.go +++ b/lib/events/s3sessions/s3handler.go @@ -37,8 +37,9 @@ import ( "github.com/aws/aws-sdk-go-v2/feature/s3/manager" "github.com/aws/aws-sdk-go-v2/service/s3" awstypes "github.com/aws/aws-sdk-go-v2/service/s3/types" + "github.com/aws/smithy-go/tracing/smithyoteltracing" "github.com/gravitational/trace" - "go.opentelemetry.io/contrib/instrumentation/github.com/aws/aws-sdk-go-v2/otelaws" + "go.opentelemetry.io/otel" "github.com/gravitational/teleport" "github.com/gravitational/teleport/api/types" @@ -208,7 +209,12 @@ func NewHandler(ctx context.Context, cfg Config) (*Handler, error) { return nil, trace.Wrap(err) } - s3Opts := []func(*s3.Options){s3.WithEndpointResolverV2(resolver)} + s3Opts := []func(*s3.Options){ + s3.WithEndpointResolverV2(resolver), + func(o *s3.Options) { + o.TracerProvider = smithyoteltracing.Adapt(otel.GetTracerProvider()) + }, + } if cfg.Endpoint != "" { if _, err := url.Parse(cfg.Endpoint); err != nil { @@ -233,8 +239,6 @@ func NewHandler(ctx context.Context, cfg Config) (*Handler, error) { return nil, trace.Wrap(err) } - otelaws.AppendMiddlewares(&awsConfig.APIOptions) - // Create S3 client with custom options client := s3.NewFromConfig(awsConfig, s3Opts...) diff --git a/lib/kube/proxy/forwarder.go b/lib/kube/proxy/forwarder.go index 1cfd6351fddce..76443816414c8 100644 --- a/lib/kube/proxy/forwarder.go +++ b/lib/kube/proxy/forwarder.go @@ -25,6 +25,7 @@ import ( "errors" "fmt" "io" + "log/slog" "maps" "net" "net/http" @@ -1773,10 +1774,12 @@ func (f *Forwarder) portForward(authCtx *authContext, w http.ResponseWriter, req return nil, trace.Wrap(err) } + auditSent := map[string]bool{} // Set of `addr`. Can be multiple ports on single call. Using bool to simplify the check. onPortForward := func(addr string, success bool) { - if !sess.isLocalKubernetesCluster { + if !sess.isLocalKubernetesCluster || auditSent[addr] { return } + auditSent[addr] = true portForward := &apievents.PortForward{ Metadata: apievents.Metadata{ Type: events.PortForwardEvent, @@ -1792,6 +1795,11 @@ func (f *Forwarder) portForward(authCtx *authContext, w http.ResponseWriter, req Status: apievents.Status{ Success: success, }, + KubernetesClusterMetadata: sess.eventClusterMeta(req), + KubernetesPodMetadata: apievents.KubernetesPodMetadata{ + KubernetesPodNamespace: p.ByName("podNamespace"), + KubernetesPodName: p.ByName("podName"), + }, } if !success { portForward.Code = events.PortForwardFailureCode @@ -1800,6 +1808,31 @@ func (f *Forwarder) portForward(authCtx *authContext, w http.ResponseWriter, req f.log.WithError(err).Warn("Failed to emit event.") } } + defer func() { + for addr := range auditSent { + portForward := &apievents.PortForward{ + Metadata: apievents.Metadata{ + Type: events.PortForwardEvent, + Code: events.PortForwardStopCode, + }, + UserMetadata: authCtx.eventUserMeta(), + ConnectionMetadata: apievents.ConnectionMetadata{ + LocalAddr: sess.kubeAddress, + RemoteAddr: req.RemoteAddr, + Protocol: events.EventProtocolKube, + }, + Addr: addr, + KubernetesClusterMetadata: sess.eventClusterMeta(req), + KubernetesPodMetadata: apievents.KubernetesPodMetadata{ + KubernetesPodNamespace: p.ByName("podNamespace"), + KubernetesPodName: p.ByName("podName"), + }, + } + if err := f.cfg.Emitter.EmitAuditEvent(f.ctx, portForward); err != nil { + f.log.WithError(err).Warn("Failed to emit event.") + } + } + }() q := req.URL.Query() request := portForwardRequest{ @@ -2348,9 +2381,11 @@ func (s *clusterSession) monitorConn(conn net.Conn, err error, hostID string) (n Context: s.connCtx, TeleportUser: s.User.GetName(), ServerID: s.parent.cfg.HostID, - Entry: s.parent.log, - Emitter: s.parent.cfg.AuthClient, - EmitterContext: s.parent.ctx, + // TODO(tross) update this to use the child logger + // once Forwarder is converted to use a slog.Logger + Logger: slog.Default(), + Emitter: s.parent.cfg.AuthClient, + EmitterContext: s.parent.ctx, }) if err != nil { tc.CloseWithCause(err) diff --git a/lib/kubernetestoken/token_source.go b/lib/kube/token/source.go similarity index 98% rename from lib/kubernetestoken/token_source.go rename to lib/kube/token/source.go index 55a506937cc89..8a10c442088fa 100644 --- a/lib/kubernetestoken/token_source.go +++ b/lib/kube/token/source.go @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -package kubernetestoken +package token import ( "strings" diff --git a/lib/kubernetestoken/token_source_test.go b/lib/kube/token/source_test.go similarity index 99% rename from lib/kubernetestoken/token_source_test.go rename to lib/kube/token/source_test.go index 4089017378278..9d3e5fd5a4092 100644 --- a/lib/kubernetestoken/token_source_test.go +++ b/lib/kube/token/source_test.go @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -package kubernetestoken +package token import ( "io/fs" diff --git a/lib/kubernetestoken/token_validator.go b/lib/kube/token/validator.go similarity index 78% rename from lib/kubernetestoken/token_validator.go rename to lib/kube/token/validator.go index 3d04392f2eeae..056b5ee1def0d 100644 --- a/lib/kubernetestoken/token_validator.go +++ b/lib/kube/token/validator.go @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -package kubernetestoken +package token import ( "context" @@ -37,6 +37,7 @@ import ( "k8s.io/client-go/rest" "github.com/gravitational/teleport/api/types" + "github.com/gravitational/teleport/api/utils" ) const ( @@ -46,8 +47,6 @@ const ( // Kubernetes should support bound tokens on 1.20 and 1.21, // but we can have an apiserver running 1.21 and kubelets running 1.19. kubernetesBoundTokenSupportVersion = "1.22.0" - // kubernetesAudience is the Kubernetes default audience put on SA tokens if we don't specify one. - kubernetesAudience = "https://kubernetes.default.svc" ) type ValidationResult struct { @@ -85,35 +84,65 @@ func (c *ValidationResult) JoinAuditAttributes() (map[string]interface{}, error) // Kubernetes TokenRequest API endpoint. type TokenReviewValidator struct { mu sync.Mutex - // client is protected by mu and should only be accessed via the getClient - // method. + // client and clusterAudiences are protected by mu and should only be + // accessed via the getClient method. client kubernetes.Interface + // clusterAudiences contains the default Kubernetes cluster audiences. + // This field is populated when getting the Kube client and returned by + // getClient. + // A nil value indicates that the cluster doesn't support audiences. + clusterAudiences []string } -// getClient allows the lazy initialisation of the Kubernetes client -func (v *TokenReviewValidator) getClient() (kubernetes.Interface, error) { +// getClient allows the lazy initialisation of the Kubernetes client and clusterAudiences +func (v *TokenReviewValidator) getClient(_ context.Context) (kubernetes.Interface, []string, error) { v.mu.Lock() defer v.mu.Unlock() if v.client != nil { - return v.client, nil + return v.client, v.clusterAudiences, nil } config, err := rest.InClusterConfig() if err != nil { - return nil, trace.WrapWithMessage(err, "failed to initialize in-cluster Kubernetes config") + return nil, nil, trace.WrapWithMessage(err, "failed to initialize in-cluster Kubernetes config") } client, err := kubernetes.NewForConfig(config) if err != nil { - return nil, trace.WrapWithMessage(err, "failed to initialize in-cluster Kubernetes client") + return nil, nil, trace.WrapWithMessage(err, "failed to initialize in-cluster Kubernetes client") + } + + // We extract the audiences from our own token. This allows us to detect the default Kubernetes audiences. + audiences, err := unsafeGetTokenAudiences(config.BearerToken) + if err != nil { + return nil, nil, trace.Wrap(err, "doing a self-review") } v.client = client - return client, nil + v.clusterAudiences = audiences + return client, audiences, nil +} + +// unsafeGetTokenAudiences extracts the audience from the mounted token. +// THIS FUNCTION DOES NOT VALIDATE THE TOKEN SIGNATURE. +// Bound tokens always have audiences and the list will not be empty. +// Legacy tokens don't have audiences, the result will be an empty list and no error. +func unsafeGetTokenAudiences(token string) ([]string, error) { + jwt, err := josejwt.ParseSigned(token) + if err != nil { + return nil, trace.Wrap(err) + } + claims := &ServiceAccountClaims{} + err = jwt.UnsafeClaimsWithoutVerification(claims) + if err != nil { + return nil, trace.Wrap(err) + } + + return claims.Audience, nil } // Validate uses the Kubernetes TokenReview API to validate a token and return its UserInfo func (v *TokenReviewValidator) Validate(ctx context.Context, token, clusterName string) (*ValidationResult, error) { - client, err := v.getClient() + client, audiences, err := v.getClient(ctx) if err != nil { return nil, trace.Wrap(err) } @@ -121,13 +150,23 @@ func (v *TokenReviewValidator) Validate(ctx context.Context, token, clusterName review := &v1.TokenReview{ Spec: v1.TokenReviewSpec{ Token: token, - // In-cluster used to only allow tokens with the kubernetes audience - // But people kept confusing it with JWKS and set the cluster name - // as the audience/. To avoid his common footgun we now allow tokens - // whose audience is the teleport cluster name. - Audiences: []string{kubernetesAudience, clusterName}, }, } + + // In-cluster used to only allow tokens with the kubernetes audience but people + // kept confusing it with the JWKS kube join method and set the cluster name + // as the audience. To avoid his common footgun we now allow tokens whose + // audience is the teleport cluster name. + // + // We do this only if the Kubernetes cluster supports audiences. + // Earlier Kube versions don't have audience + // support, in this case, we just do a regular token review. + if len(audiences) > 0 { + // We deduplicate because the Teleport cluster name could be one of the default audiences + // And I really don't want to discover if sending the same audience multiple times is valid for Kubernetes. + review.Spec.Audiences = utils.Deduplicate(append([]string{clusterName}, audiences...)) + } + options := metav1.CreateOptions{} reviewResult, err := client.AuthenticationV1().TokenReviews().Create(ctx, review, options) diff --git a/lib/kubernetestoken/token_validator_test.go b/lib/kube/token/validator_test.go similarity index 67% rename from lib/kubernetestoken/token_validator_test.go rename to lib/kube/token/validator_test.go index 23433f62602ef..49054df1e47ee 100644 --- a/lib/kubernetestoken/token_validator_test.go +++ b/lib/kube/token/validator_test.go @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -package kubernetestoken +package token import ( "context" @@ -41,7 +41,9 @@ import ( "github.com/gravitational/teleport/lib/cryptosuites" ) -const testClusterName = "teleport.example.com" +const ( + testClusterName = "teleport.example.com" +) var userGroups = []string{"system:serviceaccounts", "system:serviceaccounts:namespace", "system:authenticated"} @@ -58,7 +60,7 @@ var legacyTokenKubernetesVersion = version.Info{ } // tokenReviewMock creates a testing.ReactionFunc validating the tokenReview request and answering it -func tokenReviewMock(t *testing.T, reviewResult *v1.TokenReview) func(ctest.Action) (bool, runtime.Object, error) { +func tokenReviewMock(t *testing.T, reviewResult *v1.TokenReview, expectedAudiences []string) func(ctest.Action) (bool, runtime.Object, error) { return func(action ctest.Action) (bool, runtime.Object, error) { createAction, ok := action.(ctest.CreateAction) require.True(t, ok) @@ -67,7 +69,7 @@ func tokenReviewMock(t *testing.T, reviewResult *v1.TokenReview) func(ctest.Acti require.True(t, ok) require.Equal(t, reviewResult.Spec.Token, reviewRequest.Spec.Token) - require.ElementsMatch(t, reviewRequest.Spec.Audiences, []string{kubernetesAudience, testClusterName}) + require.ElementsMatch(t, expectedAudiences, reviewRequest.Spec.Audiences) return true, reviewResult, nil } } @@ -93,13 +95,82 @@ func (c *fakeClientSet) Discovery() discovery.DiscoveryInterface { return &c.discovery } +const ( + // The tokens below are test data to validate that we can extract audiences properly from tokens coming from + // different Kubernetes clusters versions. + // Those tokens are only test data and don't provide access to anything. The Kube clusters who generated them + // are long gone. + // If your scanner brought you here, please save everyone's time and DO NOT REPORT accidentally committed tokens. + + // this token has no audience + testDataLegacyToken = "eyJhbGciOiJSUzI1NiIsImtpZCI6IkRVdTJXUGNPLUthZjk2c3ZJcXhFWlBsRHUyUUx5cWxrUm1qT0s2VG9XQTAifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJkZWZhdWx0Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZWNyZXQubmFtZSI6InRlc3RzYS10b2tlbi1namZxYiIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VydmljZS1hY2NvdW50Lm5hbWUiOiJ0ZXN0c2EiLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC51aWQiOiIwYWY0YTc4Zi04ZjEwLTQ2ODUtYWMyOS1jYWUwODY1OWJjYWUiLCJzdWIiOiJzeXN0ZW06c2VydmljZWFjY291bnQ6ZGVmYXVsdDp0ZXN0c2EifQ.Y683lBdmc5e0wvL3BPXj4hVkYXiu7M4bn2w1tvqIdrXdat3Fnqlv5Qgih3RS1VRETXDOMp3_CA8Jv7Nqe_PSIrBPvLStRYvvRByWDWY3PvYDfFxeARKj0E_AQnFkXQxEN21eXkJi3k0i93uhGGNvUr5bNpk7buMbD2UKt-y8N7sQmTIQ6nPdjaC3YHn32-MHpAquqwbTqXhETPrvk9RjSzE4jszcd_P1Gi7BdZoHPErnCc5XaEVBJnHiWsZCsJDL00nAaAS_Ru8TsIdX_z1pyp91sigxfvFrGwhns3oXq54rrhpBuloPwmDW0gWDAV-qjje5MPFuaiov431ocKrOsg\n" + // audience is defaultKubeAudiences + testDataBoundTokenKubeAudiences = "eyJhbGciOiJSUzI1NiIsImtpZCI6InY2VnNnUmdpVS1DNlZWaUVjLV9Wb1dCR2dpZVEtblV0RDFXQjVfY3JOckEifQ.eyJhdWQiOlsiaHR0cHM6Ly9rdWJlcm5ldGVzLmRlZmF1bHQuc3ZjLmNsdXN0ZXIubG9jYWwiLCJrM3MiXSwiZXhwIjoxNzY0OTQ3Mzc3LCJpYXQiOjE3MzM0MTEzNzcsImlzcyI6Imh0dHBzOi8va3ViZXJuZXRlcy5kZWZhdWx0LnN2Yy5jbHVzdGVyLmxvY2FsIiwianRpIjoiMjE4Y2I0ZGQtMzQyNS00Yzc0LThiODktNTRiNzIzNGRiMDE4Iiwia3ViZXJuZXRlcy5pbyI6eyJuYW1lc3BhY2UiOiJkZWZhdWx0Iiwibm9kZSI6eyJuYW1lIjoiazNkLWszcy1kZWZhdWx0LXNlcnZlci0wIiwidWlkIjoiZWMwMTUzZGUtMThiOC00OTk3LTg4ZGQtNjFiYzVmZTkzYThiIn0sInBvZCI6eyJuYW1lIjoiaHVnby10ZXN0LXBvZCIsInVpZCI6ImIxNjliZTdkLWNkYTItNGNhNy04ODVmLWMxNzJiMzZhNjUzNyJ9LCJzZXJ2aWNlYWNjb3VudCI6eyJuYW1lIjoiZGVmYXVsdCIsInVpZCI6IjQxMzgxNWFiLWNjZjctNDI4YS1iNjA4LTllNGUyYmU1OTc2ZiJ9LCJ3YXJuYWZ0ZXIiOjE3MzM0MTQ5ODR9LCJuYmYiOjE3MzM0MTEzNzcsInN1YiI6InN5c3RlbTpzZXJ2aWNlYWNjb3VudDpkZWZhdWx0OmRlZmF1bHQifQ.Cs3mekFZzEOk1Gj_w0seURuYC92aY5Xy9WdNz5LtyL0L0eKNnzTV5MNWHgAas--t8ABcvHtcbdS1-XSemqyDfn_GcNJXeZa88bX1PKyG-XdDuqfn40DRxrBXR_sim_2WUGJM2oNh6C6irHzUOQFU0Wmx4oWY3pZ_BSFUlDi3xKnPv-TFWroBVmtc_wLAbCBl5gZF1KngAgMlbdX0szBEwzewkeoFhDTh3OoNWRaRpJL7_YeZsBkKPGY107fFMDXIKmZtd6qyU8-yp3Wwn_1qwucfllNmru8_bncqN18RuDOoQyFej4R93NwntyfzGy1wQexR363QFd7veSgtBS7nJQ" + // audience is customKubeAudiences + testDataBoundTokenCustomAudiences = "eyJhbGciOiJSUzI1NiIsImtpZCI6InY2VnNnUmdpVS1DNlZWaUVjLV9Wb1dCR2dpZVEtblV0RDFXQjVfY3JOckEifQ.eyJhdWQiOlsidGVsZXBvcnQuZXhhbXBsZS5jb20iXSwiZXhwIjoxNzMzNDE2MDEyLCJpYXQiOjE3MzM0MTI0MDUsImlzcyI6Imh0dHBzOi8va3ViZXJuZXRlcy5kZWZhdWx0LnN2Yy5jbHVzdGVyLmxvY2FsIiwianRpIjoiZDE5Yjk2ZjctMTgyYy00ODVjLThkYWYtNzdkMTRhYzA4NmNlIiwia3ViZXJuZXRlcy5pbyI6eyJuYW1lc3BhY2UiOiJkZWZhdWx0Iiwibm9kZSI6eyJuYW1lIjoiazNkLWszcy1kZWZhdWx0LXNlcnZlci0wIiwidWlkIjoiZWMwMTUzZGUtMThiOC00OTk3LTg4ZGQtNjFiYzVmZTkzYThiIn0sInBvZCI6eyJuYW1lIjoiaHVnby10ZXN0LXBvZCIsInVpZCI6Ijc1ZTIwMmFjLTAwZWMtNDVmZC05ZGViLTgwM2JkODA0YjMxNSJ9LCJzZXJ2aWNlYWNjb3VudCI6eyJuYW1lIjoiZGVmYXVsdCIsInVpZCI6IjQxMzgxNWFiLWNjZjctNDI4YS1iNjA4LTllNGUyYmU1OTc2ZiJ9fSwibmJmIjoxNzMzNDEyNDA1LCJzdWIiOiJzeXN0ZW06c2VydmljZWFjY291bnQ6ZGVmYXVsdDpkZWZhdWx0In0.QwhCSQzDrXBNjZU6X642FC_fzglaT80ldCFTXQEwR6IdPvPntjbSAZq8yN6arngctgM6wEh3buc7kq0awmytgF2hbeSRN6PEeRbVvKaAClnCPTzlJYnDq4FOYezqSBZ7jVCW3cNxeU0QCNwj5w8Xy1uxCJu24iWov-ElyxqiCkpa9FjiquOu4kHq9OErXe5ZmXmTDOILnQBzsZnbg-sBKTX-mNAHro8DwQCfFtPmW27iySaScIegqwZNHXbZJDWZYDB2uj3xuHzX75amgPWpfqUq4JaNkf-xlldaH3SdZa5hlL9zvV9e9Dwgqlnergq6EpEZNHmCPb9birQFn46n_w" +) + +var ( + defaultKubeAudiences = []string{"https://kubernetes.default.svc.cluster.local", "k3s"} + customKubeAudiences = []string{testClusterName} +) + +func TestGetTokenAudiences(t *testing.T) { + tests := []struct { + name string + token string + expectedAudiences []string + expectErr require.ErrorAssertionFunc + }{ + { + name: "legacy token with no audience", + token: testDataLegacyToken, + expectedAudiences: nil, + expectErr: require.NoError, + }, + { + name: "modern bound token with default kube audience", + token: testDataBoundTokenKubeAudiences, + expectedAudiences: defaultKubeAudiences, + expectErr: require.NoError, + }, + { + name: "modern bound token with custom audience", + token: testDataBoundTokenCustomAudiences, + expectedAudiences: customKubeAudiences, + expectErr: require.NoError, + }, + { + name: "broken token", + token: "asdfghjkl", + expectedAudiences: nil, + expectErr: require.Error, + }, + { + name: "no token", + token: "", + expectedAudiences: nil, + expectErr: require.Error, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + result, err := unsafeGetTokenAudiences(tt.token) + tt.expectErr(t, err) + assert.Equal(t, tt.expectedAudiences, result) + }) + } +} + func TestIDTokenValidator_Validate(t *testing.T) { tests := []struct { - token string - review *v1.TokenReview - kubeVersion *version.Info - wantResult *ValidationResult - expectedError error + token string + review *v1.TokenReview + kubeVersion *version.Info + wantResult *ValidationResult + clusterAudiences []string + expectedAudiences []string + expectedError error }{ { token: "valid", @@ -127,6 +198,39 @@ func TestIDTokenValidator_Validate(t *testing.T) { }, kubeVersion: &boundTokenKubernetesVersion, expectedError: nil, + // As the cluster doesn't have default audiences, we should not set + // the cluster name in the tokenReview request audiences. + expectedAudiences: nil, + }, + { + token: "valid-with-cluster-audiences", + review: &v1.TokenReview{ + Spec: v1.TokenReviewSpec{ + Token: "valid-with-cluster-audiences", + }, + Status: v1.TokenReviewStatus{ + Authenticated: true, + User: v1.UserInfo{ + Username: "system:serviceaccount:namespace:my-service-account", + UID: "sa-uuid", + Groups: userGroups, + Extra: map[string]v1.ExtraValue{ + "authentication.kubernetes.io/pod-name": {"podA"}, + "authentication.kubernetes.io/pod-uid": {"podA-uuid"}, + }, + }, + }, + }, + wantResult: &ValidationResult{ + Type: types.KubernetesJoinTypeInCluster, + Username: "system:serviceaccount:namespace:my-service-account", + // Raw will be filled in during test run to value of review + }, + kubeVersion: &boundTokenKubernetesVersion, + expectedError: nil, + clusterAudiences: defaultKubeAudiences, + // We check that the cluster name got added to the default kube cluster audiences + expectedAudiences: append([]string{testClusterName}, defaultKubeAudiences...), }, { token: "valid-not-bound", @@ -237,9 +341,10 @@ func TestIDTokenValidator_Validate(t *testing.T) { } client := newFakeClientset(tt.kubeVersion) - client.AddReactor("create", "tokenreviews", tokenReviewMock(t, tt.review)) + client.AddReactor("create", "tokenreviews", tokenReviewMock(t, tt.review, tt.expectedAudiences)) v := TokenReviewValidator{ - client: client, + client: client, + clusterAudiences: tt.clusterAudiences, } result, err := v.Validate(context.Background(), tt.token, testClusterName) if tt.expectedError != nil { diff --git a/lib/service/db.go b/lib/service/db.go index 80258e66582e1..3bb3938b9321b 100644 --- a/lib/service/db.go +++ b/lib/service/db.go @@ -137,7 +137,7 @@ func (process *TeleportProcess) initDatabaseService() (retErr error) { ServerID: process.Config.HostUUID, Emitter: asyncEmitter, EmitterContext: process.ExitContext(), - Logger: process.log, + Logger: process.logger, }) if err != nil { return trace.Wrap(err) diff --git a/lib/service/service.go b/lib/service/service.go index d1e92c40675dc..97fbd4a03e370 100644 --- a/lib/service/service.go +++ b/lib/service/service.go @@ -2553,6 +2553,7 @@ func (process *TeleportProcess) newAccessCacheForServices(cfg accesspoint.Config cfg.ProvisioningStates = services.ProvisioningStates cfg.IdentityCenter = services.IdentityCenter cfg.PluginStaticCredentials = services.PluginStaticCredentials + cfg.GitServers = services.GitServers return accesspoint.NewCache(cfg) } @@ -2599,6 +2600,7 @@ func (process *TeleportProcess) newAccessCacheForClient(cfg accesspoint.Config, cfg.WindowsDesktops = client cfg.DynamicWindowsDesktops = client.DynamicDesktopClient() cfg.AutoUpdateService = client + cfg.GitServers = client.GitServerClient() return accesspoint.NewCache(cfg) } @@ -2965,7 +2967,7 @@ func (process *TeleportProcess) initSSH() error { LockEnforcer: lockWatcher, Emitter: &events.StreamerAndEmitter{Emitter: asyncEmitter, Streamer: conn.Client}, Component: teleport.ComponentNode, - Logger: process.log.WithField(teleport.ComponentKey, teleport.Component(teleport.ComponentNode, process.id)).WithField(teleport.ComponentKey, "sessionctrl"), + Logger: process.logger.With(teleport.ComponentKey, teleport.Component(teleport.ComponentNode, process.id, "sessionctrl")), TracerProvider: process.TracingProvider, ServerID: serverID, }) @@ -4466,7 +4468,7 @@ func (process *TeleportProcess) initProxyEndpoint(conn *Connector) error { LockEnforcer: lockWatcher, Emitter: asyncEmitter, Component: teleport.ComponentProxy, - Logger: process.log.WithField(teleport.ComponentKey, "sessionctrl"), + Logger: process.logger.With(teleport.ComponentKey, "sessionctrl"), TracerProvider: process.TracingProvider, ServerID: serverID, }) @@ -4559,7 +4561,7 @@ func (process *TeleportProcess) initProxyEndpoint(conn *Connector) error { ServerID: cfg.HostUUID, Emitter: asyncEmitter, EmitterContext: process.GracefulExitContext(), - Logger: process.log, + Logger: process.logger, }) if err != nil { return trace.Wrap(err) @@ -4607,7 +4609,6 @@ func (process *TeleportProcess) initProxyEndpoint(conn *Connector) error { webConfig := web.Config{ Proxy: tsrv, AuthServers: cfg.AuthServerAddresses()[0], - DomainName: cfg.Hostname, ProxyClient: conn.Client, ProxySSHAddr: proxySSHAddr, ProxyWebAddr: cfg.Proxy.WebAddr, @@ -4923,7 +4924,7 @@ func (process *TeleportProcess) initProxyEndpoint(conn *Connector) error { ServerID: serverID, Emitter: asyncEmitter, EmitterContext: process.ExitContext(), - Logger: process.log, + Logger: process.logger, }) if err != nil { return trace.Wrap(err) @@ -5141,7 +5142,7 @@ func (process *TeleportProcess) initProxyEndpoint(conn *Connector) error { ServerID: process.Config.HostUUID, Emitter: asyncEmitter, EmitterContext: process.ExitContext(), - Logger: process.log, + Logger: process.logger, }) if err != nil { return trace.Wrap(err) @@ -6023,7 +6024,7 @@ func (process *TeleportProcess) initApps() { ServerID: process.Config.HostUUID, Emitter: asyncEmitter, EmitterContext: process.ExitContext(), - Logger: process.log, + Logger: process.logger, MonitorCloseChannel: process.Config.Apps.MonitorCloseChannel, }) if err != nil { diff --git a/lib/service/service_test.go b/lib/service/service_test.go index 0ff48c3055395..e0b421ff93780 100644 --- a/lib/service/service_test.go +++ b/lib/service/service_test.go @@ -103,7 +103,7 @@ func TestAdditionalExpectedRoles(t *testing.T) { name: "everything enabled", cfg: func() *servicecfg.Config { cfg := servicecfg.MakeDefaultConfig() - cfg.DataDir = t.TempDir() + cfg.DataDir = makeTempDir(t) cfg.SetAuthServerAddress(utils.NetAddr{AddrNetwork: "tcp", Addr: "127.0.0.1:0"}) cfg.Auth.StorageConfig.Params["path"] = t.TempDir() cfg.DiagnosticAddr = utils.NetAddr{AddrNetwork: "tcp", Addr: "127.0.0.1:0"} @@ -134,7 +134,7 @@ func TestAdditionalExpectedRoles(t *testing.T) { name: "everything enabled with additional roles", cfg: func() *servicecfg.Config { cfg := servicecfg.MakeDefaultConfig() - cfg.DataDir = t.TempDir() + cfg.DataDir = makeTempDir(t) cfg.SetAuthServerAddress(utils.NetAddr{AddrNetwork: "tcp", Addr: "127.0.0.1:0"}) cfg.Auth.StorageConfig.Params["path"] = t.TempDir() cfg.DiagnosticAddr = utils.NetAddr{AddrNetwork: "tcp", Addr: "127.0.0.1:0"} @@ -194,7 +194,7 @@ func TestDynamicClientReuse(t *testing.T) { cfg := servicecfg.MakeDefaultConfig() cfg.Clock = fakeClock - cfg.DataDir = t.TempDir() + cfg.DataDir = makeTempDir(t) cfg.SetAuthServerAddress(utils.NetAddr{AddrNetwork: "tcp", Addr: "127.0.0.1:0"}) cfg.Auth.Enabled = true cfg.Auth.ListenAddr = utils.NetAddr{AddrNetwork: "tcp", Addr: "127.0.0.1:0"} @@ -276,7 +276,7 @@ func TestMonitor(t *testing.T) { cfg := servicecfg.MakeDefaultConfig() cfg.Clock = fakeClock var err error - cfg.DataDir = t.TempDir() + cfg.DataDir = makeTempDir(t) cfg.DiagnosticAddr = utils.NetAddr{AddrNetwork: "tcp", Addr: "127.0.0.1:0"} cfg.SetAuthServerAddress(utils.NetAddr{AddrNetwork: "tcp", Addr: "127.0.0.1:0"}) cfg.Auth.Enabled = true @@ -787,7 +787,7 @@ func TestDesktopAccessFIPS(t *testing.T) { cfg := servicecfg.MakeDefaultConfig() cfg.SetAuthServerAddress(utils.NetAddr{AddrNetwork: "tcp", Addr: "127.0.0.1:0"}) cfg.Clock = clockwork.NewFakeClock() - cfg.DataDir = t.TempDir() + cfg.DataDir = makeTempDir(t) cfg.Auth.Enabled = false cfg.Proxy.Enabled = false cfg.SSH.Enabled = false @@ -912,7 +912,7 @@ func TestSetupProxyTLSConfig(t *testing.T) { cfg := servicecfg.MakeDefaultConfig() cfg.CircuitBreakerConfig = breaker.NoopBreakerConfig() cfg.Proxy.ACME.Enabled = tc.acmeEnabled - cfg.DataDir = t.TempDir() + cfg.DataDir = makeTempDir(t) cfg.Proxy.PublicAddrs = utils.MustParseAddrList("localhost") process := TeleportProcess{ Config: cfg, @@ -937,7 +937,7 @@ func TestTeleportProcess_reconnectToAuth(t *testing.T) { cfg := servicecfg.MakeDefaultConfig() cfg.SetAuthServerAddress(utils.NetAddr{AddrNetwork: "tcp", Addr: "127.0.0.1:0"}) cfg.Clock = clockwork.NewRealClock() - cfg.DataDir = t.TempDir() + cfg.DataDir = makeTempDir(t) cfg.Auth.Enabled = false cfg.Proxy.Enabled = false cfg.SSH.Enabled = true @@ -1005,7 +1005,7 @@ func TestTeleportProcessAuthVersionCheck(t *testing.T) { authCfg := servicecfg.MakeDefaultConfig() authCfg.SetAuthServerAddress(listenAddr) - authCfg.DataDir = t.TempDir() + authCfg.DataDir = makeTempDir(t) authCfg.Auth.Enabled = true authCfg.Auth.StaticTokens = staticTokens authCfg.Auth.StorageConfig.Type = lite.GetName() @@ -1027,7 +1027,7 @@ func TestTeleportProcessAuthVersionCheck(t *testing.T) { authListenAddr := authProc.Config.AuthServerAddresses()[0] nodeCfg := servicecfg.MakeDefaultConfig() nodeCfg.SetAuthServerAddress(authListenAddr) - nodeCfg.DataDir = t.TempDir() + nodeCfg.DataDir = makeTempDir(t) nodeCfg.SetToken(token) nodeCfg.Auth.Enabled = false nodeCfg.Proxy.Enabled = false @@ -1614,11 +1614,7 @@ func TestDebugServiceStartSocket(t *testing.T) { t.Parallel() fakeClock := clockwork.NewFakeClock() - var err error - dataDir, err := os.MkdirTemp("", "*") - require.NoError(t, err) - t.Cleanup(func() { os.RemoveAll(dataDir) }) - + dataDir := makeTempDir(t) cfg := servicecfg.MakeDefaultConfig() cfg.DebugService.Enabled = true cfg.Clock = fakeClock @@ -1741,7 +1737,7 @@ func TestInstanceMetadata(t *testing.T) { for _, tc := range tests { t.Run(tc.name, func(t *testing.T) { cfg := newCfg() - cfg.DataDir = t.TempDir() + cfg.DataDir = makeTempDir(t) cfg.Auth.StorageConfig.Params["path"] = t.TempDir() cfg.InstanceMetadataClient = tc.imClient @@ -1802,7 +1798,7 @@ func TestInitDatabaseService(t *testing.T) { t.Parallel() cfg := servicecfg.MakeDefaultConfig() - cfg.DataDir = t.TempDir() + cfg.DataDir = makeTempDir(t) cfg.DebugService = servicecfg.DebugConfig{ Enabled: false, } @@ -1858,7 +1854,7 @@ func TestAgentRolloutController(t *testing.T) { // Test setup: create a Teleport Auth config fakeClock := clockwork.NewFakeClock() - dataDir := t.TempDir() + dataDir := makeTempDir(t) cfg := servicecfg.MakeDefaultConfig() cfg.Clock = fakeClock @@ -1920,3 +1916,14 @@ func TestAgentRolloutController(t *testing.T) { return rollout.Spec.GetTargetVersion() == version.Spec.GetAgents().GetTargetVersion() }, time.Second, 10*time.Millisecond) } + +// makeTempDir makes a temp dir with a shorter name than t.TempDir() in order to +// avoid https://github.com/golang/go/issues/62614. +func makeTempDir(t *testing.T) string { + t.Helper() + + tempDir, err := os.MkdirTemp("", "teleport-test-") + require.NoError(t, err, "os.MkdirTemp() failed") + t.Cleanup(func() { os.RemoveAll(tempDir) }) + return tempDir +} diff --git a/lib/services/access_checker.go b/lib/services/access_checker.go index 39da72d5bbf8d..6174f56d7f7ba 100644 --- a/lib/services/access_checker.go +++ b/lib/services/access_checker.go @@ -444,6 +444,18 @@ func (a *accessChecker) CheckAccess(r AccessCheckable, state AccessState, matche if err := a.checkAllowedResources(r); err != nil { return trace.Wrap(err) } + + switch rr := r.(type) { + case types.Resource153Unwrapper: + switch urr := rr.Unwrap().(type) { + case IdentityCenterAccount: + matchers = append(matchers, NewIdentityCenterAccountMatcher(urr)) + + case IdentityCenterAccountAssignment: + matchers = append(matchers, NewIdentityCenterAccountAssignmentMatcher(urr)) + } + } + return trace.Wrap(a.RoleSet.checkAccess(r, a.info.Traits, state, matchers...)) } diff --git a/lib/services/access_request.go b/lib/services/access_request.go index 1e3ef0c8fb9de..67da35cde7381 100644 --- a/lib/services/access_request.go +++ b/lib/services/access_request.go @@ -2191,19 +2191,32 @@ func (m *RequestValidator) pruneResourceRequestRoles( necessaryRoles := make(map[string]struct{}) for _, resource := range resources { var ( - rolesForResource []types.Role - resourceMatcher *KubeResourcesMatcher + rolesForResource []types.Role + matchers []RoleMatcher + kubeResourceMatcher *KubeResourcesMatcher ) kubernetesResources, err := getKubeResourcesFromResourceIDs(resourceIDs, resource.GetName()) if err != nil { return nil, trace.Wrap(err) } if len(kubernetesResources) > 0 { - resourceMatcher = NewKubeResourcesMatcher(kubernetesResources) + kubeResourceMatcher = NewKubeResourcesMatcher(kubernetesResources) + matchers = append(matchers, kubeResourceMatcher) + } + + switch rr := resource.(type) { + case types.Resource153Unwrapper: + switch urr := rr.Unwrap().(type) { + case IdentityCenterAccount: + matchers = append(matchers, NewIdentityCenterAccountMatcher(urr)) + + case IdentityCenterAccountAssignment: + matchers = append(matchers, NewIdentityCenterAccountAssignmentMatcher(urr)) + } } for _, role := range allRoles { - roleAllowsAccess, err := m.roleAllowsResource(role, resource, loginHint, resourceMatcherToMatcherSlice(resourceMatcher)...) + roleAllowsAccess, err := m.roleAllowsResource(role, resource, loginHint, matchers...) if err != nil { return nil, trace.Wrap(err) } @@ -2217,7 +2230,7 @@ func (m *RequestValidator) pruneResourceRequestRoles( // If any of the requested resources didn't match with the provided roles, // we deny the request because the user is trying to request more access // than what is allowed by its search_as_roles. - if resourceMatcher != nil && len(resourceMatcher.Unmatched()) > 0 { + if kubeResourceMatcher != nil && len(kubeResourceMatcher.Unmatched()) > 0 { resourcesStr, err := types.ResourceIDsToString(resourceIDs) if err != nil { return nil, trace.Wrap(err) @@ -2226,7 +2239,7 @@ func (m *RequestValidator) pruneResourceRequestRoles( `no roles configured in the "search_as_roles" for this user allow `+ `access to at least one requested resources. `+ `resources: %s roles: %v unmatched resources: %v`, - resourcesStr, roles, resourceMatcher.Unmatched()) + resourcesStr, roles, kubeResourceMatcher.Unmatched()) } if len(loginHint) > 0 { // If we have a login hint, request the single role with the fewest @@ -2335,15 +2348,6 @@ func (m *RequestValidator) roleAllowsResource( return true, nil } -// resourceMatcherToMatcherSlice returns the resourceMatcher in a RoleMatcher slice -// if the resourceMatcher is not nil, otherwise returns a nil slice. -func resourceMatcherToMatcherSlice(resourceMatcher *KubeResourcesMatcher) []RoleMatcher { - if resourceMatcher == nil { - return nil - } - return []RoleMatcher{resourceMatcher} -} - // getUnderlyingResourcesByResourceIDs gets the underlying resources the user // requested access. Except for resource Kinds present in types.KubernetesResourcesKinds, // the underlying resources are the same as requested. If the resource requested diff --git a/lib/services/identitycenter.go b/lib/services/identitycenter.go index d3053b544e005..7418dedf6be40 100644 --- a/lib/services/identitycenter.go +++ b/lib/services/identitycenter.go @@ -18,11 +18,15 @@ package services import ( "context" + "fmt" - "google.golang.org/protobuf/proto" + "github.com/gravitational/trace" "google.golang.org/protobuf/types/known/emptypb" identitycenterv1 "github.com/gravitational/teleport/api/gen/proto/go/teleport/identitycenter/v1" + "github.com/gravitational/teleport/api/types" + apiutils "github.com/gravitational/teleport/api/utils" + "github.com/gravitational/teleport/lib/utils" "github.com/gravitational/teleport/lib/utils/pagination" ) @@ -49,12 +53,17 @@ type IdentityCenterAccount struct { } // CloneResource creates a deep copy of the underlying account resource -func (a IdentityCenterAccount) CloneResource() IdentityCenterAccount { +func (a IdentityCenterAccount) CloneResource() types.ClonableResource153 { return IdentityCenterAccount{ - Account: proto.Clone(a.Account).(*identitycenterv1.Account), + Account: apiutils.CloneProtoMsg(a.Account), } } +// GetDisplayName returns a human-readable name for the account for UI display. +func (a IdentityCenterAccount) GetDisplayName() string { + return a.Account.GetSpec().GetName() +} + // IdentityCenterAccountID is a strongly-typed Identity Center account ID. type IdentityCenterAccountID string @@ -179,9 +188,9 @@ type IdentityCenterAccountAssignment struct { } // CloneResource creates a deep copy of the underlying account resource -func (a IdentityCenterAccountAssignment) CloneResource() IdentityCenterAccountAssignment { +func (a IdentityCenterAccountAssignment) CloneResource() types.ClonableResource153 { return IdentityCenterAccountAssignment{ - AccountAssignment: proto.Clone(a.AccountAssignment).(*identitycenterv1.AccountAssignment), + AccountAssignment: apiutils.CloneProtoMsg(a.AccountAssignment), } } @@ -189,21 +198,27 @@ func (a IdentityCenterAccountAssignment) CloneResource() IdentityCenterAccountAs // IdentityCenterAccountAssignment type IdentityCenterAccountAssignmentID string -// IdentityCenterAccountAssignments defines the operations to create and maintain -// Identity Center account assignment records in the service. -type IdentityCenterAccountAssignments interface { +// IdentityCenterAccountAssignmentGetter provides read-only access to Identity +// Center Account Assignment records +type IdentityCenterAccountAssignmentGetter interface { + // GetAccountAssignment fetches a specific Account Assignment record. + GetAccountAssignment(context.Context, IdentityCenterAccountAssignmentID) (IdentityCenterAccountAssignment, error) + // ListAccountAssignments lists all IdentityCenterAccountAssignment record // known to the service ListAccountAssignments(context.Context, int, *pagination.PageRequestToken) ([]IdentityCenterAccountAssignment, pagination.NextPageToken, error) +} + +// IdentityCenterAccountAssignments defines the operations to create and maintain +// Identity Center account assignment records in the service. +type IdentityCenterAccountAssignments interface { + IdentityCenterAccountAssignmentGetter // CreateAccountAssignment creates a new Account Assignment record in // the service from the supplied in-memory representation. Returns the // created record on success. CreateAccountAssignment(context.Context, IdentityCenterAccountAssignment) (IdentityCenterAccountAssignment, error) - // GetAccountAssignment fetches a specific Account Assignment record. - GetAccountAssignment(context.Context, IdentityCenterAccountAssignmentID) (IdentityCenterAccountAssignment, error) - // UpdateAccountAssignment performs a conditional update on the supplied // Account Assignment, returning the updated record on success. UpdateAccountAssignment(context.Context, IdentityCenterAccountAssignment) (IdentityCenterAccountAssignment, error) @@ -226,3 +241,98 @@ type IdentityCenter interface { IdentityCenterPrincipalAssignments IdentityCenterAccountAssignments } + +// NewIdentityCenterAccountMatcher creates a new [RoleMatcher] configured to +// match the supplied [IdentityCenterAccount]. +func NewIdentityCenterAccountMatcher(account IdentityCenterAccount) RoleMatcher { + return &IdentityCenterAccountMatcher{ + accountID: account.GetSpec().GetId(), + } +} + +// IdentityCenterMatcher implements a [RoleMatcher] for comparing Identity Center +// Account resources against the AccountAssignments specified in a Role condition. +type IdentityCenterAccountMatcher struct { + accountID string +} + +// Match implements Role Matching for Identity Center Account resources. It +// attempts to match the Account Assignments in a Role Condition against a +// known Account ID. +func (m *IdentityCenterAccountMatcher) Match(role types.Role, condition types.RoleConditionType) (bool, error) { + // TODO(tcsc): Expand to cover role template expansion (e.g. {{external.account_assignments}}) + for _, asmt := range role.GetIdentityCenterAccountAssignments(condition) { + accountMatches, err := matchExpression(m.accountID, asmt.Account) + if err != nil { + return false, trace.Wrap(err) + } + + if accountMatches { + return true, nil + } + } + return false, nil +} + +func (m *IdentityCenterAccountMatcher) String() string { + return fmt.Sprintf("IdentityCenterAccountMatcher(account=%v)", m.accountID) +} + +// NewIdentityCenterAccountAssignmentMatcher creates a new [IdentityCenterAccountAssignmentMatcher] +// configured to match the supplied [IdentityCenterAccountAssignment]. +func NewIdentityCenterAccountAssignmentMatcher(account IdentityCenterAccountAssignment) RoleMatcher { + return &IdentityCenterAccountMatcher{ + accountID: account.GetSpec().GetAccountId(), + } +} + +// IdentityCenterMatcher implements a [RoleMatcher] for comparing Identity Center +// Account Assignment resources against the AccountAssignments specified in a +// Role condition. +type IdentityCenterAccountAssignmentMatcher struct { + accountID string + permissionSetARN string +} + +// Match implements Role Matching for Identity Center Account resources. It +// attempts to match the Account Assignments in a Role Condition against a +// known Account ID. +func (m *IdentityCenterAccountAssignmentMatcher) Match(role types.Role, condition types.RoleConditionType) (bool, error) { + // TODO(tcsc): Expand to cover role template expansion (e.g. {{external.account_assignments}}) + for _, asmt := range role.GetIdentityCenterAccountAssignments(condition) { + accountMatches, err := matchExpression(m.accountID, asmt.Account) + if err != nil { + return false, trace.Wrap(err) + } + + if !accountMatches { + continue + } + + permissionSetMatches, err := matchExpression(m.permissionSetARN, asmt.PermissionSet) + if err != nil { + return false, trace.Wrap(err) + } + + if permissionSetMatches { + return true, nil + } + } + return false, nil +} + +func (m *IdentityCenterAccountAssignmentMatcher) String() string { + return fmt.Sprintf("IdentityCenterAccountMatcher(account=%v, permissionSet=%v)", + m.accountID, m.permissionSetARN) +} + +func matchExpression(target, expression string) (bool, error) { + if expression == types.Wildcard { + return true, nil + } + matches, err := utils.MatchString(target, expression) + if err != nil { + return false, trace.Wrap(err) + } + return matches, nil +} diff --git a/lib/services/identitycenter_test.go b/lib/services/identitycenter_test.go index 5cbc87493feed..640e780fd57ab 100644 --- a/lib/services/identitycenter_test.go +++ b/lib/services/identitycenter_test.go @@ -48,7 +48,7 @@ func TestIdentityCenterAccountClone(t *testing.T) { } // WHEN I clone the resource - dst := src.CloneResource() + dst := src.CloneResource().(IdentityCenterAccount) // EXPECT that the resulting clone compares equally require.Equal(t, src, dst) @@ -82,7 +82,7 @@ func TestIdentityCenterAccountAssignmentClone(t *testing.T) { } // WHEN I clone the resource - dst := src.CloneResource() + dst := src.CloneResource().(IdentityCenterAccountAssignment) // EXPECT that the resulting clone compares equally require.Equal(t, src, dst) @@ -95,3 +95,297 @@ func TestIdentityCenterAccountAssignmentClone(t *testing.T) { require.NotEqual(t, src, dst) require.Equal(t, "original name", dst.Spec.PermissionSet.Name) } + +func TestIdentityCenterAccountMatcher(t *testing.T) { + testCases := []struct { + name string + roleAssignments []types.IdentityCenterAccountAssignment + condition types.RoleConditionType + matcher RoleMatcher + expectMatch require.BoolAssertionFunc + }{ + { + name: "empty nonmatch", + roleAssignments: nil, + condition: types.Allow, + matcher: &IdentityCenterAccountMatcher{ + accountID: "11111111", + }, + expectMatch: require.False, + }, + { + name: "simple account match", + roleAssignments: []types.IdentityCenterAccountAssignment{{ + Account: "11111111", + PermissionSet: "some:arn", + }}, + condition: types.Allow, + matcher: &IdentityCenterAccountMatcher{ + accountID: "11111111", + }, + expectMatch: require.True, + }, + { + name: "multiple account assignments match", + roleAssignments: []types.IdentityCenterAccountAssignment{ + { + Account: "00000000", + PermissionSet: "some:arn", + }, + { + Account: "11111111", + PermissionSet: "some:arn", + }, + }, + condition: types.Allow, + matcher: &IdentityCenterAccountMatcher{ + accountID: "11111111", + }, + expectMatch: require.True, + }, + { + name: "simple account nonmatch", + roleAssignments: []types.IdentityCenterAccountAssignment{{ + Account: "11111111", + PermissionSet: "some:arn", + }}, + condition: types.Allow, + matcher: &IdentityCenterAccountMatcher{ + accountID: "potato", + }, + expectMatch: require.False, + }, + { + name: "multiple account assignments match", + roleAssignments: []types.IdentityCenterAccountAssignment{ + { + Account: "00000000", + PermissionSet: "some:arn", + }, + { + Account: "11111111", + PermissionSet: "some:arn", + }, + }, + condition: types.Allow, + matcher: &IdentityCenterAccountMatcher{ + accountID: "66666666", + }, + expectMatch: require.False, + }, + { + name: "account glob match", + roleAssignments: []types.IdentityCenterAccountAssignment{{ + Account: "*", + PermissionSet: "some:arn", + }}, + condition: types.Allow, + matcher: &IdentityCenterAccountMatcher{ + accountID: "potato", + }, + expectMatch: require.True, + }, + { + name: "account glob nonmatch", + roleAssignments: []types.IdentityCenterAccountAssignment{{ + Account: "*!", + PermissionSet: "some:arn", + }}, + condition: types.Allow, + matcher: &IdentityCenterAccountMatcher{ + accountID: "potato", + }, + expectMatch: require.False, + }, + } + + for _, testCase := range testCases { + t.Run(testCase.name, func(t *testing.T) { + roleSpec := types.RoleSpecV6{} + condition := &roleSpec.Deny + if testCase.condition == types.Allow { + condition = &roleSpec.Allow + } + condition.AccountAssignments = append(condition.AccountAssignments, + testCase.roleAssignments...) + + r, err := types.NewRole("test", roleSpec) + require.NoError(t, err) + + match, err := testCase.matcher.Match(r, testCase.condition) + require.NoError(t, err) + + testCase.expectMatch(t, match) + }) + } +} + +func TestIdentityCenterAccountAssignmentMatcher(t *testing.T) { + testCases := []struct { + name string + roleAssignments []types.IdentityCenterAccountAssignment + condition types.RoleConditionType + matcher RoleMatcher + expectMatch require.BoolAssertionFunc + }{ + { + name: "empty nonmatch", + roleAssignments: nil, + condition: types.Allow, + matcher: &IdentityCenterAccountAssignmentMatcher{ + accountID: "11111111", + permissionSetARN: "some:arn", + }, + expectMatch: require.False, + }, + { + name: "simple match", + roleAssignments: []types.IdentityCenterAccountAssignment{{ + Account: "11111111", + PermissionSet: "some:arn", + }}, + condition: types.Allow, + matcher: &IdentityCenterAccountAssignmentMatcher{ + accountID: "11111111", + permissionSetARN: "some:arn", + }, + expectMatch: require.True, + }, + { + name: "multiple match", + roleAssignments: []types.IdentityCenterAccountAssignment{ + { + Account: "00000000", + PermissionSet: "some:arn", + }, + { + Account: "11111111", + PermissionSet: "some:arn", + }, + }, + condition: types.Allow, + matcher: &IdentityCenterAccountAssignmentMatcher{ + accountID: "11111111", + permissionSetARN: "some:arn", + }, + expectMatch: require.True, + }, + { + name: "multiple nonmatch", + roleAssignments: []types.IdentityCenterAccountAssignment{ + { + Account: "00000000", + PermissionSet: "some:arn", + }, + { + Account: "11111111", + PermissionSet: "some:arn", + }, + }, + condition: types.Allow, + matcher: &IdentityCenterAccountAssignmentMatcher{ + accountID: "66666666", + permissionSetARN: "some:other:arn", + }, + expectMatch: require.False, + }, + { + name: "account glob", + roleAssignments: []types.IdentityCenterAccountAssignment{{ + Account: "*1", + PermissionSet: "some:arn", + }}, + condition: types.Allow, + matcher: &IdentityCenterAccountAssignmentMatcher{ + accountID: "11111111", + permissionSetARN: "some:arn", + }, + expectMatch: require.True, + }, + { + name: "account glob nonmatch", + roleAssignments: []types.IdentityCenterAccountAssignment{{ + Account: "*!!!!", + PermissionSet: "some:arn", + }}, + condition: types.Allow, + matcher: &IdentityCenterAccountAssignmentMatcher{ + accountID: "11111111", + permissionSetARN: "some:arn", + }, + expectMatch: require.False, + }, + { + name: "globbed", + roleAssignments: []types.IdentityCenterAccountAssignment{{ + Account: "*", + PermissionSet: "*", + }}, + condition: types.Allow, + matcher: &IdentityCenterAccountAssignmentMatcher{ + accountID: "11111111", + permissionSetARN: "some:arn", + }, + expectMatch: require.True, + }, + { + name: "globbed nonmatch", + roleAssignments: []types.IdentityCenterAccountAssignment{{ + Account: "*", + PermissionSet: ":not:an:arn:*", + }}, + condition: types.Allow, + matcher: &IdentityCenterAccountAssignmentMatcher{ + accountID: "11111111", + permissionSetARN: "some:arn", + }, + expectMatch: require.False, + }, + { + name: "bad account", + roleAssignments: []types.IdentityCenterAccountAssignment{{ + Account: "11111111", + PermissionSet: "some:arn", + }}, + condition: types.Allow, + matcher: &IdentityCenterAccountAssignmentMatcher{ + accountID: "potato", + permissionSetARN: "some:arn", + }, + expectMatch: require.False, + }, + { + name: "bad permissionset arn", + roleAssignments: []types.IdentityCenterAccountAssignment{{ + Account: "11111111", + PermissionSet: "some:arn", + }}, + condition: types.Allow, + matcher: &IdentityCenterAccountAssignmentMatcher{ + accountID: "11111111", + permissionSetARN: "banana", + }, + expectMatch: require.False, + }, + } + + for _, testCase := range testCases { + t.Run(testCase.name, func(t *testing.T) { + roleSpec := types.RoleSpecV6{} + condition := &roleSpec.Deny + if testCase.condition == types.Allow { + condition = &roleSpec.Allow + } + condition.AccountAssignments = append(condition.AccountAssignments, + testCase.roleAssignments...) + + r, err := types.NewRole("test", roleSpec) + require.NoError(t, err) + + match, err := testCase.matcher.Match(r, testCase.condition) + require.NoError(t, err) + + testCase.expectMatch(t, match) + }) + } +} diff --git a/lib/services/local/databaseservice.go b/lib/services/local/databaseservice.go index ad7f064e35b68..255f777eba679 100644 --- a/lib/services/local/databaseservice.go +++ b/lib/services/local/databaseservice.go @@ -44,6 +44,10 @@ func (s *DatabaseServicesService) UpsertDatabaseService(ctx context.Context, ser if err := services.CheckAndSetDefaults(service); err != nil { return nil, trace.Wrap(err) } + if err := types.ValidateNamespaceDefault(service.GetNamespace()); err != nil { + return nil, trace.Wrap(err) + } + rev := service.GetRevision() value, err := services.MarshalDatabaseService(service) if err != nil { diff --git a/lib/services/local/events.go b/lib/services/local/events.go index 9a63b3fea4f9e..d0522bf7bd5f2 100644 --- a/lib/services/local/events.go +++ b/lib/services/local/events.go @@ -250,6 +250,8 @@ func (e *EventsService) NewWatcher(ctx context.Context, watch types.Watch) (type parser = newIdentityCenterAccountAssignmentParser() case types.KindPluginStaticCredentials: parser = newPluginStaticCredentialsParser() + case types.KindGitServer: + parser = newGitServerParser() default: if watch.AllowPartialSuccess { continue diff --git a/lib/services/local/git_server.go b/lib/services/local/git_server.go index 2d7d7c58b3263..857bc19447ab3 100644 --- a/lib/services/local/git_server.go +++ b/lib/services/local/git_server.go @@ -23,6 +23,7 @@ import ( "github.com/gravitational/trace" + apidefaults "github.com/gravitational/teleport/api/defaults" "github.com/gravitational/teleport/api/types" "github.com/gravitational/teleport/lib/backend" "github.com/gravitational/teleport/lib/defaults" @@ -128,3 +129,44 @@ func (s *GitServerService) ListGitServers(ctx context.Context, pageSize int, pag } return items, next, nil } + +func newGitServerParser() *gitServerParser { + return &gitServerParser{ + baseParser: newBaseParser(backend.NewKey(gitServerPrefix)), + } +} + +type gitServerParser struct { + baseParser +} + +func (p *gitServerParser) parse(event backend.Event) (types.Resource, error) { + switch event.Type { + case types.OpDelete: + components := event.Item.Key.Components() + if len(components) < 2 { + return nil, trace.NotFound("failed parsing %s", event.Item.Key) + } + + return &types.ResourceHeader{ + Kind: types.KindGitServer, + Version: types.V2, + Metadata: types.Metadata{ + Name: components[1], + Namespace: apidefaults.Namespace, + }, + }, nil + case types.OpPut: + resource, err := services.UnmarshalServer(event.Item.Value, + types.KindGitServer, + services.WithExpires(event.Item.Expires), + services.WithRevision(event.Item.Revision), + ) + if err != nil { + return nil, trace.Wrap(err) + } + return resource, nil + default: + return nil, trace.BadParameter("event %v is not supported", event.Type) + } +} diff --git a/lib/services/local/presence.go b/lib/services/local/presence.go index aacc78c40f78c..ff95884151b34 100644 --- a/lib/services/local/presence.go +++ b/lib/services/local/presence.go @@ -32,6 +32,7 @@ import ( "github.com/gravitational/teleport/api/client/proto" "github.com/gravitational/teleport/api/constants" apidefaults "github.com/gravitational/teleport/api/defaults" + identitycenterv1 "github.com/gravitational/teleport/api/gen/proto/go/teleport/identitycenter/v1" "github.com/gravitational/teleport/api/internalutils/stream" "github.com/gravitational/teleport/api/types" "github.com/gravitational/teleport/api/utils/retryutils" @@ -344,10 +345,10 @@ func (s *PresenceService) UpsertNode(ctx context.Context, server types.Server) ( if server.GetNamespace() == "" { server.SetNamespace(apidefaults.Namespace) } - - if n := server.GetNamespace(); n != apidefaults.Namespace { - return nil, trace.BadParameter("cannot place node in namespace %q, custom namespaces are deprecated", n) + if err := types.ValidateNamespaceDefault(server.GetNamespace()); err != nil { + return nil, trace.Wrap(err) } + rev := server.GetRevision() value, err := services.MarshalServer(server) if err != nil { @@ -376,10 +377,10 @@ func (s *PresenceService) UpdateNode(ctx context.Context, server types.Server) ( if server.GetNamespace() == "" { server.SetNamespace(apidefaults.Namespace) } - - if n := server.GetNamespace(); n != apidefaults.Namespace { - return nil, trace.BadParameter("cannot place node in namespace %q, custom namespaces are deprecated", n) + if err := types.ValidateNamespaceDefault(server.GetNamespace()); err != nil { + return nil, trace.Wrap(err) } + rev := server.GetRevision() value, err := services.MarshalServer(server) if err != nil { @@ -1002,6 +1003,10 @@ func (s *PresenceService) UpsertDatabaseServer(ctx context.Context, server types if err := services.CheckAndSetDefaults(server); err != nil { return nil, trace.Wrap(err) } + if err := types.ValidateNamespaceDefault(server.GetNamespace()); err != nil { + return nil, trace.Wrap(err) + } + rev := server.GetRevision() value, err := services.MarshalDatabaseServer(server) if err != nil { @@ -1095,6 +1100,10 @@ func (s *PresenceService) UpsertApplicationServer(ctx context.Context, server ty if err := services.CheckAndSetDefaults(server); err != nil { return nil, trace.Wrap(err) } + if err := types.ValidateNamespaceDefault(server.GetNamespace()); err != nil { + return nil, trace.Wrap(err) + } + rev := server.GetRevision() value, err := services.MarshalAppServer(server) if err != nil { @@ -1373,6 +1382,12 @@ func (s *PresenceService) listResources(ctx context.Context, req proto.ListResou case types.KindUserGroup: keyPrefix = []string{userGroupPrefix} unmarshalItemFunc = backendItemToUserGroup + case types.KindIdentityCenterAccount: + keyPrefix = []string{awsResourcePrefix, awsAccountPrefix} + unmarshalItemFunc = backendItemToIdentityCenterAccount + case types.KindIdentityCenterAccountAssignment: + keyPrefix = []string{awsResourcePrefix, awsAccountAssignmentPrefix} + unmarshalItemFunc = backendItemToIdentityCenterAccountAssignment default: return nil, trace.NotImplemented("%s not implemented at ListResources", req.ResourceType) } @@ -1761,6 +1776,35 @@ func backendItemToUserGroup(item backend.Item) (types.ResourceWithLabels, error) ) } +func backendItemToIdentityCenterAccount(item backend.Item) (types.ResourceWithLabels, error) { + assignment, err := services.UnmarshalProtoResource[*identitycenterv1.Account]( + item.Value, + services.WithExpires(item.Expires), + services.WithRevision(item.Revision), + ) + if err != nil { + return nil, trace.Wrap(err) + } + resource := types.Resource153ToUnifiedResource( + services.IdentityCenterAccount{Account: assignment}, + ) + return resource.(types.ResourceWithLabels), nil +} + +func backendItemToIdentityCenterAccountAssignment(item backend.Item) (types.ResourceWithLabels, error) { + assignment, err := services.UnmarshalProtoResource[*identitycenterv1.AccountAssignment]( + item.Value, + services.WithExpires(item.Expires), + services.WithRevision(item.Revision), + ) + if err != nil { + return nil, trace.Wrap(err) + } + return types.Resource153ToUnifiedResource( + services.IdentityCenterAccountAssignment{AccountAssignment: assignment}, + ), nil +} + const ( reverseTunnelsPrefix = "reverseTunnels" tunnelConnectionsPrefix = "tunnelConnections" diff --git a/lib/services/local/resource.go b/lib/services/local/resource.go index c21a3fac4665c..e12eb673a1c62 100644 --- a/lib/services/local/resource.go +++ b/lib/services/local/resource.go @@ -30,8 +30,8 @@ import ( ) // CreateResources attempts to dynamically create the supplied resources. -// This function returns `trace.AlreadyExistsError` if one or more resources -// would be overwritten, and `trace.NotImplementedError` if any resources +// If any resources already exist they are skipped and not overwritten. +// This function returns a `trace.NotImplementedError` if any resources // are of an unsupported type (see `itemsFromResources(...)`). // // NOTE: This function is non-atomic and performs no internal synchronization; @@ -41,20 +41,9 @@ func CreateResources(ctx context.Context, b backend.Backend, resources ...types. if err != nil { return trace.Wrap(err) } - // ensure all items do not exist before continuing. - for _, item := range items { - _, err = b.Get(ctx, item.Key) - if !trace.IsNotFound(err) { - if err != nil { - return trace.Wrap(err) - } - return trace.AlreadyExists("resource %q already exists", item.Key.String()) - } - } - // create all items. for _, item := range items { _, err := b.Create(ctx, item) - if err != nil { + if !trace.IsAlreadyExists(err) && err != nil { return trace.Wrap(err) } } diff --git a/lib/services/local/resource_test.go b/lib/services/local/resource_test.go index 330a5cd931984..97e866c022253 100644 --- a/lib/services/local/resource_test.go +++ b/lib/services/local/resource_test.go @@ -30,6 +30,7 @@ import ( "github.com/stretchr/testify/require" "golang.org/x/crypto/bcrypt" + "github.com/gravitational/teleport/api/constants" apidefaults "github.com/gravitational/teleport/api/defaults" "github.com/gravitational/teleport/api/types" "github.com/gravitational/teleport/lib/services" @@ -55,6 +56,34 @@ func TestCreateResourcesProvisionToken(t *testing.T) { require.Empty(t, cmp.Diff(token, fetchedToken, cmpopts.IgnoreFields(types.Metadata{}, "Revision"))) } +func TestCreateResource(t *testing.T) { + t.Parallel() + ctx := context.Background() + tt := setupServicesContext(ctx, t) + cap, err := types.NewAuthPreference(types.AuthPreferenceSpecV2{ + Type: constants.Local, + }) + require.NoError(t, err) + + // Check that the initial call to CreateResources creates the given resources. + s, err := NewClusterConfigurationService(tt.bk) + require.NoError(t, err) + err = CreateResources(ctx, tt.bk, cap) + require.NoError(t, err) + got, err := s.GetAuthPreference(ctx) + require.NoError(t, err) + require.Equal(t, cap.GetType(), got.GetType()) + + // Check that already exists errors are ignored and the resource is not + // updated. + cap.SetType(constants.SAML) + err = CreateResources(ctx, tt.bk, cap) + require.NoError(t, err) + got, err = s.GetAuthPreference(ctx) + require.NoError(t, err) + require.NotEqual(t, cap.GetType(), got.GetType()) +} + func TestUserResource(t *testing.T) { t.Parallel() ctx := context.Background() diff --git a/lib/services/matchers.go b/lib/services/matchers.go index 19d543ef022c4..e625d4ca59fab 100644 --- a/lib/services/matchers.go +++ b/lib/services/matchers.go @@ -157,7 +157,10 @@ func MatchResourceByFilters(resource types.ResourceWithLabels, filter MatchResou types.KindDatabaseService, types.KindKubernetesCluster, types.KindWindowsDesktop, types.KindWindowsDesktopService, - types.KindUserGroup: + types.KindUserGroup, + types.KindIdentityCenterAccount, + types.KindIdentityCenterAccountAssignment, + types.KindGitServer: specResource = resource case types.KindKubeServer: if seenMap != nil { diff --git a/lib/services/matchers_test.go b/lib/services/matchers_test.go index 68c52858ddebb..7238c099d605d 100644 --- a/lib/services/matchers_test.go +++ b/lib/services/matchers_test.go @@ -499,7 +499,7 @@ func TestMatchResourceByFilters(t *testing.T) { { name: "kube cluster", resource: func() types.ResourceWithLabels { - cluster, err := types.NewKubernetesClusterV3FromLegacyCluster("_", &types.KubernetesCluster{ + cluster, err := types.NewKubernetesClusterV3FromLegacyCluster("", &types.KubernetesCluster{ Name: "foo", }) require.NoError(t, err) diff --git a/lib/services/resource.go b/lib/services/resource.go index b4e29d85af7e2..ed19b10f0d960 100644 --- a/lib/services/resource.go +++ b/lib/services/resource.go @@ -175,7 +175,7 @@ func ParseShortcut(in string) (string, error) { return types.KindKubeServer, nil case types.KindLock, "locks": return types.KindLock, nil - case types.KindDatabaseServer: + case types.KindDatabaseServer, "db_servers": return types.KindDatabaseServer, nil case types.KindNetworkRestrictions: return types.KindNetworkRestrictions, nil @@ -185,7 +185,7 @@ func ParseShortcut(in string) (string, error) { return types.KindApp, nil case types.KindAppServer, "app_servers": return types.KindAppServer, nil - case types.KindWindowsDesktopService, "windows_service", "win_desktop_service", "win_service": + case types.KindWindowsDesktopService, "windows_service", "win_desktop_service", "win_service", "windows_desktop_services": return types.KindWindowsDesktopService, nil case types.KindWindowsDesktop, "win_desktop": return types.KindWindowsDesktop, nil diff --git a/lib/services/role.go b/lib/services/role.go index 683dbd2d39616..485225c3ebb2c 100644 --- a/lib/services/role.go +++ b/lib/services/role.go @@ -2556,6 +2556,19 @@ func rbacDebugLogger() (debugEnabled bool, debugf func(format string, args ...in return } +// resourceRequiresLabelMatching decides if a resource requires lapel matching +// when making RBAC access decisions. +func resourceRequiresLabelMatching(r AccessCheckable) bool { + // Some resources do not need label matching when assessing whether the user + // should be granted access. Enable it by default, but turn it off in the + // special cases. + switch r.GetKind() { + case types.KindIdentityCenterAccount, types.KindIdentityCenterAccountAssignment: + return false + } + return true +} + func (set RoleSet) checkAccess(r AccessCheckable, traits wrappers.Traits, state AccessState, matchers ...RoleMatcher) error { // Note: logging in this function only happens in debug mode. This is because // adding logging to this function (which is called on every resource returned @@ -2567,6 +2580,7 @@ func (set RoleSet) checkAccess(r AccessCheckable, traits wrappers.Traits, state return ErrSessionMFARequired } + requiresLabelMatching := resourceRequiresLabelMatching(r) namespace := types.ProcessNamespace(r.GetMetadata().Namespace) // Additional message depending on kind of resource @@ -2589,18 +2603,20 @@ func (set RoleSet) checkAccess(r AccessCheckable, traits wrappers.Traits, state if !matchNamespace { continue } - - matchLabels, labelsMessage, err := checkRoleLabelsMatch(types.Deny, role, traits, r, isDebugEnabled) - if err != nil { - return trace.Wrap(err) - } - if matchLabels { - debugf("Access to %v %q denied, deny rule in role %q matched; match(namespace=%v, %s)", - r.GetKind(), r.GetName(), role.GetName(), namespaceMessage, labelsMessage) - return trace.AccessDenied("access to %v denied. User does not have permissions. %v", - r.GetKind(), additionalDeniedMessage) + if requiresLabelMatching { + matchLabels, labelsMessage, err := checkRoleLabelsMatch(types.Deny, role, traits, r, isDebugEnabled) + if err != nil { + return trace.Wrap(err) + } + if matchLabels { + debugf("Access to %v %q denied, deny rule in role %q matched; match(namespace=%v, %s)", + r.GetKind(), r.GetName(), role.GetName(), namespaceMessage, labelsMessage) + return trace.AccessDenied("access to %v denied. User does not have permissions. %v", + r.GetKind(), additionalDeniedMessage) + } + } else { + debugf("Role label matching skipped for %v %q", r.GetKind(), r.GetName()) } - // Deny rules are greedy on purpose. They will always match if // at least one of the matchers returns true. matchMatchers, matchersMessage, err := RoleMatchers(matchers).MatchAny(role, types.Deny) @@ -2634,17 +2650,21 @@ func (set RoleSet) checkAccess(r AccessCheckable, traits wrappers.Traits, state continue } - matchLabels, labelsMessage, err := checkRoleLabelsMatch(types.Allow, role, traits, r, isDebugEnabled) - if err != nil { - return trace.Wrap(err) - } + if requiresLabelMatching { + matchLabels, labelsMessage, err := checkRoleLabelsMatch(types.Allow, role, traits, r, isDebugEnabled) + if err != nil { + return trace.Wrap(err) + } - if !matchLabels { - if isDebugEnabled { - errs = append(errs, trace.AccessDenied("role=%v, match(%s)", - role.GetName(), labelsMessage)) + if !matchLabels { + if isDebugEnabled { + errs = append(errs, trace.AccessDenied("role=%v, match(%s)", + role.GetName(), labelsMessage)) + } + continue } - continue + } else { + debugf("Role label matching skipped for %v %q", r.GetKind(), r.GetName()) } // Allow rules are not greedy. They will match only if all of the diff --git a/lib/services/unified_resource.go b/lib/services/unified_resource.go index 7c06471b9d3a6..b3228849a8a25 100644 --- a/lib/services/unified_resource.go +++ b/lib/services/unified_resource.go @@ -20,6 +20,7 @@ package services import ( "context" + "maps" "strings" "sync" "time" @@ -37,6 +38,7 @@ import ( "github.com/gravitational/teleport/api/types" "github.com/gravitational/teleport/lib/backend" "github.com/gravitational/teleport/lib/utils" + "github.com/gravitational/teleport/lib/utils/pagination" ) // UnifiedResourceKinds is a list of all kinds that are stored in the unified resource cache. @@ -47,6 +49,9 @@ var UnifiedResourceKinds []string = []string{ types.KindAppServer, types.KindWindowsDesktop, types.KindSAMLIdPServiceProvider, + types.KindIdentityCenterAccount, + types.KindIdentityCenterAccountAssignment, + types.KindGitServer, } // UnifiedResourceCacheConfig is used to configure a UnifiedResourceCache @@ -352,6 +357,9 @@ type ResourceGetter interface { WindowsDesktopGetter KubernetesServerGetter SAMLIdpServiceProviderGetter + IdentityCenterAccountGetter + IdentityCenterAccountAssignmentGetter + GitServerGetter } // newWatcher starts and returns a new resource watcher for unified resources. @@ -383,8 +391,11 @@ func makeResourceSortKey(resource types.Resource) resourceSortKey { // the container type. switch r := resource.(type) { case types.Server: - name = r.GetHostname() + "/" + r.GetName() - kind = types.KindNode + switch r.GetKind() { + case types.KindNode, types.KindGitServer: + name = r.GetHostname() + "/" + r.GetName() + kind = r.GetKind() + } case types.AppServer: app := r.GetApp() if app != nil { @@ -455,6 +466,21 @@ func (c *UnifiedResourceCache) getResourcesAndUpdateCurrent(ctx context.Context) return trace.Wrap(err) } + newICAccounts, err := c.getIdentityCenterAccounts(ctx) + if err != nil { + return trace.Wrap(err) + } + + newICAccountAssignments, err := c.getIdentityCenterAccountAssignments(ctx) + if err != nil { + return trace.Wrap(err) + } + + newGitServers, err := c.getGitServers(ctx) + if err != nil { + return trace.Wrap(err) + } + c.rw.Lock() defer c.rw.Unlock() // empty the trees @@ -470,6 +496,9 @@ func (c *UnifiedResourceCache) getResourcesAndUpdateCurrent(ctx context.Context) putResources[types.KubeServer](c, newKubes) putResources[types.SAMLIdPServiceProvider](c, newSAMLApps) putResources[types.WindowsDesktop](c, newDesktops) + putResources[resource](c, newICAccounts) + putResources[resource](c, newICAccountAssignments) + putResources[types.Server](c, newGitServers) c.stale = false c.defineCollectorAsInitialized() return nil @@ -581,6 +610,63 @@ func (c *UnifiedResourceCache) getSAMLApps(ctx context.Context) ([]types.SAMLIdP return newSAMLApps, nil } +func (c *UnifiedResourceCache) getIdentityCenterAccounts(ctx context.Context) ([]resource, error) { + var accounts []resource + var pageRequest pagination.PageRequestToken + for { + resultsPage, nextPage, err := c.ListIdentityCenterAccounts(ctx, apidefaults.DefaultChunkSize, &pageRequest) + if err != nil { + return nil, trace.Wrap(err, "getting AWS Identity Center accounts for resource watcher") + } + for _, a := range resultsPage { + accounts = append(accounts, types.Resource153ToUnifiedResource(a)) + } + + if nextPage == pagination.EndOfList { + break + } + pageRequest.Update(nextPage) + } + return accounts, nil +} + +func (c *UnifiedResourceCache) getIdentityCenterAccountAssignments(ctx context.Context) ([]resource, error) { + var accounts []resource + var pageRequest pagination.PageRequestToken + for { + resultsPage, nextPage, err := c.ListAccountAssignments(ctx, apidefaults.DefaultChunkSize, &pageRequest) + if err != nil { + return nil, trace.Wrap(err, "getting AWS Identity Center accounts for resource watcher") + } + for _, a := range resultsPage { + accounts = append(accounts, types.Resource153ToUnifiedResource(a)) + } + + if nextPage == pagination.EndOfList { + break + } + pageRequest.Update(nextPage) + } + return accounts, nil +} + +func (c *UnifiedResourceCache) getGitServers(ctx context.Context) (all []types.Server, err error) { + var page []types.Server + nextToken := "" + for { + page, nextToken, err = c.ListGitServers(ctx, apidefaults.DefaultChunkSize, nextToken) + if err != nil { + return nil, trace.Wrap(err, "getting Git servers for unified resource watcher") + } + + all = append(all, page...) + if nextToken == "" { + break + } + } + return all, nil +} + // read applies the supplied closure to either the primary tree or the ttl-based fallback tree depending on // wether or not the cache is currently healthy. locking is handled internally and the passed-in tree should // not be accessed after the closure completes. @@ -670,7 +756,33 @@ func (c *UnifiedResourceCache) processEventsAndUpdateCurrent(ctx context.Context case types.OpDelete: c.deleteLocked(event.Resource) case types.OpPut: - c.putLocked(event.Resource.(resource)) + switch r := event.Resource.(type) { + case resource: + c.putLocked(r) + + case types.Resource153Unwrapper: + // Raw RFD-153 style resources generally have very few methods + // defined on them by design. One way to add complex behavior to + // these resources is to wrap them inside another type that implements + // any methods or interfaces they need. Resources arriving here + // via the cache protocol will have those wrappers stripped away, + // so we unfortunately need to unwrap and re-wrap these values + // to restore them to a useful state. + switch unwrapped := r.Unwrap().(type) { + case IdentityCenterAccount: + c.putLocked(types.Resource153ToUnifiedResource(unwrapped)) + + case IdentityCenterAccountAssignment: + c.putLocked(types.Resource153ToUnifiedResource(unwrapped)) + + default: + c.log.Warnf("unsupported Resource153 type %T.", unwrapped) + } + + default: + c.log.Warnf("unsupported Resource type %T.", r) + } + default: c.log.Warnf("unsupported event type %s.", event.Type) continue @@ -879,6 +991,43 @@ func MakePaginatedResource(ctx context.Context, requestType string, r types.Reso RequiresRequest: requiresRequest, } } + case types.KindIdentityCenterAccount: + var err error + protoResource, err = makePaginatedIdentityCenterAccount(resourceKind, resource, requiresRequest) + if err != nil { + return nil, trace.Wrap(err) + } + + case types.KindIdentityCenterAccountAssignment: + unwrapper, ok := resource.(types.Resource153Unwrapper) + if !ok { + return nil, trace.BadParameter("%s has invalid type %T", resourceKind, resource) + } + assignment, ok := unwrapper.Unwrap().(IdentityCenterAccountAssignment) + if !ok { + return nil, trace.BadParameter( + "Unexpected type for Identity Center Account Assignment: %T", + unwrapper) + } + + protoResource = &proto.PaginatedResource{ + Resource: proto.PackICAccountAssignment(assignment.AccountAssignment), + RequiresRequest: requiresRequest, + } + + case types.KindGitServer: + server, ok := resource.(*types.ServerV2) + if !ok { + return nil, trace.BadParameter("%s has invalid type %T", resourceKind, resource) + } + + protoResource = &proto.PaginatedResource{ + Resource: &proto.PaginatedResource_GitServer{ + GitServer: server, + }, + RequiresRequest: requiresRequest, + } + default: return nil, trace.NotImplemented("resource type %s doesn't support pagination", resource.GetKind()) } @@ -886,6 +1035,64 @@ func MakePaginatedResource(ctx context.Context, requestType string, r types.Reso return protoResource, nil } +// makePaginatedIdentityCenterAccount returns a representation of the supplied +// Identity Center account as an App. +func makePaginatedIdentityCenterAccount(resourceKind string, resource types.ResourceWithLabels, requiresRequest bool) (*proto.PaginatedResource, error) { + unwrapper, ok := resource.(types.Resource153Unwrapper) + if !ok { + return nil, trace.BadParameter("%s has invalid type %T", resourceKind, resource) + } + acct, ok := unwrapper.Unwrap().(IdentityCenterAccount) + if !ok { + return nil, trace.BadParameter("%s has invalid inner type %T", resourceKind, resource) + } + srcPSs := acct.GetSpec().GetPermissionSetInfo() + pss := make([]*types.IdentityCenterPermissionSet, len(srcPSs)) + for i, ps := range acct.GetSpec().GetPermissionSetInfo() { + pss[i] = &types.IdentityCenterPermissionSet{ + ARN: ps.Arn, + Name: ps.Name, + AssignmentID: ps.AssignmentId, + } + } + + protoResource := &proto.PaginatedResource{ + Resource: &proto.PaginatedResource_AppServer{ + AppServer: &types.AppServerV3{ + Kind: types.KindAppServer, + Version: types.V3, + Metadata: resource.GetMetadata(), + Spec: types.AppServerSpecV3{ + App: &types.AppV3{ + Kind: types.KindApp, + SubKind: types.KindIdentityCenterAccount, + Version: types.V3, + Metadata: types.Metadata{ + Name: acct.Spec.Name, + Description: acct.Spec.Description, + Labels: maps.Clone(acct.Metadata.Labels), + }, + Spec: types.AppSpecV3{ + URI: acct.Spec.StartUrl, + PublicAddr: acct.Spec.StartUrl, + AWS: &types.AppAWS{ + ExternalID: acct.Spec.Id, + }, + IdentityCenter: &types.AppIdentityCenter{ + AccountID: acct.Spec.Id, + PermissionSets: pss, + }, + }, + }, + }, + }, + }, + RequiresRequest: requiresRequest, + } + + return protoResource, nil +} + // MakePaginatedResources converts a list of resources into a list of paginated proto representations. func MakePaginatedResources(ctx context.Context, requestType string, resources []types.ResourceWithLabels, requestableMap map[string]struct{}) ([]*proto.PaginatedResource, error) { paginatedResources := make([]*proto.PaginatedResource, 0, len(resources)) diff --git a/lib/services/unified_resource_test.go b/lib/services/unified_resource_test.go index 6e27cd2f45a71..7dea1251469ca 100644 --- a/lib/services/unified_resource_test.go +++ b/lib/services/unified_resource_test.go @@ -35,41 +35,62 @@ import ( "github.com/gravitational/teleport" "github.com/gravitational/teleport/api/client/proto" "github.com/gravitational/teleport/api/defaults" + headerv1 "github.com/gravitational/teleport/api/gen/proto/go/teleport/header/v1" + identitycenterv1 "github.com/gravitational/teleport/api/gen/proto/go/teleport/identitycenter/v1" apimetadata "github.com/gravitational/teleport/api/metadata" "github.com/gravitational/teleport/api/types" + "github.com/gravitational/teleport/api/types/common" "github.com/gravitational/teleport/api/types/header" "github.com/gravitational/teleport/lib/backend/memory" "github.com/gravitational/teleport/lib/services" "github.com/gravitational/teleport/lib/services/local" ) -func TestUnifiedResourceWatcher(t *testing.T) { - t.Parallel() +type client struct { + services.Presence + services.WindowsDesktops + services.SAMLIdPServiceProviders + services.GitServers + services.IdentityCenterAccounts + services.IdentityCenterAccountAssignments + types.Events +} - ctx := context.Background() +func newClient(t *testing.T) *client { + t.Helper() bk, err := memory.New(memory.Config{}) require.NoError(t, err) - type client struct { - services.Presence - services.WindowsDesktops - services.SAMLIdPServiceProviders - types.Events - } - samlService, err := local.NewSAMLIdPServiceProviderService(bk) require.NoError(t, err) + gitService, err := local.NewGitServerService(bk) + require.NoError(t, err) + icService, err := local.NewIdentityCenterService(local.IdentityCenterServiceConfig{ + Backend: bk, + }) + require.NoError(t, err) - clt := &client{ - Presence: local.NewPresenceService(bk), - WindowsDesktops: local.NewWindowsDesktopService(bk), - SAMLIdPServiceProviders: samlService, - Events: local.NewEventsService(bk), + return &client{ + Presence: local.NewPresenceService(bk), + WindowsDesktops: local.NewWindowsDesktopService(bk), + SAMLIdPServiceProviders: samlService, + Events: local.NewEventsService(bk), + GitServers: gitService, + IdentityCenterAccounts: icService, + IdentityCenterAccountAssignments: icService, } +} + +func TestUnifiedResourceWatcher(t *testing.T) { + t.Parallel() + + ctx := context.Background() + clt := newClient(t) + // Add node to the backend. node := newNodeServer(t, "node1", "hostname1", "127.0.0.1:22", false /*tunnel*/) - _, err = clt.UpsertNode(ctx, node) + _, err := clt.UpsertNode(ctx, node) require.NoError(t, err) db, err := types.NewDatabaseV3(types.Metadata{ @@ -89,6 +110,10 @@ func TestUnifiedResourceWatcher(t *testing.T) { require.NoError(t, err) _, err = clt.UpsertDatabaseServer(ctx, dbServer) require.NoError(t, err) + gitServer := newGitServer(t, "my-org") + require.NoError(t, err) + _, err = clt.CreateGitServer(ctx, gitServer) + require.NoError(t, err) w, err := services.NewUnifiedResourceCache(ctx, services.UnifiedResourceCacheConfig{ ResourceWatcherConfig: services.ResourceWatcherConfig{ @@ -98,10 +123,10 @@ func TestUnifiedResourceWatcher(t *testing.T) { ResourceGetter: clt, }) require.NoError(t, err) - // node and db expected initially + // node, db, and git_server expected initially res, err := w.GetUnifiedResources(ctx) require.NoError(t, err) - require.Len(t, res, 2) + require.Len(t, res, 3) assert.Eventually(t, func() bool { return w.IsInitialized() @@ -142,8 +167,20 @@ func TestUnifiedResourceWatcher(t *testing.T) { err = clt.UpsertWindowsDesktop(ctx, win) require.NoError(t, err) + // add another git server + gitServer2 := newGitServer(t, "my-org-2") + _, err = clt.UpsertGitServer(ctx, gitServer2) + require.NoError(t, err) + + icAcct := newICAccount(t, ctx, clt) + icAcctAssignment := newICAccountAssignment(t, ctx, clt) + // we expect each of the resources above to exist - expectedRes := []types.ResourceWithLabels{node, app, samlapp, dbServer, win} + expectedRes := []types.ResourceWithLabels{node, app, samlapp, dbServer, win, + gitServer, gitServer2, + types.Resource153ToUnifiedResource(icAcct), + types.Resource153ToUnifiedResource(icAcctAssignment), + } assert.Eventually(t, func() bool { res, err = w.GetUnifiedResources(ctx) return len(res) == len(expectedRes) @@ -156,6 +193,21 @@ func TestUnifiedResourceWatcher(t *testing.T) { cmpopts.IgnoreFields(header.Metadata{}, "Revision"), // Ignore order. cmpopts.SortSlices(func(a, b types.ResourceWithLabels) bool { return a.GetName() < b.GetName() }), + + // Allow comparison of the wrapped resource inside a resource153ToLegacyAdapter + cmp.Transformer("Unwrap", + func(t types.Resource153Unwrapper) types.Resource153 { + return t.Unwrap() + }), + + // Ignore unexported values in RFD153-style resources + cmpopts.IgnoreUnexported( + headerv1.Metadata{}, + identitycenterv1.Account{}, + identitycenterv1.AccountSpec{}, + identitycenterv1.PermissionSetInfo{}, + identitycenterv1.AccountAssignment{}, + identitycenterv1.AccountAssignmentSpec{}), )) // // Update and remove some resources. @@ -166,7 +218,11 @@ func TestUnifiedResourceWatcher(t *testing.T) { require.NoError(t, err) // this should include the updated node, and shouldn't have any apps included - expectedRes = []types.ResourceWithLabels{nodeUpdated, samlapp, dbServer, win} + expectedRes = []types.ResourceWithLabels{nodeUpdated, samlapp, dbServer, win, + gitServer, gitServer2, + types.Resource153ToUnifiedResource(icAcct), + types.Resource153ToUnifiedResource(icAcctAssignment)} + assert.Eventually(t, func() bool { res, err = w.GetUnifiedResources(ctx) require.NoError(t, err) @@ -182,6 +238,22 @@ func TestUnifiedResourceWatcher(t *testing.T) { cmpopts.EquateEmpty(), cmpopts.IgnoreFields(types.Metadata{}, "Revision"), cmpopts.IgnoreFields(header.Metadata{}, "Revision"), + + // Allow comparison of the wrapped values inside a Resource153ToLegacyAdapter + cmp.Transformer("Unwrap", + func(t types.Resource153Unwrapper) types.Resource153 { + return t.Unwrap() + }), + + // Ignore unexported values in RFD153-style resources + cmpopts.IgnoreUnexported( + headerv1.Metadata{}, + identitycenterv1.Account{}, + identitycenterv1.AccountSpec{}, + identitycenterv1.PermissionSetInfo{}, + identitycenterv1.AccountAssignment{}, + identitycenterv1.AccountAssignmentSpec{}), + // Ignore order. cmpopts.SortSlices(func(a, b types.ResourceWithLabels) bool { return a.GetName() < b.GetName() }), )) @@ -191,26 +263,7 @@ func TestUnifiedResourceWatcher_PreventDuplicates(t *testing.T) { t.Parallel() ctx := context.Background() - - bk, err := memory.New(memory.Config{}) - require.NoError(t, err) - - type client struct { - services.Presence - services.WindowsDesktops - services.SAMLIdPServiceProviders - types.Events - } - - samlService, err := local.NewSAMLIdPServiceProviderService(bk) - require.NoError(t, err) - - clt := &client{ - Presence: local.NewPresenceService(bk), - WindowsDesktops: local.NewWindowsDesktopService(bk), - SAMLIdPServiceProviders: samlService, - Events: local.NewEventsService(bk), - } + clt := newClient(t) w, err := services.NewUnifiedResourceCache(ctx, services.UnifiedResourceCacheConfig{ ResourceWatcherConfig: services.ResourceWatcherConfig{ Component: teleport.ComponentUnifiedResource, @@ -247,26 +300,7 @@ func TestUnifiedResourceWatcher_DeleteEvent(t *testing.T) { t.Parallel() ctx := context.Background() - - bk, err := memory.New(memory.Config{}) - require.NoError(t, err) - - type client struct { - services.Presence - services.WindowsDesktops - services.SAMLIdPServiceProviders - types.Events - } - - samlService, err := local.NewSAMLIdPServiceProviderService(bk) - require.NoError(t, err) - - clt := &client{ - Presence: local.NewPresenceService(bk), - WindowsDesktops: local.NewWindowsDesktopService(bk), - SAMLIdPServiceProviders: samlService, - Events: local.NewEventsService(bk), - } + clt := newClient(t) w, err := services.NewUnifiedResourceCache(ctx, services.UnifiedResourceCacheConfig{ ResourceWatcherConfig: services.ResourceWatcherConfig{ Component: teleport.ComponentUnifiedResource, @@ -360,9 +394,17 @@ func TestUnifiedResourceWatcher_DeleteEvent(t *testing.T) { require.NoError(t, err) _, err = clt.UpsertKubernetesServer(ctx, kubeServer) require.NoError(t, err) + + icAcct := newICAccount(t, ctx, clt) + + // add git server + gitServer := newGitServer(t, "my-org") + _, err = clt.CreateGitServer(ctx, gitServer) + require.NoError(t, err) + assert.Eventually(t, func() bool { res, _ := w.GetUnifiedResources(ctx) - return len(res) == 6 + return len(res) == 8 }, 5*time.Second, 10*time.Millisecond, "Timed out waiting for unified resources to be added") // delete everything @@ -378,6 +420,10 @@ func TestUnifiedResourceWatcher_DeleteEvent(t *testing.T) { require.NoError(t, err) err = clt.DeleteKubernetesServer(ctx, kubeServer.Spec.HostID, kubeServer.GetName()) require.NoError(t, err) + err = clt.DeleteIdentityCenterAccount(ctx, services.IdentityCenterAccountID(icAcct.GetMetadata().GetName())) + require.NoError(t, err) + err = clt.DeleteGitServer(ctx, gitServer.GetName()) + require.NoError(t, err) assert.Eventually(t, func() bool { res, _ := w.GetUnifiedResources(ctx) @@ -430,6 +476,16 @@ func newTestEntityDescriptor(entityID string) string { return fmt.Sprintf(testEntityDescriptor, entityID) } +func newGitServer(t *testing.T, githubOrg string) types.Server { + t.Helper() + gitServer, err := types.NewGitHubServer(types.GitHubServerMetadata{ + Organization: githubOrg, + Integration: githubOrg, + }) + require.NoError(t, err) + return gitServer +} + // A test entity descriptor from https://sptest.iamshowcase.com/testsp_metadata.xml. const testEntityDescriptor = ` @@ -440,3 +496,67 @@ const testEntityDescriptor = ` ` + +func newICAccount(t *testing.T, ctx context.Context, svc services.IdentityCenterAccounts) services.IdentityCenterAccount { + t.Helper() + + accountID := t.Name() + + icAcct, err := svc.CreateIdentityCenterAccount(ctx, services.IdentityCenterAccount{ + Account: &identitycenterv1.Account{ + Kind: types.KindIdentityCenterAccount, + Version: types.V1, + Metadata: &headerv1.Metadata{ + Name: t.Name(), + Labels: map[string]string{ + types.OriginLabel: common.OriginAWSIdentityCenter, + }, + }, + Spec: &identitycenterv1.AccountSpec{ + Id: accountID, + Arn: "arn:aws:sso:::account/" + accountID, + Name: "Test AWS Account", + Description: "Used for testing", + PermissionSetInfo: []*identitycenterv1.PermissionSetInfo{ + { + Name: "Alpha", + Arn: "arn:aws:sso:::permissionSet/ssoins-1234567890/ps-alpha", + }, + { + Name: "Beta", + Arn: "arn:aws:sso:::permissionSet/ssoins-1234567890/ps-beta", + }, + }, + }, + }}) + require.NoError(t, err, "creating Identity Center Account") + return icAcct +} + +func newICAccountAssignment(t *testing.T, ctx context.Context, svc services.IdentityCenterAccountAssignments) services.IdentityCenterAccountAssignment { + t.Helper() + + assignment, err := svc.CreateAccountAssignment(ctx, services.IdentityCenterAccountAssignment{ + AccountAssignment: &identitycenterv1.AccountAssignment{ + Kind: types.KindIdentityCenterAccountAssignment, + Version: types.V1, + Metadata: &headerv1.Metadata{ + Name: t.Name(), + Labels: map[string]string{ + types.OriginLabel: common.OriginAWSIdentityCenter, + }, + }, + Spec: &identitycenterv1.AccountAssignmentSpec{ + Display: "Admin access on Production", + PermissionSet: &identitycenterv1.PermissionSetInfo{ + Arn: "arn:aws::::ps-Admin", + Name: "Admin", + AssignmentId: "production--admin", + }, + AccountName: "Production", + AccountId: "99999999", + }, + }}) + require.NoError(t, err, "creating Identity Center Account Assignment") + return assignment +} diff --git a/lib/services/useracl.go b/lib/services/useracl.go index d1511651f8adc..4a6c39b554ee5 100644 --- a/lib/services/useracl.go +++ b/lib/services/useracl.go @@ -118,6 +118,8 @@ type UserACL struct { ReviewRequests bool `json:"reviewRequests"` // Contact defines the ability to manage contacts Contact ResourceAccess `json:"contact"` + // FileTransferAccess defines the ability to perform remote file operations via SCP or SFTP + FileTransferAccess bool `json:"fileTransferAccess"` } func hasAccess(roleSet RoleSet, ctx *Context, kind string, verbs ...string) bool { @@ -210,6 +212,7 @@ func NewUserACL(user types.User, userRoles RoleSet, features proto.Features, des crownJewelAccess := newAccess(userRoles, ctx, types.KindCrownJewel) userTasksAccess := newAccess(userRoles, ctx, types.KindUserTask) reviewRequests := userRoles.MaybeCanReviewRequests() + fileTransferAccess := userRoles.CanCopyFiles() var auditQuery ResourceAccess var securityReports ResourceAccess @@ -262,5 +265,6 @@ func NewUserACL(user types.User, userRoles RoleSet, features proto.Features, des CrownJewel: crownJewelAccess, AccessGraphSettings: accessGraphSettings, Contact: contact, + FileTransferAccess: fileTransferAccess, } } diff --git a/lib/srv/alpnproxy/aws_local_proxy.go b/lib/srv/alpnproxy/aws_local_proxy.go index 794fc6b9b78c9..56c1bbabe4dd5 100644 --- a/lib/srv/alpnproxy/aws_local_proxy.go +++ b/lib/srv/alpnproxy/aws_local_proxy.go @@ -22,6 +22,7 @@ import ( "net/http" "strings" + awsv2 "github.com/aws/aws-sdk-go-v2/aws" "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/aws/credentials" "github.com/aws/aws-sdk-go/service/sts" @@ -33,6 +34,7 @@ import ( appcommon "github.com/gravitational/teleport/lib/srv/app/common" "github.com/gravitational/teleport/lib/utils" awsutils "github.com/gravitational/teleport/lib/utils/aws" + "github.com/gravitational/teleport/lib/utils/aws/migration" ) // AWSAccessMiddleware verifies the requests to AWS proxy are properly signed. @@ -42,6 +44,11 @@ type AWSAccessMiddleware struct { // AWSCredentials are AWS Credentials used by LocalProxy for request's signature verification. AWSCredentials *credentials.Credentials + // AWSCredentialsV2Provider is an aws sdk v2 credential provider used by + // LocalProxy for request's signature verification if AWSCredentials is not + // specified. + AWSCredentialsV2Provider awsv2.CredentialsProvider + Log logrus.FieldLogger assumedRoles utils.SyncMap[string, *sts.AssumeRoleOutput] @@ -55,7 +62,10 @@ func (m *AWSAccessMiddleware) CheckAndSetDefaults() error { } if m.AWSCredentials == nil { - return trace.BadParameter("missing AWSCredentials") + if m.AWSCredentialsV2Provider == nil { + return trace.BadParameter("missing AWSCredentials") + } + m.AWSCredentials = credentials.NewCredentials(migration.NewProviderAdapter(m.AWSCredentialsV2Provider)) } return nil diff --git a/lib/srv/alpnproxy/aws_local_proxy_test.go b/lib/srv/alpnproxy/aws_local_proxy_test.go index 59a044ec8a45c..30f39290d697b 100644 --- a/lib/srv/alpnproxy/aws_local_proxy_test.go +++ b/lib/srv/alpnproxy/aws_local_proxy_test.go @@ -25,6 +25,7 @@ import ( "testing" "time" + credentialsv2 "github.com/aws/aws-sdk-go-v2/credentials" "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/aws/credentials" v4 "github.com/aws/aws-sdk-go/aws/signer/v4" @@ -42,60 +43,80 @@ func TestAWSAccessMiddleware(t *testing.T) { localProxyCred := credentials.NewStaticCredentials("local-proxy", "local-proxy-secret", "") assumedRoleCred := credentials.NewStaticCredentials("assumed-role", "assumed-role-secret", "assumed-role-token") - stsRequestByLocalProxyCred := httptest.NewRequest(http.MethodPost, "http://sts.us-east-2.amazonaws.com", nil) - v4.NewSigner(localProxyCred).Sign(stsRequestByLocalProxyCred, nil, "sts", "us-west-1", time.Now()) - - requestByAssumedRole := httptest.NewRequest(http.MethodGet, "http://s3.amazonaws.com", nil) - v4.NewSigner(assumedRoleCred).Sign(requestByAssumedRole, nil, "s3", "us-west-1", time.Now()) + tests := []struct { + name string + middleware *AWSAccessMiddleware + }{ + { + name: "v1", + middleware: &AWSAccessMiddleware{ + AWSCredentials: localProxyCred, + }, + }, + { + name: "v2", + middleware: &AWSAccessMiddleware{ + AWSCredentialsV2Provider: credentialsv2.NewStaticCredentialsProvider("local-proxy", "local-proxy-secret", ""), + }, + }, + } - m := &AWSAccessMiddleware{ - AWSCredentials: localProxyCred, + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + m := test.middleware + require.NoError(t, m.CheckAndSetDefaults()) + + stsRequestByLocalProxyCred := httptest.NewRequest(http.MethodPost, "http://sts.us-east-2.amazonaws.com", nil) + v4.NewSigner(localProxyCred).Sign(stsRequestByLocalProxyCred, nil, "sts", "us-west-1", time.Now()) + + requestByAssumedRole := httptest.NewRequest(http.MethodGet, "http://s3.amazonaws.com", nil) + v4.NewSigner(assumedRoleCred).Sign(requestByAssumedRole, nil, "s3", "us-west-1", time.Now()) + + t.Run("request no authorization", func(t *testing.T) { + recorder := httptest.NewRecorder() + require.True(t, m.HandleRequest(recorder, httptest.NewRequest("", "http://localhost", nil))) + require.Equal(t, http.StatusForbidden, recorder.Code) + }) + + t.Run("request signed by unknown credentials", func(t *testing.T) { + recorder := httptest.NewRecorder() + require.True(t, m.HandleRequest(recorder, requestByAssumedRole)) + require.Equal(t, http.StatusForbidden, recorder.Code) + }) + + t.Run("request signed by local proxy credentials", func(t *testing.T) { + recorder := httptest.NewRecorder() + require.False(t, m.HandleRequest(recorder, stsRequestByLocalProxyCred)) + require.Equal(t, http.StatusOK, recorder.Code) + }) + + // Verifies sts:AssumeRole output can be handled successfully. The + // credentials should be saved afterwards. + t.Run("handle sts:AssumeRole response", func(t *testing.T) { + response := assumeRoleResponse(t, assumedRoleARN, assumedRoleCred) + response.Request = stsRequestByLocalProxyCred + defer response.Body.Close() + require.NoError(t, m.HandleResponse(response)) + }) + + // This is the same request as the "unknown credentials" test above. But at + // this point, the assumed role credentials should have been saved by the + // middleware so the request can be handled successfully now. + t.Run("request signed by assumed role", func(t *testing.T) { + recorder := httptest.NewRecorder() + require.False(t, m.HandleRequest(recorder, requestByAssumedRole)) + require.Equal(t, http.StatusOK, recorder.Code) + }) + + // Verifies non sts:AssumeRole responses do not give errors. + t.Run("handle sts:GetCallerIdentity response", func(t *testing.T) { + response := getCallerIdentityResponse(t, assumedRoleARN) + response.Request = stsRequestByLocalProxyCred + defer response.Body.Close() + require.NoError(t, m.HandleResponse(response)) + }) + }) } - require.NoError(t, m.CheckAndSetDefaults()) - - t.Run("request no authorization", func(t *testing.T) { - recorder := httptest.NewRecorder() - require.True(t, m.HandleRequest(recorder, httptest.NewRequest("", "http://localhost", nil))) - require.Equal(t, http.StatusForbidden, recorder.Code) - }) - - t.Run("request signed by unknown credentials", func(t *testing.T) { - recorder := httptest.NewRecorder() - require.True(t, m.HandleRequest(recorder, requestByAssumedRole)) - require.Equal(t, http.StatusForbidden, recorder.Code) - }) - - t.Run("request signed by local proxy credentials", func(t *testing.T) { - recorder := httptest.NewRecorder() - require.False(t, m.HandleRequest(recorder, stsRequestByLocalProxyCred)) - require.Equal(t, http.StatusOK, recorder.Code) - }) - - // Verifies sts:AssumeRole output can be handled successfully. The - // credentials should be saved afterwards. - t.Run("handle sts:AssumeRole response", func(t *testing.T) { - response := assumeRoleResponse(t, assumedRoleARN, assumedRoleCred) - response.Request = stsRequestByLocalProxyCred - defer response.Body.Close() - require.NoError(t, m.HandleResponse(response)) - }) - - // This is the same request as the "unknown credentials" test above. But at - // this point, the assumed role credentials should have been saved by the - // middleware so the request can be handled successfully now. - t.Run("request signed by assumed role", func(t *testing.T) { - recorder := httptest.NewRecorder() - require.False(t, m.HandleRequest(recorder, requestByAssumedRole)) - require.Equal(t, http.StatusOK, recorder.Code) - }) - - // Verifies non sts:AssumeRole responses do not give errors. - t.Run("handle sts:GetCallerIdentity response", func(t *testing.T) { - response := getCallerIdentityResponse(t, assumedRoleARN) - response.Request = stsRequestByLocalProxyCred - defer response.Body.Close() - require.NoError(t, m.HandleResponse(response)) - }) } func assumeRoleResponse(t *testing.T, roleARN string, cred *credentials.Credentials) *http.Response { diff --git a/lib/srv/app/transport.go b/lib/srv/app/transport.go index d019af70dbe9f..262ce70626825 100644 --- a/lib/srv/app/transport.go +++ b/lib/srv/app/transport.go @@ -21,12 +21,15 @@ package app import ( "context" "crypto/tls" + "io" "log/slog" "net" "net/http" "net/url" "path" "slices" + "strings" + "time" "github.com/gravitational/trace" @@ -97,6 +100,12 @@ func newTransport(ctx context.Context, c *transportConfig) (*transport, error) { if err != nil { return nil, trace.Wrap(err) } + + // Add a timeout to control how long it takes to (start) getting a response + // from the target server. This allows Teleport to show the user a helpful + // error message when the target service is slow in responding. + tr.ResponseHeaderTimeout = requestTimeout + tr.TLSClientConfig, err = configureTLS(c) if err != nil { return nil, trace.Wrap(err) @@ -143,15 +152,35 @@ func (t *transport) RoundTrip(r *http.Request) (*http.Response, error) { return nil, trace.Wrap(err) } - // Forward the request to the target application and emit an audit event. + // Forward the request to the target application. + // + // If a network error occurred when connecting to the target application, + // log and return a helpful error message to the user and Teleport + // administrator. resp, err := t.tr.RoundTrip(r) + if message, ok := utils.CanExplainNetworkError(err); ok { + if t.log.Enabled(r.Context(), slog.LevelDebug) { + t.log.DebugContext(r.Context(), "application request failed with a network error", + "raw_error", err, "human_error", strings.Join(strings.Fields(message), " ")) + } + + code := trace.ErrorToCode(err) + return &http.Response{ + StatusCode: code, + Status: http.StatusText(code), + Proto: r.Proto, + ProtoMajor: r.ProtoMajor, + ProtoMinor: r.ProtoMinor, + Body: io.NopCloser(strings.NewReader(charWrap(message))), + TLS: r.TLS, + }, nil + } if err != nil { return nil, trace.Wrap(err) } - status := uint32(resp.StatusCode) // Emit the event to the audit log. - if err := sessCtx.Audit.OnRequest(t.closeContext, sessCtx, r, status, nil /*aws endpoint*/); err != nil { + if err := sessCtx.Audit.OnRequest(t.closeContext, sessCtx, r, uint32(resp.StatusCode), nil /*aws endpoint*/); err != nil { return nil, trace.Wrap(err) } @@ -293,3 +322,30 @@ func host(addr string) string { } return host } + +// charWrap wraps a line to about 80 characters to make it easier to read. +func charWrap(message string) string { + var sb strings.Builder + for _, line := range strings.Split(message, "\n") { + var n int + for _, word := range strings.Fields(line) { + sb.WriteString(word) + sb.WriteString(" ") + + n += len(word) + 1 + if n > 80 { + sb.WriteString("\n") + n = 0 + } + } + sb.WriteString("\n") + } + return sb.String() +} + +const ( + // requestTimeout is the timeout to receive a response from the upstream + // server. Start it out large (not to break things) and slowly decrease it + // over time. + requestTimeout = 5 * time.Minute +) diff --git a/lib/srv/authhandlers.go b/lib/srv/authhandlers.go index d80f5704acfe4..0947c6a975709 100644 --- a/lib/srv/authhandlers.go +++ b/lib/srv/authhandlers.go @@ -22,6 +22,7 @@ import ( "context" "encoding/json" "fmt" + "log/slog" "net" "strconv" "time" @@ -30,7 +31,6 @@ import ( "github.com/gravitational/trace" "github.com/jonboulle/clockwork" "github.com/prometheus/client_golang/prometheus" - log "github.com/sirupsen/logrus" "golang.org/x/crypto/ssh" "github.com/gravitational/teleport" @@ -123,7 +123,7 @@ func (c *AuthHandlerConfig) CheckAndSetDefaults() error { type AuthHandlers struct { loginChecker - log *log.Entry + log *slog.Logger c *AuthHandlerConfig } @@ -140,7 +140,7 @@ func NewAuthHandlers(config *AuthHandlerConfig) (*AuthHandlers, error) { ah := &AuthHandlers{ c: config, - log: log.WithField(teleport.ComponentKey, config.Component), + log: slog.With(teleport.ComponentKey, config.Component), } ah.loginChecker = &ahLoginChecker{ log: ah.log, @@ -284,10 +284,10 @@ func (h *AuthHandlers) CheckPortForward(addr string, ctx *ServerContext) error { Error: systemErrorMessage, }, }); err != nil { - h.log.WithError(err).Warn("Failed to emit port forward deny audit event.") + h.log.WarnContext(h.c.Server.Context(), "Failed to emit port forward deny audit event", "error", err) } - h.log.Warnf("Port forwarding request denied: %v.", systemErrorMessage) + h.log.WarnContext(h.c.Server.Context(), "Port forwarding request denied", "error", systemErrorMessage) return trace.AccessDenied(userErrorMessage) } @@ -303,28 +303,38 @@ func (h *AuthHandlers) UserKeyAuth(conn ssh.ConnMetadata, key ssh.PublicKey) (*s fingerprint := fmt.Sprintf("%v %v", key.Type(), sshutils.Fingerprint(key)) // create a new logging entry with info specific to this login attempt - log := h.log.WithField(teleport.ComponentFields, log.Fields{ - "local": conn.LocalAddr(), - "remote": conn.RemoteAddr(), - "user": conn.User(), - "fingerprint": fingerprint, - }) - - cid := fmt.Sprintf("conn(%v->%v, user=%v)", conn.RemoteAddr(), conn.LocalAddr(), conn.User()) - log.Debugf("%v auth attempt", cid) + log := h.log.With( + "local_addr", conn.LocalAddr(), + "remote_addr", conn.RemoteAddr(), + "user", conn.User(), + "fingerprint", fingerprint, + ) cert, ok := key.(*ssh.Certificate) - log.Debugf("%v auth attempt with key %v, %#v", cid, fingerprint, cert) if !ok { - log.Debugf("auth attempt, unsupported key type") + log.DebugContext(ctx, "rejecting auth attempt, unsupported key type") return nil, trace.BadParameter("unsupported key type: %v", fingerprint) } + + log.DebugContext(ctx, "processing auth attempt with key", + slog.Group("cert", + "serial", cert.Serial, + "type", cert.CertType, + "key_id", cert.KeyId, + "valid_principals", cert.ValidPrincipals, + "valid_after", cert.ValidAfter, + "valid_before", cert.ValidBefore, + "permissions", cert.Permissions, + "reserved", cert.Reserved, + ), + ) + if len(cert.ValidPrincipals) == 0 { - log.Debugf("need a valid principal for key") + log.DebugContext(ctx, "rejecting auth attempt without valid principals") return nil, trace.BadParameter("need a valid principal for key %v", fingerprint) } if len(cert.KeyId) == 0 { - log.Debugf("need a valid key ID for key") + log.DebugContext(ctx, "rejecting auth attempt without valid key ID") return nil, trace.BadParameter("need a valid key for key %v", fingerprint) } teleportUser := cert.KeyId @@ -380,7 +390,7 @@ func (h *AuthHandlers) UserKeyAuth(conn ssh.ConnMetadata, key ssh.PublicKey) (*s message, err, ); err != nil { - h.log.WithError(err).Warn("Failed to append Trace to ConnectionDiagnostic.") + h.log.WarnContext(ctx, "Failed to append Trace to ConnectionDiagnostic", "error", err) } if err := h.c.Emitter.EmitAuditEvent(h.c.Server.Context(), &apievents.AuthAttempt{ @@ -402,7 +412,7 @@ func (h *AuthHandlers) UserKeyAuth(conn ssh.ConnMetadata, key ssh.PublicKey) (*s Error: err.Error(), }, }); err != nil { - h.log.WithError(err).Warn("Failed to emit failed login audit event.") + h.log.WarnContext(ctx, "Failed to emit failed login audit event", "error", err) } auditdMsg := auditd.Message{ @@ -412,7 +422,7 @@ func (h *AuthHandlers) UserKeyAuth(conn ssh.ConnMetadata, key ssh.PublicKey) (*s } if err := auditd.SendEvent(auditd.AuditUserErr, auditd.Failed, auditdMsg); err != nil { - log.Warnf("Failed to send an event to auditd: %v", err) + log.WarnContext(ctx, "Failed to send an event to auditd", "error", err) } } @@ -433,7 +443,7 @@ func (h *AuthHandlers) UserKeyAuth(conn ssh.ConnMetadata, key ssh.PublicKey) (*s recordFailedLogin(err) return nil, trace.Wrap(err) } - log.Debugf("Successfully authenticated") + log.DebugContext(ctx, "Successfully authenticated") clusterName, err := h.c.AccessPoint.GetClusterName() if err != nil { @@ -452,7 +462,7 @@ func (h *AuthHandlers) UserKeyAuth(conn ssh.ConnMetadata, key ssh.PublicKey) (*s case ssh.HostCert: permissions.Extensions[utils.ExtIntCertType] = utils.ExtIntCertTypeHost default: - log.Warnf("Unexpected cert type: %v", cert.CertType) + log.WarnContext(ctx, "Received unexpected cert type", "cert_type", cert.CertType) } if h.isProxy() { @@ -464,7 +474,7 @@ func (h *AuthHandlers) UserKeyAuth(conn ssh.ConnMetadata, key ssh.PublicKey) (*s // client's certificate ca, err := h.authorityForCert(types.UserCA, cert.SignatureKey) if err != nil { - log.Errorf("Permission denied: %v", err) + log.ErrorContext(ctx, "Permission denied", "error", err) recordFailedLogin(err) return nil, trace.Wrap(err) } @@ -483,7 +493,7 @@ func (h *AuthHandlers) UserKeyAuth(conn ssh.ConnMetadata, key ssh.PublicKey) (*s err = h.canLoginWithRBAC(cert, ca, clusterName.GetClusterName(), h.c.Server.GetInfo(), teleportUser, conn.User()) } if err != nil { - log.Errorf("Permission denied: %v", err) + log.ErrorContext(ctx, "Permission denied", "error", err) recordFailedLogin(err) return nil, trace.Wrap(err) } @@ -572,7 +582,7 @@ func (h *AuthHandlers) hostKeyCallback(hostname string, remote net.Addr, key ssh // If strict host key checking is not enabled, log that Teleport trusted an // insecure key, but allow the request to go through. - h.log.Warnf("Insecure configuration! Strict host key checking disabled, allowing login without checking host key of type %v.", key.Type()) + h.log.WarnContext(ctx, "Insecure configuration! Strict host key checking disabled, allowing login without checking host key", "key_type", key.Type()) return nil } @@ -591,7 +601,7 @@ func (h *AuthHandlers) IsUserAuthority(cert ssh.PublicKey) bool { // Teleport CA. func (h *AuthHandlers) IsHostAuthority(cert ssh.PublicKey, address string) bool { if _, err := h.authorityForCert(types.HostCA, cert); err != nil { - h.log.Debugf("Unable to find SSH host CA: %v.", err) + h.log.DebugContext(h.c.Server.Context(), "Unable to find SSH host CA", "error", err) return false } return true @@ -607,7 +617,7 @@ type loginChecker interface { } type ahLoginChecker struct { - log *log.Entry + log *slog.Logger c *AuthHandlerConfig } @@ -618,7 +628,7 @@ func (a *ahLoginChecker) canLoginWithRBAC(cert *ssh.Certificate, ca types.CertAu // Use the server's shutdown context. ctx := a.c.Server.Context() - a.log.Debugf("Checking permissions for (%v,%v) to login to node with RBAC checks.", teleportUser, osUser) + a.log.DebugContext(ctx, "Checking permissions for (%v,%v) to login to node with RBAC checks.", teleportUser, osUser) // get roles assigned to this user accessInfo, err := fetchAccessInfo(cert, ca, teleportUser, clusterName) @@ -694,9 +704,9 @@ func fetchAccessInfo(cert *ssh.Certificate, ca types.CertAuthority, teleportUser // Certificate Authority and returns it. func (h *AuthHandlers) authorityForCert(caType types.CertAuthType, key ssh.PublicKey) (types.CertAuthority, error) { // get all certificate authorities for given type - cas, err := h.c.AccessPoint.GetCertAuthorities(context.TODO(), caType, false) + cas, err := h.c.AccessPoint.GetCertAuthorities(h.c.Server.Context(), caType, false) if err != nil { - h.log.Warnf("%v", trace.DebugReport(err)) + h.log.WarnContext(h.c.Server.Context(), "failed retrieving cert authority", "error", err) return nil, trace.Wrap(err) } @@ -705,7 +715,7 @@ func (h *AuthHandlers) authorityForCert(caType types.CertAuthType, key ssh.Publi for i := range cas { checkers, err := sshutils.GetCheckers(cas[i]) if err != nil { - h.log.Warnf("%v", err) + h.log.WarnContext(h.c.Server.Context(), "unable to get cert checker for ca", "ca", cas[i].GetName(), "error", err) return nil, trace.Wrap(err) } for _, checker := range checkers { diff --git a/lib/srv/ctx.go b/lib/srv/ctx.go index 802851d6c7b68..60f9a0ae660c1 100644 --- a/lib/srv/ctx.go +++ b/lib/srv/ctx.go @@ -22,6 +22,7 @@ import ( "context" "fmt" "io" + "log/slog" "net" "os" "strconv" @@ -406,14 +407,14 @@ type ServerContext struct { // the ServerContext is closed. The ctx parameter should be a child of the ctx // associated with the scope of the parent ConnectionContext to ensure that // cancellation of the ConnectionContext propagates to the ServerContext. -func NewServerContext(ctx context.Context, parent *sshutils.ConnectionContext, srv Server, identityContext IdentityContext, monitorOpts ...func(*MonitorConfig)) (context.Context, *ServerContext, error) { +func NewServerContext(ctx context.Context, parent *sshutils.ConnectionContext, srv Server, identityContext IdentityContext, monitorOpts ...func(*MonitorConfig)) (*ServerContext, error) { netConfig, err := srv.GetAccessPoint().GetClusterNetworkingConfig(ctx) if err != nil { - return nil, nil, trace.Wrap(err) + return nil, trace.Wrap(err) } recConfig, err := srv.GetAccessPoint().GetSessionRecordingConfig(ctx) if err != nil { - return nil, nil, trace.Wrap(err) + return nil, trace.Wrap(err) } cancelContext, cancel := context.WithCancel(ctx) @@ -452,7 +453,7 @@ func NewServerContext(ctx context.Context, parent *sshutils.ConnectionContext, s authPref, err := srv.GetAccessPoint().GetAuthPreference(ctx) if err != nil { childErr := child.Close() - return nil, nil, trace.NewAggregate(err, childErr) + return nil, trace.NewAggregate(err, childErr) } child.disconnectExpiredCert = getDisconnectExpiredCertFromIdentityContext( @@ -474,7 +475,7 @@ func NewServerContext(ctx context.Context, parent *sshutils.ConnectionContext, s clusterName, err := srv.GetAccessPoint().GetClusterName() if err != nil { childErr := child.Close() - return nil, nil, trace.NewAggregate(err, childErr) + return nil, trace.NewAggregate(err, childErr) } monitorConfig := MonitorConfig{ @@ -490,9 +491,11 @@ func NewServerContext(ctx context.Context, parent *sshutils.ConnectionContext, s TeleportUser: child.Identity.TeleportUser, Login: child.Identity.Login, ServerID: child.srv.ID(), - Entry: child.Entry, - Emitter: child.srv, - EmitterContext: ctx, + // TODO(tross) update this to use the child logger + // once ServerContext is converted to use a slog.Logger + Logger: slog.Default(), + Emitter: child.srv, + EmitterContext: ctx, } for _, opt := range monitorOpts { opt(&monitorConfig) @@ -500,14 +503,14 @@ func NewServerContext(ctx context.Context, parent *sshutils.ConnectionContext, s err = StartMonitor(monitorConfig) if err != nil { childErr := child.Close() - return nil, nil, trace.NewAggregate(err, childErr) + return nil, trace.NewAggregate(err, childErr) } // Create pipe used to send command to child process. child.cmdr, child.cmdw, err = os.Pipe() if err != nil { childErr := child.Close() - return nil, nil, trace.NewAggregate(err, childErr) + return nil, trace.NewAggregate(err, childErr) } child.AddCloser(child.cmdr) child.AddCloser(child.cmdw) @@ -516,7 +519,7 @@ func NewServerContext(ctx context.Context, parent *sshutils.ConnectionContext, s child.contr, child.contw, err = os.Pipe() if err != nil { childErr := child.Close() - return nil, nil, trace.NewAggregate(err, childErr) + return nil, trace.NewAggregate(err, childErr) } child.AddCloser(child.contr) child.AddCloser(child.contw) @@ -525,7 +528,7 @@ func NewServerContext(ctx context.Context, parent *sshutils.ConnectionContext, s child.readyr, child.readyw, err = os.Pipe() if err != nil { childErr := child.Close() - return nil, nil, trace.NewAggregate(err, childErr) + return nil, trace.NewAggregate(err, childErr) } child.AddCloser(child.readyr) child.AddCloser(child.readyw) @@ -533,12 +536,12 @@ func NewServerContext(ctx context.Context, parent *sshutils.ConnectionContext, s child.killShellr, child.killShellw, err = os.Pipe() if err != nil { childErr := child.Close() - return nil, nil, trace.NewAggregate(err, childErr) + return nil, trace.NewAggregate(err, childErr) } child.AddCloser(child.killShellr) child.AddCloser(child.killShellw) - return ctx, child, nil + return child, nil } // Parent grants access to the connection-level context of which this @@ -945,6 +948,15 @@ func (c *ServerContext) String() string { return fmt.Sprintf("ServerContext(%v->%v, user=%v, id=%v)", c.ServerConn.RemoteAddr(), c.ServerConn.LocalAddr(), c.ServerConn.User(), c.id) } +func (c *ServerContext) LogValue() slog.Value { + return slog.GroupValue( + slog.String("remote_addr", c.ServerConn.RemoteAddr().String()), + slog.String("local_addr", c.ServerConn.LocalAddr().String()), + slog.String("user", c.ServerConn.User()), + slog.Int("id", c.id), + ) +} + func getPAMConfig(c *ServerContext) (*PAMConfig, error) { // PAM should be disabled. if c.srv.Component() != teleport.ComponentNode { diff --git a/lib/srv/db/access_test.go b/lib/srv/db/access_test.go index b53da925e0669..0adc9a8b28796 100644 --- a/lib/srv/db/access_test.go +++ b/lib/srv/db/access_test.go @@ -2389,7 +2389,7 @@ func setupTestContext(ctx context.Context, t testing.TB, withDatabases ...withDa ServerID: testCtx.hostID, Emitter: testCtx.emitter, EmitterContext: ctx, - Logger: utils.NewLoggerForTests(), + Logger: utils.NewSlogLoggerForTests(), }) require.NoError(t, err) @@ -2542,7 +2542,7 @@ func (c *testContext) setupDatabaseServer(ctx context.Context, t testing.TB, p a ServerID: p.HostID, Emitter: c.emitter, EmitterContext: context.Background(), - Logger: utils.NewLoggerForTests(), + Logger: utils.NewSlogLoggerForTests(), }) require.NoError(t, err) diff --git a/lib/srv/db/spanner/test.go b/lib/srv/db/spanner/test.go index 44b74085c05bf..5dcef45959735 100644 --- a/lib/srv/db/spanner/test.go +++ b/lib/srv/db/spanner/test.go @@ -105,7 +105,8 @@ func makeTestClient(ctx context.Context, config common.TestClientConfig, useTLS } clientCfg := spanner.ClientConfig{ - SessionPoolConfig: spanner.DefaultSessionPoolConfig, + DisableNativeMetrics: true, + SessionPoolConfig: spanner.DefaultSessionPoolConfig, } clt, err := spanner.NewClientWithConfig(ctx, databaseID, clientCfg, opts...) if err != nil { diff --git a/lib/srv/desktop/windows_server.go b/lib/srv/desktop/windows_server.go index 7196425b79bff..9d42bdcf74333 100644 --- a/lib/srv/desktop/windows_server.go +++ b/lib/srv/desktop/windows_server.go @@ -1000,7 +1000,7 @@ func (s *WindowsService) connectRDP(ctx context.Context, log *slog.Logger, tdpCo Clock: s.cfg.Clock, ClientIdleTimeout: authCtx.Checker.AdjustClientIdleTimeout(netConfig.GetClientIdleTimeout()), DisconnectExpiredCert: authCtx.GetDisconnectCertExpiry(authPref), - Entry: logrus.NewEntry(logrus.StandardLogger()), + Logger: s.cfg.Logger, Emitter: s.cfg.Emitter, EmitterContext: s.closeCtx, LockWatcher: s.cfg.LockWatcher, diff --git a/lib/srv/discovery/discovery.go b/lib/srv/discovery/discovery.go index 2f8c4d097b845..3138ccc052f52 100644 --- a/lib/srv/discovery/discovery.go +++ b/lib/srv/discovery/discovery.go @@ -30,12 +30,11 @@ import ( "time" "github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/compute/armcompute/v3" - awsv2 "github.com/aws/aws-sdk-go-v2/aws" + "github.com/aws/aws-sdk-go-v2/aws" "github.com/aws/aws-sdk-go-v2/service/ec2" - "github.com/aws/aws-sdk-go/aws" - "github.com/aws/aws-sdk-go/aws/awserr" + "github.com/aws/aws-sdk-go-v2/service/ssm" + ssmtypes "github.com/aws/aws-sdk-go-v2/service/ssm/types" "github.com/aws/aws-sdk-go/aws/session" - "github.com/aws/aws-sdk-go/service/ssm" "github.com/gravitational/trace" "github.com/jonboulle/clockwork" "github.com/sirupsen/logrus" @@ -116,6 +115,8 @@ type Config struct { CloudClients cloud.Clients // GetEC2Client gets an AWS EC2 client for the given region. GetEC2Client server.EC2ClientGetter + // GetSSMClient gets an AWS SSM client for the given region. + GetSSMClient func(ctx context.Context, region string, opts ...config.AWSOptionsFn) (server.SSMClient, error) // IntegrationOnlyCredentials discards any Matcher that don't have an Integration. // When true, ambient credentials (used by the Cloud SDKs) are not used. IntegrationOnlyCredentials bool @@ -221,32 +222,22 @@ kubernetes matchers are present.`) } if c.GetEC2Client == nil { c.GetEC2Client = func(ctx context.Context, region string, opts ...config.AWSOptionsFn) (ec2.DescribeInstancesAPIClient, error) { - opts = append(opts, config.WithAWSIntegrationCredentialProvider(func(ctx context.Context, region, integrationName string) (awsv2.CredentialsProvider, error) { - integration, err := c.AccessPoint.GetIntegration(ctx, integrationName) - if err != nil { - return nil, trace.Wrap(err) - } - if integration.GetAWSOIDCIntegrationSpec() == nil { - return nil, trace.BadParameter("integration does not have aws oidc spec fields %q", integrationName) - } - token, err := c.AccessPoint.GenerateAWSOIDCToken(ctx, integrationName) - if err != nil { - return nil, trace.Wrap(err) - } - cred, err := awsoidc.NewAWSCredentialsProvider(ctx, &awsoidc.AWSClientRequest{ - Token: token, - RoleARN: integration.GetAWSOIDCIntegrationSpec().RoleARN, - Region: region, - }) - return cred, trace.Wrap(err) - })) - cfg, err := config.GetAWSConfig(ctx, region, opts...) + cfg, err := c.getAWSConfig(ctx, region, opts...) if err != nil { return nil, trace.Wrap(err) } return ec2.NewFromConfig(cfg), nil } } + if c.GetSSMClient == nil { + c.GetSSMClient = func(ctx context.Context, region string, opts ...config.AWSOptionsFn) (server.SSMClient, error) { + cfg, err := c.getAWSConfig(ctx, region, opts...) + if err != nil { + return nil, trace.Wrap(err) + } + return ssm.NewFromConfig(cfg), nil + } + } if c.KubernetesClient == nil && len(c.Matchers.Kubernetes) > 0 { cfg, err := rest.InClusterConfig() if err != nil { @@ -302,6 +293,30 @@ kubernetes matchers are present.`) return nil } +func (c *Config) getAWSConfig(ctx context.Context, region string, opts ...config.AWSOptionsFn) (aws.Config, error) { + opts = append(opts, config.WithAWSIntegrationCredentialProvider(func(ctx context.Context, region, integrationName string) (aws.CredentialsProvider, error) { + integration, err := c.AccessPoint.GetIntegration(ctx, integrationName) + if err != nil { + return nil, trace.Wrap(err) + } + if integration.GetAWSOIDCIntegrationSpec() == nil { + return nil, trace.BadParameter("integration does not have aws oidc spec fields %q", integrationName) + } + token, err := c.AccessPoint.GenerateAWSOIDCToken(ctx, integrationName) + if err != nil { + return nil, trace.Wrap(err) + } + cred, err := awsoidc.NewAWSCredentialsProvider(ctx, &awsoidc.AWSClientRequest{ + Token: token, + RoleARN: integration.GetAWSOIDCIntegrationSpec().RoleARN, + Region: region, + }) + return cred, trace.Wrap(err) + })) + cfg, err := config.GetAWSConfig(ctx, region, opts...) + return cfg, trace.Wrap(err) +} + // Server is a discovery server, used to discover cloud resources for // inclusion in Teleport type Server struct { @@ -863,7 +878,7 @@ func genEC2InstancesLogStr(instances []server.EC2Instance) string { func genAzureInstancesLogStr(instances []*armcompute.VirtualMachine) string { return genInstancesLogStr(instances, func(i *armcompute.VirtualMachine) string { - return aws.StringValue(i.Name) + return aws.ToString(i.Name) }) } @@ -1019,9 +1034,9 @@ func (s *Server) heartbeatEICEInstance(instances *server.EC2Instances) { func (s *Server) handleEC2RemoteInstallation(instances *server.EC2Instances) error { // TODO(gavin): support assume_role_arn for ec2. - ec2Client, err := s.CloudClients.GetAWSSSMClient(s.ctx, + ssmClient, err := s.GetSSMClient(s.ctx, instances.Region, - cloud.WithCredentialsMaybeIntegration(instances.Integration), + config.WithCredentialsMaybeIntegration(instances.Integration), ) if err != nil { return trace.Wrap(err) @@ -1031,7 +1046,7 @@ func (s *Server) handleEC2RemoteInstallation(instances *server.EC2Instances) err req := server.SSMRunRequest{ DocumentName: instances.DocumentName, - SSM: ec2Client, + SSM: ssmClient, Instances: instances.Instances, Params: instances.Parameters, Region: instances.Region, @@ -1070,8 +1085,8 @@ func (s *Server) handleEC2RemoteInstallation(instances *server.EC2Instances) err } func (s *Server) logHandleInstancesErr(err error) { - var aErr awserr.Error - if errors.As(err, &aErr) && aErr.Code() == ssm.ErrCodeInvalidInstanceId { + var instanceIDErr *ssmtypes.InvalidInstanceId + if errors.As(err, &instanceIDErr) { const errorMessage = "SSM SendCommand failed with ErrCodeInvalidInstanceId. " + "Make sure that the instances have AmazonSSMManagedInstanceCore policy assigned. " + "Also check that SSM agent is running and registered with the SSM endpoint on that instance and try restarting or reinstalling it in case of issues. " + @@ -1210,7 +1225,7 @@ outer: for _, node := range nodes { var vmID string if inst.Properties != nil { - vmID = aws.StringValue(inst.Properties.VMID) + vmID = aws.ToString(inst.Properties.VMID) } match := types.MatchLabels(node, map[string]string{ types.SubscriptionIDLabel: instances.SubscriptionID, diff --git a/lib/srv/discovery/discovery_test.go b/lib/srv/discovery/discovery_test.go index 8c9c08b0aff95..7f569caee654b 100644 --- a/lib/srv/discovery/discovery_test.go +++ b/lib/srv/discovery/discovery_test.go @@ -39,15 +39,14 @@ import ( awsv2 "github.com/aws/aws-sdk-go-v2/aws" "github.com/aws/aws-sdk-go-v2/service/ec2" ec2types "github.com/aws/aws-sdk-go-v2/service/ec2/types" + "github.com/aws/aws-sdk-go-v2/service/ssm" + ssmtypes "github.com/aws/aws-sdk-go-v2/service/ssm/types" "github.com/aws/aws-sdk-go/aws" - "github.com/aws/aws-sdk-go/aws/awserr" "github.com/aws/aws-sdk-go/aws/request" "github.com/aws/aws-sdk-go/service/eks" "github.com/aws/aws-sdk-go/service/eks/eksiface" "github.com/aws/aws-sdk-go/service/rds" "github.com/aws/aws-sdk-go/service/redshift" - "github.com/aws/aws-sdk-go/service/ssm" - "github.com/aws/aws-sdk-go/service/ssm/ssmiface" "github.com/google/go-cmp/cmp" "github.com/google/go-cmp/cmp/cmpopts" "github.com/google/uuid" @@ -98,26 +97,19 @@ func TestMain(m *testing.M) { } type mockSSMClient struct { - ssmiface.SSMAPI + server.SSMClient commandOutput *ssm.SendCommandOutput invokeOutput *ssm.GetCommandInvocationOutput } -func (sm *mockSSMClient) SendCommandWithContext(_ context.Context, input *ssm.SendCommandInput, _ ...request.Option) (*ssm.SendCommandOutput, error) { +func (sm *mockSSMClient) SendCommand(_ context.Context, input *ssm.SendCommandInput, _ ...func(*ssm.Options)) (*ssm.SendCommandOutput, error) { return sm.commandOutput, nil } -func (sm *mockSSMClient) GetCommandInvocationWithContext(_ context.Context, input *ssm.GetCommandInvocationInput, _ ...request.Option) (*ssm.GetCommandInvocationOutput, error) { +func (sm *mockSSMClient) GetCommandInvocation(_ context.Context, input *ssm.GetCommandInvocationInput, _ ...func(*ssm.Options)) (*ssm.GetCommandInvocationOutput, error) { return sm.invokeOutput, nil } -func (sm *mockSSMClient) WaitUntilCommandExecutedWithContext(aws.Context, *ssm.GetCommandInvocationInput, ...request.WaiterOption) error { - if aws.StringValue(sm.commandOutput.Command.Status) == ssm.CommandStatusFailed { - return awserr.New(request.WaiterResourceNotReadyErrorCode, "err", nil) - } - return nil -} - type mockEmitter struct { eventHandler func(*testing.T, events.AuditEvent, *Server) server *Server @@ -325,13 +317,13 @@ func TestDiscoveryServer(t *testing.T) { }, ssm: &mockSSMClient{ commandOutput: &ssm.SendCommandOutput{ - Command: &ssm.Command{ - CommandId: aws.String("command-id-1"), + Command: &ssmtypes.Command{ + CommandId: awsv2.String("command-id-1"), }, }, invokeOutput: &ssm.GetCommandInvocationOutput{ - Status: aws.String(ssm.CommandStatusSuccess), - ResponseCode: aws.Int64(0), + Status: ssmtypes.CommandInvocationStatusSuccess, + ResponseCode: 0, }, }, emitter: &mockEmitter{ @@ -347,7 +339,7 @@ func TestDiscoveryServer(t *testing.T) { InstanceID: "instance-id-1", Region: "eu-central-1", ExitCode: 0, - Status: ssm.CommandStatusSuccess, + Status: string(ssmtypes.CommandInvocationStatusSuccess), }, ae) }, }, @@ -383,13 +375,13 @@ func TestDiscoveryServer(t *testing.T) { }, ssm: &mockSSMClient{ commandOutput: &ssm.SendCommandOutput{ - Command: &ssm.Command{ - CommandId: aws.String("command-id-1"), + Command: &ssmtypes.Command{ + CommandId: awsv2.String("command-id-1"), }, }, invokeOutput: &ssm.GetCommandInvocationOutput{ - Status: aws.String(ssm.CommandStatusSuccess), - ResponseCode: aws.Int64(0), + Status: ssmtypes.CommandInvocationStatusSuccess, + ResponseCode: 0, }, }, staticMatchers: defaultStaticMatcher, @@ -424,13 +416,13 @@ func TestDiscoveryServer(t *testing.T) { }, ssm: &mockSSMClient{ commandOutput: &ssm.SendCommandOutput{ - Command: &ssm.Command{ - CommandId: aws.String("command-id-1"), + Command: &ssmtypes.Command{ + CommandId: awsv2.String("command-id-1"), }, }, invokeOutput: &ssm.GetCommandInvocationOutput{ - Status: aws.String(ssm.CommandStatusSuccess), - ResponseCode: aws.Int64(0), + Status: ssmtypes.CommandInvocationStatusSuccess, + ResponseCode: 0, }, }, emitter: &mockEmitter{}, @@ -443,13 +435,13 @@ func TestDiscoveryServer(t *testing.T) { foundEC2Instances: genEC2Instances(58), ssm: &mockSSMClient{ commandOutput: &ssm.SendCommandOutput{ - Command: &ssm.Command{ - CommandId: aws.String("command-id-1"), + Command: &ssmtypes.Command{ + CommandId: awsv2.String("command-id-1"), }, }, invokeOutput: &ssm.GetCommandInvocationOutput{ - Status: aws.String(ssm.CommandStatusSuccess), - ResponseCode: aws.Int64(0), + Status: ssmtypes.CommandInvocationStatusSuccess, + ResponseCode: 0, }, }, emitter: &mockEmitter{}, @@ -473,13 +465,13 @@ func TestDiscoveryServer(t *testing.T) { }, ssm: &mockSSMClient{ commandOutput: &ssm.SendCommandOutput{ - Command: &ssm.Command{ - CommandId: aws.String("command-id-1"), + Command: &ssmtypes.Command{ + CommandId: awsv2.String("command-id-1"), }, }, invokeOutput: &ssm.GetCommandInvocationOutput{ - Status: aws.String(ssm.CommandStatusSuccess), - ResponseCode: aws.Int64(0), + Status: ssmtypes.CommandInvocationStatusSuccess, + ResponseCode: 0, }, }, emitter: &mockEmitter{ @@ -495,7 +487,7 @@ func TestDiscoveryServer(t *testing.T) { InstanceID: "instance-id-1", Region: "eu-central-1", ExitCode: 0, - Status: ssm.CommandStatusSuccess, + Status: string(ssmtypes.CommandInvocationStatusSuccess), }, ae) }, }, @@ -520,13 +512,13 @@ func TestDiscoveryServer(t *testing.T) { }, ssm: &mockSSMClient{ commandOutput: &ssm.SendCommandOutput{ - Command: &ssm.Command{ - CommandId: aws.String("command-id-1"), + Command: &ssmtypes.Command{ + CommandId: awsv2.String("command-id-1"), }, }, invokeOutput: &ssm.GetCommandInvocationOutput{ - Status: aws.String(ssm.CommandStatusSuccess), - ResponseCode: aws.Int64(0), + Status: ssmtypes.CommandInvocationStatusSuccess, + ResponseCode: 0, }, }, emitter: &mockEmitter{ @@ -542,7 +534,7 @@ func TestDiscoveryServer(t *testing.T) { InstanceID: "instance-id-1", Region: "eu-central-1", ExitCode: 0, - Status: ssm.CommandStatusSuccess, + Status: string(ssmtypes.CommandInvocationStatusSuccess), }, ae) }, }, @@ -582,13 +574,13 @@ func TestDiscoveryServer(t *testing.T) { }, ssm: &mockSSMClient{ commandOutput: &ssm.SendCommandOutput{ - Command: &ssm.Command{ - CommandId: aws.String("command-id-1"), + Command: &ssmtypes.Command{ + CommandId: awsv2.String("command-id-1"), }, }, invokeOutput: &ssm.GetCommandInvocationOutput{ - Status: aws.String(ssm.CommandStatusSuccess), - ResponseCode: aws.Int64(0), + Status: ssmtypes.CommandInvocationStatusSuccess, + ResponseCode: 0, }, }, ssmRunError: trace.BadParameter("ssm run failed"), @@ -605,7 +597,7 @@ func TestDiscoveryServer(t *testing.T) { InstanceID: "instance-id-1", Region: "eu-central-1", ExitCode: 0, - Status: ssm.CommandStatusSuccess, + Status: string(ssmtypes.CommandInvocationStatusSuccess), }, ae) }, }, @@ -640,9 +632,6 @@ func TestDiscoveryServer(t *testing.T) { t.Run(tc.name, func(t *testing.T) { t.Parallel() - testCloudClients := &cloud.TestCloudClients{ - SSM: tc.ssm, - } ec2Client := &mockEC2Client{output: &ec2.DescribeInstancesOutput{ Reservations: []ec2types.Reservation{ { @@ -691,10 +680,12 @@ func TestDiscoveryServer(t *testing.T) { } server, err := New(authz.ContextWithUser(context.Background(), identity.I), &Config{ - CloudClients: testCloudClients, GetEC2Client: func(ctx context.Context, region string, opts ...config.AWSOptionsFn) (ec2.DescribeInstancesAPIClient, error) { return ec2Client, nil }, + GetSSMClient: func(ctx context.Context, region string, opts ...config.AWSOptionsFn) (server.SSMClient, error) { + return tc.ssm, nil + }, ClusterFeatures: func() proto.Features { return proto.Features{} }, KubernetesClient: fake.NewSimpleClientset(), AccessPoint: getDiscoveryAccessPoint(tlsServer.Auth(), authClient), diff --git a/lib/srv/forward/sshserver.go b/lib/srv/forward/sshserver.go index 978be8c89ea32..53b432e0fea5e 100644 --- a/lib/srv/forward/sshserver.go +++ b/lib/srv/forward/sshserver.go @@ -24,6 +24,7 @@ import ( "errors" "fmt" "io" + "log/slog" "net" "strings" "time" @@ -31,7 +32,6 @@ import ( "github.com/google/uuid" "github.com/gravitational/trace" "github.com/jonboulle/clockwork" - "github.com/sirupsen/logrus" semconv "go.opentelemetry.io/otel/semconv/v1.10.0" oteltrace "go.opentelemetry.io/otel/trace" "golang.org/x/crypto/ssh" @@ -79,7 +79,7 @@ import ( // return nil, trace.Wrap(err) // } type Server struct { - log *logrus.Entry + logger *slog.Logger id string @@ -329,13 +329,10 @@ func New(c ServerConfig) (*Server, error) { } s := &Server{ - log: logrus.WithFields(logrus.Fields{ - teleport.ComponentKey: teleport.ComponentForwardingNode, - teleport.ComponentFields: map[string]string{ - "src-addr": c.SrcAddr.String(), - "dst-addr": c.DstAddr.String(), - }, - }), + logger: slog.With(teleport.ComponentKey, teleport.ComponentForwardingNode, + "src_addr", c.SrcAddr.String(), + "dst_addr", c.DstAddr.String(), + ), id: uuid.New().String(), targetConn: c.TargetConn, serverConn: utils.NewTrackingConn(serverConn), @@ -563,13 +560,15 @@ func (s *Server) Serve() { netConfig, err := s.GetAccessPoint().GetClusterNetworkingConfig(s.Context()) if err != nil { - s.log.Errorf("Unable to fetch cluster config: %v.", err) + s.logger.ErrorContext(s.Context(), "Unable to fetch cluster config", "error", err) return } - s.log.Debugf("Supported ciphers: %q.", s.ciphers) - s.log.Debugf("Supported KEX algorithms: %q.", s.kexAlgorithms) - s.log.Debugf("Supported MAC algorithms: %q.", s.macAlgorithms) + s.logger.DebugContext(s.Context(), "proxying ssh connection via forward server", + "ciphers", s.ciphers, + "kex_algorithms", s.kexAlgorithms, + "mac_algorithms", s.macAlgorithms, + ) // close defer func() { @@ -587,7 +586,7 @@ func (s *Server) Serve() { sconn, chans, reqs, err := ssh.NewServerConn(s.serverConn, config) if err != nil { - s.log.Errorf("Unable to create server connection: %v.", err) + s.logger.ErrorContext(s.Context(), "Unable to create server connection", "error", err) return } s.sconn = sconn @@ -598,7 +597,7 @@ func (s *Server) Serve() { // Take connection and extract identity information for the user from it. s.identityContext, err = s.authHandlers.CreateIdentityContext(sconn) if err != nil { - s.log.Errorf("Unable to create server connection: %v.", err) + s.logger.ErrorContext(s.Context(), "Unable to create server connection", "error", err) return } @@ -611,14 +610,14 @@ func (s *Server) Serve() { s.rejectChannel(chans, "Moderated sessions cannot be created for OpenSSH nodes") sconn.Close() - s.log.Debugf("Dropping connection to %s@%s that needs moderation", sconn.User(), s.clientConn.RemoteAddr()) + s.logger.DebugContext(s.Context(), "Dropping connection which required moderation", "user", sconn.User(), "client_addr", s.clientConn.RemoteAddr()) return } if s.targetServer.GetSubKind() == types.SubKindOpenSSHEICENode { sshSigner, err := s.sendSSHPublicKeyToTarget(ctx) if err != nil { - s.log.Warnf("Unable to upload SSH Public Key to EC2 Instance %q: %v", s.targetServer.GetName(), err) + s.logger.WarnContext(s.Context(), "Unable to upload SSH Public Key to EC2 Instance", "instance", s.targetServer.GetName(), "error", err) return } @@ -627,7 +626,7 @@ func (s *Server) Serve() { } // Connect and authenticate to the remote node. - s.log.Debugf("Creating remote connection to %s@%s", sconn.User(), s.clientConn.RemoteAddr()) + s.logger.DebugContext(s.Context(), "Creating remote connection", "user", sconn.User(), "client_addr", s.clientConn.RemoteAddr()) s.remoteClient, err = s.newRemoteClient(ctx, sconn.User(), netConfig) if err != nil { // Reject the connection with an error so the client doesn't hang then @@ -635,14 +634,14 @@ func (s *Server) Serve() { s.rejectChannel(chans, err.Error()) sconn.Close() - s.log.Errorf("Unable to create remote connection: %v", err) + s.logger.ErrorContext(s.Context(), "Unable to create remote connection", "error", err) return } // Once the client and server connections are established, ensure we forward // x11 channel requests from the server to the client. if err := x11.ServeChannelRequests(ctx, s.remoteClient.Client, s.handleX11ChannelRequest); err != nil { - s.log.Errorf("Unable to forward x11 channel requests: %v.", err) + s.logger.ErrorContext(s.Context(), "Unable to forward x11 channel requests", "error", err) return } @@ -818,7 +817,7 @@ func signersWithSHA1Fallback(signers []ssh.Signer) func() ([]ssh.Signer, error) } func (s *Server) handleConnection(ctx context.Context, chans <-chan ssh.NewChannel, reqs <-chan *ssh.Request) { - defer s.log.Debugf("Closing forwarding server connected to %v and releasing resources.", s.sconn.LocalAddr()) + defer s.logger.DebugContext(ctx, "Closing forwarding server connection and releasing resources", "server_addr", s.sconn.LocalAddr()) defer s.Close() for { @@ -891,7 +890,7 @@ func (s *Server) handleClientChannels(ctx context.Context, forwardedTCPIP <-chan go func() { defer span.End() if err := s.handleForwardedTCPIPRequest(ctx, nch); err != nil && !utils.IsOKNetworkError(err) { - s.log.WithError(err).Errorf("Error handling %s request.", teleport.ChanForwardedTCPIP) + s.logger.ErrorContext(ctx, "Error handling forwarded-tcpip request", "error", err) } }() } @@ -902,17 +901,17 @@ func (s *Server) handleForwardedTCPIPRequest(ctx context.Context, nch ssh.NewCha req, err := sshutils.ParseDirectTCPIPReq(nch.ExtraData()) if err != nil { if err := nch.Reject(ssh.ConnectionFailed, "failed to parse forwarded-tcpip request"); err != nil { - s.log.WithError(err).Errorf("Error rejecting %s channel.", teleport.ChanForwardedTCPIP) + s.logger.ErrorContext(ctx, "Error rejecting forwarded-tcpip channel", "error", err) } return trace.Wrap(err) } // Create context for this channel. This context will be closed when // forwarding is complete. - ctx, scx, err := srv.NewServerContext(ctx, s.connectionContext, s, s.identityContext) + scx, err := srv.NewServerContext(ctx, s.connectionContext, s, s.identityContext) if err != nil { if err := nch.Reject(ssh.ConnectionFailed, "failed to open server context"); err != nil { - s.log.WithError(err).Errorf("Error rejecting %s channel.", teleport.ChanForwardedTCPIP) + s.logger.ErrorContext(ctx, "Error rejecting forwarded-tcpip channel", "error", err) } return trace.Wrap(err) } @@ -926,7 +925,7 @@ func (s *Server) handleForwardedTCPIPRequest(ctx context.Context, nch ssh.NewCha outCh, outRequests, err := scx.ServerConn.OpenChannel(nch.ChannelType(), nch.ExtraData()) if err != nil { if err := nch.Reject(ssh.ConnectionFailed, "failed to open remote client channel"); err != nil { - s.log.WithError(err).Errorf("Error rejecting %s channel.", teleport.ChanForwardedTCPIP) + s.logger.ErrorContext(ctx, "Error rejecting forwarded-tcpip channel", "error", err) } return trace.Wrap(err) } @@ -943,7 +942,7 @@ func (s *Server) handleForwardedTCPIPRequest(ctx context.Context, nch ssh.NewCha event := scx.GetPortForwardEvent() if err := s.EmitAuditEvent(ctx, &event); err != nil { - s.log.WithError(err).Error("Failed to emit audit event.") + s.logger.ErrorContext(ctx, "Failed to emit audit event", "error", err) } return trace.Wrap(utils.ProxyConn(ctx, ch, outCh)) @@ -955,7 +954,7 @@ func (s *Server) rejectChannel(chans <-chan ssh.NewChannel, errMessage string) { return } if err := newChannel.Reject(ssh.ConnectionFailed, errMessage); err != nil { - s.log.Errorf("Unable to reject and close connection.") + s.logger.ErrorContext(s.Context(), "Unable to reject and close connection") } } @@ -966,15 +965,15 @@ func (s *Server) handleGlobalRequest(ctx context.Context, req *ssh.Request) { // forwarded to the remote server. err := req.Reply(true, []byte(teleport.Version)) if err != nil { - s.log.Debugf("Failed to reply to version request: %v.", err) + s.logger.DebugContext(ctx, "Failed to reply to version request", "error", err) } return case teleport.TCPIPForwardRequest, teleport.CancelTCPIPForwardRequest: // Forwarding requests need to be authorized first. - if err := s.checkTCPIPForwardRequest(req); err != nil { - s.log.WithError(err).Warnf("Failed to check tcpip forward request") + if err := s.checkTCPIPForwardRequest(ctx, req); err != nil { + s.logger.WarnContext(ctx, "Failed to check tcpip forward request", "error", err) if err := req.Reply(false, nil); err != nil { - s.log.Warnf("Failed to reply to global request: %v: %v", req.Type, err) + s.logger.WarnContext(ctx, "Failed to reply to global tcpip forward request", "request_type", req.Type, "error", err) } return } @@ -983,36 +982,36 @@ func (s *Server) handleGlobalRequest(ctx context.Context, req *ssh.Request) { // Reply true to session ID query requests, we will set new // session IDs for new sessions if err := req.Reply(true, nil); err != nil { - s.log.WithError(err).Warnf("Failed to reply to session ID query request") + s.logger.WarnContext(ctx, "Failed to reply to session ID query request", "error", err) } return case teleport.KeepAliveReqType: default: - s.log.Debugf("Rejecting unknown global request %q.", req.Type) + s.logger.DebugContext(ctx, "Rejecting unknown global request", "request_type", req.Type) _ = req.Reply(false, nil) return } ok, payload, err := s.remoteClient.SendRequest(ctx, req.Type, req.WantReply, req.Payload) if err != nil { - s.log.Warnf("Failed to forward global request %v: %v", req.Type, err) + s.logger.WarnContext(ctx, "Failed to forward global request", "request_type", req.Type, "error", err) return } if err := req.Reply(ok, payload); err != nil { - s.log.Warnf("Failed to reply to global request: %v: %v", req.Type, err) + s.logger.WarnContext(ctx, "Failed to reply to global request", "request_type", req.Type, "error", err) } } // checkTCPIPForwardRequest handles remote port forwarding requests. -func (s *Server) checkTCPIPForwardRequest(r *ssh.Request) error { +func (s *Server) checkTCPIPForwardRequest(ctx context.Context, r *ssh.Request) error { // On forward server in "tcpip-forward" requests from SessionJoinPrincipal // should be rejected, otherwise it's possible to use the // "-teleport-internal-join" user to bypass RBAC. if s.identityContext.Login == teleport.SSHSessionJoinPrincipal { - s.log.Error("Request rejected, tcpip-forward with SessionJoinPrincipal in forward node must be blocked") + s.logger.ErrorContext(ctx, "Request rejected, tcpip-forward with SessionJoinPrincipal in forward node must be blocked") err := trace.AccessDenied("attempted tcpip-forward request in join-only mode") if replyErr := r.Reply(false, []byte(utils.FormatErrorWithNewline(err))); replyErr != nil { - s.log.Errorf("sending error reply to SSH global request: %v", replyErr) + s.logger.ErrorContext(ctx, "sending error reply to SSH global request", "request_type", r.Type, "error", replyErr) } return err } @@ -1035,25 +1034,25 @@ func (s *Server) handleChannel(ctx context.Context, nch ssh.NewChannel) { // should be rejected, otherwise it's possible to use the // "-teleport-internal-join" user to bypass RBAC. if s.identityContext.Login == teleport.SSHSessionJoinPrincipal { - s.log.Error("Connection rejected, direct-tcpip with SessionJoinPrincipal in forward node must be blocked") + s.logger.ErrorContext(ctx, "Connection rejected, direct-tcpip with SessionJoinPrincipal in forward node must be blocked") if err := nch.Reject(ssh.Prohibited, fmt.Sprintf("attempted %v channel open in join-only mode", channelType)); err != nil { - s.log.Warnf("Failed to reject channel: %v", err) + s.logger.WarnContext(ctx, "Failed to reject channel", "error", err) } return } req, err := sshutils.ParseDirectTCPIPReq(nch.ExtraData()) if err != nil { - s.log.Errorf("Failed to parse request data: %v, err: %v", string(nch.ExtraData()), err) + s.logger.ErrorContext(ctx, "Failed to parse request data", "data", string(nch.ExtraData()), "error", err) if err := nch.Reject(ssh.UnknownChannelType, "failed to parse direct-tcpip request"); err != nil { - s.log.Warnf("Failed to reject channel: %v", err) + s.logger.WarnContext(ctx, "Failed to reject channel", "error", err) } return } ch, reqC, err := nch.Accept() if err != nil { - s.log.Warnf("Unable to accept channel: %v", err) + s.logger.WarnContext(ctx, "Unable to accept channel", "error", err) if err := nch.Reject(ssh.ConnectionFailed, fmt.Sprintf("unable to accept channel: %v", err)); err != nil { - s.log.Warnf("Failed to reject channel: %v", err) + s.logger.WarnContext(ctx, "Failed to reject channel", "error", err) } return } @@ -1061,7 +1060,7 @@ func (s *Server) handleChannel(ctx context.Context, nch ssh.NewChannel) { go s.handleDirectTCPIPRequest(ctx, ch, req) default: if err := nch.Reject(ssh.UnknownChannelType, fmt.Sprintf("unknown channel type: %v", channelType)); err != nil { - s.log.Warnf("Failed to reject channel of unknown type: %v", err) + s.logger.WarnContext(ctx, "Failed to reject unknown channel", "channel", channelType, "error", err) } } } @@ -1070,10 +1069,10 @@ func (s *Server) handleChannel(ctx context.Context, nch ssh.NewChannel) { func (s *Server) handleDirectTCPIPRequest(ctx context.Context, ch ssh.Channel, req *sshutils.DirectTCPIPReq) { // Create context for this channel. This context will be closed when // forwarding is complete. - ctx, scx, err := srv.NewServerContext(ctx, s.connectionContext, s, s.identityContext) + scx, err := srv.NewServerContext(ctx, s.connectionContext, s, s.identityContext) if err != nil { - s.log.Errorf("Unable to create connection context: %v.", err) - s.stderrWrite(ch, "Unable to create connection context.") + s.logger.ErrorContext(ctx, "Unable to create connection context", "error", err) + s.stderrWrite(ctx, ch, "Unable to create connection context.") return } scx.RemoteClient = s.remoteClient @@ -1087,28 +1086,28 @@ func (s *Server) handleDirectTCPIPRequest(ctx context.Context, ch ssh.Channel, r // Check if the role allows port forwarding for this user. err = s.authHandlers.CheckPortForward(scx.DstAddr, scx) if err != nil { - s.stderrWrite(ch, err.Error()) + s.stderrWrite(ctx, ch, err.Error()) return } - s.log.Debugf("Opening direct-tcpip channel from %v to %v in context %v.", scx.SrcAddr, scx.DstAddr, scx.ID()) - defer s.log.Debugf("Completing direct-tcpip request from %v to %v in context %v.", scx.SrcAddr, scx.DstAddr, scx.ID()) + s.logger.DebugContext(ctx, "Opening direct-tcpip channel", "source_addr", scx.SrcAddr, "dest_addr", scx.DstAddr, "session_id", scx.ID()) + defer s.logger.DebugContext(ctx, "Completing direct-tcpip request ", "source_addr", scx.SrcAddr, "dest_addr", scx.DstAddr, "session_id", scx.ID()) // Create "direct-tcpip" channel from the remote host to the target host. conn, err := s.remoteClient.DialContext(ctx, "tcp", scx.DstAddr) if err != nil { - scx.Infof("Failed to connect to: %v: %v", scx.DstAddr, err) + s.logger.InfoContext(ctx, "Failed to connect to remote host", "target_addr", scx.DstAddr, "error", err) return } defer conn.Close() event := scx.GetPortForwardEvent() if err := s.EmitAuditEvent(s.closeContext, &event); err != nil { - scx.WithError(err).Warn("Failed to emit port forward event.") + s.logger.WarnContext(ctx, "Failed to emit port forward event", "error", err) } if err := utils.ProxyConn(ctx, ch, conn); err != nil { - s.log.WithError(err).Warn("Pailed proxying data for port forwarding connection.") + s.logger.WarnContext(ctx, "Failed proxying data for port forwarding connection", "error", err) } } @@ -1121,11 +1120,11 @@ func (s *Server) handleSessionChannel(ctx context.Context, nch ssh.NewChannel) { // There is no need for the forwarding server to initiate disconnects, // based on teleport business logic, because this logic is already // done on the server's terminating side. - ctx, scx, err := srv.NewServerContext(ctx, s.connectionContext, s, s.identityContext) + scx, err := srv.NewServerContext(ctx, s.connectionContext, s, s.identityContext) if err != nil { - s.log.Warnf("Server context setup failed: %v", err) + s.logger.WarnContext(ctx, "Server context setup failed", "error", err) if err := nch.Reject(ssh.ConnectionFailed, fmt.Sprintf("server context setup failed: %v", err)); err != nil { - s.log.Warnf("Failed to reject channel: %v", err) + s.logger.WarnContext(ctx, "Failed to reject channel", "channel", nch.ChannelType(), "error", err) } return } @@ -1144,14 +1143,14 @@ func (s *Server) handleSessionChannel(ctx context.Context, nch ssh.NewChannel) { // reason/message in the event the channel is rejected. remoteSession, err := s.remoteClient.NewSession(ctx) if err != nil { - s.log.Warnf("Remote session open failed: %v", err) + s.logger.WarnContext(ctx, "Remote session open failed", "error", err) reason, msg := ssh.ConnectionFailed, fmt.Sprintf("remote session open failed: %v", err) var e *ssh.OpenChannelError if errors.As(trace.Unwrap(err), &e) { reason, msg = e.Reason, e.Message } if err := nch.Reject(reason, msg); err != nil { - s.log.Warnf("Failed to reject channel: %v", err) + s.logger.WarnContext(ctx, "Failed to reject channel", "error", err) } return } @@ -1160,9 +1159,9 @@ func (s *Server) handleSessionChannel(ctx context.Context, nch ssh.NewChannel) { // Accept the session channel request ch, in, err := nch.Accept() if err != nil { - s.log.Warnf("Unable to accept channel: %v", err) + s.logger.WarnContext(ctx, "Unable to accept channel", "channel", nch.ChannelType(), "error", err) if err := nch.Reject(ssh.ConnectionFailed, fmt.Sprintf("unable to accept channel: %v", err)); err != nil { - s.log.Warnf("Failed to reject channel: %v", err) + s.logger.WarnContext(ctx, "Failed to reject channel", "channel", nch.ChannelType(), "error", err) } return } @@ -1170,21 +1169,20 @@ func (s *Server) handleSessionChannel(ctx context.Context, nch ssh.NewChannel) { ch = scx.TrackActivity(ch) - s.log.Debugf("Opening session request to %v in context %v.", s.sconn.RemoteAddr(), scx.ID()) - defer s.log.Debugf("Closing session request to %v in context %v.", s.sconn.RemoteAddr(), scx.ID()) + s.logger.DebugContext(ctx, "Opening session request", "target_addr", s.sconn.RemoteAddr(), "session_id", scx.ID()) + defer s.logger.DebugContext(ctx, "Closing session request", "target_addr", s.sconn.RemoteAddr(), "session_id", scx.ID()) for { // Update the context with the session ID. err := scx.CreateOrJoinSession(s.sessionRegistry) if err != nil { - errorMessage := fmt.Sprintf("unable to update context: %v", err) - scx.Errorf("%v", errorMessage) + s.logger.ErrorContext(ctx, "unable create or join session", "error", err) // Write the error to channel and close it. - s.stderrWrite(ch, errorMessage) + s.stderrWrite(ctx, ch, fmt.Sprintf("unable to update context: %v", err)) _, err := ch.SendRequest("exit-status", false, ssh.Marshal(struct{ C uint32 }{C: teleport.RemoteCommandFailure})) if err != nil { - scx.Errorf("Failed to send exit status %v", errorMessage) + s.logger.ErrorContext(ctx, "Failed to send exit status", "error", err) } return } @@ -1192,12 +1190,12 @@ func (s *Server) handleSessionChannel(ctx context.Context, nch ssh.NewChannel) { select { case result := <-scx.SubsystemResultCh: // Subsystem has finished executing, close the channel and session. - scx.Debugf("Subsystem execution result: %v", result.Err) + s.logger.DebugContext(ctx, "Subsystem execution result", "error", result.Err) return case req := <-in: if req == nil { // The client has closed or dropped the connection. - scx.Debugf("Client %v disconnected", s.sconn.RemoteAddr()) + s.logger.DebugContext(ctx, "Client disconnected", "remote_addr", s.sconn.RemoteAddr()) return } @@ -1217,24 +1215,24 @@ func (s *Server) handleSessionChannel(ctx context.Context, nch ssh.NewChannel) { // rather than leaving the reply to be handled inside this loop. in that case, those functions must // set req.WantReply to false so that two replies are not sent. if err := s.dispatch(ctx, ch, req, scx); err != nil { - s.replyError(ch, req, err) + s.replyError(ctx, ch, req, err) span.End() return } if req.WantReply { if err := req.Reply(true, nil); err != nil { - scx.Errorf("failed sending OK response on %q request: %v", req.Type, err) + s.logger.ErrorContext(ctx, "failed replying OK to SSH request", "request_type", req.Type, "error", err) } } span.End() case result := <-scx.ExecResultCh: - scx.Debugf("Exec request (%q) complete: %v", result.Command, result.Code) + s.logger.DebugContext(ctx, "Exec request complete", "command", result.Command, "code", result.Code) // The exec process has finished and delivered the execution result, send // the result back to the client, and close the session and channel. _, err := ch.SendRequest("exit-status", false, ssh.Marshal(struct{ C uint32 }{C: uint32(result.Code)})) if err != nil { - scx.Infof("Failed to send exit status for %v: %v", result.Command, err) + s.logger.InfoContext(ctx, "Failed to send exit status", "command", result.Command, "error", err) } return @@ -1245,7 +1243,7 @@ func (s *Server) handleSessionChannel(ctx context.Context, nch ssh.NewChannel) { } func (s *Server) dispatch(ctx context.Context, ch ssh.Channel, req *ssh.Request, scx *srv.ServerContext) error { - scx.Debugf("Handling request %v, want reply %v.", req.Type, req.WantReply) + s.logger.DebugContext(ctx, "Handling request", "request_type", req.Type, "want_reply", req.WantReply) // Certs with a join-only principal can only use a // subset of all the possible request types. @@ -1270,11 +1268,11 @@ func (s *Server) dispatch(ctx context.Context, ch ssh.Channel, req *ssh.Request, // processing requests. err := s.handleAgentForward(ch, req, scx) if err != nil { - s.log.Debug(err) + s.logger.DebugContext(ctx, "failure forwarding agent", "error", err) } return nil case sshutils.PuTTYWinadjRequest: - return s.handlePuTTYWinadj(ch, req) + return s.handlePuTTYWinadj(ctx, ch, req) default: return trace.AccessDenied("attempted %v request in join-only mode", req.Type) } @@ -1305,16 +1303,16 @@ func (s *Server) dispatch(ctx context.Context, ch ssh.Channel, req *ssh.Request, // processing requests. err := s.handleAgentForward(ch, req, scx) if err != nil { - s.log.Debug(err) + s.logger.DebugContext(ctx, "failure forwarding agent", "error", err) } return nil case sshutils.PuTTYWinadjRequest: - return s.handlePuTTYWinadj(ch, req) + return s.handlePuTTYWinadj(ctx, ch, req) default: - s.log.Warnf("%v doesn't support request type '%v'", s.Component(), req.Type) + s.logger.WarnContext(ctx, "received unsupported SSH request", "request_type", req.Type) if req.WantReply { if err := req.Reply(false, nil); err != nil { - s.log.Errorf("sending error reply on SSH channel: %v", err) + s.logger.ErrorContext(ctx, "failed sending error reply on SSH channel", "error", err) } } return nil @@ -1366,7 +1364,7 @@ func (s *Server) handleX11ChannelRequest(ctx context.Context, nch ssh.NewChannel // accept inbound X11 channel from remote server sch, sin, err := nch.Accept() if err != nil { - s.log.Errorf("X11 channel fwd failed: %v", err) + s.logger.ErrorContext(ctx, "X11 channel fwd failed", "error", err) return } defer sch.Close() @@ -1374,7 +1372,7 @@ func (s *Server) handleX11ChannelRequest(ctx context.Context, nch ssh.NewChannel // setup outbound X11 channel to client cch, cin, err := s.sconn.OpenChannel(x11.ChannelRequest, nch.ExtraData()) if err != nil { - s.log.Errorf("X11 channel fwd failed: %v", err) + s.logger.ErrorContext(ctx, "X11 channel fwd failed", "error", err) return } defer cch.Close() @@ -1386,19 +1384,19 @@ func (s *Server) handleX11ChannelRequest(ctx context.Context, nch ssh.NewChannel go func() { err := sshutils.ForwardRequests(ctx, cin, tracessh.NewTraceChannel(sch, tracing.WithTracerProvider(s.tracerProvider))) if err != nil { - s.log.WithError(err).Debug("Failed to forward ssh request from client during X11 forwarding") + s.logger.DebugContext(ctx, "Failed to forward ssh request from client during X11 forwarding", "error", err) } }() go func() { err := sshutils.ForwardRequests(ctx, sin, tracessh.NewTraceChannel(cch, tracing.WithTracerProvider(s.tracerProvider))) if err != nil { - s.log.WithError(err).Debug("Failed to forward ssh request from server during X11 forwarding") + s.logger.DebugContext(ctx, "Failed to forward ssh request from server during X11 forwarding", "error", err) } }() if err := utils.ProxyConn(ctx, cch, sch); err != nil { - s.log.WithError(err).Debug("Encountered error during x11 forwarding") + s.logger.DebugContext(ctx, "Encountered error during x11 forwarding", "error", err) } } @@ -1428,11 +1426,11 @@ func (s *Server) handleX11Forward(ctx context.Context, ch ssh.Channel, req *ssh. if trace.IsAccessDenied(err) { // denied X11 requests are ok from a protocol perspective so we // don't return them, just reply over ssh and emit the audit log. - s.replyError(ch, req, err) + s.replyError(ctx, ch, req, err) err = nil } if err := s.EmitAuditEvent(ctx, event); err != nil { - s.log.WithError(err).Warn("Failed to emit x11-forward event.") + s.logger.WarnContext(ctx, "Failed to emit x11-forward event", "error", err) } }() @@ -1501,7 +1499,7 @@ func (s *Server) handleSubsystem(ctx context.Context, ch ssh.Channel, req *ssh.R func (s *Server) handleEnv(ctx context.Context, ch ssh.Channel, req *ssh.Request, scx *srv.ServerContext) error { var e sshutils.EnvReqParams if err := ssh.Unmarshal(req.Payload, &e); err != nil { - scx.Error(err) + s.logger.ErrorContext(ctx, "failed to parse env request", "error", err) return trace.Wrap(err, "failed to parse env request") } @@ -1517,7 +1515,7 @@ func (s *Server) handleEnv(ctx context.Context, ch ssh.Channel, req *ssh.Request err := scx.RemoteSession.Setenv(ctx, e.Name, e.Value) if err != nil { - s.log.Debugf("Unable to set environment variable: %v: %v", e.Name, e.Value) + s.logger.DebugContext(ctx, "Unable to set environment variable", "key", e.Name, "value", e.Value, "error", err) } return nil @@ -1528,7 +1526,7 @@ func (s *Server) handleEnv(ctx context.Context, ch ssh.Channel, req *ssh.Request func (s *Server) handleEnvs(ctx context.Context, ch ssh.Channel, req *ssh.Request, scx *srv.ServerContext) error { var raw tracessh.EnvsReq if err := ssh.Unmarshal(req.Payload, &raw); err != nil { - scx.Error(err) + s.logger.ErrorContext(ctx, "failed to parse envs request", "error", err) return trace.Wrap(err, "failed to parse envs request") } @@ -1550,30 +1548,30 @@ func (s *Server) handleEnvs(ctx context.Context, ch ssh.Channel, req *ssh.Reques } if err := scx.RemoteSession.SetEnvs(ctx, envs); err != nil { - s.log.WithError(err).Debug("Unable to set environment variables") + s.logger.DebugContext(ctx, "Unable to set environment variables", "error", err) } return nil } -func (s *Server) replyError(ch ssh.Channel, req *ssh.Request, err error) { - s.log.WithError(err).Errorf("failure handling SSH %q request", req.Type) +func (s *Server) replyError(ctx context.Context, ch ssh.Channel, req *ssh.Request, err error) { + s.logger.ErrorContext(ctx, "failure handling SSH request", "request_type", req.Type, "error", err) // Terminate the error with a newline when writing to remote channel's // stderr so the output does not mix with the rest of the output if the remote // side is not doing additional formatting for extended data. // See github.com/gravitational/teleport/issues/4542 message := utils.FormatErrorWithNewline(err) - s.stderrWrite(ch, message) + s.stderrWrite(ctx, ch, message) if req.WantReply { if err := req.Reply(false, []byte(message)); err != nil { - s.log.Errorf("sending error reply on SSH channel: %v", err) + s.logger.ErrorContext(ctx, "failed sending error reply on SSH channel", "error", err) } } } -func (s *Server) stderrWrite(ch ssh.Channel, message string) { +func (s *Server) stderrWrite(ctx context.Context, ch ssh.Channel, message string) { if _, err := ch.Stderr().Write([]byte(message)); err != nil { - s.log.Errorf("failed writing to SSH stderr channel: %v", err) + s.logger.ErrorContext(ctx, "failed writing to SSH stderr channel", "error", err) } } @@ -1593,9 +1591,9 @@ func parseSubsystemRequest(req *ssh.Request, ctx *srv.ServerContext) (*remoteSub // tuning. It can be sent on any type of channel. There is no message-specific data. Servers MUST treat it // as an unrecognized request and respond with SSH_MSG_CHANNEL_FAILURE. // https://the.earth.li/~sgtatham/putty/0.76/htmldoc/AppendixG.html#sshnames-channel -func (s *Server) handlePuTTYWinadj(ch ssh.Channel, req *ssh.Request) error { +func (s *Server) handlePuTTYWinadj(ctx context.Context, ch ssh.Channel, req *ssh.Request) error { if err := req.Reply(false, nil); err != nil { - s.log.Warnf("Failed to reply to %q request: %v", req.Type, err) + s.logger.WarnContext(ctx, "Failed to reply to request", "request_type", req.Type, "error", err) return err } // the reply has been handled inside this function (rather than relying on the standard behavior diff --git a/lib/srv/forward/sshserver_test.go b/lib/srv/forward/sshserver_test.go index 98e409e63b692..36eec86b3314d 100644 --- a/lib/srv/forward/sshserver_test.go +++ b/lib/srv/forward/sshserver_test.go @@ -219,7 +219,7 @@ func TestDirectTCPIP(t *testing.T) { t.Parallel() s := Server{ - log: utils.NewLoggerForTests().WithField(teleport.ComponentKey, "test"), + logger: utils.NewSlogLoggerForTests(), identityContext: srv.IdentityContext{Login: tt.login}, } @@ -255,17 +255,18 @@ func TestCheckTCPIPForward(t *testing.T) { t.Parallel() s := Server{ - log: utils.NewLoggerForTests().WithField(teleport.ComponentKey, "test"), + logger: utils.NewSlogLoggerForTests(), identityContext: srv.IdentityContext{Login: tt.login}, } - err := s.checkTCPIPForwardRequest(&ssh.Request{ - Type: teleport.TCPIPForwardRequest, - WantReply: false, - Payload: ssh.Marshal(sshutils.TCPIPForwardReq{ - Addr: "localhost", - Port: 0, - }), - }) + err := s.checkTCPIPForwardRequest(context.Background(), + &ssh.Request{ + Type: teleport.TCPIPForwardRequest, + WantReply: false, + Payload: ssh.Marshal(sshutils.TCPIPForwardReq{ + Addr: "localhost", + Port: 0, + }), + }) tt.assert(t, err) }) } diff --git a/lib/srv/forward/subsystem.go b/lib/srv/forward/subsystem.go index f97d8fd3123e8..905145888b111 100644 --- a/lib/srv/forward/subsystem.go +++ b/lib/srv/forward/subsystem.go @@ -22,9 +22,9 @@ import ( "context" "errors" "io" + "log/slog" "github.com/gravitational/trace" - log "github.com/sirupsen/logrus" "golang.org/x/crypto/ssh" "github.com/gravitational/teleport" @@ -35,7 +35,7 @@ import ( // remoteSubsystem is a subsystem that executes on a remote node. type remoteSubsystem struct { - log *log.Entry + logger *slog.Logger serverContext *srv.ServerContext subsystemName string @@ -47,12 +47,10 @@ type remoteSubsystem struct { // parseRemoteSubsystem returns *remoteSubsystem which can be used to run a subsystem on a remote node. func parseRemoteSubsystem(ctx context.Context, subsystemName string, serverContext *srv.ServerContext) *remoteSubsystem { return &remoteSubsystem{ - log: log.WithFields(log.Fields{ - teleport.ComponentKey: teleport.ComponentRemoteSubsystem, - teleport.ComponentFields: map[string]string{ - "name": subsystemName, - }, - }), + logger: slog.With( + teleport.ComponentKey, teleport.ComponentRemoteSubsystem, + "name", subsystemName, + ), serverContext: serverContext, subsystemName: subsystemName, ctx: ctx, @@ -118,7 +116,7 @@ func (r *remoteSubsystem) Wait() error { select { case err := <-r.errorCh: if err != nil && !errors.Is(err, io.EOF) { - r.log.Warnf("Connection problem: %v %T", trace.DebugReport(err), err) + r.logger.WarnContext(r.ctx, "Connection problem", "error", err) lastErr = err } case <-r.ctx.Done(): @@ -154,6 +152,6 @@ func (r *remoteSubsystem) emitAuditEvent(ctx context.Context, err error) { } if err := r.serverContext.GetServer().EmitAuditEvent(ctx, subsystemEvent); err != nil { - r.log.WithError(err).Warn("Failed to emit subsystem audit event.") + r.logger.WarnContext(ctx, "Failed to emit subsystem audit event", "error", err) } } diff --git a/lib/srv/heartbeat.go b/lib/srv/heartbeat.go index 639f6581e1e31..82ea1eafacca2 100644 --- a/lib/srv/heartbeat.go +++ b/lib/srv/heartbeat.go @@ -21,11 +21,11 @@ package srv import ( "context" "fmt" + "log/slog" "time" "github.com/gravitational/trace" "github.com/jonboulle/clockwork" - log "github.com/sirupsen/logrus" "github.com/gravitational/teleport" "github.com/gravitational/teleport/api/types" @@ -155,14 +155,17 @@ func NewHeartbeat(cfg HeartbeatConfig) (*Heartbeat, error) { cancelCtx: ctx, cancel: cancel, HeartbeatConfig: cfg, - Entry: log.WithFields(log.Fields{ - teleport.ComponentKey: teleport.Component(cfg.Component, "beat"), - }), - checkTicker: cfg.Clock.NewTicker(cfg.CheckPeriod), - announceC: make(chan struct{}, 1), - sendC: make(chan struct{}, 1), + logger: slog.With(teleport.ComponentKey, teleport.Component(cfg.Component, "beat")), + checkTicker: cfg.Clock.NewTicker(cfg.CheckPeriod), + announceC: make(chan struct{}, 1), + sendC: make(chan struct{}, 1), } - h.Debugf("Starting %v heartbeat with announce period: %v, keep-alive period %v, poll period: %v", cfg.Mode, cfg.KeepAlivePeriod, cfg.AnnouncePeriod, cfg.CheckPeriod) + h.logger.DebugContext(ctx, "Starting heartbeat with announce period", + "mode", cfg.Mode, + "keep_alive_period", cfg.KeepAlivePeriod, + "announce_period", cfg.AnnouncePeriod, + "check_period", cfg.CheckPeriod, + ) return h, nil } @@ -249,7 +252,7 @@ type Heartbeat struct { HeartbeatConfig cancelCtx context.Context cancel context.CancelFunc - *log.Entry + logger *slog.Logger state KeepAliveState current types.Resource keepAlive *types.KeepAlive @@ -280,15 +283,15 @@ func (h *Heartbeat) Run() error { for { err := h.fetchAndAnnounce() if err != nil { - h.Warningf("Heartbeat failed %v.", err) + h.logger.WarnContext(h.Context, "Heartbeat failed", "error", err) } h.OnHeartbeat(err) select { case <-h.checkTicker.Chan(): case <-h.sendC: - h.Debugf("Asked check out of cycle") + h.logger.DebugContext(h.Context, "Asked check out of cycle") case <-h.cancelCtx.Done(): - h.Debugf("Heartbeat exited.") + h.logger.DebugContext(h.Context, "Heartbeat exited") return nil } } @@ -324,7 +327,7 @@ func (h *Heartbeat) reset(state KeepAliveState) { h.keepAlive = nil if h.keepAliver != nil { if err := h.keepAliver.Close(); err != nil { - h.Warningf("Failed to close keep aliver: %v", err) + h.logger.WarnContext(h.Context, "Failed to close keep aliver", "error", err) } h.keepAliver = nil } @@ -590,7 +593,7 @@ func (h *Heartbeat) announce() error { case <-h.cancelCtx.Done(): return nil case <-timeout.C: - h.Warningf("Blocked on keep alive send, going to reset.") + h.logger.WarnContext(h.Context, "Blocked on keep alive send, going to reset.") h.reset(HeartbeatStateInit) return trace.ConnectionProblem(nil, "timeout sending keep alive") case h.keepAliver.KeepAlives() <- keepAlive: @@ -599,7 +602,7 @@ func (h *Heartbeat) announce() error { h.setState(HeartbeatStateKeepAliveWait) return nil case <-h.keepAliver.Done(): - h.Warningf("Keep alive has failed: %v.", h.keepAliver.Error()) + h.logger.WarnContext(h.Context, "Keep alive has failed", "error", h.keepAliver.Error()) err := h.keepAliver.Error() h.reset(HeartbeatStateInit) return trace.ConnectionProblem(err, "keep alive channel closed") diff --git a/lib/srv/heartbeatv2.go b/lib/srv/heartbeatv2.go index 7a95020e7a31d..299c1b274e09c 100644 --- a/lib/srv/heartbeatv2.go +++ b/lib/srv/heartbeatv2.go @@ -21,10 +21,10 @@ package srv import ( "context" "errors" + "log/slog" "time" "github.com/gravitational/trace" - log "github.com/sirupsen/logrus" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" @@ -559,12 +559,12 @@ func (h *sshServerHeartbeatV2) FallbackAnnounce(ctx context.Context) (ok bool) { } server, err := h.getServer(ctx) if err != nil { - log.Warnf("Failed to perform fallback heartbeat for ssh server: %v", err) + slog.WarnContext(ctx, "Failed to perform fallback heartbeat for ssh server", "error", err) return false } if _, err := h.announcer.UpsertNode(ctx, server); err != nil { - log.Warnf("Failed to perform fallback heartbeat for ssh server: %v", err) + slog.WarnContext(ctx, "Failed to perform fallback heartbeat for ssh server", "error", err) return false } @@ -575,12 +575,12 @@ func (h *sshServerHeartbeatV2) FallbackAnnounce(ctx context.Context) (ok bool) { func (h *sshServerHeartbeatV2) Announce(ctx context.Context, sender inventory.DownstreamSender) (ok bool) { server, err := h.getServer(ctx) if err != nil { - log.Warnf("Failed to perform inventory heartbeat for ssh server: %v", err) + slog.WarnContext(ctx, "Failed to perform inventory heartbeat for ssh server", "error", err) return false } if err := sender.Send(ctx, proto.InventoryHeartbeat{SSHServer: apiutils.CloneProtoMsg(server)}); err != nil { - log.Warnf("Failed to perform inventory heartbeat for ssh server: %v", err) + slog.WarnContext(ctx, "Failed to perform inventory heartbeat for ssh server", "error", err) return false } h.prev = server @@ -617,13 +617,13 @@ func (h *appServerHeartbeatV2) FallbackAnnounce(ctx context.Context) (ok bool) { } server, err := h.getServer(ctx) if err != nil { - log.Warnf("Failed to perform fallback heartbeat for app server: %v", err) + slog.WarnContext(ctx, "Failed to perform fallback heartbeat for app server", "error", err) return false } if _, err := h.announcer.UpsertApplicationServer(ctx, server); err != nil { if !errors.Is(err, context.Canceled) && status.Code(err) != codes.Canceled { - log.Warnf("Failed to perform fallback heartbeat for app server: %v", err) + slog.WarnContext(ctx, "Failed to perform fallback heartbeat for app server", "error", err) } return false } @@ -645,13 +645,13 @@ func (h *appServerHeartbeatV2) Announce(ctx context.Context, sender inventory.Do server, err := h.getServer(ctx) if err != nil { - log.Warnf("Failed to perform inventory heartbeat for app server: %v", err) + slog.WarnContext(ctx, "Failed to perform inventory heartbeat for app server", "error", err) return false } if err := sender.Send(ctx, proto.InventoryHeartbeat{AppServer: apiutils.CloneProtoMsg(server)}); err != nil { if !errors.Is(err, context.Canceled) && status.Code(err) != codes.Canceled { - log.Warnf("Failed to perform inventory heartbeat for app server: %v", err) + slog.WarnContext(ctx, "Failed to perform inventory heartbeat for app server", "error", err) } return false } @@ -690,12 +690,12 @@ func (h *dbServerHeartbeatV2) FallbackAnnounce(ctx context.Context) (ok bool) { } server, err := h.getServer(ctx) if err != nil { - log.Warnf("Failed to perform fallback heartbeat for database server: %v", err) + slog.WarnContext(ctx, "Failed to perform fallback heartbeat for database server", "error", err) return false } if _, err := h.announcer.UpsertDatabaseServer(ctx, server); err != nil { if !errors.Is(err, context.Canceled) && status.Code(err) != codes.Canceled { - log.Warnf("Failed to perform fallback heartbeat for database server: %v", err) + slog.WarnContext(ctx, "Failed to perform fallback heartbeat for database server", "error", err) } return false } @@ -717,12 +717,12 @@ func (h *dbServerHeartbeatV2) Announce(ctx context.Context, sender inventory.Dow server, err := h.getServer(ctx) if err != nil { - log.Warnf("Failed to perform inventory heartbeat for database server: %v", err) + slog.WarnContext(ctx, "Failed to perform inventory heartbeat for database server", "error", err) return false } if err := sender.Send(ctx, proto.InventoryHeartbeat{DatabaseServer: apiutils.CloneProtoMsg(server)}); err != nil { if !errors.Is(err, context.Canceled) && status.Code(err) != codes.Canceled { - log.Warnf("Failed to perform inventory heartbeat for database server: %v", err) + slog.WarnContext(ctx, "Failed to perform inventory heartbeat for database server", "error", err) } return false } @@ -761,13 +761,13 @@ func (h *kubeServerHeartbeatV2) FallbackAnnounce(ctx context.Context) (ok bool) } server, err := h.getServer(ctx) if err != nil { - log.Warnf("Failed to perform fallback heartbeat for kubernetes server: %v", err) + slog.WarnContext(ctx, "Failed to perform fallback heartbeat for kubernetes server", "error", err) return false } if _, err := h.announcer.UpsertKubernetesServer(ctx, apiutils.CloneProtoMsg(server)); err != nil { if !errors.Is(err, context.Canceled) && status.Code(err) != codes.Canceled { - log.Warnf("Failed to perform fallback heartbeat for kubernetes server: %v", err) + slog.WarnContext(ctx, "Failed to perform fallback heartbeat for kubernetes server", "error", err) } return false } @@ -789,12 +789,12 @@ func (h *kubeServerHeartbeatV2) Announce(ctx context.Context, sender inventory.D server, err := h.getServer(ctx) if err != nil { - log.Warnf("Failed to perform inventory heartbeat for kubernetes server: %v", err) + slog.WarnContext(ctx, "Failed to perform inventory heartbeat for kubernetes server", "error", err) return false } if err := sender.Send(ctx, proto.InventoryHeartbeat{KubernetesServer: apiutils.CloneProtoMsg(server)}); err != nil { if !errors.Is(err, context.Canceled) && status.Code(err) != codes.Canceled { - log.Warnf("Failed to perform inventory heartbeat for kubernetes server: %v", err) + slog.WarnContext(ctx, "Failed to perform inventory heartbeat for kubernetes server", "error", err) } return false } diff --git a/lib/srv/keepalive.go b/lib/srv/keepalive.go index 18d3418041f33..1f11bc1847248 100644 --- a/lib/srv/keepalive.go +++ b/lib/srv/keepalive.go @@ -20,10 +20,9 @@ package srv import ( "context" + "log/slog" "time" - "github.com/sirupsen/logrus" - "github.com/gravitational/teleport" "github.com/gravitational/teleport/lib/defaults" ) @@ -59,10 +58,8 @@ type KeepAliveParams struct { func StartKeepAliveLoop(p KeepAliveParams) { var missedCount int64 - log := logrus.WithFields(logrus.Fields{ - teleport.ComponentKey: teleport.ComponentKeepAlive, - }) - log.Debugf("Starting keep-alive loop with interval %v and max count %v.", p.Interval, p.MaxCount) + log := slog.With(teleport.ComponentKey, teleport.ComponentKeepAlive) + log.DebugContext(p.CloseContext, "Starting keep-alive loop", "interval", p.Interval, "max_count", p.MaxCount) tickerCh := time.NewTicker(p.Interval) defer tickerCh.Stop() @@ -89,7 +86,7 @@ func StartKeepAliveLoop(p KeepAliveParams) { // and notify the server to disconnect and cleanup. missedCount = missedCount + 1 if missedCount > p.MaxCount { - log.Infof("Missed %v keep-alive messages, closing connection.", missedCount) + log.InfoContext(p.CloseContext, "Missed too keep-alive messages, closing connection", "missed_count", missedCount) p.CloseCancel() return } diff --git a/lib/srv/monitor.go b/lib/srv/monitor.go index 183aeba78b7e8..8381c6e8bde4a 100644 --- a/lib/srv/monitor.go +++ b/lib/srv/monitor.go @@ -22,13 +22,13 @@ import ( "context" "fmt" "io" + "log/slog" "net" "sync" "time" "github.com/gravitational/trace" "github.com/jonboulle/clockwork" - log "github.com/sirupsen/logrus" "golang.org/x/crypto/ssh" "github.com/gravitational/teleport" @@ -75,8 +75,8 @@ type ConnectionMonitorConfig struct { Emitter apievents.Emitter // EmitterContext is long-lived context suitable to be used with Emitter EmitterContext context.Context - // Logger is a logging entry. - Logger log.FieldLogger + // Logger emits log messages. + Logger *slog.Logger // MonitorCloseChannel will be signaled when the monitor closes a connection. // Used only for testing. Optional. MonitorCloseChannel chan struct{} @@ -191,7 +191,7 @@ func (c *ConnectionMonitor) MonitorConn(ctx context.Context, authzCtx *authz.Con TeleportUser: identity.Username, Emitter: c.cfg.Emitter, EmitterContext: c.cfg.EmitterContext, - Entry: c.cfg.Logger, + Logger: c.cfg.Logger, IdleTimeoutMessage: netConfig.GetClientIdleTimeoutMessage(), MonitorCloseChannel: c.cfg.MonitorCloseChannel, }); err != nil { @@ -234,8 +234,8 @@ type MonitorConfig struct { Emitter apievents.Emitter // EmitterContext is long-lived context suitable to be used with Emitter. Typically, a server exit context will be used here. EmitterContext context.Context - // Entry is a logging entry - Entry log.FieldLogger + // Logger emits log messages. + Logger *slog.Logger // IdleTimeoutMessage is sent to the client when the idle timeout expires. IdleTimeoutMessage string // MessageWriter wraps a channel to send text messages to the client. Use @@ -260,8 +260,8 @@ func (m *MonitorConfig) CheckAndSetDefaults() error { if m.Conn == nil { return trace.BadParameter("missing parameter Conn") } - if m.Entry == nil { - return trace.BadParameter("missing parameter Entry") + if m.Logger == nil { + return trace.BadParameter("missing parameter Logger") } if m.Tracker == nil { return trace.BadParameter("missing parameter Tracker") @@ -321,7 +321,7 @@ func (w *Monitor) start(lockWatch types.Watcher) { lockWatchDoneC := lockWatch.Done() defer func() { if err := lockWatch.Close(); err != nil { - w.Entry.WithError(err).Warn("Failed to close lock watcher subscription.") + w.Logger.WarnContext(w.Context, "Failed to close lock watcher subscription", "error", err) } }() @@ -366,14 +366,14 @@ func (w *Monitor) start(lockWatch types.Watcher) { msg = reason } if _, err := w.MessageWriter.WriteString(msg); err != nil { - w.Entry.WithError(err).Warn("Failed to send idle timeout message.") + w.Logger.WarnContext(w.Context, "Failed to send idle timeout message", "error", err) } } w.disconnectClient(reason) return } next := w.ClientIdleTimeout - since - w.Entry.Debugf("Client activity detected %v ago; next check in %v", since, next) + w.Logger.DebugContext(w.Context, "Client activity detected", "last_active", since, "next_check", next) idleTime = w.Clock.After(next) // Lock in force. @@ -383,7 +383,7 @@ func (w *Monitor) start(lockWatch types.Watcher) { case types.OpPut: lock, ok := lockEvent.Resource.(types.Lock) if !ok { - w.Entry.Warnf("Skipping unexpected lock event resource type %T.", lockEvent.Resource) + w.Logger.WarnContext(w.Context, "Skipping unexpected lock event resource type", "resource_kind", lockEvent.Resource.GetKind()) } else { lockErr = services.LockInForceAccessDenied(lock) } @@ -394,7 +394,7 @@ func (w *Monitor) start(lockWatch types.Watcher) { lockErr = services.StrictLockingModeAccessDenied } default: - w.Entry.Warnf("Skipping unexpected lock event type %q.", lockEvent.Type) + w.Logger.WarnContext(w.Context, "Skipping unexpected lock event type", "event_type", lockEvent.Type) } if lockErr != nil { w.handleLockInForce(lockErr) @@ -402,7 +402,7 @@ func (w *Monitor) start(lockWatch types.Watcher) { } case <-lockWatchDoneC: - w.Entry.WithError(lockWatch.Error()).Warn("Lock watcher subscription was closed.") + w.Logger.WarnContext(w.Context, "Lock watcher subscription was closed", "error", lockWatch.Error()) if w.DisconnectExpiredCert.IsZero() && w.ClientIdleTimeout == 0 { return } @@ -425,21 +425,21 @@ type withCauseCloser interface { } func (w *Monitor) disconnectClient(reason string) { - w.Entry.Debugf("Disconnecting client: %v", reason) + w.Logger.DebugContext(w.Context, "Disconnecting client", "reason", reason) if connWithCauseCloser, ok := w.Conn.(withCauseCloser); ok { if err := connWithCauseCloser.CloseWithCause(trace.AccessDenied(reason)); err != nil { - w.Entry.WithError(err).Error("Failed to close connection.") + w.Logger.ErrorContext(w.Context, "Failed to close connection", "error", err) } } else { if err := w.Conn.Close(); err != nil { - w.Entry.WithError(err).Error("Failed to close connection.") + w.Logger.ErrorContext(w.Context, "Failed to close connection", "error", err) } } // emit audit event after client has been disconnected. if err := w.emitDisconnectEvent(reason); err != nil { - w.Entry.WithError(err).Warn("Failed to emit audit event.") + w.Logger.WarnContext(w.Context, "Failed to emit audit event", "error", err) } } @@ -470,7 +470,7 @@ func (w *Monitor) handleLockInForce(lockErr error) { reason := lockErr.Error() if w.MessageWriter != nil { if _, err := w.MessageWriter.WriteString(reason); err != nil { - w.Entry.WithError(err).Warn("Failed to send lock-in-force message.") + w.Logger.WarnContext(w.Context, "Failed to send lock-in-force message", "error", err) } } w.disconnectClient(reason) diff --git a/lib/srv/monitor_test.go b/lib/srv/monitor_test.go index ad95adefef345..db39dbef2c3d3 100644 --- a/lib/srv/monitor_test.go +++ b/lib/srv/monitor_test.go @@ -28,7 +28,6 @@ import ( "github.com/gravitational/trace" "github.com/jonboulle/clockwork" - "github.com/sirupsen/logrus" "github.com/stretchr/testify/require" "github.com/gravitational/teleport/api/constants" @@ -39,6 +38,7 @@ import ( "github.com/gravitational/teleport/lib/events/eventstest" "github.com/gravitational/teleport/lib/services" "github.com/gravitational/teleport/lib/tlsca" + "github.com/gravitational/teleport/lib/utils" ) func newTestMonitor(ctx context.Context, t *testing.T, asrv *auth.TestAuthServer, mut ...func(*MonitorConfig)) (*mockTrackingConn, *eventstest.ChannelEmitter, MonitorConfig) { @@ -54,7 +54,7 @@ func newTestMonitor(ctx context.Context, t *testing.T, asrv *auth.TestAuthServer EmitterContext: context.Background(), Clock: asrv.Clock(), Tracker: &mockActivityTracker{asrv.Clock()}, - Entry: logrus.StandardLogger(), + Logger: utils.NewSlogLoggerForTests(), LockWatcher: asrv.LockWatcher, LockTargets: []types.LockTarget{{User: "test-user"}}, LockingMode: constants.LockingModeBestEffort, @@ -86,7 +86,7 @@ func TestConnectionMonitorLockInForce(t *testing.T) { Emitter: emitter, EmitterContext: ctx, Clock: asrv.Clock(), - Logger: logrus.StandardLogger(), + Logger: utils.NewSlogLoggerForTests(), LockWatcher: asrv.LockWatcher, ServerID: "test", }) diff --git a/lib/srv/regular/fuzz_test.go b/lib/srv/regular/fuzz_test.go index 892e95fce25a9..c1ab280ac0f39 100644 --- a/lib/srv/regular/fuzz_test.go +++ b/lib/srv/regular/fuzz_test.go @@ -19,11 +19,14 @@ package regular import ( + "context" + "log/slog" "testing" "github.com/stretchr/testify/require" "github.com/gravitational/teleport/lib/srv" + logutils "github.com/gravitational/teleport/lib/utils/log" ) func FuzzParseProxySubsys(f *testing.F) { @@ -40,12 +43,13 @@ func FuzzParseProxySubsys(f *testing.F) { server := &Server{ hostname: "redhorse", proxyMode: true, + logger: slog.New(logutils.DiscardHandler{}), } ctx := &srv.ServerContext{} require.NotPanics(t, func() { - parseProxySubsys(request, server, ctx) + server.parseProxySubsys(context.Background(), request, ctx) }) }) } diff --git a/lib/srv/regular/proxy.go b/lib/srv/regular/proxy.go index c55e05b3ea787..1e421d54748a8 100644 --- a/lib/srv/regular/proxy.go +++ b/lib/srv/regular/proxy.go @@ -21,11 +21,11 @@ package regular import ( "context" "fmt" + "log/slog" "net" "strings" "github.com/gravitational/trace" - "github.com/sirupsen/logrus" "golang.org/x/crypto/ssh" "github.com/gravitational/teleport" @@ -53,7 +53,7 @@ type proxySubsys struct { proxySubsysRequest router *proxy.Router ctx *srv.ServerContext - log *logrus.Entry + logger *slog.Logger closeC chan error proxySigner PROXYHeaderSigner localCluster string @@ -68,8 +68,8 @@ type proxySubsys struct { // "proxy:@clustername" - Teleport request to connect to an auth server for cluster with name 'clustername' // "proxy:host:22@clustername" - Teleport request to connect to host:22 on cluster 'clustername' // "proxy:host:22@namespace@clustername" -func parseProxySubsysRequest(request string) (proxySubsysRequest, error) { - log.Debugf("parse_proxy_subsys(%q)", request) +func (s *Server) parseProxySubsysRequest(ctx context.Context, request string) (proxySubsysRequest, error) { + s.logger.DebugContext(ctx, "parsing proxy subsystem request", "request", request) var ( clusterName string targetHost string @@ -124,12 +124,12 @@ func parseProxySubsysRequest(request string) (proxySubsysRequest, error) { // parseProxySubsys decodes a proxy subsystem request and sets up a proxy subsystem instance. // See parseProxySubsysRequest for details on the request format. -func parseProxySubsys(request string, srv *Server, ctx *srv.ServerContext) (*proxySubsys, error) { - req, err := parseProxySubsysRequest(request) +func (s *Server) parseProxySubsys(ctx context.Context, request string, serverContext *srv.ServerContext) (*proxySubsys, error) { + req, err := s.parseProxySubsysRequest(ctx, request) if err != nil { return nil, trace.Wrap(err) } - subsys, err := newProxySubsys(ctx, srv, req) + subsys, err := newProxySubsys(ctx, serverContext, s, req) if err != nil { return nil, trace.Wrap(err) } @@ -163,16 +163,17 @@ func (p *proxySubsysRequest) SetDefaults() { // newProxySubsys is a helper that creates a proxy subsystem from // a port forwarding request, used to implement ProxyJump feature in proxy // and reuse the code -func newProxySubsys(ctx *srv.ServerContext, srv *Server, req proxySubsysRequest) (*proxySubsys, error) { +func newProxySubsys(ctx context.Context, serverContext *srv.ServerContext, srv *Server, req proxySubsysRequest) (*proxySubsys, error) { req.SetDefaults() - if req.clusterName == "" && ctx.Identity.RouteToCluster != "" { - log.Debugf("Proxy subsystem: routing user %q to cluster %q based on the route to cluster extension.", - ctx.Identity.TeleportUser, ctx.Identity.RouteToCluster, + if req.clusterName == "" && serverContext.Identity.RouteToCluster != "" { + srv.logger.DebugContext(ctx, "Proxy subsystem: routing user to cluster based on the route to cluster extension", + "user", serverContext.Identity.TeleportUser, + "cluster", serverContext.Identity.RouteToCluster, ) - req.clusterName = ctx.Identity.RouteToCluster + req.clusterName = serverContext.Identity.RouteToCluster } if req.clusterName != "" && srv.proxyTun != nil { - checker, err := srv.tunnelWithAccessChecker(ctx) + checker, err := srv.tunnelWithAccessChecker(serverContext) if err != nil { return nil, trace.Wrap(err) } @@ -181,18 +182,15 @@ func newProxySubsys(ctx *srv.ServerContext, srv *Server, req proxySubsysRequest) return nil, trace.BadParameter("invalid format for proxy request: unknown cluster %q", req.clusterName) } } - log.Debugf("newProxySubsys(%v).", req) + srv.logger.DebugContext(ctx, "successfully created proxy subsystem request", "request", &req) return &proxySubsys{ proxySubsysRequest: req, - ctx: ctx, - log: logrus.WithFields(logrus.Fields{ - teleport.ComponentKey: teleport.ComponentSubsystemProxy, - teleport.ComponentFields: map[string]string{}, - }), - closeC: make(chan error), - router: srv.router, - proxySigner: srv.proxySigner, - localCluster: ctx.ClusterName, + ctx: serverContext, + logger: slog.With(teleport.ComponentKey, teleport.ComponentSubsystemProxy), + closeC: make(chan error), + router: srv.router, + proxySigner: srv.proxySigner, + localCluster: serverContext.ClusterName, }, nil } @@ -205,15 +203,12 @@ func (t *proxySubsys) String() string { // a mapping connection between a client & remote node we're proxying to) func (t *proxySubsys) Start(ctx context.Context, sconn *ssh.ServerConn, ch ssh.Channel, req *ssh.Request, serverContext *srv.ServerContext) error { // once we start the connection, update logger to include component fields - t.log = logrus.WithFields(logrus.Fields{ - teleport.ComponentKey: teleport.ComponentSubsystemProxy, - teleport.ComponentFields: map[string]string{ - "src": sconn.RemoteAddr().String(), - "dst": sconn.LocalAddr().String(), - "subsystem": t.String(), - }, - }) - t.log.Debugf("Starting subsystem") + t.logger = t.logger.With( + "src", sconn.RemoteAddr().String(), + "dst", sconn.LocalAddr().String(), + "subsystem", t.String(), + ) + t.logger.DebugContext(ctx, "Starting subsystem") clientAddr := sconn.RemoteAddr() @@ -229,13 +224,13 @@ func (t *proxySubsys) Start(ctx context.Context, sconn *ssh.ServerConn, ch ssh.C // proxyToSite establishes a proxy connection from the connected SSH client to the // auth server of the requested remote site func (t *proxySubsys) proxyToSite(ctx context.Context, ch ssh.Channel, clusterName string, clientSrcAddr, clientDstAddr net.Addr) error { - t.log.Debugf("Connecting from cluster %q to site: %q", t.localCluster, clusterName) + t.logger.DebugContext(ctx, "attempting to proxy connection to auth server", "local_cluster", t.localCluster, "proxied_cluster", clusterName) conn, err := t.router.DialSite(ctx, clusterName, clientSrcAddr, clientDstAddr) if err != nil { return trace.Wrap(err) } - t.log.Infof("Connected to cluster %v at %v", clusterName, conn.RemoteAddr()) + t.logger.InfoContext(ctx, "Connected to cluster", "cluster", clusterName, "address", conn.RemoteAddr()) go func() { t.close(utils.ProxyConn(ctx, ch, conn)) @@ -246,7 +241,7 @@ func (t *proxySubsys) proxyToSite(ctx context.Context, ch ssh.Channel, clusterNa // proxyToHost establishes a proxy connection from the connected SSH client to the // requested remote node (t.host:t.port) via the given site func (t *proxySubsys) proxyToHost(ctx context.Context, ch ssh.Channel, clientSrcAddr, clientDstAddr net.Addr) error { - t.log.Debugf("proxy connecting to host=%v port=%v, exact port=%v", t.host, t.port, t.SpecifiedPort()) + t.logger.DebugContext(ctx, "proxying connection to target host", "host", t.host, "port", t.port, "exact_port", t.SpecifiedPort()) authClient, err := t.router.GetSiteClient(ctx, t.localCluster) if err != nil { diff --git a/lib/srv/regular/proxy_test.go b/lib/srv/regular/proxy_test.go index 3333d2f79de75..178fedccdcae9 100644 --- a/lib/srv/regular/proxy_test.go +++ b/lib/srv/regular/proxy_test.go @@ -19,12 +19,15 @@ package regular import ( + "context" + "log/slog" "testing" "github.com/stretchr/testify/require" apidefaults "github.com/gravitational/teleport/api/defaults" "github.com/gravitational/teleport/lib/srv" + logutils "github.com/gravitational/teleport/lib/utils/log" ) func TestParseProxyRequest(t *testing.T) { @@ -86,6 +89,12 @@ func TestParseProxyRequest(t *testing.T) { }, } + server := &Server{ + hostname: "redhorse", + proxyMode: true, + logger: slog.New(logutils.DiscardHandler{}), + } + for i, tt := range testCases { t.Run(tt.desc, func(t *testing.T) { if tt.expected.namespace == "" { @@ -94,7 +103,7 @@ func TestParseProxyRequest(t *testing.T) { // never actually be empty. tt.expected.namespace = apidefaults.Namespace } - req, err := parseProxySubsysRequest(tt.req) + req, err := server.parseProxySubsysRequest(context.Background(), tt.req) require.NoError(t, err, "Test case %d: req=%s, expected=%+v", i, tt.req, tt.expected) require.Equal(t, tt.expected, req, "Test case %d: req=%s, expected=%+v", i, tt.req, tt.expected) }) @@ -107,6 +116,7 @@ func TestParseBadRequests(t *testing.T) { server := &Server{ hostname: "redhorse", proxyMode: true, + logger: slog.New(logutils.DiscardHandler{}), } ctx := &srv.ServerContext{} @@ -122,7 +132,7 @@ func TestParseBadRequests(t *testing.T) { } for _, tt := range testCases { t.Run(tt.desc, func(t *testing.T) { - subsystem, err := parseProxySubsys(tt.input, server, ctx) + subsystem, err := server.parseProxySubsys(context.Background(), tt.input, ctx) require.Error(t, err, "test case: %q", tt.input) require.Nil(t, subsystem, "test case: %q", tt.input) }) diff --git a/lib/srv/regular/sftp.go b/lib/srv/regular/sftp.go index f3f194ab16ae0..456c805b5ee51 100644 --- a/lib/srv/regular/sftp.go +++ b/lib/srv/regular/sftp.go @@ -24,13 +24,13 @@ import ( "encoding/json" "errors" "io" + "log/slog" "os" "os/exec" "time" "github.com/gogo/protobuf/jsonpb" "github.com/gravitational/trace" - "github.com/sirupsen/logrus" "golang.org/x/crypto/ssh" "github.com/gravitational/teleport" @@ -45,7 +45,7 @@ import ( const copyingGoroutines = 2 type sftpSubsys struct { - log *logrus.Entry + logger *slog.Logger fileTransferReq *srv.FileTransferRequest sftpCmd *exec.Cmd @@ -55,9 +55,7 @@ type sftpSubsys struct { func newSFTPSubsys(fileTransferReq *srv.FileTransferRequest) (*sftpSubsys, error) { return &sftpSubsys{ - log: logrus.WithFields(logrus.Fields{ - teleport.ComponentKey: teleport.ComponentSubsystemSFTP, - }), + logger: slog.With(teleport.ComponentKey, teleport.ComponentSubsystemSFTP), fileTransferReq: fileTransferReq, }, nil } @@ -125,7 +123,7 @@ func (s *sftpSubsys) Start(ctx context.Context, s.sftpCmd.Stdout = os.Stdout s.sftpCmd.Stderr = os.Stderr - s.log.Debug("starting SFTP process") + s.logger.DebugContext(ctx, "starting SFTP process") err = s.sftpCmd.Start() if err != nil { return trace.Wrap(err) @@ -184,7 +182,7 @@ func (s *sftpSubsys) Start(ctx context.Context, eventStr, err := r.ReadString(0x0) if err != nil { if !errors.Is(err, io.EOF) { - s.log.WithError(err).Warn("Failed to read SFTP event.") + s.logger.WarnContext(ctx, "Failed to read SFTP event", "error", err) } return } @@ -192,12 +190,12 @@ func (s *sftpSubsys) Start(ctx context.Context, var oneOfEvent apievents.OneOf err = jsonpb.UnmarshalString(eventStr[:len(eventStr)-1], &oneOfEvent) if err != nil { - s.log.WithError(err).Warn("Failed to unmarshal SFTP event.") + s.logger.WarnContext(ctx, "Failed to unmarshal SFTP event", "error", err) continue } event, err := apievents.FromOneOf(oneOfEvent) if err != nil { - s.log.WithError(err).Warn("Failed to convert SFTP event from OneOf.") + s.logger.WarnContext(ctx, "Failed to convert SFTP event from OneOf", "error", err) continue } @@ -214,11 +212,11 @@ func (s *sftpSubsys) Start(ctx context.Context, e.UserMetadata = userMeta e.ConnectionMetadata = connectionMeta default: - s.log.WithError(err).Warnf("Unknown event type received from SFTP server process: %q", event.GetType()) + s.logger.WarnContext(ctx, "Unknown event type received from SFTP server process", "error", err, "event_type", event.GetType()) } if err := serverCtx.GetServer().EmitAuditEvent(ctx, event); err != nil { - log.WithError(err).Warn("Failed to emit SFTP event.") + s.logger.WarnContext(ctx, "Failed to emit SFTP event", "error", err) } } }() @@ -227,8 +225,9 @@ func (s *sftpSubsys) Start(ctx context.Context, } func (s *sftpSubsys) Wait() error { + ctx := context.Background() waitErr := s.sftpCmd.Wait() - s.log.Debug("SFTP process finished") + s.logger.DebugContext(ctx, "SFTP process finished") s.serverCtx.SendExecResult(srv.ExecResult{ Command: s.sftpCmd.String(), @@ -239,7 +238,7 @@ func (s *sftpSubsys) Wait() error { for i := 0; i < copyingGoroutines; i++ { err := <-s.errCh if err != nil && !utils.IsOKNetworkError(err) { - s.log.WithError(err).Warn("Connection problem.") + s.logger.WarnContext(ctx, "Connection problem", "error", err) errs = append(errs, err) } } diff --git a/lib/srv/regular/sites.go b/lib/srv/regular/sites.go index 5e80844365eb5..029ca982af845 100644 --- a/lib/srv/regular/sites.go +++ b/lib/srv/regular/sites.go @@ -53,7 +53,7 @@ func (t *proxySitesSubsys) Wait() error { // Start serves a request for "proxysites" custom SSH subsystem. It builds an array of // service.Site structures, and writes it serialized as JSON back to the SSH client func (t *proxySitesSubsys) Start(ctx context.Context, sconn *ssh.ServerConn, ch ssh.Channel, req *ssh.Request, serverContext *srv.ServerContext) error { - log.Debugf("proxysites.start(%v)", serverContext) + t.srv.logger.DebugContext(ctx, "starting proxysites subsystem", "server_context", serverContext) checker, err := t.srv.tunnelWithAccessChecker(serverContext) if err != nil { return trace.Wrap(err) diff --git a/lib/srv/regular/sshserver.go b/lib/srv/regular/sshserver.go index a4bbd56a552df..d80c143e96118 100644 --- a/lib/srv/regular/sshserver.go +++ b/lib/srv/regular/sshserver.go @@ -38,7 +38,6 @@ import ( "github.com/gravitational/trace" "github.com/jonboulle/clockwork" - "github.com/sirupsen/logrus" semconv "go.opentelemetry.io/otel/semconv/v1.10.0" oteltrace "go.opentelemetry.io/otel/trace" "golang.org/x/crypto/ssh" @@ -74,16 +73,12 @@ import ( "github.com/gravitational/teleport/lib/utils/hostid" ) -var log = logrus.WithFields(logrus.Fields{ - teleport.ComponentKey: teleport.ComponentNode, -}) - // Server implements SSH server that uses configuration backend and // certificate-based authentication type Server struct { sync.Mutex - *logrus.Entry + logger *slog.Logger namespace string addr utils.NetAddr @@ -333,7 +328,7 @@ func (s *Server) close() { s.reg.Close() if s.heartbeat != nil { if err := s.heartbeat.Close(); err != nil { - s.Warningf("Failed to close heartbeat: %v", err) + s.logger.WarnContext(s.ctx, "Failed to close heartbeat", "error", err) } } if s.dynamicLabels != nil { @@ -368,7 +363,7 @@ func (s *Server) Shutdown(ctx context.Context) error { // from making the server appear alive and well. if s.heartbeat != nil { if err := s.heartbeat.Close(); err != nil { - s.Warningf("Failed to close heartbeat: %v", err) + s.logger.WarnContext(ctx, "Failed to close heartbeat", "error", err) } } @@ -792,10 +787,7 @@ func New( component = teleport.ComponentNode } - s.Entry = logrus.WithFields(logrus.Fields{ - teleport.ComponentKey: component, - teleport.ComponentFields: logrus.Fields{}, - }) + s.logger = slog.With(teleport.ComponentKey, component) if s.GetCreateHostUser() { s.users = srv.NewHostUsers(ctx, s.storage, s.ID()) @@ -858,7 +850,7 @@ func New( if !s.proxyMode { if err := s.startAuthorizedKeysManager(ctx, auth); err != nil { - log.WithError(err).Infof("Failed to start authorized keys manager.") + s.logger.InfoContext(ctx, "Failed to start authorized keys manager", "error", err) } } @@ -871,14 +863,14 @@ func New( var heartbeat srv.HeartbeatI if heartbeatMode == srv.HeartbeatModeNode && s.inventoryHandle != nil { - s.Logger.Debug("starting control-stream based heartbeat.") + s.logger.DebugContext(ctx, "starting control-stream based heartbeat") heartbeat, err = srv.NewSSHServerHeartbeat(srv.HeartbeatV2Config[*types.ServerV2]{ InventoryHandle: s.inventoryHandle, GetResource: s.getServerInfo, OnHeartbeat: s.onHeartbeat, }) } else { - s.Logger.Debug("starting legacy heartbeat.") + s.logger.DebugContext(ctx, "starting legacy heartbeat") heartbeat, err = srv.NewHeartbeat(srv.HeartbeatConfig{ Mode: heartbeatMode, Context: ctx, @@ -935,7 +927,7 @@ func (s *Server) startAuthorizedKeysManager(ctx context.Context, auth authclient go func() { if err := authorizedKeysWatcher.Run(ctx); err != nil { - s.Warningf("Failed to start authorized keys watcher: %v", err) + s.logger.WarnContext(ctx, "Failed to start authorized keys watcher", "error", err) } }() return nil @@ -1005,7 +997,7 @@ func (s *Server) AdvertiseAddr() string { _, port, _ := net.SplitHostPort(listenAddr) ahost, aport, err := utils.ParseAdvertiseAddr(advertiseAddr.String()) if err != nil { - s.Logger.Warningf("Failed to parse advertise address %q, %v, using default value %q.", advertiseAddr, err, listenAddr) + s.logger.WarnContext(s.ctx, "Failed to parse advertise address, using default value", "advertise_addr", advertiseAddr, "error", err, "default_addr", listenAddr) return listenAddr } if aport == "" { @@ -1094,13 +1086,13 @@ func (s *Server) getBasicInfo() *types.ServerV2 { return srv } -func (s *Server) getServerInfo(context.Context) (*types.ServerV2, error) { +func (s *Server) getServerInfo(ctx context.Context) (*types.ServerV2, error) { server := s.getBasicInfo() if s.getRotation != nil { rotation, err := s.getRotation(s.getRole()) if err != nil { if !trace.IsNotFound(err) { - s.Logger.Warningf("Failed to get rotation state: %v", err) + s.logger.WarnContext(ctx, "Failed to get rotation state", "error", err) } } else { server.SetRotation(*rotation) @@ -1176,7 +1168,7 @@ func (s *Server) getNetworkingProcess(scx *srv.ServerContext) (*networking.Proce // the server connection is closed. func (s *Server) startNetworkingProcess(scx *srv.ServerContext) (*networking.Process, error) { // Create context for the networking process. - _, nsctx, err := srv.NewServerContext(context.Background(), scx.ConnectionContext, s, scx.Identity) + nsctx, err := srv.NewServerContext(context.Background(), scx.ConnectionContext, s, scx.Identity) if err != nil { return nil, trace.Wrap(err) } @@ -1210,44 +1202,44 @@ func (s *Server) HandleRequest(ctx context.Context, ccx *sshutils.ConnectionCont case teleport.ClusterDetailsReqType: s.handleClusterDetails(ctx, r) case teleport.VersionRequest: - s.handleVersionRequest(r) + s.handleVersionRequest(ctx, r) case teleport.TerminalSizeRequest: if err := s.termHandlers.HandleTerminalSize(r); err != nil { - s.Logger.WithError(err).Warn("failed to handle terminal size request") + s.logger.WarnContext(ctx, "failed to handle terminal size request", "error", err) if r.WantReply { if err := r.Reply(false, nil); err != nil { - s.Logger.Warnf("Failed to reply to %q request: %v", r.Type, err) + s.logger.WarnContext(ctx, "Failed to reply to terminal size request", "error", err) } } } case teleport.TCPIPForwardRequest: if err := s.handleTCPIPForwardRequest(ctx, ccx, r); err != nil { - s.Logger.WithError(err).Warn("failed to handle tcpip forward request") + s.logger.WarnContext(ctx, "failed to handle tcpip forward request", "error", err) if err := r.Reply(false, nil); err != nil { - s.Logger.Warnf("Failed to reply to %q request: %v", r.Type, err) + s.logger.WarnContext(ctx, "Failed to reply to tcpip forward request", "error", err) } } case teleport.CancelTCPIPForwardRequest: if err := s.handleCancelTCPIPForwardRequest(ctx, ccx, r); err != nil { - s.Logger.WithError(err).Warn("failed to handle cancel tcpip forward request") + s.logger.WarnContext(ctx, "failed to handle cancel tcpip forward request", "error", err) if err := r.Reply(false, nil); err != nil { - s.Logger.Warnf("Failed to reply to %q request: %v", r.Type, err) + s.logger.WarnContext(ctx, "Failed to reply to tcpip forward request", "error", err) } } case teleport.SessionIDQueryRequest: // Reply true to session ID query requests, we will set new // session IDs for new sessions if err := r.Reply(true, nil); err != nil { - s.Logger.WithError(err).Warnf("Failed to reply to session ID query request") + s.logger.WarnContext(ctx, "Failed to reply to session ID query request", "error", err) } return default: if r.WantReply { if err := r.Reply(false, nil); err != nil { - s.Logger.Warnf("Failed to reply to %q request: %v", r.Type, err) + s.logger.WarnContext(ctx, "Failed to reply to ssh request", "request_type", r.Type, "error", err) } } - s.Logger.Debugf("Discarding %q global request: %+v", r.Type, r) + s.logger.DebugContext(ctx, "Discarding global request", "request_type", r.Type) } } @@ -1268,7 +1260,7 @@ func (s *Server) HandleNewConn(ctx context.Context, ccx *sshutils.ConnectionCont // Create host user. created, userCloser, err := s.termHandlers.SessionRegistry.UpsertHostUser(identityContext) if err != nil { - log.Warnf("error while creating host users: %s", err) + s.logger.WarnContext(ctx, "error while creating host users", "error", err) } // Indicate that the user was created by Teleport. @@ -1279,7 +1271,7 @@ func (s *Server) HandleNewConn(ctx context.Context, ccx *sshutils.ConnectionCont sudoersCloser, err := s.termHandlers.SessionRegistry.WriteSudoersFile(identityContext) if err != nil { - log.Warnf("error while writing sudoers: %s", err) + s.logger.WarnContext(ctx, "error while writing sudoers", "error", err) } if sudoersCloser != nil { @@ -1293,7 +1285,7 @@ func (s *Server) HandleNewConn(ctx context.Context, ccx *sshutils.ConnectionCont func (s *Server) HandleNewChan(ctx context.Context, ccx *sshutils.ConnectionContext, nch ssh.NewChannel) { identityContext, err := s.authHandlers.CreateIdentityContext(ccx.ServerConn) if err != nil { - rejectChannel(nch, ssh.Prohibited, fmt.Sprintf("Unable to create identity from connection: %v", err)) + s.rejectChannel(ctx, nch, ssh.Prohibited, fmt.Sprintf("Unable to create identity from connection: %v", err)) return } @@ -1305,14 +1297,14 @@ func (s *Server) HandleNewChan(ctx context.Context, ccx *sshutils.ConnectionCont case teleport.ChanDirectTCPIP: req, err := sshutils.ParseDirectTCPIPReq(nch.ExtraData()) if err != nil { - s.Logger.Errorf("Failed to parse request data: %v, err: %v.", string(nch.ExtraData()), err) - rejectChannel(nch, ssh.UnknownChannelType, "failed to parse direct-tcpip request") + s.logger.ErrorContext(ctx, "Failed to parse request data", "data", string(nch.ExtraData()), "error", err) + s.rejectChannel(ctx, nch, ssh.UnknownChannelType, "failed to parse direct-tcpip request") return } ch, reqC, err := nch.Accept() if err != nil { - s.Logger.Warnf("Unable to accept channel: %v.", err) - rejectChannel(nch, ssh.ConnectionFailed, fmt.Sprintf("unable to accept channel: %v", err)) + s.logger.WarnContext(ctx, "Unable to accept channel", "error", err) + s.rejectChannel(ctx, nch, ssh.ConnectionFailed, fmt.Sprintf("unable to accept channel: %v", err)) return } go ssh.DiscardRequests(reqC) @@ -1324,14 +1316,14 @@ func (s *Server) HandleNewChan(ctx context.Context, ccx *sshutils.ConnectionCont case teleport.ChanSession: ch, requests, err := nch.Accept() if err != nil { - s.Logger.Warnf("Unable to accept channel: %v.", err) - rejectChannel(nch, ssh.ConnectionFailed, fmt.Sprintf("unable to accept channel: %v", err)) + s.logger.WarnContext(ctx, "Unable to accept channel", "error", err) + s.rejectChannel(ctx, nch, ssh.ConnectionFailed, fmt.Sprintf("unable to accept channel: %v", err)) return } go s.handleSessionRequests(ctx, ccx, identityContext, ch, requests) return default: - rejectChannel(nch, ssh.UnknownChannelType, fmt.Sprintf("unknown channel type: %v", channelType)) + s.rejectChannel(ctx, nch, ssh.UnknownChannelType, fmt.Sprintf("unknown channel type: %v", channelType)) return } } @@ -1364,17 +1356,17 @@ func (s *Server) HandleNewChan(ctx context.Context, ccx *sshutils.ConnectionCont Reason: events.SessionRejectedReasonMaxSessions, Maximum: max, }); err != nil { - s.Logger.WithError(err).Warn("Failed to emit session reject event.") + s.logger.WarnContext(ctx, "Failed to emit session reject event", "error", err) } - rejectChannel(nch, ssh.Prohibited, fmt.Sprintf("too many session channels for user %q (max=%d)", identityContext.TeleportUser, max)) + s.rejectChannel(ctx, nch, ssh.Prohibited, fmt.Sprintf("too many session channels for user %q (max=%d)", identityContext.TeleportUser, max)) return } decr = d } ch, requests, err := nch.Accept() if err != nil { - s.Logger.Warnf("Unable to accept channel: %v.", err) - rejectChannel(nch, ssh.ConnectionFailed, fmt.Sprintf("unable to accept channel: %v", err)) + s.logger.WarnContext(ctx, "Unable to accept channel", "error", err) + s.rejectChannel(ctx, nch, ssh.ConnectionFailed, fmt.Sprintf("unable to accept channel: %v", err)) if decr != nil { decr() } @@ -1392,28 +1384,29 @@ func (s *Server) HandleNewChan(ctx context.Context, ccx *sshutils.ConnectionCont // SessionJoinPrincipal should be rejected, otherwise it's possible // to use the "-teleport-internal-join" user to bypass RBAC. if identityContext.Login == teleport.SSHSessionJoinPrincipal { - s.Logger.Error("Connection rejected, direct-tcpip with SessionJoinPrincipal in regular node must be blocked") - rejectChannel( + s.logger.ErrorContext(ctx, "Connection rejected, direct-tcpip with SessionJoinPrincipal in regular node must be blocked") + s.rejectChannel( + ctx, nch, ssh.Prohibited, fmt.Sprintf("attempted %v channel open in join-only mode", channelType)) return } req, err := sshutils.ParseDirectTCPIPReq(nch.ExtraData()) if err != nil { - s.Logger.Errorf("Failed to parse request data: %v, err: %v.", string(nch.ExtraData()), err) - rejectChannel(nch, ssh.UnknownChannelType, "failed to parse direct-tcpip request") + s.logger.ErrorContext(ctx, "Failed to parse request data", "data", string(nch.ExtraData()), "error", err) + s.rejectChannel(ctx, nch, ssh.UnknownChannelType, "failed to parse direct-tcpip request") return } ch, reqC, err := nch.Accept() if err != nil { - s.Logger.Warnf("Unable to accept channel: %v.", err) - rejectChannel(nch, ssh.ConnectionFailed, fmt.Sprintf("unable to accept channel: %v", err)) + s.logger.WarnContext(ctx, "Unable to accept channel", "error", err) + s.rejectChannel(ctx, nch, ssh.ConnectionFailed, fmt.Sprintf("unable to accept channel: %v", err)) return } go ssh.DiscardRequests(reqC) go s.handleDirectTCPIPRequest(ctx, ccx, identityContext, ch, req) default: - rejectChannel(nch, ssh.UnknownChannelType, fmt.Sprintf("unknown channel type: %v", channelType)) + s.rejectChannel(ctx, nch, ssh.UnknownChannelType, fmt.Sprintf("unknown channel type: %v", channelType)) } } @@ -1438,11 +1431,11 @@ func (s *Server) canPortForward(scx *srv.ServerContext) error { // stderrWriter wraps an ssh.Channel in an implementation of io.StringWriter // that sends anything written back the client over its stderr stream type stderrWriter struct { - channel ssh.Channel + writer func(s string) } func (w *stderrWriter) WriteString(s string) (int, error) { - writeStderr(w.channel, s) + w.writer(s) return len(s), nil } @@ -1450,12 +1443,12 @@ func (w *stderrWriter) WriteString(s string) (int, error) { func (s *Server) handleDirectTCPIPRequest(ctx context.Context, ccx *sshutils.ConnectionContext, identityContext srv.IdentityContext, channel ssh.Channel, req *sshutils.DirectTCPIPReq) { // Create context for this channel. This context will be closed when // forwarding is complete. - ctx, scx, err := srv.NewServerContext(ctx, ccx, s, identityContext) + scx, err := srv.NewServerContext(ctx, ccx, s, identityContext) if err != nil { - s.Logger.WithError(err).Error("Unable to create connection context.") - writeStderr(channel, "Unable to create connection context.") + s.logger.ErrorContext(ctx, "Unable to create connection context", "error", err) + s.writeStderr(ctx, channel, "Unable to create connection context.") if err := channel.Close(); err != nil { - s.Logger.WithError(err).Warn("Failed to close channel.") + s.logger.WarnContext(ctx, "Failed to close channel", "error", err) } return } @@ -1473,7 +1466,7 @@ func (s *Server) handleDirectTCPIPRequest(ctx context.Context, ccx *sshutils.Con // Bail out now if TCP port forwarding is not allowed for this node/user/role // combo if err = s.canPortForward(scx); err != nil { - writeStderr(channel, err.Error()) + s.writeStderr(ctx, channel, err.Error()) return } @@ -1484,20 +1477,20 @@ func (s *Server) handleDirectTCPIPRequest(ctx context.Context, ccx *sshutils.Con if err != nil { if errors.Is(err, trace.NotFound(user.UnknownUserError(scx.Identity.Login).Error())) || errors.Is(err, trace.BadParameter("unknown user")) { // user does not exist for the provided login. Terminate the connection. - s.Logger.Warnf("Forwarding data via direct-tcpip channel failed. Terminating connection because user %q does not exist", scx.Identity.Login) + s.logger.WarnContext(ctx, "terminating direct-tcpip request because user does not exist", "user", scx.Identity.Login) if err := ccx.ServerConn.Close(); err != nil { - s.Logger.Warnf("Unable to terminate connection: %v", err) + s.logger.WarnContext(ctx, "Unable to terminate connection", "error", err) } return } - s.Logger.WithError(err).Error("Forwarding data via direct-tcpip channel failed") - writeStderr(channel, err.Error()) + s.logger.ErrorContext(ctx, "Forwarding data via direct-tcpip channel failed", "error", err) + s.writeStderr(ctx, channel, err.Error()) return } if err := utils.ProxyConn(ctx, conn, channel); err != nil && !errors.Is(err, io.EOF) && !errors.Is(err, os.ErrClosed) { - s.Logger.Warnf("Connection problem in direct-tcpip channel: %v %T.", trace.DebugReport(err), err) + s.logger.WarnContext(ctx, "Connection problem in direct-tcpip channel", "error", err) } if err := s.EmitAuditEvent(s.ctx, &apievents.PortForward{ @@ -1515,7 +1508,7 @@ func (s *Server) handleDirectTCPIPRequest(ctx context.Context, ccx *sshutils.Con Success: true, }, }); err != nil { - s.Logger.WithError(err).Warn("Failed to emit port forward event.") + s.logger.WarnContext(ctx, "Failed to emit port forward event", "error", err) } } @@ -1525,22 +1518,22 @@ func (s *Server) handleDirectTCPIPRequest(ctx context.Context, ccx *sshutils.Con func (s *Server) handleSessionRequests(ctx context.Context, ccx *sshutils.ConnectionContext, identityContext srv.IdentityContext, ch ssh.Channel, in <-chan *ssh.Request) { netConfig, err := s.GetAccessPoint().GetClusterNetworkingConfig(ctx) if err != nil { - s.Logger.Errorf("Unable to fetch cluster networking config: %v.", err) - writeStderr(ch, "Unable to fetch cluster networking configuration.") + s.logger.ErrorContext(ctx, "Unable to fetch cluster networking config", "error", err) + s.writeStderr(ctx, ch, "Unable to fetch cluster networking configuration.") return } // Create context for this channel. This context will be closed when the // session request is complete. - ctx, scx, err := srv.NewServerContext(ctx, ccx, s, identityContext, func(cfg *srv.MonitorConfig) { + scx, err := srv.NewServerContext(ctx, ccx, s, identityContext, func(cfg *srv.MonitorConfig) { cfg.IdleTimeoutMessage = netConfig.GetClientIdleTimeoutMessage() - cfg.MessageWriter = &stderrWriter{channel: ch} + cfg.MessageWriter = &stderrWriter{writer: func(msg string) { s.writeStderr(ctx, ch, msg) }} }) if err != nil { - s.Logger.WithError(err).Error("Unable to create connection context.") - writeStderr(ch, "Unable to create connection context.") + s.logger.ErrorContext(ctx, "Unable to create connection context", "error", err) + s.writeStderr(ctx, ch, "Unable to create connection context.") if err := ch.Close(); err != nil { - s.Logger.WithError(err).Warn("Failed to close channel.") + s.logger.WarnContext(ctx, "Failed to close channel", "error", err) } return } @@ -1550,7 +1543,7 @@ func (s *Server) handleSessionRequests(ctx context.Context, ccx *sshutils.Connec scx.SetAllowFileCopying(s.allowFileCopying) defer scx.Close() - ch = scx.TrackActivity(ch) + trackingChan := scx.TrackActivity(ch) // The keep-alive loop will keep pinging the remote server and after it has // missed a certain number of keep-alive requests it will cancel the @@ -1574,8 +1567,8 @@ func (s *Server) handleSessionRequests(ctx context.Context, ccx *sshutils.Connec scx.Errorf("Unable to update context: %v.", errorMessage) // write the error to channel and close it - writeStderr(ch, errorMessage) - _, err := ch.SendRequest("exit-status", false, ssh.Marshal(struct{ C uint32 }{C: teleport.RemoteCommandFailure})) + s.writeStderr(ctx, trackingChan, errorMessage) + _, err := trackingChan.SendRequest("exit-status", false, ssh.Marshal(struct{ C uint32 }{C: teleport.RemoteCommandFailure})) if err != nil { scx.Errorf("Failed to send exit status %v.", errorMessage) } @@ -1609,14 +1602,14 @@ func (s *Server) handleSessionRequests(ctx context.Context, ccx *sshutils.Connec // some functions called inside dispatch() may handle replies to SSH channel requests internally, // rather than leaving the reply to be handled inside this loop. in that case, those functions must // set req.WantReply to false so that two replies are not sent. - if err := s.dispatch(ctx, ch, req, scx); err != nil { - s.replyError(ch, req, err) + if err := s.dispatch(ctx, trackingChan, req, scx); err != nil { + s.replyError(ctx, trackingChan, req, err) span.End() return } if req.WantReply { if err := req.Reply(true, nil); err != nil { - s.Logger.Warnf("Failed to reply to %q request: %v", req.Type, err) + s.logger.WarnContext(ctx, "Failed to reply to request", "request_type", req.Type, "error", err) } } span.End() @@ -1625,14 +1618,14 @@ func (s *Server) handleSessionRequests(ctx context.Context, ccx *sshutils.Connec // The exec process has finished and delivered the execution result, send // the result back to the client, and close the session and channel. - _, err := ch.SendRequest("exit-status", false, ssh.Marshal(struct{ C uint32 }{C: uint32(result.Code)})) + _, err := trackingChan.SendRequest("exit-status", false, ssh.Marshal(struct{ C uint32 }{C: uint32(result.Code)})) if err != nil { scx.Infof("Failed to send exit status for %v: %v", result.Command, err) } return case <-ctx.Done(): - s.Logger.Debugf("Closing session due to cancellation.") + s.logger.DebugContext(ctx, "Closing session due to cancellation") return } } @@ -1658,7 +1651,7 @@ func (s *Server) dispatch(ctx context.Context, ch ssh.Channel, req *ssh.Request, // recording proxy mode. err := s.handleAgentForwardProxy(req, serverContext) if err != nil { - s.Logger.Warn(err) + s.logger.WarnContext(ctx, "Failure forwarding agent", "error", err) } return nil case sshutils.PuTTYSimpleRequest: @@ -1666,13 +1659,13 @@ func (s *Server) dispatch(ctx context.Context, ch ssh.Channel, req *ssh.Request, // as a proxy to indicate that it's in "simple" node and won't be requesting any other channels. // As we don't support this request, we ignore it. // https://the.earth.li/~sgtatham/putty/0.76/htmldoc/AppendixG.html#sshnames-channel - s.Logger.Debugf("%v: deliberately ignoring request for '%v' channel", s.Component(), sshutils.PuTTYSimpleRequest) + s.logger.DebugContext(ctx, "deliberately ignoring simple@putty.projects.tartarus.org request") return nil default: - s.Logger.Warnf("(%v) proxy doesn't support request type '%v'", s.Component(), req.Type) + s.logger.WarnContext(ctx, "server doesn't support request type", "request_type", req.Type) if req.WantReply { if err := req.Reply(false, nil); err != nil { - s.Logger.Errorf("sending error reply on SSH channel: %v", err) + s.logger.ErrorContext(ctx, "error sending reply on SSH channel", "error", err) } } return nil @@ -1711,11 +1704,11 @@ func (s *Server) dispatch(ctx context.Context, ch ssh.Channel, req *ssh.Request, // processing requests. err := s.handleAgentForwardNode(req, serverContext) if err != nil { - s.Logger.Warn(err) + s.logger.WarnContext(ctx, "failure forwarding agent", "error", err) } return nil case sshutils.PuTTYWinadjRequest: - return s.handlePuTTYWinadj(ch, req) + return s.handlePuTTYWinadj(ctx, req) default: return trace.AccessDenied("attempted %v request in join-only mode", req.Type) } @@ -1744,7 +1737,7 @@ func (s *Server) dispatch(ctx context.Context, ch ssh.Channel, req *ssh.Request, // they are in essence SSH session extensions, allowing to implement new SSH commands return s.handleSubsystem(ctx, ch, req, serverContext) case x11.ForwardRequest: - return s.handleX11Forward(ch, req, serverContext) + return s.handleX11Forward(ctx, ch, req, serverContext) case sshutils.AgentForwardRequest: // This happens when SSH client has agent forwarding enabled, in this case // client sends a special request, in return SSH server opens new channel @@ -1758,16 +1751,16 @@ func (s *Server) dispatch(ctx context.Context, ch ssh.Channel, req *ssh.Request, // processing requests. err := s.handleAgentForwardNode(req, serverContext) if err != nil { - s.Logger.Warn(err) + s.logger.WarnContext(ctx, "failure forwarding agent", "error", err) } return nil case sshutils.PuTTYWinadjRequest: - return s.handlePuTTYWinadj(ch, req) + return s.handlePuTTYWinadj(ctx, req) default: - s.Logger.Warnf("%v doesn't support request type '%v'", s.Component(), req.Type) + s.logger.WarnContext(ctx, "server doesn't support request type", "request_type", req.Type) if req.WantReply { if err := req.Reply(false, nil); err != nil { - s.Logger.Errorf("sending error reply on SSH channel: %v", err) + s.logger.ErrorContext(ctx, "error sending reply on SSH channel", "error", err) } } return nil @@ -1848,7 +1841,7 @@ func (s *Server) handleAgentForwardProxy(_ *ssh.Request, ctx *srv.ServerContext) } // handleX11Forward handles an X11 forwarding request from the client. -func (s *Server) handleX11Forward(ch ssh.Channel, req *ssh.Request, scx *srv.ServerContext) (err error) { +func (s *Server) handleX11Forward(ctx context.Context, ch ssh.Channel, req *ssh.Request, scx *srv.ServerContext) (err error) { event := &apievents.X11Forward{ Metadata: apievents.Metadata{ Type: events.X11ForwardEvent, @@ -1873,11 +1866,11 @@ func (s *Server) handleX11Forward(ch ssh.Channel, req *ssh.Request, scx *srv.Ser if trace.IsAccessDenied(err) { // denied X11 requests are ok from a protocol perspective so we // don't return them, just reply over ssh and emit the audit s.Logger. - s.replyError(ch, req, err) + s.replyError(ctx, ch, req, err) err = nil } if err := s.EmitAuditEvent(s.ctx, event); err != nil { - s.Logger.WithError(err).Warn("Failed to emit x11-forward event.") + s.logger.WarnContext(s.ctx, "Failed to emit x11-forward event", "error", err) } }() @@ -1922,7 +1915,7 @@ func (s *Server) handleX11Forward(ch ssh.Channel, req *ssh.Request, scx *srv.Ser } func (s *Server) handleSubsystem(ctx context.Context, ch ssh.Channel, req *ssh.Request, serverContext *srv.ServerContext) error { - sb, err := s.parseSubsystemRequest(req, serverContext) + sb, err := s.parseSubsystemRequest(ctx, req, serverContext) if err != nil { serverContext.Warnf("Failed to parse subsystem request: %v: %v.", req, err) return trace.Wrap(err) @@ -1937,7 +1930,7 @@ func (s *Server) handleSubsystem(ctx context.Context, ch ssh.Channel, req *ssh.R } go func() { err := sb.Wait() - s.Logger.Debugf("Subsystem %v finished with result: %v.", sb, err) + s.logger.DebugContext(ctx, "Subsystem finished", "subsystem", sb, "error", err) serverContext.SendSubsystemResult(srv.SubsystemResult{Err: trace.Wrap(err)}) }() return nil @@ -1984,16 +1977,16 @@ func (s *Server) handleKeepAlive(req *ssh.Request) { } if err := req.Reply(true, nil); err != nil { - s.Logger.Warnf("Unable to reply to %q request: %v", req.Type, err) + s.logger.WarnContext(s.ctx, "Unable to reply to request", "request_type", req.Type, "error", err) return } - s.Logger.Debugf("Replied to %q", req.Type) + s.logger.DebugContext(s.ctx, "successfully replied to request", "request_type", req.Type) } // handleClusterDetails responds to global out-of-band with details about the cluster. func (s *Server) handleClusterDetails(ctx context.Context, req *ssh.Request) { - s.Logger.Debugf("Global request (%v, %v) received", req.Type, req.WantReply) + s.logger.DebugContext(ctx, "cluster details request received") if !req.WantReply { return @@ -2002,7 +1995,7 @@ func (s *Server) handleClusterDetails(ctx context.Context, req *ssh.Request) { recConfig, err := s.authService.GetSessionRecordingConfig(ctx) if err != nil { if err := req.Reply(false, nil); err != nil { - s.Logger.Warnf("Unable to respond to global request (%v, %v): %v", req.Type, req.WantReply, err) + s.logger.WarnContext(ctx, "Unable to respond to cluster details request", "error", err) } return } @@ -2013,18 +2006,18 @@ func (s *Server) handleClusterDetails(ctx context.Context, req *ssh.Request) { } if err = req.Reply(true, ssh.Marshal(details)); err != nil { - s.Logger.Warnf("Unable to respond to global request (%v, %v): %v: %v", req.Type, req.WantReply, details, err) + s.logger.WarnContext(ctx, "Unable to respond to cluster details request", "error", err) return } - s.Logger.Debugf("Replied to global request (%v, %v): %v", req.Type, req.WantReply, details) + s.logger.DebugContext(ctx, "Replied to cluster details request") } // handleVersionRequest replies with the Teleport version of the server. -func (s *Server) handleVersionRequest(req *ssh.Request) { +func (s *Server) handleVersionRequest(ctx context.Context, req *ssh.Request) { err := req.Reply(true, []byte(teleport.Version)) if err != nil { - s.Logger.Debugf("Failed to reply to version request: %v.", err) + s.logger.DebugContext(ctx, "Failed to reply to version request", "error", err) } } @@ -2032,12 +2025,12 @@ func (s *Server) handleVersionRequest(req *ssh.Request) { func (s *Server) handleProxyJump(ctx context.Context, ccx *sshutils.ConnectionContext, identityContext srv.IdentityContext, ch ssh.Channel, req sshutils.DirectTCPIPReq) { // Create context for this channel. This context will be closed when the // session request is complete. - ctx, scx, err := srv.NewServerContext(ctx, ccx, s, identityContext) + scx, err := srv.NewServerContext(ctx, ccx, s, identityContext) if err != nil { - s.Logger.WithError(err).Error("Unable to create connection context.") - writeStderr(ch, "Unable to create connection context.") + s.logger.ErrorContext(ctx, "Unable to create connection context", "error", err) + s.writeStderr(ctx, ch, "Unable to create connection context.") if err := ch.Close(); err != nil { - s.Logger.WithError(err).Warn("Failed to close channel.") + s.logger.WarnContext(ctx, "Failed to close channel", "error", err) } return } @@ -2050,8 +2043,8 @@ func (s *Server) handleProxyJump(ctx context.Context, ccx *sshutils.ConnectionCo recConfig, err := s.GetAccessPoint().GetSessionRecordingConfig(ctx) if err != nil { - s.Logger.Errorf("Unable to fetch session recording config: %v.", err) - writeStderr(ch, "Unable to fetch session recording configuration.") + s.logger.ErrorContext(ctx, "Unable to fetch session recording config", "error", err) + s.writeStderr(ctx, ch, "Unable to fetch session recording configuration.") return } @@ -2083,16 +2076,16 @@ func (s *Server) handleProxyJump(ctx context.Context, ccx *sshutils.ConnectionCo if services.IsRecordAtProxy(recConfig.GetMode()) { err = s.handleAgentForwardProxy(&ssh.Request{}, scx) if err != nil { - s.Logger.Warningf("Failed to request agent in recording mode: %v", err) - writeStderr(ch, "Failed to request agent") + s.logger.WarnContext(ctx, "Failed to request agent in recording mode", "error", err) + s.writeStderr(ctx, ch, "Failed to request agent") return } } netConfig, err := s.GetAccessPoint().GetClusterNetworkingConfig(ctx) if err != nil { - s.Logger.Errorf("Unable to fetch cluster networking config: %v.", err) - writeStderr(ch, "Unable to fetch cluster networking configuration.") + s.logger.ErrorContext(ctx, "Unable to fetch cluster networking config", "error", err) + s.writeStderr(ctx, ch, "Unable to fetch cluster networking configuration.") return } @@ -2109,19 +2102,19 @@ func (s *Server) handleProxyJump(ctx context.Context, ccx *sshutils.ConnectionCo CloseCancel: scx.CancelFunc(), }) - subsys, err := newProxySubsys(scx, s, proxySubsysRequest{ + subsys, err := newProxySubsys(ctx, scx, s, proxySubsysRequest{ host: req.Host, port: fmt.Sprintf("%v", req.Port), }) if err != nil { - s.Logger.Errorf("Unable instantiate proxy subsystem: %v.", err) - writeStderr(ch, "Unable to instantiate proxy subsystem.") + s.logger.ErrorContext(ctx, "Unable instantiate proxy subsystem", "error", err) + s.writeStderr(ctx, ch, "Unable to instantiate proxy subsystem.") return } if err := subsys.Start(ctx, scx.ServerConn, ch, &ssh.Request{}, scx); err != nil { - s.Logger.Errorf("Unable to start proxy subsystem: %v.", err) - writeStderr(ch, "Unable to start proxy subsystem.") + s.logger.ErrorContext(ctx, "Unable to start proxy subsystem", "error", err) + s.writeStderr(ctx, ch, "Unable to start proxy subsystem.") return } @@ -2129,8 +2122,8 @@ func (s *Server) handleProxyJump(ctx context.Context, ccx *sshutils.ConnectionCo go func() { defer close(wch) if err := subsys.Wait(); err != nil { - s.Logger.Errorf("Proxy subsystem failed: %v.", err) - writeStderr(ch, "Proxy subsystem failed.") + s.logger.ErrorContext(ctx, "Proxy subsystem failed", "error", err) + s.writeStderr(ctx, ch, "Proxy subsystem failed.") } }() select { @@ -2155,10 +2148,10 @@ func (s *Server) createForwardingContext(ctx context.Context, ccx *sshutils.Conn // SessionJoinPrincipal should be rejected, otherwise it's possible to use // the "-teleport-internal-join" user to bypass RBAC. if identityContext.Login == teleport.SSHSessionJoinPrincipal { - log.Errorf("Request rejected, %q with SessionJoinPrincipal in forward node must be blocked", r.Type) + s.logger.ErrorContext(ctx, "Request with SessionJoinPrincipal rejected", "request_type", r.Type) err := trace.AccessDenied("attempted %q request in join-only mode", r.Type) if replyErr := r.Reply(false, []byte(utils.FormatErrorWithNewline(err))); replyErr != nil { - s.Logger.Warnf("Failed to reply to %q request: %v", r.Type, err) + s.logger.WarnContext(ctx, "Failed to reply to request", "request_type", r.Type, "error", err) } // Disable default reply by caller, we already handled it. r.WantReply = false @@ -2166,7 +2159,7 @@ func (s *Server) createForwardingContext(ctx context.Context, ccx *sshutils.Conn } // Create context for this request. - ctx, scx, err := srv.NewServerContext(ctx, ccx, s, identityContext) + scx, err := srv.NewServerContext(ctx, ccx, s, identityContext) if err != nil { return nil, nil, trace.Wrap(err) } @@ -2211,7 +2204,7 @@ func (s *Server) handleTCPIPForwardRequest(ctx context.Context, ccx *sshutils.Co event := scx.GetPortForwardEvent() if err := s.EmitAuditEvent(ctx, &event); err != nil { - s.Logger.WithError(err).Warn("Failed to emit audit event.") + s.logger.WarnContext(ctx, "Failed to emit audit event", "error", err) } if err := sshutils.StartRemoteListener(ctx, scx.ConnectionContext.ServerConn, scx.SrcAddr, listener); err != nil { return trace.Wrap(err) @@ -2231,7 +2224,7 @@ func (s *Server) handleTCPIPForwardRequest(ctx context.Context, ccx *sshutils.Co } if err := r.Reply(true, payload); err != nil { - s.Logger.Warnf("Failed to reply to %q request: %v", r.Type, err) + s.logger.WarnContext(ctx, "Failed to reply to request", "request_type", r.Type, "error", err) } } @@ -2264,27 +2257,27 @@ func (s *Server) handleCancelTCPIPForwardRequest(ctx context.Context, ccx *sshut return trace.NotFound("no remote forwarding listener at %v", scx.SrcAddr) } if err := r.Reply(true, nil); err != nil { - s.Logger.Warnf("Failed to reply to %q request: %v", r.Type, err) + s.logger.WarnContext(ctx, "Failed to reply to request", "request_type", r.Type, "error", err) } return trace.Wrap(listener.Close()) } -func (s *Server) replyError(ch ssh.Channel, req *ssh.Request, err error) { - s.Logger.WithError(err).Errorf("failure handling SSH %q request", req.Type) +func (s *Server) replyError(ctx context.Context, ch ssh.Channel, req *ssh.Request, err error) { + s.logger.ErrorContext(ctx, "failure handling SSH request", "request_type", req.Type, "error", err) // Terminate the error with a newline when writing to remote channel's // stderr so the output does not mix with the rest of the output if the remote // side is not doing additional formatting for extended data. // See github.com/gravitational/teleport/issues/4542 message := utils.FormatErrorWithNewline(err) - writeStderr(ch, message) + s.writeStderr(ctx, ch, message) if req.WantReply { if err := req.Reply(false, []byte(message)); err != nil { - s.Logger.Warnf("Failed to reply to %q request: %v", req.Type, err) + s.logger.WarnContext(ctx, "Failed to reply with error to request", "request_type", req.Type, "error", err) } } } -func (s *Server) parseSubsystemRequest(req *ssh.Request, ctx *srv.ServerContext) (srv.Subsystem, error) { +func (s *Server) parseSubsystemRequest(ctx context.Context, req *ssh.Request, serverContext *srv.ServerContext) (srv.Subsystem, error) { var r sshutils.SubsystemReq if err := ssh.Unmarshal(req.Payload, &r); err != nil { return nil, trace.BadParameter("failed to parse subsystem request: %v", err) @@ -2293,7 +2286,7 @@ func (s *Server) parseSubsystemRequest(req *ssh.Request, ctx *srv.ServerContext) if s.proxyMode { switch { case strings.HasPrefix(r.Name, "proxy:"): - return parseProxySubsys(r.Name, s, ctx) + return s.parseProxySubsys(ctx, r.Name, serverContext) case strings.HasPrefix(r.Name, "proxysites"): return parseProxySitesSubsys(r.Name, s) default: @@ -2306,7 +2299,7 @@ func (s *Server) parseSubsystemRequest(req *ssh.Request, ctx *srv.ServerContext) case r.Name == teleport.GetHomeDirSubsystem: return newHomeDirSubsys(), nil case r.Name == teleport.SFTPSubsystem: - err := ctx.CheckSFTPAllowed(s.reg) + err := serverContext.CheckSFTPAllowed(s.reg) if err != nil { s.EmitAuditEvent(context.Background(), &apievents.SFTP{ Metadata: apievents.Metadata{ @@ -2314,28 +2307,28 @@ func (s *Server) parseSubsystemRequest(req *ssh.Request, ctx *srv.ServerContext) Type: events.SFTPEvent, Time: time.Now(), }, - UserMetadata: ctx.Identity.GetUserMetadata(), - ServerMetadata: ctx.GetServer().TargetMetadata(), + UserMetadata: serverContext.Identity.GetUserMetadata(), + ServerMetadata: serverContext.GetServer().TargetMetadata(), Error: err.Error(), }) return nil, trace.Wrap(err) } - return newSFTPSubsys(ctx.ConsumeApprovedFileTransferRequest()) + return newSFTPSubsys(serverContext.ConsumeApprovedFileTransferRequest()) default: return nil, trace.BadParameter("unrecognized subsystem: %v", r.Name) } } -func writeStderr(ch ssh.Channel, msg string) { +func (s *Server) writeStderr(ctx context.Context, ch ssh.Channel, msg string) { if _, err := io.WriteString(ch.Stderr(), msg); err != nil { - log.Warnf("Failed writing to ssh.Channel.Stderr(): %v", err) + s.logger.WarnContext(ctx, "Failed writing to stderr of SSH channel", "error", err) } } -func rejectChannel(ch ssh.NewChannel, reason ssh.RejectionReason, msg string) { +func (s *Server) rejectChannel(ctx context.Context, ch ssh.NewChannel, reason ssh.RejectionReason, msg string) { if err := ch.Reject(reason, msg); err != nil { - log.Warnf("Failed to reject new ssh.Channel: %v", err) + s.logger.WarnContext(ctx, "Failed to reject new SSH channel", "error", err) } } @@ -2345,9 +2338,9 @@ func rejectChannel(ch ssh.NewChannel, reason ssh.RejectionReason, msg string) { // tuning. It can be sent on any type of channel. There is no message-specific data. Servers MUST treat it // as an unrecognized request and respond with SSH_MSG_CHANNEL_FAILURE. // https://the.earth.li/~sgtatham/putty/0.76/htmldoc/AppendixG.html#sshnames-channel -func (s *Server) handlePuTTYWinadj(ch ssh.Channel, req *ssh.Request) error { +func (s *Server) handlePuTTYWinadj(ctx context.Context, req *ssh.Request) error { if err := req.Reply(false, nil); err != nil { - s.Logger.Warnf("Failed to reply to %q request: %v", req.Type, err) + s.logger.WarnContext(ctx, "Failed to reply to PuTTY winadj request", "error", err) return err } // the reply has been handled inside this function (rather than relying on the standard behavior diff --git a/lib/srv/regular/sshserver_test.go b/lib/srv/regular/sshserver_test.go index c2f5990339255..5e0b9a18bfec9 100644 --- a/lib/srv/regular/sshserver_test.go +++ b/lib/srv/regular/sshserver_test.go @@ -1227,10 +1227,7 @@ func x11EchoSession(ctx context.Context, t *testing.T, clt *tracessh.Client) x11 defer clientConn.Close() go func() { - err := sshutils.ForwardRequests(ctx, sin, se) - if err != nil { - log.WithError(err).Debug("Failed to forward ssh request from server during X11 forwarding") - } + _ = sshutils.ForwardRequests(ctx, sin, se) }() err = utils.ProxyConn(ctx, clientXConn, sch) @@ -2278,13 +2275,11 @@ func x11Handler(ctx context.Context, conn *ssh.ServerConn, chs <-chan ssh.NewCha // echo all bytes back across the X11 channel _, err = io.Copy(xch, xch) - if err == nil { - xch.CloseWrite() - } else { - log.Errorf("X11 channel error: %v", err) + if err != nil { + return trace.Wrap(err) } - return nil + return trace.Wrap(xch.CloseWrite()) } // startX11EchoServer starts a fake node which, for each incoming SSH connection, accepts an @@ -2298,7 +2293,6 @@ func startX11EchoServer(ctx context.Context, t *testing.T, authSrv *auth.Server) for { conn, chs, _, err := node.accept() if err != nil { - log.Warnf("X11 echo server closing: %v", err) return } go func() { diff --git a/lib/srv/server/azure_installer.go b/lib/srv/server/azure_installer.go index a724288ad1585..4d7e17e9c6c5c 100644 --- a/lib/srv/server/azure_installer.go +++ b/lib/srv/server/azure_installer.go @@ -25,7 +25,6 @@ import ( "net/url" "github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/compute/armcompute/v3" - "github.com/aws/aws-sdk-go/aws" "github.com/gravitational/trace" "golang.org/x/sync/errgroup" @@ -70,7 +69,7 @@ func (ai *AzureInstaller) Run(ctx context.Context, req AzureRunRequest) error { runRequest := azure.RunCommandRequest{ Region: req.Region, ResourceGroup: req.ResourceGroup, - VMName: aws.StringValue(inst.Name), + VMName: azure.StringVal(inst.Name), Parameters: req.Params, Script: script, } diff --git a/lib/srv/server/azure_watcher.go b/lib/srv/server/azure_watcher.go index 4339bfc713713..645658e8f77fe 100644 --- a/lib/srv/server/azure_watcher.go +++ b/lib/srv/server/azure_watcher.go @@ -24,7 +24,6 @@ import ( "time" "github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/compute/armcompute/v3" - "github.com/aws/aws-sdk-go/aws" "github.com/gravitational/trace" usageeventsv1 "github.com/gravitational/teleport/api/gen/proto/go/usageevents/v1" @@ -66,7 +65,7 @@ func (instances *AzureInstances) MakeEvents() map[string]*usageeventsv1.Resource } events := make(map[string]*usageeventsv1.ResourceCreateEvent, len(instances.Instances)) for _, inst := range instances.Instances { - events[azureEventPrefix+aws.StringValue(inst.ID)] = &usageeventsv1.ResourceCreateEvent{ + events[azureEventPrefix+azure.StringVal(inst.ID)] = &usageeventsv1.ResourceCreateEvent{ ResourceType: resourceType, ResourceOrigin: types.OriginCloud, CloudProvider: types.CloudAzure, @@ -177,13 +176,13 @@ func (f *azureInstanceFetcher) GetInstances(ctx context.Context, _ bool) ([]Inst } for _, vm := range vms { - location := aws.StringValue(vm.Location) + location := azure.StringVal(vm.Location) if _, ok := instancesByRegion[location]; !ok && !allowAllRegions { continue } vmTags := make(map[string]string, len(vm.Tags)) for key, value := range vm.Tags { - vmTags[key] = aws.StringValue(value) + vmTags[key] = azure.StringVal(value) } if match, _, _ := services.MatchLabels(f.Labels, vmTags); !match { continue diff --git a/lib/srv/server/ssm_install.go b/lib/srv/server/ssm_install.go index 3c23f672884a3..51943f4400058 100644 --- a/lib/srv/server/ssm_install.go +++ b/lib/srv/server/ssm_install.go @@ -26,12 +26,11 @@ import ( "maps" "slices" "strings" + "time" - "github.com/aws/aws-sdk-go/aws" - "github.com/aws/aws-sdk-go/aws/awserr" - "github.com/aws/aws-sdk-go/aws/request" - "github.com/aws/aws-sdk-go/service/ssm" - "github.com/aws/aws-sdk-go/service/ssm/ssmiface" + "github.com/aws/aws-sdk-go-v2/aws" + "github.com/aws/aws-sdk-go-v2/service/ssm" + ssmtypes "github.com/aws/aws-sdk-go-v2/service/ssm/types" "github.com/gravitational/trace" "golang.org/x/sync/errgroup" @@ -42,6 +41,23 @@ import ( libevents "github.com/gravitational/teleport/lib/events" ) +// waiterTimedOutErrorMessage is the error message returned by the AWS SDK command +// executed waiter when it times out. +const waiterTimedOutErrorMessage = "exceeded max wait time for CommandExecuted waiter" + +// SSMClient is the subset of the AWS SSM API required for EC2 discovery. +type SSMClient interface { + ssm.DescribeInstanceInformationAPIClient + ssm.GetCommandInvocationAPIClient + ssm.ListCommandInvocationsAPIClient + // SendCommand runs commands on one or more managed nodes. + SendCommand(ctx context.Context, params *ssm.SendCommandInput, optFns ...func(*ssm.Options)) (*ssm.SendCommandOutput, error) +} + +type commandWaiter interface { + Wait(ctx context.Context, params *ssm.GetCommandInvocationInput, maxWaitDur time.Duration, optFns ...func(*ssm.CommandExecutedWaiterOptions)) error +} + // SSMInstallerConfig represents configuration for an SSM install // script executor. type SSMInstallerConfig struct { @@ -50,6 +66,9 @@ type SSMInstallerConfig struct { // Logger is used to log messages. // Optional. A logger is created if one not supplied. Logger *slog.Logger + // getWaiter replaces the default command waiter for a given SSM client. + // Used in tests. + getWaiter func(SSMClient) commandWaiter } // SSMInstallationResult contains the result of trying to install teleport @@ -84,7 +103,7 @@ type SSMRunRequest struct { // DocumentName is the name of the SSM document to run. DocumentName string // SSM is an SSM API client. - SSM ssmiface.SSMAPI + SSM SSMClient // Instances is the list of instances that will have the SSM // document executed on them. Instances []EC2Instance @@ -124,6 +143,12 @@ func (c *SSMInstallerConfig) checkAndSetDefaults() error { c.Logger = slog.Default().With(teleport.ComponentKey, "ssminstaller") } + if c.getWaiter == nil { + c.getWaiter = func(s SSMClient) commandWaiter { + return ssm.NewCommandExecutedWaiter(s) + } + } + return nil } @@ -144,9 +169,9 @@ func (si *SSMInstaller) Run(ctx context.Context, req SSMRunRequest) error { instances[inst.InstanceID] = inst.InstanceName } - params := make(map[string][]*string) + params := make(map[string][]string) for k, v := range req.Params { - params[k] = []*string{aws.String(v)} + params[k] = []string{v} } validInstances := instances @@ -175,9 +200,9 @@ func (si *SSMInstaller) Run(ctx context.Context, req SSMRunRequest) error { } validInstanceIDs := instanceIDsFrom(validInstances) - output, err := req.SSM.SendCommandWithContext(ctx, &ssm.SendCommandInput{ + output, err := req.SSM.SendCommand(ctx, &ssm.SendCommandInput{ DocumentName: aws.String(req.DocumentName), - InstanceIds: aws.StringSlice(validInstanceIDs), + InstanceIds: validInstanceIDs, Parameters: params, }) if err != nil { @@ -194,9 +219,9 @@ func (si *SSMInstaller) Run(ctx context.Context, req SSMRunRequest) error { // As a best effort, we try to call ssm.SendCommand again but this time without the "sshdConfigPath" param // We must not remove the Param "sshdConfigPath" beforehand because customers might be using custom SSM Documents for ec2 auto discovery. delete(params, ParamSSHDConfigPath) - output, err = req.SSM.SendCommandWithContext(ctx, &ssm.SendCommandInput{ + output, err = req.SSM.SendCommand(ctx, &ssm.SendCommandInput{ DocumentName: aws.String(req.DocumentName), - InstanceIds: aws.StringSlice(validInstanceIDs), + InstanceIds: validInstanceIDs, Parameters: params, }) if err != nil { @@ -296,20 +321,20 @@ func (si *SSMInstaller) describeSSMAgentState(ctx context.Context, req SSMRunReq } instanceIDs := instanceIDsFrom(allInstances) - ssmInstancesInfo, err := req.SSM.DescribeInstanceInformationWithContext(ctx, &ssm.DescribeInstanceInformationInput{ - Filters: []*ssm.InstanceInformationStringFilter{ - {Key: aws.String(ssm.InstanceInformationFilterKeyInstanceIds), Values: aws.StringSlice(instanceIDs)}, + ssmInstancesInfo, err := req.SSM.DescribeInstanceInformation(ctx, &ssm.DescribeInstanceInformationInput{ + Filters: []ssmtypes.InstanceInformationStringFilter{ + {Key: aws.String(string(ssmtypes.InstanceInformationFilterKeyInstanceIds)), Values: instanceIDs}, }, - MaxResults: aws.Int64(awsEC2APIChunkSize), + MaxResults: aws.Int32(awsEC2APIChunkSize), }) if err != nil { return nil, trace.Wrap(awslib.ConvertRequestFailureError(err)) } - instanceStateByInstanceID := make(map[string]*ssm.InstanceInformation, len(ssmInstancesInfo.InstanceInformationList)) + instanceStateByInstanceID := make(map[string]ssmtypes.InstanceInformation, len(ssmInstancesInfo.InstanceInformationList)) for _, instanceState := range ssmInstancesInfo.InstanceInformationList { // instanceState.InstanceId always has the InstanceID value according to AWS Docs. - instanceStateByInstanceID[aws.StringValue(instanceState.InstanceId)] = instanceState + instanceStateByInstanceID[aws.ToString(instanceState.InstanceId)] = instanceState } for instanceID, instanceName := range allInstances { @@ -319,12 +344,12 @@ func (si *SSMInstaller) describeSSMAgentState(ctx context.Context, req SSMRunReq continue } - if aws.StringValue(instanceState.PingStatus) == ssm.PingStatusConnectionLost { + if instanceState.PingStatus == ssmtypes.PingStatusConnectionLost { ret.connectionLost[instanceID] = instanceName continue } - if aws.StringValue(instanceState.PlatformType) != ssm.PlatformTypeLinux { + if instanceState.PlatformType != ssmtypes.PlatformTypeLinux { ret.unsupportedOS[instanceID] = instanceName continue } @@ -336,23 +361,22 @@ func (si *SSMInstaller) describeSSMAgentState(ctx context.Context, req SSMRunReq } // skipAWSWaitErr is used to ignore the error returned from -// WaitUntilCommandExecutedWithContext if it is a resource not ready -// code as this can represent one of several different errors which +// Wait if it times out, as this can represent one of several different errors which // are handled by checking the command invocation after calling this // to get more information about the error. func skipAWSWaitErr(err error) error { - var aErr awserr.Error - if errors.As(err, &aErr) && aErr.Code() == request.WaiterResourceNotReadyErrorCode { + if err != nil && err.Error() == waiterTimedOutErrorMessage { return nil } return trace.Wrap(err) } func (si *SSMInstaller) checkCommand(ctx context.Context, req SSMRunRequest, commandID, instanceID *string, instanceName string) error { - err := req.SSM.WaitUntilCommandExecutedWithContext(ctx, &ssm.GetCommandInvocationInput{ + err := si.getWaiter(req.SSM).Wait(ctx, &ssm.GetCommandInvocationInput{ CommandId: commandID, InstanceId: instanceID, - }) + // 100 seconds to match v1 sdk waiter default. + }, 100*time.Second) if err := skipAWSWaitErr(err); err != nil { return trace.Wrap(err) @@ -378,7 +402,7 @@ func (si *SSMInstaller) checkCommand(ctx context.Context, req SSMRunRequest, com for i, step := range invocationSteps { stepResultEvent, err := si.getCommandStepStatusEvent(ctx, step, req, commandID, instanceID) if err != nil { - var invalidPluginNameErr *ssm.InvalidPluginName + var invalidPluginNameErr *ssmtypes.InvalidPluginName if errors.As(err, &invalidPluginNameErr) { // If using a custom SSM Document and the client does not have access to ssm:ListCommandInvocations // the list of invocationSteps (ie plugin name) might be wrong. @@ -422,10 +446,10 @@ func (si *SSMInstaller) checkCommand(ctx context.Context, req SSMRunRequest, com func (si *SSMInstaller) getInvocationSteps(ctx context.Context, req SSMRunRequest, commandID, instanceID *string) ([]string, error) { // ssm:ListCommandInvocations is used to list the actual steps because users might be using a custom SSM Document. - listCommandInvocationResp, err := req.SSM.ListCommandInvocationsWithContext(ctx, &ssm.ListCommandInvocationsInput{ + listCommandInvocationResp, err := req.SSM.ListCommandInvocations(ctx, &ssm.ListCommandInvocationsInput{ CommandId: commandID, InstanceId: instanceID, - Details: aws.Bool(true), + Details: true, }) if err != nil { return nil, trace.Wrap(awslib.ConvertRequestFailureError(err)) @@ -436,8 +460,8 @@ func (si *SSMInstaller) getInvocationSteps(ctx context.Context, req SSMRunReques if len(listCommandInvocationResp.CommandInvocations) == 0 { si.Logger.WarnContext(ctx, "No command invocation was found.", - "command_id", aws.StringValue(commandID), - "instance_id", aws.StringValue(instanceID), + "command_id", aws.ToString(commandID), + "instance_id", aws.ToString(instanceID), ) return nil, trace.BadParameter("no command invocation was found") } @@ -445,7 +469,7 @@ func (si *SSMInstaller) getInvocationSteps(ctx context.Context, req SSMRunReques documentSteps := make([]string, 0, len(commandInvocation.CommandPlugins)) for _, step := range commandInvocation.CommandPlugins { - documentSteps = append(documentSteps, aws.StringValue(step.Name)) + documentSteps = append(documentSteps, aws.ToString(step.Name)) } return documentSteps, nil } @@ -458,16 +482,16 @@ func (si *SSMInstaller) getCommandStepStatusEvent(ctx context.Context, step stri if step != "" { getCommandInvocationReq.PluginName = aws.String(step) } - stepResult, err := req.SSM.GetCommandInvocationWithContext(ctx, getCommandInvocationReq) + stepResult, err := req.SSM.GetCommandInvocation(ctx, getCommandInvocationReq) if err != nil { return nil, trace.Wrap(err) } - status := aws.StringValue(stepResult.Status) - exitCode := aws.Int64Value(stepResult.ResponseCode) + status := stepResult.Status + exitCode := int64(stepResult.ResponseCode) eventCode := libevents.SSMRunSuccessCode - if status != ssm.CommandStatusSuccess { + if status != ssmtypes.CommandInvocationStatusSuccess { eventCode = libevents.SSMRunFailCode if exitCode == 0 { exitCode = -1 @@ -479,7 +503,7 @@ func (si *SSMInstaller) getCommandStepStatusEvent(ctx context.Context, step stri // Example: // https://eu-west-2.console.aws.amazon.com/systems-manager/run-command/3cb11aaa-11aa-1111-aaaa-2188108225de/i-0775091aa11111111 invocationURL := fmt.Sprintf("https://%s.console.aws.amazon.com/systems-manager/run-command/%s/%s", - req.Region, aws.StringValue(commandID), aws.StringValue(instanceID), + req.Region, aws.ToString(commandID), aws.ToString(instanceID), ) return &apievents.SSMRun{ @@ -487,14 +511,14 @@ func (si *SSMInstaller) getCommandStepStatusEvent(ctx context.Context, step stri Type: libevents.SSMRunEvent, Code: eventCode, }, - CommandID: aws.StringValue(commandID), - InstanceID: aws.StringValue(instanceID), + CommandID: aws.ToString(commandID), + InstanceID: aws.ToString(instanceID), AccountID: req.AccountID, Region: req.Region, ExitCode: exitCode, - Status: status, - StandardOutput: aws.StringValue(stepResult.StandardOutputContent), - StandardError: aws.StringValue(stepResult.StandardErrorContent), + Status: string(status), + StandardOutput: aws.ToString(stepResult.StandardOutputContent), + StandardError: aws.ToString(stepResult.StandardErrorContent), InvocationURL: invocationURL, }, nil } diff --git a/lib/srv/server/ssm_install_test.go b/lib/srv/server/ssm_install_test.go index c56b286258527..102bcbf5a4475 100644 --- a/lib/srv/server/ssm_install_test.go +++ b/lib/srv/server/ssm_install_test.go @@ -21,15 +21,13 @@ package server import ( "context" "fmt" - "net/http" "testing" + "time" - "github.com/aws/aws-sdk-go/aws" - "github.com/aws/aws-sdk-go/aws/awserr" - "github.com/aws/aws-sdk-go/aws/request" - "github.com/aws/aws-sdk-go/service/ssm" - "github.com/aws/aws-sdk-go/service/ssm/ssmiface" - "github.com/google/uuid" + "github.com/aws/aws-sdk-go-v2/aws" + "github.com/aws/aws-sdk-go-v2/service/ssm" + ssmtypes "github.com/aws/aws-sdk-go-v2/service/ssm/types" + "github.com/gravitational/trace" "github.com/stretchr/testify/require" "github.com/gravitational/teleport/api/types/events" @@ -37,7 +35,7 @@ import ( ) type mockSSMClient struct { - ssmiface.SSMAPI + SSMClient commandOutput *ssm.SendCommandOutput commandInvokeOutput map[string]*ssm.GetCommandInvocationOutput describeOutput *ssm.DescribeInstanceInformationOutput @@ -46,37 +44,37 @@ type mockSSMClient struct { const docWithoutSSHDConfigPathParam = "ssmdocument-without-sshdConfigPath-param" -func (sm *mockSSMClient) SendCommandWithContext(_ context.Context, input *ssm.SendCommandInput, _ ...request.Option) (*ssm.SendCommandOutput, error) { - if _, hasExtraParam := input.Parameters["sshdConfigPath"]; hasExtraParam && aws.StringValue(input.DocumentName) == docWithoutSSHDConfigPathParam { +func (sm *mockSSMClient) SendCommand(_ context.Context, input *ssm.SendCommandInput, _ ...func(*ssm.Options)) (*ssm.SendCommandOutput, error) { + if _, hasExtraParam := input.Parameters["sshdConfigPath"]; hasExtraParam && aws.ToString(input.DocumentName) == docWithoutSSHDConfigPathParam { return nil, fmt.Errorf("InvalidParameters: document %s does not support parameters", docWithoutSSHDConfigPathParam) } return sm.commandOutput, nil } -func (sm *mockSSMClient) GetCommandInvocationWithContext(_ context.Context, input *ssm.GetCommandInvocationInput, _ ...request.Option) (*ssm.GetCommandInvocationOutput, error) { - if stepResult, found := sm.commandInvokeOutput[aws.StringValue(input.PluginName)]; found { +func (sm *mockSSMClient) GetCommandInvocation(_ context.Context, input *ssm.GetCommandInvocationInput, _ ...func(*ssm.Options)) (*ssm.GetCommandInvocationOutput, error) { + if stepResult, found := sm.commandInvokeOutput[aws.ToString(input.PluginName)]; found { return stepResult, nil } - return nil, &ssm.InvalidPluginName{} + return nil, &ssmtypes.InvalidPluginName{} } -func (sm *mockSSMClient) DescribeInstanceInformationWithContext(_ context.Context, input *ssm.DescribeInstanceInformationInput, _ ...request.Option) (*ssm.DescribeInstanceInformationOutput, error) { +func (sm *mockSSMClient) DescribeInstanceInformation(_ context.Context, input *ssm.DescribeInstanceInformationInput, _ ...func(*ssm.Options)) (*ssm.DescribeInstanceInformationOutput, error) { if sm.describeOutput == nil { - return nil, awserr.NewRequestFailure(awserr.New("AccessDeniedException", "message", nil), http.StatusBadRequest, uuid.NewString()) + return nil, trace.AccessDenied("") } return sm.describeOutput, nil } -func (sm *mockSSMClient) ListCommandInvocationsWithContext(aws.Context, *ssm.ListCommandInvocationsInput, ...request.Option) (*ssm.ListCommandInvocationsOutput, error) { +func (sm *mockSSMClient) ListCommandInvocations(_ context.Context, input *ssm.ListCommandInvocationsInput, _ ...func(*ssm.Options)) (*ssm.ListCommandInvocationsOutput, error) { if sm.listCommandInvocations == nil { - return nil, awserr.NewRequestFailure(awserr.New("AccessDeniedException", "message", nil), http.StatusBadRequest, uuid.NewString()) + return nil, trace.AccessDenied("") } return sm.listCommandInvocations, nil } -func (sm *mockSSMClient) WaitUntilCommandExecutedWithContext(aws.Context, *ssm.GetCommandInvocationInput, ...request.WaiterOption) error { - if aws.StringValue(sm.commandOutput.Command.Status) == ssm.CommandStatusFailed { - return awserr.New(request.WaiterResourceNotReadyErrorCode, "err", nil) +func (sm *mockSSMClient) Wait(ctx context.Context, params *ssm.GetCommandInvocationInput, maxWaitDur time.Duration, optFns ...func(*ssm.CommandExecutedWaiterOptions)) error { + if sm.commandOutput.Command.Status == ssmtypes.CommandStatusFailed { + return trace.Errorf(waiterTimedOutErrorMessage) } return nil } @@ -94,6 +92,7 @@ func TestSSMInstaller(t *testing.T) { document := "ssmdocument" for _, tc := range []struct { + client *mockSSMClient req SSMRunRequest expectedInstallations []*SSMInstallationResult name string @@ -108,25 +107,25 @@ func TestSSMInstaller(t *testing.T) { Params: map[string]string{"token": "abcdefg"}, IntegrationName: "aws-integration", DiscoveryConfig: "dc001", - SSM: &mockSSMClient{ - commandOutput: &ssm.SendCommandOutput{ - Command: &ssm.Command{ - CommandId: aws.String("command-id-1"), - }, + Region: "eu-central-1", + AccountID: "account-id", + }, + client: &mockSSMClient{ + commandOutput: &ssm.SendCommandOutput{ + Command: &ssmtypes.Command{ + CommandId: aws.String("command-id-1"), }, - commandInvokeOutput: map[string]*ssm.GetCommandInvocationOutput{ - "downloadContent": { - Status: aws.String(ssm.CommandStatusSuccess), - ResponseCode: aws.Int64(0), - }, - "runShellScript": { - Status: aws.String(ssm.CommandStatusSuccess), - ResponseCode: aws.Int64(0), - }, + }, + commandInvokeOutput: map[string]*ssm.GetCommandInvocationOutput{ + "downloadContent": { + Status: ssmtypes.CommandInvocationStatusSuccess, + ResponseCode: 0, + }, + "runShellScript": { + Status: ssmtypes.CommandInvocationStatusSuccess, + ResponseCode: 0, }, }, - Region: "eu-central-1", - AccountID: "account-id", }, expectedInstallations: []*SSMInstallationResult{{ IntegrationName: "aws-integration", @@ -141,7 +140,7 @@ func TestSSMInstaller(t *testing.T) { AccountID: "account-id", Region: "eu-central-1", ExitCode: 0, - Status: ssm.CommandStatusSuccess, + Status: string(ssmtypes.CommandInvocationStatusSuccess), InvocationURL: "https://eu-central-1.console.aws.amazon.com/systems-manager/run-command/command-id-1/instance-id-1", }, IssueType: "ec2-ssm-script-failure", @@ -157,25 +156,25 @@ func TestSSMInstaller(t *testing.T) { }, DocumentName: docWithoutSSHDConfigPathParam, Params: map[string]string{"sshdConfigPath": "abcdefg"}, - SSM: &mockSSMClient{ - commandOutput: &ssm.SendCommandOutput{ - Command: &ssm.Command{ - CommandId: aws.String("command-id-1"), - }, + Region: "eu-central-1", + AccountID: "account-id", + }, + client: &mockSSMClient{ + commandOutput: &ssm.SendCommandOutput{ + Command: &ssmtypes.Command{ + CommandId: aws.String("command-id-1"), }, - commandInvokeOutput: map[string]*ssm.GetCommandInvocationOutput{ - "downloadContent": { - Status: aws.String(ssm.CommandStatusSuccess), - ResponseCode: aws.Int64(0), - }, - "runShellScript": { - Status: aws.String(ssm.CommandStatusSuccess), - ResponseCode: aws.Int64(0), - }, + }, + commandInvokeOutput: map[string]*ssm.GetCommandInvocationOutput{ + "downloadContent": { + Status: ssmtypes.CommandInvocationStatusSuccess, + ResponseCode: 0, + }, + "runShellScript": { + Status: ssmtypes.CommandInvocationStatusSuccess, + ResponseCode: 0, }, }, - Region: "eu-central-1", - AccountID: "account-id", }, expectedInstallations: []*SSMInstallationResult{{ SSMRunEvent: &events.SSMRun{ @@ -188,7 +187,7 @@ func TestSSMInstaller(t *testing.T) { AccountID: "account-id", Region: "eu-central-1", ExitCode: 0, - Status: ssm.CommandStatusSuccess, + Status: string(ssmtypes.CommandInvocationStatusSuccess), InvocationURL: "https://eu-central-1.console.aws.amazon.com/systems-manager/run-command/command-id-1/instance-id-1", }, IssueType: "ec2-ssm-script-failure", @@ -204,23 +203,23 @@ func TestSSMInstaller(t *testing.T) { }, IntegrationName: "aws-1", Params: map[string]string{"token": "abcdefg"}, - SSM: &mockSSMClient{ - commandOutput: &ssm.SendCommandOutput{ - Command: &ssm.Command{ - CommandId: aws.String("command-id-1"), - }, + Region: "eu-central-1", + AccountID: "account-id", + }, + client: &mockSSMClient{ + commandOutput: &ssm.SendCommandOutput{ + Command: &ssmtypes.Command{ + CommandId: aws.String("command-id-1"), }, - commandInvokeOutput: map[string]*ssm.GetCommandInvocationOutput{ - "downloadContent": { - Status: aws.String(ssm.CommandStatusFailed), - ResponseCode: aws.Int64(1), - StandardErrorContent: aws.String("timeout error"), - StandardOutputContent: aws.String(""), - }, + }, + commandInvokeOutput: map[string]*ssm.GetCommandInvocationOutput{ + "downloadContent": { + Status: ssmtypes.CommandInvocationStatusFailed, + ResponseCode: 1, + StandardErrorContent: aws.String("timeout error"), + StandardOutputContent: aws.String(""), }, }, - Region: "eu-central-1", - AccountID: "account-id", }, expectedInstallations: []*SSMInstallationResult{{ IntegrationName: "aws-1", @@ -234,7 +233,7 @@ func TestSSMInstaller(t *testing.T) { AccountID: "account-id", Region: "eu-central-1", ExitCode: 1, - Status: ssm.CommandStatusFailed, + Status: string(ssmtypes.CommandInvocationStatusFailed), StandardOutput: "", StandardError: "timeout error", InvocationURL: "https://eu-central-1.console.aws.amazon.com/systems-manager/run-command/command-id-1/instance-id-1", @@ -250,30 +249,30 @@ func TestSSMInstaller(t *testing.T) { Instances: []EC2Instance{ {InstanceID: "instance-id-1"}, }, - Params: map[string]string{"token": "abcdefg"}, - SSM: &mockSSMClient{ - commandOutput: &ssm.SendCommandOutput{ - Command: &ssm.Command{ - CommandId: aws.String("command-id-1"), - }, + Params: map[string]string{"token": "abcdefg"}, + Region: "eu-central-1", + AccountID: "account-id", + }, + client: &mockSSMClient{ + commandOutput: &ssm.SendCommandOutput{ + Command: &ssmtypes.Command{ + CommandId: aws.String("command-id-1"), }, - commandInvokeOutput: map[string]*ssm.GetCommandInvocationOutput{ - "downloadContent": { - Status: aws.String(ssm.CommandStatusSuccess), - ResponseCode: aws.Int64(0), - StandardErrorContent: aws.String("no error"), - StandardOutputContent: aws.String(""), - }, - "runShellScript": { - Status: aws.String(ssm.CommandStatusFailed), - ResponseCode: aws.Int64(1), - StandardErrorContent: aws.String("timeout error"), - StandardOutputContent: aws.String(""), - }, + }, + commandInvokeOutput: map[string]*ssm.GetCommandInvocationOutput{ + "downloadContent": { + Status: ssmtypes.CommandInvocationStatusSuccess, + ResponseCode: 0, + StandardErrorContent: aws.String("no error"), + StandardOutputContent: aws.String(""), + }, + "runShellScript": { + Status: ssmtypes.CommandInvocationStatusFailed, + ResponseCode: 1, + StandardErrorContent: aws.String("timeout error"), + StandardOutputContent: aws.String(""), }, }, - Region: "eu-central-1", - AccountID: "account-id", }, expectedInstallations: []*SSMInstallationResult{{ SSMRunEvent: &events.SSMRun{ @@ -286,7 +285,7 @@ func TestSSMInstaller(t *testing.T) { AccountID: "account-id", Region: "eu-central-1", ExitCode: 1, - Status: ssm.CommandStatusFailed, + Status: string(ssmtypes.CommandInvocationStatusFailed), StandardOutput: "", StandardError: "timeout error", InvocationURL: "https://eu-central-1.console.aws.amazon.com/systems-manager/run-command/command-id-1/instance-id-1", @@ -306,44 +305,44 @@ func TestSSMInstaller(t *testing.T) { }, DocumentName: document, Params: map[string]string{"token": "abcdefg"}, - SSM: &mockSSMClient{ - commandOutput: &ssm.SendCommandOutput{ - Command: &ssm.Command{ - CommandId: aws.String("command-id-1"), - }, + Region: "eu-central-1", + AccountID: "account-id", + }, + client: &mockSSMClient{ + commandOutput: &ssm.SendCommandOutput{ + Command: &ssmtypes.Command{ + CommandId: aws.String("command-id-1"), + }, + }, + commandInvokeOutput: map[string]*ssm.GetCommandInvocationOutput{ + "downloadContent": { + Status: ssmtypes.CommandInvocationStatusSuccess, + ResponseCode: 0, + }, + "runShellScript": { + Status: ssmtypes.CommandInvocationStatusSuccess, + ResponseCode: 0, }, - commandInvokeOutput: map[string]*ssm.GetCommandInvocationOutput{ - "downloadContent": { - Status: aws.String(ssm.CommandStatusSuccess), - ResponseCode: aws.Int64(0), + }, + describeOutput: &ssm.DescribeInstanceInformationOutput{ + InstanceInformationList: []ssmtypes.InstanceInformation{ + { + InstanceId: aws.String("instance-id-1"), + PingStatus: ssmtypes.PingStatusOnline, + PlatformType: ssmtypes.PlatformTypeLinux, }, - "runShellScript": { - Status: aws.String(ssm.CommandStatusSuccess), - ResponseCode: aws.Int64(0), + { + InstanceId: aws.String("instance-id-2"), + PingStatus: ssmtypes.PingStatusConnectionLost, + PlatformType: ssmtypes.PlatformTypeLinux, }, - }, - describeOutput: &ssm.DescribeInstanceInformationOutput{ - InstanceInformationList: []*ssm.InstanceInformation{ - { - InstanceId: aws.String("instance-id-1"), - PingStatus: aws.String("Online"), - PlatformType: aws.String("Linux"), - }, - { - InstanceId: aws.String("instance-id-2"), - PingStatus: aws.String("ConnectionLost"), - PlatformType: aws.String("Linux"), - }, - { - InstanceId: aws.String("instance-id-3"), - PingStatus: aws.String("Online"), - PlatformType: aws.String("Windows"), - }, + { + InstanceId: aws.String("instance-id-3"), + PingStatus: ssmtypes.PingStatusOnline, + PlatformType: ssmtypes.PlatformTypeWindows, }, }, }, - Region: "eu-central-1", - AccountID: "account-id", }, expectedInstallations: []*SSMInstallationResult{ { @@ -357,7 +356,7 @@ func TestSSMInstaller(t *testing.T) { AccountID: "account-id", Region: "eu-central-1", ExitCode: 0, - Status: ssm.CommandStatusSuccess, + Status: string(ssmtypes.CommandInvocationStatusSuccess), InvocationURL: "https://eu-central-1.console.aws.amazon.com/systems-manager/run-command/command-id-1/instance-id-1", }, IssueType: "ec2-ssm-script-failure", @@ -421,34 +420,34 @@ func TestSSMInstaller(t *testing.T) { }, DocumentName: document, Params: map[string]string{"token": "abcdefg"}, - SSM: &mockSSMClient{ - commandOutput: &ssm.SendCommandOutput{ - Command: &ssm.Command{ - CommandId: aws.String("command-id-1"), - }, + Region: "eu-central-1", + AccountID: "account-id", + }, + client: &mockSSMClient{ + commandOutput: &ssm.SendCommandOutput{ + Command: &ssmtypes.Command{ + CommandId: aws.String("command-id-1"), }, - commandInvokeOutput: map[string]*ssm.GetCommandInvocationOutput{ - "downloadContentCustom": { - Status: aws.String(ssm.CommandStatusSuccess), - ResponseCode: aws.Int64(0), - }, - "runShellScriptCustom": { - Status: aws.String(ssm.CommandStatusSuccess), - ResponseCode: aws.Int64(0), - StandardOutputContent: aws.String("custom output"), - }, + }, + commandInvokeOutput: map[string]*ssm.GetCommandInvocationOutput{ + "downloadContentCustom": { + Status: ssmtypes.CommandInvocationStatusSuccess, + ResponseCode: 0, }, - listCommandInvocations: &ssm.ListCommandInvocationsOutput{ - CommandInvocations: []*ssm.CommandInvocation{{ - CommandPlugins: []*ssm.CommandPlugin{ - {Name: aws.String("downloadContentCustom")}, - {Name: aws.String("runShellScriptCustom")}, - }, - }}, + "runShellScriptCustom": { + Status: ssmtypes.CommandInvocationStatusSuccess, + ResponseCode: 0, + StandardOutputContent: aws.String("custom output"), }, }, - Region: "eu-central-1", - AccountID: "account-id", + listCommandInvocations: &ssm.ListCommandInvocationsOutput{ + CommandInvocations: []ssmtypes.CommandInvocation{{ + CommandPlugins: []ssmtypes.CommandPlugin{ + {Name: aws.String("downloadContentCustom")}, + {Name: aws.String("runShellScriptCustom")}, + }, + }}, + }, }, expectedInstallations: []*SSMInstallationResult{{ SSMRunEvent: &events.SSMRun{ @@ -461,7 +460,7 @@ func TestSSMInstaller(t *testing.T) { AccountID: "account-id", Region: "eu-central-1", ExitCode: 0, - Status: ssm.CommandStatusSuccess, + Status: string(ssmtypes.CommandInvocationStatusSuccess), StandardOutput: "custom output", InvocationURL: "https://eu-central-1.console.aws.amazon.com/systems-manager/run-command/command-id-1/instance-id-1", }, @@ -477,21 +476,21 @@ func TestSSMInstaller(t *testing.T) { }, DocumentName: document, Params: map[string]string{"token": "abcdefg"}, - SSM: &mockSSMClient{ - commandOutput: &ssm.SendCommandOutput{ - Command: &ssm.Command{ - CommandId: aws.String("command-id-1"), - }, + Region: "eu-central-1", + AccountID: "account-id", + }, + client: &mockSSMClient{ + commandOutput: &ssm.SendCommandOutput{ + Command: &ssmtypes.Command{ + CommandId: aws.String("command-id-1"), }, - commandInvokeOutput: map[string]*ssm.GetCommandInvocationOutput{ - "": { - Status: aws.String(ssm.CommandStatusSuccess), - ResponseCode: aws.Int64(0), - }, + }, + commandInvokeOutput: map[string]*ssm.GetCommandInvocationOutput{ + "": { + Status: ssmtypes.CommandInvocationStatusSuccess, + ResponseCode: 0, }, }, - Region: "eu-central-1", - AccountID: "account-id", }, expectedInstallations: []*SSMInstallationResult{{ SSMRunEvent: &events.SSMRun{ @@ -504,7 +503,7 @@ func TestSSMInstaller(t *testing.T) { AccountID: "account-id", Region: "eu-central-1", ExitCode: 0, - Status: ssm.CommandStatusSuccess, + Status: string(ssmtypes.CommandInvocationStatusSuccess), InvocationURL: "https://eu-central-1.console.aws.amazon.com/systems-manager/run-command/command-id-1/instance-id-1", }, IssueType: "ec2-ssm-script-failure", @@ -516,9 +515,11 @@ func TestSSMInstaller(t *testing.T) { } { t.Run(tc.name, func(t *testing.T) { ctx := context.Background() + tc.req.SSM = tc.client installationResultsCollector := &mockInstallationResults{} inst, err := NewSSMInstaller(SSMInstallerConfig{ ReportSSMInstallationResultFunc: installationResultsCollector.ReportInstallationResult, + getWaiter: func(s SSMClient) commandWaiter { return tc.client }, }) require.NoError(t, err) diff --git a/lib/srv/session_control.go b/lib/srv/session_control.go index bd340e53279cc..748aa111062eb 100644 --- a/lib/srv/session_control.go +++ b/lib/srv/session_control.go @@ -21,12 +21,12 @@ package srv import ( "context" "io" + "log/slog" "strings" "github.com/gravitational/trace" "github.com/jonboulle/clockwork" "github.com/prometheus/client_golang/prometheus" - "github.com/sirupsen/logrus" oteltrace "go.opentelemetry.io/otel/trace" "golang.org/x/crypto/ssh" @@ -75,7 +75,7 @@ type SessionControllerConfig struct { // have different flows Component string // Logger is used to emit log entries - Logger *logrus.Entry + Logger *slog.Logger // TracerProvider creates a tracer so that spans may be emitted TracerProvider oteltrace.TracerProvider // ServerID is the UUID of the server @@ -114,7 +114,7 @@ func (c *SessionControllerConfig) CheckAndSetDefaults() error { } if c.Logger == nil { - c.Logger = logrus.WithField(teleport.ComponentKey, "SessionCtrl") + c.Logger = slog.With(teleport.ComponentKey, "SessionCtrl") } if c.Clock == nil { @@ -342,6 +342,6 @@ func (s *SessionController) emitRejection(ctx context.Context, userMetadata apie Reason: reason, Maximum: max, }); err != nil { - s.cfg.Logger.WithError(err).Warn("Failed to emit session reject event.") + s.cfg.Logger.WarnContext(ctx, "Failed to emit session reject event", "error", err) } } diff --git a/lib/srv/termmanager.go b/lib/srv/termmanager.go index 3c47011672f7f..ddb0d1f3bbc88 100644 --- a/lib/srv/termmanager.go +++ b/lib/srv/termmanager.go @@ -19,12 +19,12 @@ package srv import ( + "context" "errors" "io" + "log/slog" "sync" "sync/atomic" - - log "github.com/sirupsen/logrus" ) // maxHistoryBytes is the maximum bytes that are retained as history and broadcasted to new clients. @@ -107,7 +107,7 @@ func (g *TermManager) writeToClients(p []byte) { _, err := w.Write(p) if err != nil { if !errors.Is(err, io.EOF) { - log.Warnf("Failed to write to remote terminal: %v", err) + slog.WarnContext(context.Background(), "Failed to write to remote terminal", "error", err) } toDelete = append( toDelete, struct { @@ -244,7 +244,7 @@ func (g *TermManager) AddReader(name string, r io.Reader) { n, err := r.Read(buf) if err != nil { if !errors.Is(err, io.EOF) { - log.Warnf("Failed to read from remote terminal: %v", err) + slog.WarnContext(context.Background(), "Failed to read from remote terminal", "error", err) } // Let term manager decide how to handle broken party readers. if g.OnReadError != nil { diff --git a/lib/srv/usermgmt.go b/lib/srv/usermgmt.go index c73e1db41390e..9415c7148096c 100644 --- a/lib/srv/usermgmt.go +++ b/lib/srv/usermgmt.go @@ -485,6 +485,8 @@ func (u *HostUserManagement) UpsertUser(name string, ui services.HostUsersInfo) return closer, nil } +const userLeaseDuration = time.Second * 20 + func (u *HostUserManagement) doWithUserLock(f func(types.SemaphoreLease) error) error { lock, err := services.AcquireSemaphoreWithRetry(u.ctx, services.AcquireSemaphoreWithRetryConfig{ @@ -493,7 +495,7 @@ func (u *HostUserManagement) doWithUserLock(f func(types.SemaphoreLease) error) SemaphoreKind: types.SemaphoreKindHostUserModification, SemaphoreName: "host_user_modification", MaxLeases: 1, - Expires: time.Now().Add(time.Second * 20), + Expires: time.Now().Add(userLeaseDuration), }, Retry: retryutils.LinearConfig{ Step: time.Second * 5, @@ -556,26 +558,35 @@ func (u *HostUserManagement) DeleteAllUsers() error { return trace.Wrap(err) } var errs []error - for _, name := range users { - lt, err := u.storage.GetHostUserInteractionTime(u.ctx, name) - if err != nil { - u.log.DebugContext(u.ctx, "Failed to find user login time", "host_username", name, "error", err) - continue - } - u.doWithUserLock(func(l types.SemaphoreLease) error { + u.doWithUserLock(func(l types.SemaphoreLease) error { + for _, name := range users { + if time.Until(l.Expires) < userLeaseDuration/2 { + l.Expires = time.Now().Add(userLeaseDuration / 2) + if err := u.storage.KeepAliveSemaphoreLease(u.ctx, l); err != nil { + u.log.DebugContext(u.ctx, "Failed to keep alive host user lease", "error", err) + } + } + + lt, err := u.storage.GetHostUserInteractionTime(u.ctx, name) + if err != nil { + u.log.DebugContext(u.ctx, "Failed to find user login time", "host_username", name, "error", err) + continue + } + if time.Since(lt) < u.userGrace { // small grace period in order to avoid deleting users // in-between them starting their SSH session and // entering the shell - return nil + continue } - errs = append(errs, u.DeleteUser(name, teleportGroup.Gid)) - l.Expires = time.Now().Add(time.Second * 10) - u.storage.KeepAliveSemaphoreLease(u.ctx, l) - return nil - }) - } + if err := u.DeleteUser(name, teleportGroup.Gid); err != nil { + errs = append(errs, err) + } + } + + return nil + }) return trace.NewAggregate(errs...) } diff --git a/lib/teleterm/apiserver/handler/handler_apps.go b/lib/teleterm/apiserver/handler/handler_apps.go index feca01117fbbd..846369c8bda8b 100644 --- a/lib/teleterm/apiserver/handler/handler_apps.go +++ b/lib/teleterm/apiserver/handler/handler_apps.go @@ -38,6 +38,11 @@ func newAPIApp(clusterApp clusters.App) *api.App { apiLabels := makeAPILabels(ui.MakeLabelsWithoutInternalPrefixes(app.GetAllLabels())) + tcpPorts := make([]*api.PortRange, 0, len(app.GetTCPPorts())) + for _, portRange := range app.GetTCPPorts() { + tcpPorts = append(tcpPorts, &api.PortRange{Port: portRange.Port, EndPort: portRange.EndPort}) + } + return &api.App{ Uri: clusterApp.URI.String(), EndpointUri: app.GetURI(), @@ -50,6 +55,7 @@ func newAPIApp(clusterApp clusters.App) *api.App { FriendlyName: types.FriendlyName(app), SamlApp: false, Labels: apiLabels, + TcpPorts: tcpPorts, } } diff --git a/lib/teleterm/clusters/cluster.go b/lib/teleterm/clusters/cluster.go index 3924941cdac9a..3899dc64fadff 100644 --- a/lib/teleterm/clusters/cluster.go +++ b/lib/teleterm/clusters/cluster.go @@ -213,6 +213,7 @@ func (c *Cluster) GetWithDetails(ctx context.Context, authClient authclient.Clie Dbs: convertToAPIResourceAccess(userACL.DBServers), Kubeservers: convertToAPIResourceAccess(userACL.KubeServers), AccessRequests: convertToAPIResourceAccess(userACL.AccessRequests), + ReviewRequests: userACL.ReviewRequests, } withDetails := &ClusterWithDetails{ diff --git a/lib/teleterm/daemon/daemon.go b/lib/teleterm/daemon/daemon.go index 19724daceb6b3..13f12f4dfa253 100644 --- a/lib/teleterm/daemon/daemon.go +++ b/lib/teleterm/daemon/daemon.go @@ -1131,10 +1131,14 @@ func (s *Service) AuthenticateWebDevice(ctx context.Context, rootClusterURI uri. } devicesClient := proxyClient.CurrentCluster().DevicesClient() - ceremony := dtauthn.NewCeremony() - confirmationToken, err := ceremony.RunWeb(ctx, devicesClient, &devicepb.DeviceWebToken{ - Id: req.DeviceWebToken.Id, - Token: req.DeviceWebToken.Token, + var confirmationToken *devicepb.DeviceConfirmationToken + err = clusters.AddMetadataToRetryableError(ctx, func() error { + ceremony := dtauthn.NewCeremony() + confirmationToken, err = ceremony.RunWeb(ctx, devicesClient, &devicepb.DeviceWebToken{ + Id: req.DeviceWebToken.Id, + Token: req.DeviceWebToken.Token, + }) + return trace.Wrap(err) }) if err != nil { return nil, trace.Wrap(err) diff --git a/lib/teleterm/vnet/service.go b/lib/teleterm/vnet/service.go index e8bf7cf3be27f..f3c4364c5040e 100644 --- a/lib/teleterm/vnet/service.go +++ b/lib/teleterm/vnet/service.go @@ -379,12 +379,20 @@ func (p *appProvider) ReissueAppCert(ctx context.Context, profileName, leafClust clusterURI := uri.NewClusterURI(profileName).AppendLeafCluster(leafClusterName) appURI := clusterURI.AppendApp(routeToApp.Name) + apiteletermRouteToApp := apiteleterm.RouteToApp{ + Name: routeToApp.Name, + PublicAddr: routeToApp.PublicAddr, + ClusterName: routeToApp.ClusterName, + Uri: routeToApp.URI, + TargetPort: routeToApp.TargetPort, + } + reloginReq := &apiteleterm.ReloginRequest{ RootClusterUri: clusterURI.GetRootClusterURI().String(), Reason: &apiteleterm.ReloginRequest_VnetCertExpired{ VnetCertExpired: &apiteleterm.VnetCertExpired{ TargetUri: appURI.String(), - PublicAddr: routeToApp.GetPublicAddr(), + RouteToApp: &apiteletermRouteToApp, }, }, } @@ -411,7 +419,7 @@ func (p *appProvider) ReissueAppCert(ctx context.Context, profileName, leafClust Subject: &apiteleterm.SendNotificationRequest_CannotProxyVnetConnection{ CannotProxyVnetConnection: &apiteleterm.CannotProxyVnetConnection{ TargetUri: appURI.String(), - PublicAddr: routeToApp.PublicAddr, + RouteToApp: &apiteletermRouteToApp, Error: err.Error(), }, }, diff --git a/lib/utils/aws/migration/migration.go b/lib/utils/aws/migration/migration.go new file mode 100644 index 0000000000000..5288f2ab2a13c --- /dev/null +++ b/lib/utils/aws/migration/migration.go @@ -0,0 +1,92 @@ +/* + * Teleport + * Copyright (C) 2024 Gravitational, Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package migration + +import ( + "context" + "sync" + + awsv2 "github.com/aws/aws-sdk-go-v2/aws" + "github.com/aws/aws-sdk-go/aws/credentials" + "github.com/gravitational/trace" +) + +// NewProviderAdapter returns a [ProviderAdapter] that can be used as an AWS SDK +// v1 credentials provider. +func NewProviderAdapter(providerV2 awsv2.CredentialsProvider) *ProviderAdapter { + return &ProviderAdapter{ + providerV2: providerV2, + } +} + +var _ credentials.ProviderWithContext = (*ProviderAdapter)(nil) + +// ProviderAdapter adapts an [awsv2.CredentialsProvider] to an AWS SDK v1 +// credentials provider. +type ProviderAdapter struct { + providerV2 awsv2.CredentialsProvider + + m sync.RWMutex + // creds are retrieved and saved to satisfy IsExpired. + creds awsv2.Credentials +} + +func (a *ProviderAdapter) IsExpired() bool { + a.m.RLock() + defer a.m.RUnlock() + + var emptyCreds awsv2.Credentials + return a.creds == emptyCreds || a.creds.Expired() +} + +func (a *ProviderAdapter) Retrieve() (credentials.Value, error) { + return a.RetrieveWithContext(context.Background()) +} + +func (a *ProviderAdapter) RetrieveWithContext(ctx context.Context) (credentials.Value, error) { + creds, err := a.retrieveLocked(ctx) + if err != nil { + return credentials.Value{}, trace.Wrap(err) + } + + return credentials.Value{ + AccessKeyID: creds.AccessKeyID, + SecretAccessKey: creds.SecretAccessKey, + SessionToken: creds.SessionToken, + ProviderName: creds.Source, + }, nil +} + +func (a *ProviderAdapter) retrieveLocked(ctx context.Context) (awsv2.Credentials, error) { + a.m.Lock() + defer a.m.Unlock() + + var emptyCreds awsv2.Credentials + if a.creds != emptyCreds && !a.creds.Expired() { + return a.creds, nil + } + + creds, err := a.providerV2.Retrieve(ctx) + if err != nil { + return emptyCreds, trace.Wrap(err) + } + + a.creds = creds + return creds, nil +} diff --git a/lib/utils/errors.go b/lib/utils/errors.go index ed557b2168b76..14e56b188c418 100644 --- a/lib/utils/errors.go +++ b/lib/utils/errors.go @@ -19,6 +19,7 @@ package utils import ( + "context" "errors" "io" "net" @@ -86,6 +87,71 @@ func IsUntrustedCertErr(err error) bool { strings.Contains(errMsg, "certificate is not trusted") } +// CanExplainNetworkError returns a simple to understand error message that can +// be used to debug common network and/or protocol errors. +func CanExplainNetworkError(err error) (string, bool) { + var derr *net.DNSError + + switch { + // Connection refused errors can be reproduced by attempting to connect to a + // host:port that no process is listening on. The raw error typically looks + // like the following: + // + // dial tcp 127.0.0.1:8000: connect: connection refused + case errors.Is(err, syscall.ECONNREFUSED): + return `Connection Refused + +Teleport was unable to connect to the requested host, possibly because the server is not running. Ensure the server is running and listening on the correct port. + +Use "nc -vz HOST PORT" to help debug this issue.`, true + // Host unreachable errors can be reproduced by running + // "ip route add unreachable HOST" to update the routing table to make + // the host unreachable. Packets will be discarded and an ICMP message + // will be returned. The raw error typically looks like the following: + // + // dial tcp 10.10.10.10:8000: connect: no route to host + case errors.Is(err, syscall.EHOSTUNREACH): + return `No Route to Host + +Teleport could not connect to the requested host, likely because there is no valid network path to reach it. Check the network routing table to ensure a valid path to the host exists. + +Use "ping HOST" and "ip route get HOST" to help debug this issue.`, true + // Connection reset errors can be reproduced by creating a HTTP server that + // accepts requests but closes the connection before writing a response. The + // raw error typically looks like the following: + // + // read tcp 127.0.0.1:49764->127.0.0.1:8000: read: connection reset by peer + case errors.Is(err, syscall.ECONNRESET): + return `Connection Reset by Peer + +Teleport could not complete the request because the server abruptly closed the connection before the response was received. To resolve this issue, ensure the server (or load balancer) does not have a timeout terminating the connection early and verify that the server is not crash looping. + +Use protocol-specific tools (e.g., curl, psql) to help debug this issue.`, true + // Slow responses can be reprodued by creating a HTTP server that does a + // time.Sleep before responding. The raw error typically looks like the following: + // + // context deadline exceeded + case errors.Is(err, context.DeadlineExceeded): + return `Context Deadline Exceeded + +Teleport did not receive a response within the timeout period, likely due to the system being overloaded, network congestion, or a firewall blocking traffic. To resolve this issue, connect to the host directly and ensure it is responding promptly. + +Use protocol-specific tools (e.g., curl, psql) to assist in debugging this issue.`, true + // No such host errors can be reproduced by attempting to resolve a invalid + // domain name. The raw error typically looks like the following: + // + // dial tcp: lookup qweqweqwe.com: no such host + case errors.As(err, &derr) && derr.IsNotFound: + return `No Such Host + +Teleport was unable to resolve the provided domain name, likely because the domain does not exist. To resolve this issue, verify the domain is correct and ensure the DNS resolver is properly resolving it. + +Use "dig +short HOST" to help debug this issue.`, true + } + + return "", false +} + const ( // SelfSignedCertsMsg is a helper message to point users towards helpful documentation. SelfSignedCertsMsg = "Your proxy certificate is not trusted or expired. " + diff --git a/lib/utils/log/slog_handler.go b/lib/utils/log/slog_handler.go index b69b83d2a1adb..14363bca8584e 100644 --- a/lib/utils/log/slog_handler.go +++ b/lib/utils/log/slog_handler.go @@ -44,6 +44,17 @@ const TraceLevel = slog.LevelDebug - 1 // TraceLevelText is the text representation of Trace verbosity. const TraceLevelText = "TRACE" +// DiscardHandler is a [slog.Handler] that discards all messages. It +// is more efficient than a [slog.Handler] which outputs to [io.Discard] since +// it performs zero formatting. +// TODO(tross): Use slog.DiscardHandler once upgraded to Go 1.24. +type DiscardHandler struct{} + +func (dh DiscardHandler) Enabled(context.Context, slog.Level) bool { return false } +func (dh DiscardHandler) Handle(context.Context, slog.Record) error { return nil } +func (dh DiscardHandler) WithAttrs(attrs []slog.Attr) slog.Handler { return dh } +func (dh DiscardHandler) WithGroup(name string) slog.Handler { return dh } + // SlogTextHandler is a [slog.Handler] that outputs messages in a textual // manner as configured by the Teleport configuration. type SlogTextHandler struct { diff --git a/lib/web/apiserver.go b/lib/web/apiserver.go index fb8794c1272e6..d674d094248c8 100644 --- a/lib/web/apiserver.go +++ b/lib/web/apiserver.go @@ -151,13 +151,12 @@ type Handler struct { sync.Mutex httprouter.Router - cfg Config - auth *sessionCache - sessionStreamPollPeriod time.Duration - clock clockwork.Clock - limiter *limiter.RateLimiter - highLimiter *limiter.RateLimiter - healthCheckAppServer healthCheckAppServerFunc + cfg Config + auth *sessionCache + clock clockwork.Clock + limiter *limiter.RateLimiter + highLimiter *limiter.RateLimiter + healthCheckAppServer healthCheckAppServerFunc // sshPort specifies the SSH proxy port extracted // from configuration sshPort string @@ -175,32 +174,19 @@ type Handler struct { // tracer is used to create spans. tracer oteltrace.Tracer - // wsIODeadline is used to set a deadline for receiving a message from - // an authenticated websocket so unauthenticated sockets dont get left - // open. - wsIODeadline time.Duration - // findEndpointCache is used to cache the find endpoint answer. As this endpoint is unprotected and has high // rate-limits, each call must cause minimal work. The cached answer can be modulated after, for example if the // caller specified its Automatic Updates UUID or group. findEndpointCache *utils.FnCache + + // clusterMaintenanceConfig is used to cache the cluster maintenance config from the AUth Service. + clusterMaintenanceConfigCache *utils.FnCache } // HandlerOption is a functional argument - an option that can be passed // to NewHandler function type HandlerOption func(h *Handler) error -// SetSessionStreamPollPeriod sets polling period for session streams -func SetSessionStreamPollPeriod(period time.Duration) HandlerOption { - return func(h *Handler) error { - if period < 0 { - return trace.BadParameter("period should be non zero") - } - h.sessionStreamPollPeriod = period - return nil - } -} - // SetClock sets the clock on a handler func SetClock(clock clockwork.Clock) HandlerOption { return func(h *Handler) error { @@ -213,7 +199,7 @@ type ProxySettingsGetter interface { GetProxySettings(ctx context.Context) (*webclient.ProxySettings, error) } -// PresenceChecker is a function that executes an mfa prompt to enforce +// PresenceChecker is a function that executes an MFA prompt to enforce // that a user is present. type PresenceChecker = func(ctx context.Context, term io.Writer, maintainer client.PresenceMaintainer, sessionID string, mfaCeremony *mfa.Ceremony, opts ...client.PresenceOption) error @@ -226,8 +212,6 @@ type Config struct { Proxy reversetunnelclient.Tunnel // AuthServers is a list of auth servers this proxy talks to AuthServers utils.NetAddr - // DomainName is a domain name served by web handler - DomainName string // ProxyClient is a client that authenticated as proxy ProxyClient authclient.ClientI // ProxySSHAddr points to the SSH address of the proxy @@ -472,7 +456,6 @@ func NewHandler(cfg Config, opts ...HandlerOption) (*APIHandler, error) { clusterFeatures: cfg.ClusterFeatures, healthCheckAppServer: cfg.HealthCheckAppServer, tracer: cfg.TracerProvider.Tracer(teleport.ComponentWeb), - wsIODeadline: wsIODeadline, } if automaticUpgrades(cfg.ClusterFeatures) && h.cfg.AutomaticUpgradesChannels == nil { @@ -500,6 +483,18 @@ func NewHandler(cfg Config, opts ...HandlerOption) (*APIHandler, error) { } h.findEndpointCache = findCache + // We create the cache after applying the options to make sure we use the fake clock if it was passed. + cmcCache, err := utils.NewFnCache(utils.FnCacheConfig{ + TTL: findEndpointCacheTTL, + Clock: h.clock, + Context: cfg.Context, + ReloadOnErr: false, + }) + if err != nil { + return nil, trace.Wrap(err, "creating /find cache") + } + h.clusterMaintenanceConfigCache = cmcCache + sessionLingeringThreshold := cachedSessionLingeringThreshold if cfg.CachedSessionLingeringThreshold != nil { sessionLingeringThreshold = *cfg.CachedSessionLingeringThreshold @@ -977,6 +972,7 @@ func (h *Handler) bindDefaultEndpoints() { h.GET("/webapi/sites/:site/integrations/:name", h.WithClusterAuth(h.integrationsGet)) h.PUT("/webapi/sites/:site/integrations/:name", h.WithClusterAuth(h.integrationsUpdate)) h.GET("/webapi/sites/:site/integrations/:name/stats", h.WithClusterAuth(h.integrationStats)) + h.GET("/webapi/sites/:site/integrations/:name/discoveryrules", h.WithClusterAuth(h.integrationDiscoveryRules)) h.DELETE("/webapi/sites/:site/integrations/:name_or_subkind", h.WithClusterAuth(h.integrationsDelete)) // GET the Microsoft Teams plugin app.zip file. @@ -1246,7 +1242,7 @@ func (h *Handler) getUserContext(w http.ResponseWriter, r *http.Request, p httpr if err != nil { return nil, trace.Wrap(err) } - if !pingResp.LicenseExpiry.IsZero() { + if pingResp.LicenseExpiry != nil && !pingResp.LicenseExpiry.IsZero() { userContext.Cluster.LicenseExpiry = pingResp.LicenseExpiry } @@ -1547,6 +1543,8 @@ func (h *Handler) ping(w http.ResponseWriter, r *http.Request, p httprouter.Para return nil, trace.Wrap(err) } + group := r.URL.Query().Get(webclient.AgentUpdateGroupParameter) + return webclient.PingResponse{ Auth: authSettings, Proxy: *proxyConfig, @@ -1554,15 +1552,21 @@ func (h *Handler) ping(w http.ResponseWriter, r *http.Request, p httprouter.Para MinClientVersion: teleport.MinClientVersion, ClusterName: h.auth.clusterName, AutomaticUpgrades: pr.ServerFeatures.GetAutomaticUpgrades(), - AutoUpdate: h.automaticUpdateSettings184(r.Context()), + AutoUpdate: h.automaticUpdateSettings184(r.Context(), group, "" /* updater UUID */), Edition: modules.GetModules().BuildType(), FIPS: modules.IsBoringBinary(), }, nil } func (h *Handler) find(w http.ResponseWriter, r *http.Request, p httprouter.Params) (interface{}, error) { + group := r.URL.Query().Get(webclient.AgentUpdateGroupParameter) + cacheKey := "find" + if group != "" { + cacheKey += "-" + group + } + // cache the generic answer to avoid doing work for each request - resp, err := utils.FnCacheGet[*webclient.PingResponse](r.Context(), h.findEndpointCache, "find", func(ctx context.Context) (*webclient.PingResponse, error) { + resp, err := utils.FnCacheGet[*webclient.PingResponse](r.Context(), h.findEndpointCache, cacheKey, func(ctx context.Context) (*webclient.PingResponse, error) { proxyConfig, err := h.cfg.ProxySettings.GetProxySettings(ctx) if err != nil { return nil, trace.Wrap(err) @@ -1581,7 +1585,7 @@ func (h *Handler) find(w http.ResponseWriter, r *http.Request, p httprouter.Para ClusterName: h.auth.clusterName, Edition: modules.GetModules().BuildType(), FIPS: modules.IsBoringBinary(), - AutoUpdate: h.automaticUpdateSettings184(ctx), + AutoUpdate: h.automaticUpdateSettings184(ctx, group, "" /* updater UUID */), }, nil }) if err != nil { diff --git a/lib/web/apiserver_ping_test.go b/lib/web/apiserver_ping_test.go index 2bf325d4f7902..84e073ca7ae87 100644 --- a/lib/web/apiserver_ping_test.go +++ b/lib/web/apiserver_ping_test.go @@ -299,6 +299,7 @@ func TestPing_autoUpdateResources(t *testing.T) { name string config *autoupdatev1pb.AutoUpdateConfigSpec version *autoupdatev1pb.AutoUpdateVersionSpec + rollout *autoupdatev1pb.AutoUpdateAgentRolloutSpec cleanup bool expected webclient.AutoUpdateSettings }{ @@ -330,19 +331,12 @@ func TestPing_autoUpdateResources(t *testing.T) { }, { name: "enable agent auto update, immediate schedule", - config: &autoupdatev1pb.AutoUpdateConfigSpec{ - Agents: &autoupdatev1pb.AutoUpdateConfigSpecAgents{ - Mode: autoupdate.AgentsUpdateModeEnabled, - Strategy: autoupdate.AgentsStrategyHaltOnError, - }, - }, - version: &autoupdatev1pb.AutoUpdateVersionSpec{ - Agents: &autoupdatev1pb.AutoUpdateVersionSpecAgents{ - Mode: autoupdate.AgentsUpdateModeEnabled, - StartVersion: "1.2.3", - TargetVersion: "1.2.4", - Schedule: autoupdate.AgentsScheduleImmediate, - }, + rollout: &autoupdatev1pb.AutoUpdateAgentRolloutSpec{ + AutoupdateMode: autoupdate.AgentsUpdateModeEnabled, + Strategy: autoupdate.AgentsStrategyHaltOnError, + Schedule: autoupdate.AgentsScheduleImmediate, + StartVersion: "1.2.3", + TargetVersion: "1.2.4", }, expected: webclient.AutoUpdateSettings{ ToolsVersion: api.Version, @@ -354,20 +348,13 @@ func TestPing_autoUpdateResources(t *testing.T) { cleanup: true, }, { - name: "version enable agent auto update, but config disables them", - config: &autoupdatev1pb.AutoUpdateConfigSpec{ - Agents: &autoupdatev1pb.AutoUpdateConfigSpecAgents{ - Mode: autoupdate.AgentsUpdateModeDisabled, - Strategy: autoupdate.AgentsStrategyHaltOnError, - }, - }, - version: &autoupdatev1pb.AutoUpdateVersionSpec{ - Agents: &autoupdatev1pb.AutoUpdateVersionSpecAgents{ - Mode: autoupdate.AgentsUpdateModeEnabled, - StartVersion: "1.2.3", - TargetVersion: "1.2.4", - Schedule: autoupdate.AgentsScheduleImmediate, - }, + name: "agent rollout present but AU mode is disabled", + rollout: &autoupdatev1pb.AutoUpdateAgentRolloutSpec{ + AutoupdateMode: autoupdate.AgentsUpdateModeDisabled, + Strategy: autoupdate.AgentsStrategyHaltOnError, + Schedule: autoupdate.AgentsScheduleImmediate, + StartVersion: "1.2.3", + TargetVersion: "1.2.4", }, expected: webclient.AutoUpdateSettings{ ToolsVersion: api.Version, @@ -462,6 +449,12 @@ func TestPing_autoUpdateResources(t *testing.T) { _, err = env.server.Auth().UpsertAutoUpdateVersion(ctx, version) require.NoError(t, err) } + if tc.rollout != nil { + rollout, err := autoupdate.NewAutoUpdateAgentRollout(tc.rollout) + require.NoError(t, err) + _, err = env.server.Auth().UpsertAutoUpdateAgentRollout(ctx, rollout) + require.NoError(t, err) + } // expire the fn cache to force the next answer to be fresh for _, proxy := range env.proxies { @@ -480,6 +473,7 @@ func TestPing_autoUpdateResources(t *testing.T) { if tc.cleanup { require.NotErrorIs(t, env.server.Auth().DeleteAutoUpdateConfig(ctx), &trace.NotFoundError{}) require.NotErrorIs(t, env.server.Auth().DeleteAutoUpdateVersion(ctx), &trace.NotFoundError{}) + require.NotErrorIs(t, env.server.Auth().DeleteAutoUpdateAgentRollout(ctx), &trace.NotFoundError{}) } }) } diff --git a/lib/web/apiserver_test.go b/lib/web/apiserver_test.go index ff0f12fdc20cb..3a701fe65a26a 100644 --- a/lib/web/apiserver_test.go +++ b/lib/web/apiserver_test.go @@ -482,7 +482,6 @@ func newWebSuiteWithConfig(t *testing.T, cfg webSuiteConfig) *WebSuite { ClusterFeatures: features, Proxy: revTunServer, AuthServers: utils.FromAddr(s.server.TLS.Addr()), - DomainName: s.server.ClusterName(), ProxyClient: s.proxyClient, CipherSuites: utils.DefaultCipherSuites(), AccessPoint: s.proxyClient, @@ -515,7 +514,7 @@ func newWebSuiteWithConfig(t *testing.T, cfg webSuiteConfig) *WebSuite { handlerConfig.HealthCheckAppServer = func(context.Context, string, string) error { return nil } } - handler, err := NewHandler(handlerConfig, SetSessionStreamPollPeriod(200*time.Millisecond), SetClock(s.clock)) + handler, err := NewHandler(handlerConfig, SetClock(s.clock)) require.NoError(t, err) s.webServer = httptest.NewUnstartedServer(handler) @@ -8303,7 +8302,7 @@ func createProxy(ctx context.Context, t *testing.T, proxyID string, node *regula ServerID: proxyID, Emitter: client, EmitterContext: ctx, - Logger: log, + Logger: utils.NewSlogLoggerForTests(), }) require.NoError(t, err) @@ -8364,7 +8363,6 @@ func createProxy(ctx context.Context, t *testing.T, proxyID string, node *regula handler, err := NewHandler(Config{ Proxy: revTunServer, AuthServers: utils.FromAddr(authServer.Addr()), - DomainName: authServer.ClusterName(), ProxyClient: client, ProxyPublicAddrs: utils.MustParseAddrList("proxy-1.example.com", "proxy-2.example.com"), CipherSuites: utils.DefaultCipherSuites(), @@ -8390,7 +8388,7 @@ func createProxy(ctx context.Context, t *testing.T, proxyID string, node *regula return &proxyClientCert, nil }, IntegrationAppHandler: &mockIntegrationAppHandler{}, - }, SetSessionStreamPollPeriod(200*time.Millisecond), SetClock(clock)) + }, SetClock(clock)) require.NoError(t, err) webServer := httptest.NewTLSServer(handler) @@ -9643,7 +9641,6 @@ func TestWebSocketAuthenticateRequest(t *testing.T) { ctx := context.Background() env := newWebPack(t, 1) proxy := env.proxies[0] - proxy.handler.handler.wsIODeadline = time.Second pack := proxy.authPack(t, "test-user@example.com", nil) for _, tc := range []struct { name string diff --git a/lib/web/autoupdate_common.go b/lib/web/autoupdate_common.go new file mode 100644 index 0000000000000..1756172f4c6e4 --- /dev/null +++ b/lib/web/autoupdate_common.go @@ -0,0 +1,228 @@ +/* + * Teleport + * Copyright (C) 2024 Gravitational, Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package web + +import ( + "context" + "strings" + + "github.com/gravitational/trace" + + autoupdatepb "github.com/gravitational/teleport/api/gen/proto/go/teleport/autoupdate/v1" + "github.com/gravitational/teleport/api/types" + "github.com/gravitational/teleport/api/types/autoupdate" + "github.com/gravitational/teleport/lib/automaticupgrades" + "github.com/gravitational/teleport/lib/utils" +) + +// autoUpdateAgentVersion returns the version the agent should install/update to based on +// its group and updater UUID. +// If the cluster contains an autoupdate_agent_rollout resource from RFD184 it should take precedence. +// If the resource is not there, we fall back to RFD109-style updates with channels +// and maintenance window derived from the cluster_maintenance_config resource. +// Version returned follows semver without the leading "v". +func (h *Handler) autoUpdateAgentVersion(ctx context.Context, group, updaterUUID string) (string, error) { + rollout, err := h.cfg.AccessPoint.GetAutoUpdateAgentRollout(ctx) + if err != nil { + // Fallback to channels if there is no autoupdate_agent_rollout. + if trace.IsNotFound(err) { + return getVersionFromChannel(ctx, h.cfg.AutomaticUpgradesChannels, group) + } + // Something is broken, we don't want to fallback to channels, this would be harmful. + return "", trace.Wrap(err, "getting autoupdate_agent_rollout") + } + + return getVersionFromRollout(rollout, group, updaterUUID) +} + +// autoUpdateAgentShouldUpdate returns if the agent should update now to based on its group +// and updater UUID. +// If the cluster contains an autoupdate_agent_rollout resource from RFD184 it should take precedence. +// If the resource is not there, we fall back to RFD109-style updates with channels +// and maintenance window derived from the cluster_maintenance_config resource. +func (h *Handler) autoUpdateAgentShouldUpdate(ctx context.Context, group, updaterUUID string, windowLookup bool) (bool, error) { + rollout, err := h.cfg.AccessPoint.GetAutoUpdateAgentRollout(ctx) + if err != nil { + // Fallback to channels if there is no autoupdate_agent_rollout. + if trace.IsNotFound(err) { + // Updaters using the RFD184 API are not aware of maintenance windows + // like RFD109 updaters are. To have both updaters adopt the same behavior + // we must do the CMC window lookup for them. + if windowLookup { + return h.getTriggerFromWindowThenChannel(ctx, group) + } + return getTriggerFromChannel(ctx, h.cfg.AutomaticUpgradesChannels, group) + } + // Something is broken, we don't want to fallback to channels, this would be harmful. + return false, trace.Wrap(err, "failed to get auto-update rollout") + } + + return getTriggerFromRollout(rollout, group, updaterUUID) +} + +// getVersionFromRollout returns the version we should serve to the agent based +// on the RFD184 agent rollout, the agent group name, and its UUID. +// This logic is pretty complex and described in RFD 184. +// The spec is summed up in the following table: +// https://github.com/gravitational/teleport/blob/master/rfd/0184-agent-auto-updates.md#rollout-status-disabled +// Version returned follows semver without the leading "v". +func getVersionFromRollout( + rollout *autoupdatepb.AutoUpdateAgentRollout, + groupName, updaterUUID string, +) (string, error) { + switch rollout.GetSpec().GetAutoupdateMode() { + case autoupdate.AgentsUpdateModeDisabled: + // If AUs are disabled, we always answer the target version + return rollout.GetSpec().GetTargetVersion(), nil + case autoupdate.AgentsUpdateModeSuspended, autoupdate.AgentsUpdateModeEnabled: + // If AUs are enabled or suspended, we modulate the response based on the schedule and agent group state + default: + return "", trace.BadParameter("unsupported agent update mode %q", rollout.GetSpec().GetAutoupdateMode()) + } + + // If the schedule is immediate, agents always update to the latest version + if rollout.GetSpec().GetSchedule() == autoupdate.AgentsScheduleImmediate { + return rollout.GetSpec().GetTargetVersion(), nil + } + + // Else we follow the regular schedule and answer based on the agent group state + group, err := getGroup(rollout, groupName) + if err != nil { + return "", trace.Wrap(err, "getting group %q", groupName) + } + + switch group.GetState() { + case autoupdatepb.AutoUpdateAgentGroupState_AUTO_UPDATE_AGENT_GROUP_STATE_UNSTARTED, + autoupdatepb.AutoUpdateAgentGroupState_AUTO_UPDATE_AGENT_GROUP_STATE_ROLLEDBACK: + return rollout.GetSpec().GetStartVersion(), nil + case autoupdatepb.AutoUpdateAgentGroupState_AUTO_UPDATE_AGENT_GROUP_STATE_ACTIVE, + autoupdatepb.AutoUpdateAgentGroupState_AUTO_UPDATE_AGENT_GROUP_STATE_DONE: + return rollout.GetSpec().GetTargetVersion(), nil + default: + return "", trace.NotImplemented("unsupported group state %q", group.GetState()) + } +} + +// getTriggerFromRollout returns the version we should serve to the agent based +// on the RFD184 agent rollout, the agent group name, and its UUID. +// This logic is pretty complex and described in RFD 184. +// The spec is summed up in the following table: +// https://github.com/gravitational/teleport/blob/master/rfd/0184-agent-auto-updates.md#rollout-status-disabled +func getTriggerFromRollout(rollout *autoupdatepb.AutoUpdateAgentRollout, groupName, updaterUUID string) (bool, error) { + // If the mode is "paused" or "disabled", we never tell to update + switch rollout.GetSpec().GetAutoupdateMode() { + case autoupdate.AgentsUpdateModeDisabled, autoupdate.AgentsUpdateModeSuspended: + // If AUs are disabled or suspended, never tell to update + return false, nil + case autoupdate.AgentsUpdateModeEnabled: + // If AUs are enabled, we modulate the response based on the schedule and agent group state + default: + return false, trace.BadParameter("unsupported agent update mode %q", rollout.GetSpec().GetAutoupdateMode()) + } + + // If the schedule is immediate, agents always update to the latest version + if rollout.GetSpec().GetSchedule() == autoupdate.AgentsScheduleImmediate { + return true, nil + } + + // Else we follow the regular schedule and answer based on the agent group state + group, err := getGroup(rollout, groupName) + if err != nil { + return false, trace.Wrap(err, "getting group %q", groupName) + } + + switch group.GetState() { + case autoupdatepb.AutoUpdateAgentGroupState_AUTO_UPDATE_AGENT_GROUP_STATE_UNSTARTED: + return false, nil + case autoupdatepb.AutoUpdateAgentGroupState_AUTO_UPDATE_AGENT_GROUP_STATE_ACTIVE, + autoupdatepb.AutoUpdateAgentGroupState_AUTO_UPDATE_AGENT_GROUP_STATE_ROLLEDBACK: + return true, nil + case autoupdatepb.AutoUpdateAgentGroupState_AUTO_UPDATE_AGENT_GROUP_STATE_DONE: + return rollout.GetSpec().GetStrategy() == autoupdate.AgentsStrategyHaltOnError, nil + default: + return false, trace.NotImplemented("Unsupported group state %q", group.GetState()) + } +} + +// getGroup returns the agent rollout group the requesting agent belongs to. +// If a group matches the agent-provided group name, this group is returned. +// Else the default group is returned. The default group currently is the last +// one. This might change in the future. +func getGroup( + rollout *autoupdatepb.AutoUpdateAgentRollout, + groupName string, +) (*autoupdatepb.AutoUpdateAgentRolloutStatusGroup, error) { + groups := rollout.GetStatus().GetGroups() + if len(groups) == 0 { + return nil, trace.BadParameter("no groups found") + } + + // Try to find a group with our name + for _, group := range groups { + if group.Name == groupName { + return group, nil + } + } + + // Fallback to the default group (currently the last one but this might change). + return groups[len(groups)-1], nil +} + +// getVersionFromChannel gets the target version from the RFD109 channels. +// Version returned follows semver without the leading "v". +func getVersionFromChannel(ctx context.Context, channels automaticupgrades.Channels, groupName string) (version string, err error) { + // RFD109 channels return the version with the 'v' prefix. + // We can't change the internals for backward compatibility, so we must trim the prefix if it's here. + defer func() { + version = strings.TrimPrefix(version, "v") + }() + + if channel, ok := channels[groupName]; ok { + return channel.GetVersion(ctx) + } + return channels.DefaultVersion(ctx) +} + +// getTriggerFromWindowThenChannel gets the target version from the RFD109 maintenance window and channels. +func (h *Handler) getTriggerFromWindowThenChannel(ctx context.Context, groupName string) (bool, error) { + // Caching the CMC for 10 seconds because this resource is cached neither by the auth nor the proxy. + // And this function can be accessed via unauthenticated endpoints. + cmc, err := utils.FnCacheGet[types.ClusterMaintenanceConfig](ctx, h.clusterMaintenanceConfigCache, "cmc", func(ctx context.Context) (types.ClusterMaintenanceConfig, error) { + return h.cfg.ProxyClient.GetClusterMaintenanceConfig(ctx) + }) + + // If we have a CMC, we check if the window is active, else we just check if the update is critical. + if err == nil && cmc.WithinUpgradeWindow(h.clock.Now()) { + return true, nil + } + + return getTriggerFromChannel(ctx, h.cfg.AutomaticUpgradesChannels, groupName) +} + +// getTriggerFromWindowThenChannel gets the target version from the RFD109 channels. +func getTriggerFromChannel(ctx context.Context, channels automaticupgrades.Channels, groupName string) (bool, error) { + if channel, ok := channels[groupName]; ok { + return channel.GetCritical(ctx) + } + defaultChannel, err := channels.DefaultChannel() + if err != nil { + return false, trace.Wrap(err, "creating new default channel") + } + return defaultChannel.GetCritical(ctx) +} diff --git a/lib/web/autoupdate_common_test.go b/lib/web/autoupdate_common_test.go new file mode 100644 index 0000000000000..e0a1a31719586 --- /dev/null +++ b/lib/web/autoupdate_common_test.go @@ -0,0 +1,799 @@ +/* + * Teleport + * Copyright (C) 2024 Gravitational, Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package web + +import ( + "context" + "fmt" + "net/http" + "net/http/httptest" + "strings" + "testing" + "time" + + "github.com/gravitational/trace" + "github.com/jonboulle/clockwork" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + autoupdatepb "github.com/gravitational/teleport/api/gen/proto/go/teleport/autoupdate/v1" + "github.com/gravitational/teleport/api/types" + "github.com/gravitational/teleport/api/types/autoupdate" + "github.com/gravitational/teleport/lib/auth/authclient" + "github.com/gravitational/teleport/lib/automaticupgrades" + "github.com/gravitational/teleport/lib/automaticupgrades/constants" + "github.com/gravitational/teleport/lib/utils" +) + +const ( + testVersionHigh = "2.3.4" + testVersionLow = "2.0.4" +) + +// fakeRolloutAccessPoint allows us to mock the ProxyAccessPoint in autoupdate +// tests. +type fakeRolloutAccessPoint struct { + authclient.ProxyAccessPoint + + rollout *autoupdatepb.AutoUpdateAgentRollout + err error +} + +func (ap *fakeRolloutAccessPoint) GetAutoUpdateAgentRollout(_ context.Context) (*autoupdatepb.AutoUpdateAgentRollout, error) { + return ap.rollout, ap.err +} + +// fakeRolloutAccessPoint allows us to mock the proxy's auth client in autoupdate +// tests. +type fakeCMCAuthClient struct { + authclient.ClientI + + cmc types.ClusterMaintenanceConfig + err error +} + +func (c *fakeCMCAuthClient) GetClusterMaintenanceConfig(_ context.Context) (types.ClusterMaintenanceConfig, error) { + return c.cmc, c.err +} + +func TestAutoUpdateAgentVersion(t *testing.T) { + t.Parallel() + groupName := "test-group" + ctx := context.Background() + + // brokenChannelUpstream is a buggy upstream version server. + // This allows us to craft version channels returning errors. + brokenChannelUpstream := httptest.NewServer( + http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.WriteHeader(http.StatusBadRequest) + })) + t.Cleanup(brokenChannelUpstream.Close) + + tests := []struct { + name string + rollout *autoupdatepb.AutoUpdateAgentRollout + rolloutErr error + channel *automaticupgrades.Channel + expectedVersion string + expectError require.ErrorAssertionFunc + }{ + { + name: "version is looked up from rollout if it is here", + rollout: &autoupdatepb.AutoUpdateAgentRollout{ + Spec: &autoupdatepb.AutoUpdateAgentRolloutSpec{ + AutoupdateMode: autoupdate.AgentsUpdateModeEnabled, + TargetVersion: testVersionHigh, + Schedule: autoupdate.AgentsScheduleImmediate, + }, + }, + channel: &automaticupgrades.Channel{StaticVersion: testVersionLow}, + expectError: require.NoError, + expectedVersion: testVersionHigh, + }, + { + name: "version is looked up from channel if rollout is not here", + rolloutErr: trace.NotFound("rollout is not here"), + channel: &automaticupgrades.Channel{StaticVersion: testVersionLow}, + expectError: require.NoError, + expectedVersion: testVersionLow, + }, + { + name: "hard error getting rollout should not fallback to version channels", + rolloutErr: trace.AccessDenied("something is very broken"), + channel: &automaticupgrades.Channel{ + StaticVersion: testVersionLow, + }, + expectError: require.Error, + }, + { + name: "no rollout, error checking channel", + rolloutErr: trace.NotFound("rollout is not here"), + channel: &automaticupgrades.Channel{ForwardURL: brokenChannelUpstream.URL}, + expectError: require.Error, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + // Test setup: building the channel, mock client, and handler with test config. + require.NoError(t, tt.channel.CheckAndSetDefaults()) + h := &Handler{ + cfg: Config{ + AccessPoint: &fakeRolloutAccessPoint{ + rollout: tt.rollout, + err: tt.rolloutErr, + }, + AutomaticUpgradesChannels: map[string]*automaticupgrades.Channel{ + groupName: tt.channel, + }, + }, + } + + // Test execution + result, err := h.autoUpdateAgentVersion(ctx, groupName, "") + tt.expectError(t, err) + require.Equal(t, tt.expectedVersion, result) + }) + } +} + +// TestAutoUpdateAgentShouldUpdate also accidentally tests getTriggerFromWindowThenChannel. +func TestAutoUpdateAgentShouldUpdate(t *testing.T) { + t.Parallel() + + groupName := "test-group" + ctx := context.Background() + + // brokenChannelUpstream is a buggy upstream version server. + // This allows us to craft version channels returning errors. + brokenChannelUpstream := httptest.NewServer( + http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.WriteHeader(http.StatusBadRequest) + })) + t.Cleanup(brokenChannelUpstream.Close) + + cacheClock := clockwork.NewFakeClock() + cmcCache, err := utils.NewFnCache(utils.FnCacheConfig{ + TTL: findEndpointCacheTTL, + Clock: cacheClock, + Context: ctx, + ReloadOnErr: false, + }) + require.NoError(t, err) + t.Cleanup(func() { + cmcCache.Shutdown(ctx) + }) + + // We don't use the cache clock because we are advancing it to invalidate the cmc cache and + // this would interfere with the test logic + clock := clockwork.NewFakeClock() + activeUpgradeWindow := types.AgentUpgradeWindow{UTCStartHour: uint32(clock.Now().Hour())} + inactiveUpgradeWindow := types.AgentUpgradeWindow{UTCStartHour: uint32(clock.Now().Add(2 * time.Hour).Hour())} + tests := []struct { + name string + rollout *autoupdatepb.AutoUpdateAgentRollout + rolloutErr error + channel *automaticupgrades.Channel + upgradeWindow types.AgentUpgradeWindow + cmcErr error + windowLookup bool + expectedTrigger bool + expectError require.ErrorAssertionFunc + }{ + { + name: "trigger is looked up from rollout if it is here, trigger firing", + rollout: &autoupdatepb.AutoUpdateAgentRollout{ + Spec: &autoupdatepb.AutoUpdateAgentRolloutSpec{ + AutoupdateMode: autoupdate.AgentsUpdateModeEnabled, + TargetVersion: testVersionHigh, + Schedule: autoupdate.AgentsScheduleImmediate, + }, + }, + channel: &automaticupgrades.Channel{StaticVersion: testVersionLow}, + expectError: require.NoError, + expectedTrigger: true, + }, + { + name: "trigger is looked up from rollout if it is here, trigger not firing", + rollout: &autoupdatepb.AutoUpdateAgentRollout{ + Spec: &autoupdatepb.AutoUpdateAgentRolloutSpec{ + AutoupdateMode: autoupdate.AgentsUpdateModeDisabled, + TargetVersion: testVersionHigh, + Schedule: autoupdate.AgentsScheduleImmediate, + }, + }, + channel: &automaticupgrades.Channel{StaticVersion: testVersionLow}, + expectError: require.NoError, + expectedTrigger: false, + }, + { + name: "trigger is looked up from channel if rollout is not here and window lookup is disabled, trigger not firing", + rolloutErr: trace.NotFound("rollout is not here"), + channel: &automaticupgrades.Channel{ + StaticVersion: testVersionLow, + Critical: false, + }, + expectError: require.NoError, + expectedTrigger: false, + }, + { + name: "trigger is looked up from channel if rollout is not here and window lookup is disabled, trigger firing", + rolloutErr: trace.NotFound("rollout is not here"), + channel: &automaticupgrades.Channel{ + StaticVersion: testVersionLow, + Critical: true, + }, + expectError: require.NoError, + expectedTrigger: true, + }, + { + name: "trigger is looked up from cmc, then channel if rollout is not here and window lookup is enabled, cmc firing", + rolloutErr: trace.NotFound("rollout is not here"), + channel: &automaticupgrades.Channel{ + StaticVersion: testVersionLow, + Critical: false, + }, + upgradeWindow: activeUpgradeWindow, + windowLookup: true, + expectError: require.NoError, + expectedTrigger: true, + }, + { + name: "trigger is looked up from cmc, then channel if rollout is not here and window lookup is enabled, cmc not firing", + rolloutErr: trace.NotFound("rollout is not here"), + channel: &automaticupgrades.Channel{ + StaticVersion: testVersionLow, + Critical: false, + }, + upgradeWindow: inactiveUpgradeWindow, + windowLookup: true, + expectError: require.NoError, + expectedTrigger: false, + }, + { + name: "trigger is looked up from cmc, then channel if rollout is not here and window lookup is enabled, cmc not firing but channel firing", + rolloutErr: trace.NotFound("rollout is not here"), + channel: &automaticupgrades.Channel{ + StaticVersion: testVersionLow, + Critical: true, + }, + upgradeWindow: inactiveUpgradeWindow, + windowLookup: true, + expectError: require.NoError, + expectedTrigger: true, + }, + { + name: "trigger is looked up from cmc, then channel if rollout is not here and window lookup is enabled, no cmc and channel not firing", + rolloutErr: trace.NotFound("rollout is not here"), + channel: &automaticupgrades.Channel{ + StaticVersion: testVersionLow, + Critical: false, + }, + cmcErr: trace.NotFound("no cmc for this cluster"), + windowLookup: true, + expectError: require.NoError, + expectedTrigger: false, + }, + { + name: "trigger is looked up from cmc, then channel if rollout is not here and window lookup is enabled, no cmc and channel firing", + rolloutErr: trace.NotFound("rollout is not here"), + channel: &automaticupgrades.Channel{ + StaticVersion: testVersionLow, + Critical: true, + }, + cmcErr: trace.NotFound("no cmc for this cluster"), + windowLookup: true, + expectError: require.NoError, + expectedTrigger: true, + }, + { + name: "hard error getting rollout should not fallback to RFD109 trigger", + rolloutErr: trace.AccessDenied("something is very broken"), + channel: &automaticupgrades.Channel{ + StaticVersion: testVersionLow, + }, + expectError: require.Error, + }, + { + name: "no rollout, error checking channel", + rolloutErr: trace.NotFound("rollout is not here"), + channel: &automaticupgrades.Channel{ + ForwardURL: brokenChannelUpstream.URL, + }, + expectError: require.Error, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + // Test setup: building the channel, mock clients, and handler with test config. + cmc := types.NewClusterMaintenanceConfig() + cmc.SetAgentUpgradeWindow(tt.upgradeWindow) + require.NoError(t, tt.channel.CheckAndSetDefaults()) + // Advance cache clock to expire cached cmc + cacheClock.Advance(2 * findEndpointCacheTTL) + h := &Handler{ + cfg: Config{ + AccessPoint: &fakeRolloutAccessPoint{ + rollout: tt.rollout, + err: tt.rolloutErr, + }, + ProxyClient: &fakeCMCAuthClient{ + cmc: cmc, + err: tt.cmcErr, + }, + AutomaticUpgradesChannels: map[string]*automaticupgrades.Channel{ + groupName: tt.channel, + }, + }, + clock: clock, + clusterMaintenanceConfigCache: cmcCache, + } + + // Test execution + result, err := h.autoUpdateAgentShouldUpdate(ctx, groupName, "", tt.windowLookup) + tt.expectError(t, err) + require.Equal(t, tt.expectedTrigger, result) + }) + } +} + +func TestGetVersionFromRollout(t *testing.T) { + t.Parallel() + groupName := "test-group" + + // This test matrix is written based on: + // https://github.com/gravitational/teleport/blob/master/rfd/0184-agent-auto-updates.md#rollout-status-disabled + latestAllTheTime := map[autoupdatepb.AutoUpdateAgentGroupState]string{ + autoupdatepb.AutoUpdateAgentGroupState_AUTO_UPDATE_AGENT_GROUP_STATE_UNSTARTED: testVersionHigh, + autoupdatepb.AutoUpdateAgentGroupState_AUTO_UPDATE_AGENT_GROUP_STATE_DONE: testVersionHigh, + autoupdatepb.AutoUpdateAgentGroupState_AUTO_UPDATE_AGENT_GROUP_STATE_ACTIVE: testVersionHigh, + autoupdatepb.AutoUpdateAgentGroupState_AUTO_UPDATE_AGENT_GROUP_STATE_ROLLEDBACK: testVersionHigh, + } + + activeDoneOnly := map[autoupdatepb.AutoUpdateAgentGroupState]string{ + autoupdatepb.AutoUpdateAgentGroupState_AUTO_UPDATE_AGENT_GROUP_STATE_UNSTARTED: testVersionLow, + autoupdatepb.AutoUpdateAgentGroupState_AUTO_UPDATE_AGENT_GROUP_STATE_DONE: testVersionHigh, + autoupdatepb.AutoUpdateAgentGroupState_AUTO_UPDATE_AGENT_GROUP_STATE_ACTIVE: testVersionHigh, + autoupdatepb.AutoUpdateAgentGroupState_AUTO_UPDATE_AGENT_GROUP_STATE_ROLLEDBACK: testVersionLow, + } + + tests := map[string]map[string]map[autoupdatepb.AutoUpdateAgentGroupState]string{ + autoupdate.AgentsUpdateModeDisabled: { + autoupdate.AgentsScheduleImmediate: latestAllTheTime, + autoupdate.AgentsScheduleRegular: latestAllTheTime, + }, + autoupdate.AgentsUpdateModeSuspended: { + autoupdate.AgentsScheduleImmediate: latestAllTheTime, + autoupdate.AgentsScheduleRegular: activeDoneOnly, + }, + autoupdate.AgentsUpdateModeEnabled: { + autoupdate.AgentsScheduleImmediate: latestAllTheTime, + autoupdate.AgentsScheduleRegular: activeDoneOnly, + }, + } + for mode, scheduleCases := range tests { + for schedule, stateCases := range scheduleCases { + for state, expectedVersion := range stateCases { + t.Run(fmt.Sprintf("%s/%s/%s", mode, schedule, state), func(t *testing.T) { + rollout := &autoupdatepb.AutoUpdateAgentRollout{ + Spec: &autoupdatepb.AutoUpdateAgentRolloutSpec{ + StartVersion: testVersionLow, + TargetVersion: testVersionHigh, + Schedule: schedule, + AutoupdateMode: mode, + // Strategy does not affect which version are served + Strategy: autoupdate.AgentsStrategyTimeBased, + }, + Status: &autoupdatepb.AutoUpdateAgentRolloutStatus{ + Groups: []*autoupdatepb.AutoUpdateAgentRolloutStatusGroup{ + { + Name: groupName, + State: state, + }, + }, + }, + } + version, err := getVersionFromRollout(rollout, groupName, "") + require.NoError(t, err) + require.Equal(t, expectedVersion, version) + }) + } + } + } +} + +func TestGetTriggerFromRollout(t *testing.T) { + t.Parallel() + groupName := "test-group" + + // This test matrix is written based on: + // https://github.com/gravitational/teleport/blob/master/rfd/0184-agent-auto-updates.md#rollout-status-disabled + neverUpdate := map[autoupdatepb.AutoUpdateAgentGroupState]bool{ + autoupdatepb.AutoUpdateAgentGroupState_AUTO_UPDATE_AGENT_GROUP_STATE_UNSTARTED: false, + autoupdatepb.AutoUpdateAgentGroupState_AUTO_UPDATE_AGENT_GROUP_STATE_DONE: false, + autoupdatepb.AutoUpdateAgentGroupState_AUTO_UPDATE_AGENT_GROUP_STATE_ACTIVE: false, + autoupdatepb.AutoUpdateAgentGroupState_AUTO_UPDATE_AGENT_GROUP_STATE_ROLLEDBACK: false, + } + alwaysUpdate := map[autoupdatepb.AutoUpdateAgentGroupState]bool{ + autoupdatepb.AutoUpdateAgentGroupState_AUTO_UPDATE_AGENT_GROUP_STATE_UNSTARTED: true, + autoupdatepb.AutoUpdateAgentGroupState_AUTO_UPDATE_AGENT_GROUP_STATE_DONE: true, + autoupdatepb.AutoUpdateAgentGroupState_AUTO_UPDATE_AGENT_GROUP_STATE_ACTIVE: true, + autoupdatepb.AutoUpdateAgentGroupState_AUTO_UPDATE_AGENT_GROUP_STATE_ROLLEDBACK: true, + } + + tests := map[string]map[string]map[string]map[autoupdatepb.AutoUpdateAgentGroupState]bool{ + autoupdate.AgentsUpdateModeDisabled: { + autoupdate.AgentsStrategyTimeBased: { + autoupdate.AgentsScheduleImmediate: neverUpdate, + autoupdate.AgentsScheduleRegular: neverUpdate, + }, + autoupdate.AgentsStrategyHaltOnError: { + autoupdate.AgentsScheduleImmediate: neverUpdate, + autoupdate.AgentsScheduleRegular: neverUpdate, + }, + }, + autoupdate.AgentsUpdateModeSuspended: { + autoupdate.AgentsStrategyTimeBased: { + autoupdate.AgentsScheduleImmediate: neverUpdate, + autoupdate.AgentsScheduleRegular: neverUpdate, + }, + autoupdate.AgentsStrategyHaltOnError: { + autoupdate.AgentsScheduleImmediate: neverUpdate, + autoupdate.AgentsScheduleRegular: neverUpdate, + }, + }, + autoupdate.AgentsUpdateModeEnabled: { + autoupdate.AgentsStrategyTimeBased: { + autoupdate.AgentsScheduleImmediate: alwaysUpdate, + autoupdate.AgentsScheduleRegular: { + autoupdatepb.AutoUpdateAgentGroupState_AUTO_UPDATE_AGENT_GROUP_STATE_UNSTARTED: false, + autoupdatepb.AutoUpdateAgentGroupState_AUTO_UPDATE_AGENT_GROUP_STATE_DONE: false, + autoupdatepb.AutoUpdateAgentGroupState_AUTO_UPDATE_AGENT_GROUP_STATE_ACTIVE: true, + autoupdatepb.AutoUpdateAgentGroupState_AUTO_UPDATE_AGENT_GROUP_STATE_ROLLEDBACK: true, + }, + }, + autoupdate.AgentsStrategyHaltOnError: { + autoupdate.AgentsScheduleImmediate: alwaysUpdate, + autoupdate.AgentsScheduleRegular: { + autoupdatepb.AutoUpdateAgentGroupState_AUTO_UPDATE_AGENT_GROUP_STATE_UNSTARTED: false, + autoupdatepb.AutoUpdateAgentGroupState_AUTO_UPDATE_AGENT_GROUP_STATE_DONE: true, + autoupdatepb.AutoUpdateAgentGroupState_AUTO_UPDATE_AGENT_GROUP_STATE_ACTIVE: true, + autoupdatepb.AutoUpdateAgentGroupState_AUTO_UPDATE_AGENT_GROUP_STATE_ROLLEDBACK: true, + }, + }, + }, + } + for mode, strategyCases := range tests { + for strategy, scheduleCases := range strategyCases { + for schedule, stateCases := range scheduleCases { + for state, expectedTrigger := range stateCases { + t.Run(fmt.Sprintf("%s/%s/%s/%s", mode, strategy, schedule, state), func(t *testing.T) { + rollout := &autoupdatepb.AutoUpdateAgentRollout{ + Spec: &autoupdatepb.AutoUpdateAgentRolloutSpec{ + StartVersion: testVersionLow, + TargetVersion: testVersionHigh, + Schedule: schedule, + AutoupdateMode: mode, + Strategy: strategy, + }, + Status: &autoupdatepb.AutoUpdateAgentRolloutStatus{ + Groups: []*autoupdatepb.AutoUpdateAgentRolloutStatusGroup{ + { + Name: groupName, + State: state, + }, + }, + }, + } + shouldUpdate, err := getTriggerFromRollout(rollout, groupName, "") + require.NoError(t, err) + require.Equal(t, expectedTrigger, shouldUpdate) + }) + } + } + } + } +} + +func TestGetGroup(t *testing.T) { + groupName := "test-group" + t.Parallel() + tests := []struct { + name string + rollout *autoupdatepb.AutoUpdateAgentRollout + expectedResult *autoupdatepb.AutoUpdateAgentRolloutStatusGroup + expectError require.ErrorAssertionFunc + }{ + { + name: "nil", + expectError: require.Error, + }, + { + name: "nil status", + rollout: &autoupdatepb.AutoUpdateAgentRollout{}, + expectError: require.Error, + }, + { + name: "nil status groups", + rollout: &autoupdatepb.AutoUpdateAgentRollout{Status: &autoupdatepb.AutoUpdateAgentRolloutStatus{}}, + expectError: require.Error, + }, + { + name: "empty status groups", + rollout: &autoupdatepb.AutoUpdateAgentRollout{ + Status: &autoupdatepb.AutoUpdateAgentRolloutStatus{ + Groups: []*autoupdatepb.AutoUpdateAgentRolloutStatusGroup{}, + }, + }, + expectError: require.Error, + }, + { + name: "group matching name", + rollout: &autoupdatepb.AutoUpdateAgentRollout{ + Status: &autoupdatepb.AutoUpdateAgentRolloutStatus{ + Groups: []*autoupdatepb.AutoUpdateAgentRolloutStatusGroup{ + {Name: "foo", State: 1}, + {Name: "bar", State: 1}, + {Name: groupName, State: 2}, + {Name: "baz", State: 1}, + }, + }, + }, + expectedResult: &autoupdatepb.AutoUpdateAgentRolloutStatusGroup{ + Name: groupName, + State: 2, + }, + expectError: require.NoError, + }, + { + name: "no group matching name, should fallback to default", + rollout: &autoupdatepb.AutoUpdateAgentRollout{ + Status: &autoupdatepb.AutoUpdateAgentRolloutStatus{ + Groups: []*autoupdatepb.AutoUpdateAgentRolloutStatusGroup{ + {Name: "foo", State: 1}, + {Name: "bar", State: 1}, + {Name: "baz", State: 1}, + }, + }, + }, + expectedResult: &autoupdatepb.AutoUpdateAgentRolloutStatusGroup{ + Name: "baz", + State: 1, + }, + expectError: require.NoError, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + result, err := getGroup(tt.rollout, groupName) + tt.expectError(t, err) + require.Equal(t, tt.expectedResult, result) + }) + } +} + +type mockRFD109VersionServer struct { + t *testing.T + channels map[string]channelStub +} + +type channelStub struct { + // with our without the leading "v" + version string + critical bool + fail bool +} + +func (m *mockRFD109VersionServer) ServeHTTP(w http.ResponseWriter, r *http.Request) { + var path string + var writeResp func(w http.ResponseWriter, stub channelStub) error + + switch { + case strings.HasSuffix(r.URL.Path, constants.VersionPath): + path = strings.Trim(strings.TrimSuffix(r.URL.Path, constants.VersionPath), "/") + writeResp = func(w http.ResponseWriter, stub channelStub) error { + _, err := w.Write([]byte(stub.version)) + return err + } + case strings.HasSuffix(r.URL.Path, constants.MaintenancePath): + path = strings.Trim(strings.TrimSuffix(r.URL.Path, constants.MaintenancePath), "/") + writeResp = func(w http.ResponseWriter, stub channelStub) error { + response := "no" + if stub.critical { + response = "yes" + } + _, err := w.Write([]byte(response)) + return err + } + default: + assert.Fail(m.t, "unsupported path %q", r.URL.Path) + w.WriteHeader(http.StatusNotFound) + return + } + + channel, ok := m.channels[path] + if !ok { + w.WriteHeader(http.StatusNotFound) + assert.Fail(m.t, "channel %q not found", path) + return + } + if channel.fail { + w.WriteHeader(http.StatusInternalServerError) + return + } + assert.NoError(m.t, writeResp(w, channel), "failed to write response") +} + +func TestGetVersionFromChannel(t *testing.T) { + t.Parallel() + ctx := context.Background() + + channelName := "test-channel" + + mock := mockRFD109VersionServer{ + t: t, + channels: map[string]channelStub{ + "broken": {fail: true}, + "with-leading-v": {version: "v" + testVersionHigh}, + "without-leading-v": {version: testVersionHigh}, + "low": {version: testVersionLow}, + }, + } + srv := httptest.NewServer(http.HandlerFunc(mock.ServeHTTP)) + t.Cleanup(srv.Close) + + tests := []struct { + name string + channels automaticupgrades.Channels + expectedResult string + expectError require.ErrorAssertionFunc + }{ + { + name: "channel with leading v", + channels: automaticupgrades.Channels{ + channelName: {ForwardURL: srv.URL + "/with-leading-v"}, + "default": {ForwardURL: srv.URL + "/low"}, + }, + expectedResult: testVersionHigh, + expectError: require.NoError, + }, + { + name: "channel without leading v", + channels: automaticupgrades.Channels{ + channelName: {ForwardURL: srv.URL + "/without-leading-v"}, + "default": {ForwardURL: srv.URL + "/low"}, + }, + expectedResult: testVersionHigh, + expectError: require.NoError, + }, + { + name: "fallback to default with leading v", + channels: automaticupgrades.Channels{ + "default": {ForwardURL: srv.URL + "/with-leading-v"}, + }, + expectedResult: testVersionHigh, + expectError: require.NoError, + }, + { + name: "fallback to default without leading v", + channels: automaticupgrades.Channels{ + "default": {ForwardURL: srv.URL + "/without-leading-v"}, + }, + expectedResult: testVersionHigh, + expectError: require.NoError, + }, + { + name: "broken channel", + channels: automaticupgrades.Channels{ + channelName: {ForwardURL: srv.URL + "/broken"}, + "default": {ForwardURL: srv.URL + "/without-leading-v"}, + }, + expectError: require.Error, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + // Test setup + require.NoError(t, tt.channels.CheckAndSetDefaults()) + + // Test execution + result, err := getVersionFromChannel(ctx, tt.channels, channelName) + tt.expectError(t, err) + require.Equal(t, tt.expectedResult, result) + }) + } +} + +func TestGetTriggerFromChannel(t *testing.T) { + t.Parallel() + ctx := context.Background() + + channelName := "test-channel" + + mock := mockRFD109VersionServer{ + t: t, + channels: map[string]channelStub{ + "broken": {fail: true}, + "critical": {critical: true}, + "non-critical": {critical: false}, + }, + } + srv := httptest.NewServer(http.HandlerFunc(mock.ServeHTTP)) + t.Cleanup(srv.Close) + + tests := []struct { + name string + channels automaticupgrades.Channels + expectedResult bool + expectError require.ErrorAssertionFunc + }{ + { + name: "critical channel", + channels: automaticupgrades.Channels{ + channelName: {ForwardURL: srv.URL + "/critical"}, + "default": {ForwardURL: srv.URL + "/non-critical"}, + }, + expectedResult: true, + expectError: require.NoError, + }, + { + name: "non-critical channel", + channels: automaticupgrades.Channels{ + channelName: {ForwardURL: srv.URL + "/non-critical"}, + "default": {ForwardURL: srv.URL + "/critical"}, + }, + expectedResult: false, + expectError: require.NoError, + }, + { + name: "fallback to default which is critical", + channels: automaticupgrades.Channels{ + "default": {ForwardURL: srv.URL + "/critical"}, + }, + expectedResult: true, + expectError: require.NoError, + }, + { + name: "fallback to default which is non-critical", + channels: automaticupgrades.Channels{ + "default": {ForwardURL: srv.URL + "/non-critical"}, + }, + expectedResult: false, + expectError: require.NoError, + }, + { + name: "broken channel", + channels: automaticupgrades.Channels{ + channelName: {ForwardURL: srv.URL + "/broken"}, + "default": {ForwardURL: srv.URL + "/critical"}, + }, + expectError: require.Error, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + // Test setup + require.NoError(t, tt.channels.CheckAndSetDefaults()) + + // Test execution + result, err := getTriggerFromChannel(ctx, tt.channels, channelName) + tt.expectError(t, err) + require.Equal(t, tt.expectedResult, result) + }) + } +} diff --git a/lib/web/autoupdate_rfd109.go b/lib/web/autoupdate_rfd109.go index b09b151220754..3bbdd0175b106 100644 --- a/lib/web/autoupdate_rfd109.go +++ b/lib/web/autoupdate_rfd109.go @@ -21,6 +21,7 @@ package web import ( "context" "errors" + "fmt" "net/http" "strings" "time" @@ -28,7 +29,6 @@ import ( "github.com/gravitational/trace" "github.com/julienschmidt/httprouter" - "github.com/gravitational/teleport/lib/automaticupgrades" "github.com/gravitational/teleport/lib/automaticupgrades/constants" "github.com/gravitational/teleport/lib/automaticupgrades/version" ) @@ -59,31 +59,25 @@ func (h *Handler) automaticUpgrades109(w http.ResponseWriter, r *http.Request, p return nil, trace.BadParameter("a channel name is required") } - // We check if the channel is configured - channel, ok := h.cfg.AutomaticUpgradesChannels[channelName] - if !ok { - return nil, trace.NotFound("channel %s not found", channelName) - } - // Finally, we treat the request based on its type switch requestType { case "version": h.log.Debugf("Agent requesting version for channel %s", channelName) - return h.automaticUpgradesVersion109(w, r, channel) + return h.automaticUpgradesVersion109(w, r, channelName) case "critical": h.log.Debugf("Agent requesting criticality for channel %s", channelName) - return h.automaticUpgradesCritical109(w, r, channel) + return h.automaticUpgradesCritical109(w, r, channelName) default: return nil, trace.BadParameter("requestType path must end with 'version' or 'critical'") } } // automaticUpgradesVersion109 handles version requests from upgraders -func (h *Handler) automaticUpgradesVersion109(w http.ResponseWriter, r *http.Request, channel *automaticupgrades.Channel) (interface{}, error) { +func (h *Handler) automaticUpgradesVersion109(w http.ResponseWriter, r *http.Request, channelName string) (interface{}, error) { ctx, cancel := context.WithTimeout(r.Context(), defaultChannelTimeout) defer cancel() - targetVersion, err := channel.GetVersion(ctx) + targetVersion, err := h.autoUpdateAgentVersion(ctx, channelName, "" /* updater UUID */) if err != nil { // If the error is that the upstream channel has no version // We gracefully handle by serving "none" @@ -96,16 +90,20 @@ func (h *Handler) automaticUpgradesVersion109(w http.ResponseWriter, r *http.Req return nil, trace.Wrap(err) } - _, err = w.Write([]byte(targetVersion)) + // RFD 109 specifies that version from channels must have the leading "v". + // As h.autoUpdateAgentVersion doesn't, we must add it. + _, err = fmt.Fprintf(w, "v%s", targetVersion) return nil, trace.Wrap(err) } // automaticUpgradesCritical109 handles criticality requests from upgraders -func (h *Handler) automaticUpgradesCritical109(w http.ResponseWriter, r *http.Request, channel *automaticupgrades.Channel) (interface{}, error) { +func (h *Handler) automaticUpgradesCritical109(w http.ResponseWriter, r *http.Request, channelName string) (interface{}, error) { ctx, cancel := context.WithTimeout(r.Context(), defaultChannelTimeout) defer cancel() - critical, err := channel.GetCritical(ctx) + // RFD109 agents already retrieve maintenance windows from the CMC, no need to + // do a maintenance window lookup for them. + critical, err := h.autoUpdateAgentShouldUpdate(ctx, channelName, "" /* updater UUID */, false /* window lookup */) if err != nil { return nil, trace.Wrap(err) } diff --git a/lib/web/autoupdate_rfd184.go b/lib/web/autoupdate_rfd184.go index 4c3ccdeaef907..6ac532650cb64 100644 --- a/lib/web/autoupdate_rfd184.go +++ b/lib/web/autoupdate_rfd184.go @@ -23,6 +23,7 @@ import ( "github.com/gravitational/trace" + "github.com/gravitational/teleport" "github.com/gravitational/teleport/api" "github.com/gravitational/teleport/api/client/webclient" autoupdatepb "github.com/gravitational/teleport/api/gen/proto/go/teleport/autoupdate/v1" @@ -31,8 +32,8 @@ import ( // automaticUpdateSettings184 crafts the automatic updates part of the ping/find response // as described in RFD-184 (agents) and RFD-144 (tools). -// TODO: add the request as a parameter when we'll need to modulate the content based on the UUID and group -func (h *Handler) automaticUpdateSettings184(ctx context.Context) webclient.AutoUpdateSettings { +func (h *Handler) automaticUpdateSettings184(ctx context.Context, group, updaterUUID string) webclient.AutoUpdateSettings { + // Tools auto updates section. autoUpdateConfig, err := h.cfg.AccessPoint.GetAutoUpdateConfig(ctx) // TODO(vapopov) DELETE IN v18.0.0 check of IsNotImplemented, must be backported to all latest supported versions. if err != nil && !trace.IsNotFound(err) && !trace.IsNotImplemented(err) { @@ -45,12 +46,29 @@ func (h *Handler) automaticUpdateSettings184(ctx context.Context) webclient.Auto h.logger.ErrorContext(ctx, "failed to receive AutoUpdateVersion", "error", err) } + // Agent auto updates section. + agentVersion, err := h.autoUpdateAgentVersion(ctx, group, updaterUUID) + if err != nil { + h.logger.ErrorContext(ctx, "failed to resolve AgentVersion", "error", err) + // Defaulting to current version + agentVersion = teleport.Version + } + // If the source of truth is RFD 109 configuration (channels + CMC) we must emulate the + // RFD109 agent maintenance window behavior by looking up the CMC and checking if + // we are in a maintenance window. + shouldUpdate, err := h.autoUpdateAgentShouldUpdate(ctx, group, updaterUUID, true /* window lookup */) + if err != nil { + h.logger.ErrorContext(ctx, "failed to resolve AgentAutoUpdate", "error", err) + // Failing open + shouldUpdate = false + } + return webclient.AutoUpdateSettings{ ToolsAutoUpdate: getToolsAutoUpdate(autoUpdateConfig), ToolsVersion: getToolsVersion(autoUpdateVersion), AgentUpdateJitterSeconds: DefaultAgentUpdateJitterSeconds, - AgentVersion: getAgentVersion184(autoUpdateVersion), - AgentAutoUpdate: agentShouldUpdate184(autoUpdateConfig, autoUpdateVersion), + AgentVersion: agentVersion, + AgentAutoUpdate: shouldUpdate, } } @@ -73,39 +91,3 @@ func getToolsVersion(version *autoupdatepb.AutoUpdateVersion) string { } return version.GetSpec().GetTools().GetTargetVersion() } - -func getAgentVersion184(version *autoupdatepb.AutoUpdateVersion) string { - // If we can't get the AU version or tools AU version is not specified, we default to the current proxy version. - // This ensures we always advertise a version compatible with the cluster. - // TODO: read the version from the autoupdate_agent_rollout when the resource is implemented - if version.GetSpec().GetAgents() == nil { - return api.Version - } - - return version.GetSpec().GetAgents().GetTargetVersion() -} - -func agentShouldUpdate184(config *autoupdatepb.AutoUpdateConfig, version *autoupdatepb.AutoUpdateVersion) bool { - // TODO: read the data from the autoupdate_agent_rollout when the resource is implemented - - // If we can't get the AU config or if AUs are not configured, we default to "disabled". - // This ensures we fail open and don't accidentally update agents if something is going wrong. - // If we want to enable AUs by default, it would be better to create a default "autoupdate_config" resource - // than changing this logic. - if config.GetSpec().GetAgents() == nil { - return false - } - if version.GetSpec().GetAgents() == nil { - return false - } - configMode := config.GetSpec().GetAgents().GetMode() - versionMode := version.GetSpec().GetAgents().GetMode() - - // We update only if both version and config agent modes are "enabled" - if configMode != autoupdate.AgentsUpdateModeEnabled || versionMode != autoupdate.AgentsUpdateModeEnabled { - return false - } - - scheduleName := version.GetSpec().GetAgents().GetSchedule() - return scheduleName == autoupdate.AgentsScheduleImmediate -} diff --git a/lib/web/conn_upgrade.go b/lib/web/conn_upgrade.go index df8c4684dcfc7..7a081aa9ea975 100644 --- a/lib/web/conn_upgrade.go +++ b/lib/web/conn_upgrade.go @@ -109,7 +109,7 @@ func (h *Handler) upgradeALPNWebSocket(w http.ResponseWriter, r *http.Request, u } wsConn, err := upgrader.Upgrade(w, r, nil) if err != nil { - h.logger.DebugContext(r.Context(), "Failed to upgrade weboscket.", "error", err) + h.logger.DebugContext(r.Context(), "Failed to upgrade WebSocket.", "error", err) return nil, trace.Wrap(err) } defer wsConn.Close() diff --git a/lib/web/integrations.go b/lib/web/integrations.go index 4693418dd3b9d..6705afcf8dc48 100644 --- a/lib/web/integrations.go +++ b/lib/web/integrations.go @@ -36,6 +36,7 @@ import ( "github.com/gravitational/teleport/lib/defaults" "github.com/gravitational/teleport/lib/httplib" "github.com/gravitational/teleport/lib/reversetunnelclient" + libui "github.com/gravitational/teleport/lib/ui" "github.com/gravitational/teleport/lib/web/ui" ) @@ -319,6 +320,109 @@ func rulesWithIntegration(dc *discoveryconfig.DiscoveryConfig, matcherType strin return ret } +// integrationDiscoveryRules returns the Discovery Rules that are using a given integration. +// A Discovery Rule is just like a DiscoveryConfig Matcher, except that it breaks down by region. +// So, if a Matcher exists for two regions, that will be represented as two Rules. +func (h *Handler) integrationDiscoveryRules(w http.ResponseWriter, r *http.Request, p httprouter.Params, sctx *SessionContext, site reversetunnelclient.RemoteSite) (interface{}, error) { + integrationName := p.ByName("name") + if integrationName == "" { + return nil, trace.BadParameter("an integration name is required") + } + + values := r.URL.Query() + startKey := values.Get("startKey") + resourceType := values.Get("resourceType") + + clt, err := sctx.GetUserClient(r.Context(), site) + if err != nil { + return nil, trace.Wrap(err) + } + + ig, err := clt.GetIntegration(r.Context(), integrationName) + if err != nil { + return nil, trace.Wrap(err) + } + + rules, err := collectAutoDiscoveryRules(r.Context(), ig.GetName(), startKey, resourceType, clt.DiscoveryConfigClient()) + if err != nil { + return nil, trace.Wrap(err) + } + + return rules, nil +} + +// collectAutoDiscoveryRules will iterate over all DiscoveryConfigs's Matchers and collect the Discovery Rules that exist in them for the given integration. +// It can also be filtered by Matcher Type (eg ec2, rds, eks) +// A Discovery Rule is a close match to a DiscoveryConfig's Matcher, except that it will count as many rules as regions exist. +// Eg if a DiscoveryConfig's Matcher has two regions, then it will output two (almost equal) Rules, one for each Region. +func collectAutoDiscoveryRules( + ctx context.Context, + integrationName string, + nextPage string, + resourceTypeFilter string, + clt interface { + ListDiscoveryConfigs(ctx context.Context, pageSize int, nextToken string) ([]*discoveryconfig.DiscoveryConfig, string, error) + }, +) (ui.IntegrationDiscoveryRules, error) { + const ( + maxPerPage = 100 + ) + var ret ui.IntegrationDiscoveryRules + for { + discoveryConfigs, nextToken, err := clt.ListDiscoveryConfigs(ctx, 0, nextPage) + if err != nil { + return ret, trace.Wrap(err) + } + for _, dc := range discoveryConfigs { + lastSync := &dc.Status.LastSyncTime + if lastSync.IsZero() { + lastSync = nil + } + + for _, matcher := range dc.Spec.AWS { + if matcher.Integration != integrationName { + continue + } + + for _, resourceType := range matcher.Types { + if resourceTypeFilter != "" && resourceType != resourceTypeFilter { + continue + } + + for _, region := range matcher.Regions { + uiLables := make([]libui.Label, 0, len(matcher.Tags)) + for labelKey, labelValues := range matcher.Tags { + for _, labelValue := range labelValues { + uiLables = append(uiLables, libui.Label{ + Name: labelKey, + Value: labelValue, + }) + } + } + ret.Rules = append(ret.Rules, ui.IntegrationDiscoveryRule{ + ResourceType: resourceType, + Region: region, + LabelMatcher: uiLables, + DiscoveryConfig: dc.GetName(), + LastSync: lastSync, + }) + } + } + } + } + + ret.NextKey = nextToken + + if nextToken == "" || len(ret.Rules) > maxPerPage { + break + } + + nextPage = nextToken + } + + return ret, nil +} + // integrationsList returns a page of Integrations func (h *Handler) integrationsList(w http.ResponseWriter, r *http.Request, p httprouter.Params, sctx *SessionContext, site reversetunnelclient.RemoteSite) (interface{}, error) { clt, err := sctx.GetUserClient(r.Context(), site) diff --git a/lib/web/integrations_awsoidc.go b/lib/web/integrations_awsoidc.go index 39ebb250a9452..331df6ba78dd1 100644 --- a/lib/web/integrations_awsoidc.go +++ b/lib/web/integrations_awsoidc.go @@ -35,6 +35,7 @@ import ( "github.com/gravitational/teleport" "github.com/gravitational/teleport/api/client" "github.com/gravitational/teleport/api/client/proto" + "github.com/gravitational/teleport/api/constants" apidefaults "github.com/gravitational/teleport/api/defaults" integrationv1 "github.com/gravitational/teleport/api/gen/proto/go/teleport/integration/v1" "github.com/gravitational/teleport/api/types" @@ -49,6 +50,7 @@ import ( "github.com/gravitational/teleport/lib/reversetunnelclient" "github.com/gravitational/teleport/lib/services" libutils "github.com/gravitational/teleport/lib/utils" + awsutils "github.com/gravitational/teleport/lib/utils/aws" "github.com/gravitational/teleport/lib/utils/oidc" "github.com/gravitational/teleport/lib/web/scripts/oneoff" "github.com/gravitational/teleport/lib/web/ui" @@ -984,7 +986,16 @@ func (h *Handler) awsOIDCCreateAWSAppAccess(w http.ResponseWriter, r *http.Reque publicAddr := libutils.DefaultAppPublicAddr(integrationName, h.PublicProxyAddr()) - appServer, err := types.NewAppServerForAWSOIDCIntegration(integrationName, h.cfg.HostUUID, publicAddr) + parsedRoleARN, err := awsutils.ParseRoleARN(ig.GetAWSOIDCIntegrationSpec().RoleARN) + if err != nil { + return nil, trace.Wrap(err) + } + + labels := map[string]string{ + constants.AWSAccountIDLabel: parsedRoleARN.AccountID, + } + + appServer, err := types.NewAppServerForAWSOIDCIntegration(integrationName, h.cfg.HostUUID, publicAddr, labels) if err != nil { return nil, trace.Wrap(err) } diff --git a/lib/web/integrations_awsoidc_test.go b/lib/web/integrations_awsoidc_test.go index 200d68ef7d9a0..9b2660fe36e99 100644 --- a/lib/web/integrations_awsoidc_test.go +++ b/lib/web/integrations_awsoidc_test.go @@ -1067,7 +1067,7 @@ func TestAWSOIDCAppAccessAppServerCreationDeletion(t *testing.T) { myIntegration, err := types.NewIntegrationAWSOIDC(types.Metadata{ Name: "my-integration", }, &types.AWSOIDCIntegrationSpecV1{ - RoleARN: "some-arn-role", + RoleARN: "arn:aws:iam::123456789012:role/teleport", }) require.NoError(t, err) @@ -1094,7 +1094,8 @@ func TestAWSOIDCAppAccessAppServerCreationDeletion(t *testing.T) { Kind: types.KindAppServer, Version: types.V3, Metadata: types.Metadata{ - Name: "my-integration", + Name: "my-integration", + Labels: map[string]string{"aws_account_id": "123456789012"}, }, Spec: types.AppServerSpecV3{ Version: api.Version, @@ -1103,7 +1104,8 @@ func TestAWSOIDCAppAccessAppServerCreationDeletion(t *testing.T) { Kind: types.KindApp, Version: types.V3, Metadata: types.Metadata{ - Name: "my-integration", + Name: "my-integration", + Labels: map[string]string{"aws_account_id": "123456789012"}, }, Spec: types.AppSpecV3{ URI: "https://console.aws.amazon.com", @@ -1133,7 +1135,7 @@ func TestAWSOIDCAppAccessAppServerCreationDeletion(t *testing.T) { myIntegrationWithAccountID, err := types.NewIntegrationAWSOIDC(types.Metadata{ Name: "123456789012", }, &types.AWSOIDCIntegrationSpecV1{ - RoleARN: "some-arn-role", + RoleARN: "arn:aws:iam::123456789012:role/teleport", }) require.NoError(t, err) diff --git a/lib/web/intgrations_test.go b/lib/web/integrations_test.go similarity index 64% rename from lib/web/intgrations_test.go rename to lib/web/integrations_test.go index f60eabd623041..9719de251d0ec 100644 --- a/lib/web/intgrations_test.go +++ b/lib/web/integrations_test.go @@ -24,12 +24,15 @@ import ( "testing" "time" + "github.com/google/uuid" "github.com/stretchr/testify/require" discoveryconfigv1 "github.com/gravitational/teleport/api/gen/proto/go/teleport/discoveryconfig/v1" "github.com/gravitational/teleport/api/types" "github.com/gravitational/teleport/api/types/discoveryconfig" + "github.com/gravitational/teleport/api/types/header" "github.com/gravitational/teleport/lib/services" + libui "github.com/gravitational/teleport/lib/ui" "github.com/gravitational/teleport/lib/web/ui" ) @@ -212,6 +215,142 @@ func TestCollectAWSOIDCAutoDiscoverStats(t *testing.T) { }) } +func TestCollectAutoDiscoveryRules(t *testing.T) { + ctx := context.Background() + integrationName := "my-integration" + + t.Run("without discovery configs, returns no rules", func(t *testing.T) { + clt := &mockDiscoveryConfigsGetter{ + discoveryConfigs: make([]*discoveryconfig.DiscoveryConfig, 0), + } + + gotRules, err := collectAutoDiscoveryRules(ctx, integrationName, "", "", clt) + require.NoError(t, err) + expectedRules := ui.IntegrationDiscoveryRules{} + require.Equal(t, expectedRules, gotRules) + }) + + t.Run("collects multiple discovery configs", func(t *testing.T) { + syncTime := time.Now() + dcForEC2 := &discoveryconfig.DiscoveryConfig{ + ResourceHeader: header.ResourceHeader{Metadata: header.Metadata{ + Name: uuid.NewString(), + }}, + Spec: discoveryconfig.Spec{AWS: []types.AWSMatcher{{ + Integration: integrationName, + Types: []string{"ec2"}, + Regions: []string{"us-east-1"}, + Tags: types.Labels{"*": []string{"*"}}, + }}}, + Status: discoveryconfig.Status{ + LastSyncTime: syncTime, + }, + } + dcForRDS := &discoveryconfig.DiscoveryConfig{ + ResourceHeader: header.ResourceHeader{Metadata: header.Metadata{ + Name: uuid.NewString(), + }}, + Spec: discoveryconfig.Spec{AWS: []types.AWSMatcher{{ + Integration: integrationName, + Types: []string{"rds"}, + Regions: []string{"us-east-1", "us-east-2"}, + Tags: types.Labels{ + "env": []string{"dev", "prod"}, + }, + }}}, + Status: discoveryconfig.Status{ + LastSyncTime: syncTime, + }, + } + dcForEKS := &discoveryconfig.DiscoveryConfig{ + ResourceHeader: header.ResourceHeader{Metadata: header.Metadata{ + Name: uuid.NewString(), + }}, + Spec: discoveryconfig.Spec{AWS: []types.AWSMatcher{{ + Integration: integrationName, + Types: []string{"eks"}, + Regions: []string{"us-east-1"}, + Tags: types.Labels{"*": []string{"*"}}, + }}}, + Status: discoveryconfig.Status{ + LastSyncTime: syncTime, + }, + } + dcForEKSWithoutStatus := &discoveryconfig.DiscoveryConfig{ + ResourceHeader: header.ResourceHeader{Metadata: header.Metadata{ + Name: uuid.NewString(), + }}, + Spec: discoveryconfig.Spec{AWS: []types.AWSMatcher{{ + Integration: integrationName, + Types: []string{"eks"}, + Regions: []string{"eu-west-1"}, + Tags: types.Labels{"*": []string{"*"}}, + }}}, + } + clt := &mockDiscoveryConfigsGetter{ + discoveryConfigs: []*discoveryconfig.DiscoveryConfig{ + dcForEC2, + dcForRDS, + dcForEKS, + dcForEKSWithoutStatus, + }, + } + + got, err := collectAutoDiscoveryRules(ctx, integrationName, "", "", clt) + require.NoError(t, err) + expectedRules := []ui.IntegrationDiscoveryRule{ + { + ResourceType: "ec2", + Region: "us-east-1", + LabelMatcher: []libui.Label{ + {Name: "*", Value: "*"}, + }, + DiscoveryConfig: dcForEC2.GetName(), + LastSync: &syncTime, + }, + { + ResourceType: "eks", + Region: "us-east-1", + LabelMatcher: []libui.Label{ + {Name: "*", Value: "*"}, + }, + DiscoveryConfig: dcForEKS.GetName(), + LastSync: &syncTime, + }, + { + ResourceType: "eks", + Region: "eu-west-1", + LabelMatcher: []libui.Label{ + {Name: "*", Value: "*"}, + }, + DiscoveryConfig: dcForEKSWithoutStatus.GetName(), + }, + { + ResourceType: "rds", + Region: "us-east-1", + LabelMatcher: []libui.Label{ + {Name: "env", Value: "dev"}, + {Name: "env", Value: "prod"}, + }, + DiscoveryConfig: dcForRDS.GetName(), + LastSync: &syncTime, + }, + { + ResourceType: "rds", + Region: "us-east-2", + LabelMatcher: []libui.Label{ + {Name: "env", Value: "dev"}, + {Name: "env", Value: "prod"}, + }, + DiscoveryConfig: dcForRDS.GetName(), + LastSync: &syncTime, + }, + } + require.Empty(t, got.NextKey) + require.ElementsMatch(t, expectedRules, got.Rules) + }) +} + type mockDiscoveryConfigsGetter struct { discoveryConfigs []*discoveryconfig.DiscoveryConfig } diff --git a/lib/web/ui/app.go b/lib/web/ui/app.go index e77958486b729..313cb4f103603 100644 --- a/lib/web/ui/app.go +++ b/lib/web/ui/app.go @@ -34,6 +34,9 @@ import ( type App struct { // Kind is the kind of resource. Used to parse which kind in a list of unified resources in the UI Kind string `json:"kind"` + // SubKind is the subkind of the app resource. Used to differentiate different + // flavors of app. + SubKind string `json:"subkind,omitempty"` // Name is the name of the application. Name string `json:"name"` // Description is the app description. @@ -66,6 +69,9 @@ type App struct { // Integration is the integration name that must be used to access this Application. // Only applicable to AWS App Access. Integration string `json:"integration,omitempty"` + // PermissionSets holds the permission sets that this app grants access to. + // Only valid for Identity Center Account apps + PermissionSets []IdentityCenterPermissionSet `json:"permissionSets,omitempty"` } // UserGroupAndDescription is a user group name and its description. @@ -76,6 +82,19 @@ type UserGroupAndDescription struct { Description string `json:"description"` } +// IdentityCenterPermissionSet holds information about Identity Center +// Permission Sets for transmission to the UI +type IdentityCenterPermissionSet struct { + // Name is the human-readable name of the permission set + Name string `json:"name"` + // ARN is the AWS-assigned ARN of the permission set + ARN string `json:"arn"` + // AssignmentID is the assignment resource that will provision an Account + // Assignment for this Permission Set on the enclosing account + AssignmentID string `json:"accountAssignment,omitempty"` + RequiresRequest bool `json:"requiresRequest,omitempty"` +} + // MakeAppsConfig contains parameters for converting apps to UI representation. type MakeAppsConfig struct { // LocalClusterName is the name of the local cluster. @@ -129,8 +148,11 @@ func MakeApp(app types.Application, c MakeAppsConfig) App { description = oktaDescription } + permissionSets := makePermissionSets(app.GetIdentityCenter().GetPermissionSets()) + resultApp := App{ Kind: types.KindApp, + SubKind: app.GetSubKind(), Name: app.GetName(), Description: description, URI: app.GetURI(), @@ -144,6 +166,7 @@ func MakeApp(app types.Application, c MakeAppsConfig) App { SAMLApp: false, RequiresRequest: c.RequiresRequest, Integration: app.GetIntegration(), + PermissionSets: permissionSets, } if app.IsAWSConsole() { @@ -155,6 +178,21 @@ func MakeApp(app types.Application, c MakeAppsConfig) App { return resultApp } +func makePermissionSets(src []*types.IdentityCenterPermissionSet) []IdentityCenterPermissionSet { + if src == nil { + return nil + } + dst := make([]IdentityCenterPermissionSet, len(src)) + for i, srcPS := range src { + dst[i] = IdentityCenterPermissionSet{ + Name: srcPS.Name, + ARN: srcPS.ARN, + AssignmentID: srcPS.AssignmentID, + } + } + return dst +} + // MakeAppTypeFromSAMLApp creates App type from SAMLIdPServiceProvider type for the WebUI. // Keep in sync with lib/teleterm/apiserver/handler/handler_apps.go. // Note: The SAMLAppPreset field is used in SAML service provider update flow in the diff --git a/lib/web/ui/integration.go b/lib/web/ui/integration.go index 106af1872a70c..c2b71117f954b 100644 --- a/lib/web/ui/integration.go +++ b/lib/web/ui/integration.go @@ -101,6 +101,31 @@ type ResourceTypeSummary struct { ECSDatabaseServiceCount int `json:"ecsDatabaseServiceCount,omitempty"` } +// IntegrationDiscoveryRule describes a discovery rule associated with an integration. +type IntegrationDiscoveryRule struct { + // ResourceType indicates the type of resource that this rule targets. + // This is the same value that is set in DiscoveryConfig.AWS..Types + // Example: ec2, rds, eks + ResourceType string `json:"resourceType,omitempty"` + // Region where this rule applies to. + Region string `json:"region,omitempty"` + // LabelMatcher is the set of labels that are used to filter the resources before trying to auto-enroll them. + LabelMatcher []ui.Label `json:"labelMatcher,omitempty"` + // DiscoveryConfig is the name of the DiscoveryConfig that created this rule. + DiscoveryConfig string `json:"discoveryConfig,omitempty"` + // LastSync contains the time when this rule was used. + // If empty, it indicates that the rule is not being used. + LastSync *time.Time `json:"lastSync,omitempty"` +} + +// IntegrationDiscoveryRules contains the list of discovery rules for a given Integration. +type IntegrationDiscoveryRules struct { + // Rules is the list of integration rules. + Rules []IntegrationDiscoveryRule `json:"rules"` + // NextKey is the position to resume listing rules. + NextKey string `json:"nextKey,omitempty"` +} + // Integration describes Integration fields type Integration struct { // Name is the Integration name. diff --git a/proto/teleport/lib/teleterm/v1/app.proto b/proto/teleport/lib/teleterm/v1/app.proto index 8920a84b2d33a..ebd361306752a 100644 --- a/proto/teleport/lib/teleterm/v1/app.proto +++ b/proto/teleport/lib/teleterm/v1/app.proto @@ -79,6 +79,11 @@ message App { string fqdn = 10; // aws_roles is a list of AWS IAM roles for the application representing AWS console. repeated AWSRole aws_roles = 11; + // TCPPorts is a list of ports and port ranges that an app agent can forward connections to. + // Only applicable to TCP App Access. + // If this field is not empty, URI is expected to contain no port number and start with the tcp + // protocol. + repeated PortRange tcp_ports = 12; } // AwsRole describes AWS IAM role. @@ -92,3 +97,35 @@ message AWSRole { // AccountID is the AWS Account ID this role refers to. string account_id = 4; } + +// PortRange describes a port range for TCP apps. The range starts with Port and ends with EndPort. +// PortRange can be used to describe a single port in which case the Port field is the port and the +// EndPort field is 0. +message PortRange { + // Port describes the start of the range. It must be between 1 and 65535. + uint32 port = 1; + // EndPort describes the end of the range, inclusive. If set, it must be between 2 and 65535 and + // be greater than Port when describing a port range. When omitted or set to zero, it signifies + // that the port range defines a single port. + uint32 end_port = 2; +} + +// RouteToApp is used by the auth service and the app service during cert generation and routing. +// It's purpose is to point to a specific app within a root cluster. Kind of like an app URI in +// Connect, but with extra data attached. +message RouteToApp { + // name is the name of the app within a cluster. + string name = 1; + // public_addr is the address under which the app can be reached. It's just the hostname, it does + // not include the schema or the port number. See the docs for public_addr of + // the App message for a more thorough description. + string public_addr = 2; + // cluster_name is the name of the cluster that the app belongs to. In the case of the root + // cluster, it's not guaranteed to be equal to the proxy hostname – the root cluster might have a + // distinct name set. + string cluster_name = 3; + // uri is the URI which the app service is going to proxy requests to. + string uri = 4; + // target_port is the port of a multi-port TCP app that the connection is going to be proxied to. + uint32 target_port = 5; +} diff --git a/proto/teleport/lib/teleterm/v1/cluster.proto b/proto/teleport/lib/teleterm/v1/cluster.proto index f0bafaf348419..8663547ab2cfd 100644 --- a/proto/teleport/lib/teleterm/v1/cluster.proto +++ b/proto/teleport/lib/teleterm/v1/cluster.proto @@ -141,6 +141,8 @@ message ACL { ResourceAccess recorded_sessions = 13; // active_sessions defines access to active sessions. ResourceAccess active_sessions = 14; + // review_requests defines the ability to review requests + bool review_requests = 15; } // ResourceAccess describes access verbs diff --git a/proto/teleport/lib/teleterm/v1/tshd_events_service.proto b/proto/teleport/lib/teleterm/v1/tshd_events_service.proto index 840d1eaad844e..600a99d124bde 100644 --- a/proto/teleport/lib/teleterm/v1/tshd_events_service.proto +++ b/proto/teleport/lib/teleterm/v1/tshd_events_service.proto @@ -20,6 +20,8 @@ syntax = "proto3"; package teleport.lib.teleterm.v1; +import "teleport/lib/teleterm/v1/app.proto"; + option go_package = "github.com/gravitational/teleport/gen/proto/go/teleport/lib/teleterm/v1;teletermv1"; // TshdEventsService is served by the Electron app. The tsh daemon calls this service to notify the @@ -100,8 +102,10 @@ message GatewayCertExpired { message VnetCertExpired { // target_uri for now points solely at apps, but it's not called app_uri to make it future-proof. string target_uri = 1; - // public_addr is the public address of the app that the user tried to access. - string public_addr = 2; + reserved 2; + reserved "public_addr"; + // route_to_app is the metadata associated with the app that the user was trying to reach. + RouteToApp route_to_app = 3; } // Response for Relogin. @@ -134,8 +138,10 @@ message CannotProxyGatewayConnection { message CannotProxyVnetConnection { string target_uri = 1; string error = 2; - // public_addr is the public address of the app that the user tried to access. - string public_addr = 3; + reserved 3; + reserved "public_addr"; + // route_to_app is the metadata associated with the app that the user was trying to reach. + RouteToApp route_to_app = 4; } // Response for SendNotification. diff --git a/tool/tctl/common/auth_command.go b/tool/tctl/common/auth_command.go index f46934965c9b6..23f089d0e4d38 100644 --- a/tool/tctl/common/auth_command.go +++ b/tool/tctl/common/auth_command.go @@ -89,15 +89,11 @@ type AuthCommand struct { identityWriter identityfile.ConfigWriter integration string - rotateGracePeriod time.Duration - rotateType string - rotateManualMode bool - rotateTargetPhase string + authRotate authRotateCommand authGenerate *kingpin.CmdClause authExport *kingpin.CmdClause authSign *kingpin.CmdClause - authRotate *kingpin.CmdClause authLS *kingpin.CmdClause authCRL *kingpin.CmdClause // testInsecureSkipVerify is used to skip TLS verification during tests @@ -157,13 +153,7 @@ func (a *AuthCommand) Initialize(app *kingpin.Application, config *servicecfg.Co a.authSign.Flag("windows-sid", `Optional Security Identifier to embed in the certificate. Only used when --format is set to "windows"`).StringVar(&a.windowsSID) a.authSign.Flag("omit-cdp", `Omit CRL Distribution Points from the cert. Only used when --format is set to "windows"`).BoolVar(&a.omitCDP) - a.authRotate = auth.Command("rotate", "Rotate certificate authorities in the cluster.") - a.authRotate.Flag("grace-period", "Grace period keeps previous certificate authorities signatures valid, if set to 0 will force users to re-login and nodes to re-register."). - Default(fmt.Sprintf("%v", defaults.RotationGracePeriod)). - DurationVar(&a.rotateGracePeriod) - a.authRotate.Flag("manual", "Activate manual rotation , set rotation phases manually").BoolVar(&a.rotateManualMode) - a.authRotate.Flag("type", fmt.Sprintf("Certificate authority to rotate, one of: %s", strings.Join(getCertAuthTypes(), ", "))).Required().EnumVar(&a.rotateType, getCertAuthTypes()...) - a.authRotate.Flag("phase", fmt.Sprintf("Target rotation phase to set, used in manual rotation, one of: %v", strings.Join(types.RotatePhases, ", "))).StringVar(&a.rotateTargetPhase) + a.authRotate.Initialize(auth) a.authLS = auth.Command("ls", "List connected auth servers.") a.authLS.Flag("format", "Output format: 'yaml', 'json' or 'text'").Default(teleport.YAML).StringVar(&a.format) @@ -175,6 +165,9 @@ func (a *AuthCommand) Initialize(app *kingpin.Application, config *servicecfg.Co // TryRun takes the CLI command as an argument (like "auth gen") and executes it // or returns match=false if 'cmd' does not belong to it func (a *AuthCommand) TryRun(ctx context.Context, cmd string, client *authclient.Client) (match bool, err error) { + if match, err := a.authRotate.TryRun(ctx, cmd, client); match || err != nil { + return match, trace.Wrap(err) + } switch cmd { case a.authGenerate.FullCommand(): err = a.GenerateKeys(ctx, client) @@ -182,8 +175,6 @@ func (a *AuthCommand) TryRun(ctx context.Context, cmd string, client *authclient err = a.ExportAuthorities(ctx, client) case a.authSign.FullCommand(): err = a.GenerateAndSignKeys(ctx, client) - case a.authRotate.FullCommand(): - err = a.RotateCertAuthority(ctx, client) case a.authLS.FullCommand(): err = a.ListAuthServers(ctx, client) case a.authCRL.FullCommand(): @@ -431,30 +422,6 @@ func (a *AuthCommand) generateSnowflakeKey(ctx context.Context, clusterAPI certi writeHelperMessageDBmTLS(a.helperMsgDst(), filesWritten, "", a.outputFormat, "", a.streamTarfile)) } -// RotateCertAuthority starts or restarts certificate authority rotation process -func (a *AuthCommand) RotateCertAuthority(ctx context.Context, client *authclient.Client) error { - req := types.RotateRequest{ - Type: types.CertAuthType(a.rotateType), - GracePeriod: &a.rotateGracePeriod, - TargetPhase: a.rotateTargetPhase, - } - if a.rotateManualMode { - req.Mode = types.RotationModeManual - } else { - req.Mode = types.RotationModeAuto - } - if err := client.RotateCertAuthority(ctx, req); err != nil { - return err - } - if a.rotateTargetPhase != "" { - fmt.Printf("Updated rotation phase to %q. To check status use 'tctl status'\n", a.rotateTargetPhase) - } else { - fmt.Printf("Initiated certificate authority rotation. To check status use 'tctl status'\n") - } - - return nil -} - // ListAuthServers prints a list of connected auth servers func (a *AuthCommand) ListAuthServers(ctx context.Context, clusterAPI *authclient.Client) error { servers, err := clusterAPI.GetAuthServers() diff --git a/tool/tctl/common/auth_rotate_command.go b/tool/tctl/common/auth_rotate_command.go new file mode 100644 index 0000000000000..02a0d3205d9fc --- /dev/null +++ b/tool/tctl/common/auth_rotate_command.go @@ -0,0 +1,1347 @@ +/* + * Teleport + * Copyright (C) 2024 Gravitational, Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package common + +import ( + "cmp" + "context" + "fmt" + "io" + "log/slog" + "os" + "strings" + "sync" + "time" + + "github.com/alecthomas/kingpin/v2" + "github.com/charmbracelet/bubbles/help" + "github.com/charmbracelet/bubbles/key" + "github.com/charmbracelet/bubbles/spinner" + tea "github.com/charmbracelet/bubbletea" + "github.com/charmbracelet/huh" + "github.com/charmbracelet/lipgloss" + "github.com/gravitational/trace" + "github.com/sirupsen/logrus" + "golang.org/x/term" + + apiclient "github.com/gravitational/teleport/api/client" + "github.com/gravitational/teleport/api/client/proto" + apidefaults "github.com/gravitational/teleport/api/defaults" + "github.com/gravitational/teleport/api/mfa" + "github.com/gravitational/teleport/api/types" + "github.com/gravitational/teleport/api/utils/prompt" + "github.com/gravitational/teleport/lib/auth/authclient" + libmfa "github.com/gravitational/teleport/lib/client/mfa" + "github.com/gravitational/teleport/lib/defaults" + logutils "github.com/gravitational/teleport/lib/utils/log" +) + +const ( + updateInterval = 3 * time.Second + maxWidth = 80 +) + +type authRotateCommand struct { + cmd *kingpin.CmdClause + interactiveMode bool + manualMode bool + caType string + targetPhase string + gracePeriod time.Duration +} + +func (c *authRotateCommand) Initialize(authCmd *kingpin.CmdClause) { + c.cmd = authCmd.Command("rotate", "Rotate certificate authorities in the cluster. Starts in interactive mode by default, provide --type to manually send rotation requests.") + c.cmd.Flag("interactive", "Enable interactive mode").BoolVar(&c.interactiveMode) + c.cmd.Flag("manual", "Activate manual rotation, set rotation phases manually").BoolVar(&c.manualMode) + c.cmd.Flag("type", fmt.Sprintf("Certificate authority to rotate, one of: %s", strings.Join(getCertAuthTypes(), ", "))).EnumVar(&c.caType, getCertAuthTypes()...) + c.cmd.Flag("phase", fmt.Sprintf("Target rotation phase to set, used in manual rotation, one of: %v", strings.Join(types.RotatePhases, ", "))).StringVar(&c.targetPhase) + c.cmd.Flag("grace-period", "Grace period keeps previous certificate authorities signatures valid, if set to 0 will force users to re-login and nodes to re-register."). + Default(fmt.Sprintf("%v", defaults.RotationGracePeriod)). + DurationVar(&c.gracePeriod) +} + +func (c *authRotateCommand) TryRun(ctx context.Context, cmd string, client *authclient.Client) (match bool, err error) { + if c.cmd.FullCommand() == cmd { + return true, trace.Wrap(c.Run(ctx, client)) + } + return false, nil +} + +func (c *authRotateCommand) Run(ctx context.Context, client *authclient.Client) error { + if c.interactiveMode { + return trace.Wrap(c.runInteractive(ctx, client)) + } + if !c.manualMode && c.caType == "" && c.targetPhase == "" && c.gracePeriod == defaults.RotationGracePeriod { + // If the user passed zero arguments, default to interactive mode. + if !term.IsTerminal(int(os.Stdin.Fd())) { + return trace.BadParameter("required flag --type not provided, not starting interactive mode because stdin does not appear to be a terminal") + } + return trace.Wrap(c.runInteractive(ctx, client)) + } + + return trace.Wrap(c.runNoninteractive(ctx, client)) +} + +func (c *authRotateCommand) runNoninteractive(ctx context.Context, client *authclient.Client) error { + if c.caType == "" { + return trace.BadParameter("required flag --type not provided") + } + req := types.RotateRequest{ + Type: types.CertAuthType(c.caType), + TargetPhase: c.targetPhase, + GracePeriod: &c.gracePeriod, + } + if c.manualMode { + req.Mode = types.RotationModeManual + } else { + req.Mode = types.RotationModeAuto + } + if err := client.RotateCertAuthority(ctx, req); err != nil { + return trace.Wrap(err) + } + if c.targetPhase != "" { + fmt.Printf("Updated rotation phase to %q. To check status use 'tctl status'\n", c.targetPhase) + } else { + fmt.Printf("Initiated certificate authority rotation. To check status use 'tctl status'\n") + } + return nil +} + +func (c *authRotateCommand) runInteractive(ctx context.Context, client *authclient.Client) error { + pingResp, err := client.Ping(ctx) + if err != nil { + return trace.Wrap(err, "failed to ping cluster") + } + m := newRotateModel(client, pingResp, types.CertAuthType(c.caType)) + p := tea.NewProgram(m, tea.WithContext(ctx)) + _, err = p.Run() + return trace.Wrap(err) +} + +type authRotateStyle struct { + formTheme *huh.Theme + normal lipgloss.Style + title lipgloss.Style + highlight lipgloss.Style + errorMessage lipgloss.Style +} + +var formTheme = huh.ThemeBase16() +var authRotateTheme = authRotateStyle{ + formTheme: formTheme, + normal: lipgloss.NewStyle(), + title: formTheme.Focused.Title, + highlight: formTheme.Focused.SelectedOption, + errorMessage: formTheme.Focused.ErrorMessage.SetString(""), +} + +type rotateModel struct { + client *authclient.Client + pingResp proto.PingResponse + + logsModel *writerModel + rotateStatusModel *rotateStatusModel + caTypeModel *caTypeModel + currentPhaseModel *currentPhaseModel + waitForCurrentPhaseReadyModel *waitForReadyModel + targetPhaseModel *targetPhaseModel + confirmed bool + sendRotateRequestModel *sendRotateRequestModel + mfaPromptModel *writerModel + waitForTargetPhaseReadyModel *waitForReadyModel + continueBinding key.Binding + newBinding key.Binding + quitBinding key.Binding + help help.Model +} + +func newRotateModel(client *authclient.Client, pingResp proto.PingResponse, caType types.CertAuthType) *rotateModel { + m := &rotateModel{ + client: client, + pingResp: pingResp, + logsModel: newWriterModel(authRotateTheme.normal), + rotateStatusModel: newRotateStatusModel(client, pingResp), + caTypeModel: newCATypeModel(caType), + mfaPromptModel: newWriterModel(authRotateTheme.errorMessage), + continueBinding: key.NewBinding(key.WithKeys("c"), key.WithHelp("c", "continue rotating selected CA")), + newBinding: key.NewBinding(key.WithKeys("n"), key.WithHelp("n", "rotate a new CA")), + quitBinding: key.NewBinding(key.WithKeys("q", "ctrl+c"), key.WithHelp("q", "quit")), + help: help.New(), + } + if caType != "" { + m.currentPhaseModel = newCurrentPhaseModel(client, pingResp, caType) + } + setupLoggers(m.logsModel) + setupMFAPrompt(client, pingResp, m.mfaPromptModel) + return m +} + +// Init implements [tea.Model]. It is the first function that will be called by +// bubbletea. +func (m *rotateModel) Init() tea.Cmd { + cmds := []tea.Cmd{ + m.rotateStatusModel.init(), + m.caTypeModel.init(), + } + if m.currentPhaseModel != nil { + cmds = append(cmds, m.currentPhaseModel.init()) + } + return tea.Batch(cmds...) +} + +// Update implements [tea.Model], it is called every time a message is received. +// The update method reacts to the message and updates the state of the model. +// All messages are passed to the update method of all active submodels, each model +// may optionally return a [tea.Cmd] to trigger future updates with new messages. +func (m *rotateModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) { + var cmds []tea.Cmd + switch msg := msg.(type) { + case tea.KeyMsg: + switch { + case key.Matches(msg, m.quitBinding): + return m, tea.Quit + } + } + + cmds = append(cmds, m.rotateStatusModel.update(msg)) + + cmds = append(cmds, m.caTypeModel.update(msg)) + if m.caTypeModel.caType == "" { + // Return early if the user hasn't picked a CA type yet. + return m, tea.Batch(cmds...) + } + + // Now that we have a CA type, init the current phase model if we haven't yet. + if m.currentPhaseModel == nil { + m.currentPhaseModel = newCurrentPhaseModel(m.client, m.pingResp, m.caTypeModel.caType) + cmds = append(cmds, m.currentPhaseModel.init()) + } + cmds = append(cmds, m.currentPhaseModel.update(msg)) + if m.currentPhaseModel.phase == "" { + // Return early if we haven't got the current phase yet. + return m, tea.Batch(cmds...) + } + + // Now that we've got the current phase, init the waitForCurrentPhaseReady + // model if we haven't yet and the current phase is not standby. + if m.waitForCurrentPhaseReadyModel == nil && m.currentPhaseModel.phase != "standby" { + m.waitForCurrentPhaseReadyModel = newWaitForReadyModel(m.client, m.currentPhaseModel.caID, m.currentPhaseModel.phase) + cmds = append(cmds, m.waitForCurrentPhaseReadyModel.init()) + } + if m.waitForCurrentPhaseReadyModel != nil { + cmds = append(cmds, m.waitForCurrentPhaseReadyModel.update(msg)) + if !m.waitForCurrentPhaseReadyModel.ready() { + // Return early if the current phase is not ready yet. + return m, tea.Batch(cmds...) + } + } + + // Now that we know the current phase, init the target phase model if we haven't yet. + if m.targetPhaseModel == nil { + m.targetPhaseModel = newTargetPhaseModel(m.caTypeModel.caType, m.currentPhaseModel.phase) + cmds = append(cmds, m.targetPhaseModel.init()) + } + cmds = append(cmds, m.targetPhaseModel.update(msg)) + if m.targetPhaseModel.targetPhase == "" { + // Return early if we haven't got the target phase yet. + return m, tea.Batch(cmds...) + } + + // Wait for the user to confirm the rotate request. + if !m.confirmed { + switch msg := msg.(type) { + case tea.KeyMsg: + switch msg.String() { + case "n", "N": + // Go back to the beginning. + m = newRotateModel(m.client, m.pingResp, "") + return m, m.Init() + case "y", "Y": + m.confirmed = true + default: + return m, tea.Batch(cmds...) + } + default: + return m, tea.Batch(cmds...) + } + } + + // Now that we got user confirmation, send the rotate request. + if m.sendRotateRequestModel == nil { + m.sendRotateRequestModel = newSendRotateRequestModel(m.client, m.caTypeModel.caType, m.targetPhaseModel.targetPhase) + cmds = append(cmds, m.sendRotateRequestModel.init()) + return m, tea.Batch(cmds...) + } + cmds = append(cmds, m.sendRotateRequestModel.update(msg)) + if !m.sendRotateRequestModel.success { + // Return early if the rotate request hasn't been successfully sent yet. + return m, tea.Batch(cmds...) + } + + // Now that we've sent the rotate request, init the waitForTargetPhaseReady model if we haven't yet. + if m.waitForTargetPhaseReadyModel == nil { + m.waitForTargetPhaseReadyModel = newWaitForReadyModel(m.client, m.currentPhaseModel.caID, m.targetPhaseModel.targetPhase) + cmds = append(cmds, m.waitForTargetPhaseReadyModel.init()) + } + cmds = append(cmds, m.waitForTargetPhaseReadyModel.update(msg)) + + // If we've made it this far, let the user restart with the keybinds. + switch msg := msg.(type) { + case tea.KeyMsg: + switch { + case key.Matches(msg, m.continueBinding): + newModel := newRotateModel(m.client, m.pingResp, m.caTypeModel.caType) + newModel.waitForCurrentPhaseReadyModel = m.waitForTargetPhaseReadyModel + return newModel, newModel.Init() + case key.Matches(msg, m.newBinding): + newModel := newRotateModel(m.client, m.pingResp, "") + return newModel, newModel.Init() + } + } + + return m, tea.Batch(cmds...) +} + +// View implements [tea.Model], it renders the program's UI, which is just a +// string. The view is rendered after every Update. +func (m *rotateModel) View() string { + var sb strings.Builder + writeln(&sb, m.logsModel.view()) + writeln(&sb, m.rotateStatusModel.view()) + writeln(&sb, m.caTypeModel.view()) + if m.caTypeModel.caType == "" { + return sb.String() + } + + writeln(&sb, m.currentPhaseModel.view()) + if m.currentPhaseModel.phase == "" { + return sb.String() + } + + if m.waitForCurrentPhaseReadyModel != nil && !m.confirmed { + writeln(&sb, m.waitForCurrentPhaseReadyModel.view()) + if !m.waitForCurrentPhaseReadyModel.ready() { + return sb.String() + } + } + + writeln(&sb, m.targetPhaseModel.view()) + if m.targetPhaseModel.targetPhase == "" { + return sb.String() + } + + sb.WriteString(authRotateTheme.normal.Render("Send request to rotate ")) + sb.WriteString(authRotateTheme.highlight.Render(string(m.caTypeModel.caType))) + sb.WriteString(authRotateTheme.normal.Render(" CA to ")) + sb.WriteString(authRotateTheme.highlight.Render(m.targetPhaseModel.targetPhase)) + sb.WriteString(authRotateTheme.normal.Render(" phase? (y/n): ")) + if !m.confirmed { + return sb.String() + } + writeln(&sb, authRotateTheme.highlight.PaddingBottom(1).Render("y")) + + writeln(&sb, m.sendRotateRequestModel.view()) + if !m.sendRotateRequestModel.success { + if mfaPrompt := m.mfaPromptModel.view(); len(mfaPrompt) > 0 { + writeln(&sb, mfaPrompt) + } + return sb.String() + } + + writeln(&sb, m.waitForTargetPhaseReadyModel.view()) + if !m.waitForTargetPhaseReadyModel.ready() { + return sb.String() + } + + helpBindings := []key.Binding{m.continueBinding, m.newBinding, m.quitBinding} + if m.waitForTargetPhaseReadyModel.targetPhase == "standby" { + helpBindings = helpBindings[1:] + } + writeln(&sb, authRotateTheme.normal.Render(m.help.ShortHelpView(helpBindings))) + + return sb.String() +} + +type rotateStatusModel struct { + client *authclient.Client + pingResp proto.PingResponse + spinner spinner.Model + + status *statusModel + err error +} + +func newRotateStatusModel(client *authclient.Client, pingResp proto.PingResponse) *rotateStatusModel { + status, err := newStatusModel(context.TODO(), client, pingResp) + return &rotateStatusModel{ + client: client, + pingResp: pingResp, + spinner: spinner.New(spinner.WithSpinner(spinner.Spinner{ + Frames: []string{"", ".", "..", "...", "...", "...", "...", "...", "..", ".", ""}, + FPS: time.Second / 8, + })), + status: status, + err: trace.Wrap(err), + } +} + +func (m *rotateStatusModel) updateRotateStatus(_ time.Time) tea.Msg { + rotateStatus, err := newStatusModel(context.TODO(), m.client, m.pingResp) + if err != nil { + return newTaggedMsg(err, rotateStatusTag{}) + } + return newTaggedMsg(rotateStatus, rotateStatusTag{}) +} + +type rotateStatusTag struct{} + +func (m *rotateStatusModel) init() tea.Cmd { + return tea.Batch( + tea.Tick(updateInterval, m.updateRotateStatus), + m.spinner.Tick) +} + +func (m *rotateStatusModel) update(msg tea.Msg) tea.Cmd { + msg, ok := matchTaggedMsg(msg, rotateStatusTag{}) + if !ok { + s, msg := m.spinner.Update(msg) + m.spinner = s + return msg + } + switch msg := msg.(type) { + case error: + m.err = trace.Wrap(msg) + case *statusModel: + m.status = msg + } + return tea.Tick(updateInterval, m.updateRotateStatus) +} + +func (m *rotateStatusModel) view() string { + if m.err != nil { + return authRotateTheme.errorMessage.Render("Error fetching cluster status:", m.err.Error()) + } + + var table strings.Builder + m.status.renderText(&table, false /*debug*/) + + var sb strings.Builder + sb.WriteString(authRotateTheme.title.Render("Current status")) + writeln(&sb, authRotateTheme.title.Render(m.spinner.View())) + sb.WriteString(authRotateTheme.normal. + Render(table.String())) + return sb.String() +} + +type caTypeModel struct { + caType types.CertAuthType + form *huh.Form +} + +func newCATypeModel(caType types.CertAuthType) *caTypeModel { + return &caTypeModel{ + caType: caType, + form: newSelectForm("Choose CA to rotate:", types.CertAuthTypes...), + } +} + +func (m *caTypeModel) init() tea.Cmd { + if m.caType != "" { + return nil + } + return m.form.Init() +} + +func (m *caTypeModel) update(msg tea.Msg) tea.Cmd { + if m.caType != "" { + return nil + } + form, cmd := m.form.Update(msg) + m.form = form.(*huh.Form) + if m.form.State == huh.StateCompleted { + m.caType = m.form.Get("selected").(types.CertAuthType) + } + return cmd +} + +func (m *caTypeModel) view() string { + if m.caType == "" { + return m.form.View() + } + var sb strings.Builder + sb.WriteString(authRotateTheme.normal.Render("Rotating the ")) + sb.WriteString(authRotateTheme.highlight.Render(string(m.caType))) + sb.WriteString(authRotateTheme.normal.Render(" CA.")) + return sb.String() +} + +type currentPhaseModel struct { + client *authclient.Client + pingResp proto.PingResponse + + spinner spinner.Model + caType types.CertAuthType + caID types.CertAuthID + phase string + err error +} + +func newCurrentPhaseModel(client *authclient.Client, pingResp proto.PingResponse, caType types.CertAuthType) *currentPhaseModel { + return ¤tPhaseModel{ + client: client, + pingResp: pingResp, + spinner: spinner.New(spinner.WithSpinner(spinner.Dot)), + caType: caType, + } +} + +func (m *currentPhaseModel) init() tea.Cmd { + return tea.Batch(m.getCurrentPhase, m.spinner.Tick) +} + +func (m *currentPhaseModel) getCurrentPhase() tea.Msg { + m.caID = types.CertAuthID{ + Type: m.caType, + DomainName: m.pingResp.ClusterName, + } + ca, err := m.client.GetCertAuthority(context.TODO(), m.caID, false /*loadSigningKeys*/) + if err != nil { + return newTaggedMsg(trace.Wrap(err, "failed to fetch CA status"), currentPhaseTag{}) + } + return newTaggedMsg(cmp.Or(ca.GetRotation().Phase, "standby"), currentPhaseTag{}) +} + +type currentPhaseTag struct{} + +func (m *currentPhaseModel) update(msg tea.Msg) tea.Cmd { + if m.phase != "" { + // Already got the current phase, no need for more updates. + return nil + } + msg, ok := matchTaggedMsg(msg, currentPhaseTag{}) + if !ok { + s, cmd := m.spinner.Update(msg) + m.spinner = s + return cmd + } + switch msg := msg.(type) { + case string: + m.phase = msg + case error: + m.err = trace.Wrap(msg) + return tea.Quit + } + return nil +} + +func (m *currentPhaseModel) view() string { + if m.phase == "" { + var sb strings.Builder + sb.WriteString(authRotateTheme.highlight.Render(m.spinner.View())) + sb.WriteString(authRotateTheme.normal.Render("Fetching current CA rotation phase")) + return sb.String() + } + var sb strings.Builder + sb.WriteString(authRotateTheme.normal.Render("Current rotation phase is ")) + sb.WriteString(authRotateTheme.highlight.Render(m.phase)) + sb.WriteString(authRotateTheme.normal.Render(".")) + if remaining := remainingPhases(m.phase); len(remaining) > 0 { + sb.WriteString(authRotateTheme.normal.Render("\nRemaining phases: ")) + for len(remaining) > 1 { + phase := remaining[0] + remaining = remaining[1:] + sb.WriteString(authRotateTheme.highlight.Render(phase)) + sb.WriteString(authRotateTheme.normal.Render(", ")) + } + sb.WriteString(authRotateTheme.highlight.Render(remaining[0])) + sb.WriteString(authRotateTheme.normal.Render(".")) + } + return sb.String() +} + +type targetPhaseModel struct { + caType types.CertAuthType + currentPhase string + targetPhase string + form *huh.Form +} + +func newTargetPhaseModel(caType types.CertAuthType, currentPhase string) *targetPhaseModel { + options := nextPhases(currentPhase) + if len(options) == 1 { + return &targetPhaseModel{ + caType: caType, + currentPhase: currentPhase, + targetPhase: options[0], + } + } + return &targetPhaseModel{ + caType: caType, + currentPhase: currentPhase, + form: newSelectForm("Select target phase:", options...), + } +} + +func (m *targetPhaseModel) init() tea.Cmd { + if m.form == nil { + return nil + } + return m.form.Init() +} + +func (m *targetPhaseModel) update(msg tea.Msg) tea.Cmd { + if m.targetPhase != "" { + return nil + } + form, cmd := m.form.Update(msg) + m.form = form.(*huh.Form) + if m.form.State == huh.StateCompleted { + m.targetPhase = m.form.GetString("selected") + } + return cmd +} + +func (m *targetPhaseModel) view() string { + if m.targetPhase == "" { + return m.form.View() + } + var sb strings.Builder + sb.WriteString(authRotateTheme.normal.Render("Target rotation phase is ")) + sb.WriteString(authRotateTheme.highlight.Render(m.targetPhase)) + writeln(&sb, authRotateTheme.normal.Render(".")) + sb.WriteString(authRotateTheme.normal.Width(maxWidth). + MarginTop(1).MarginBottom(1).MarginLeft(2). + Render(phaseHelpText(m.caType, m.currentPhase, m.targetPhase))) + return sb.String() +} + +type sendRotateRequestModel struct { + client *authclient.Client + spinner spinner.Model + caType types.CertAuthType + targetPhase string + success bool + err error +} + +type sendRotateRequestTag struct{} + +func newSendRotateRequestModel(client *authclient.Client, caType types.CertAuthType, targetPhase string) *sendRotateRequestModel { + return &sendRotateRequestModel{ + client: client, + spinner: spinner.New(spinner.WithSpinner(spinner.Dot)), + caType: caType, + targetPhase: targetPhase, + } +} + +func (m *sendRotateRequestModel) sendRotateRequest() tea.Msg { + err := m.client.RotateCertAuthority(context.TODO(), types.RotateRequest{ + Type: m.caType, + TargetPhase: m.targetPhase, + Mode: types.RotationModeManual, + }) + return newTaggedMsg(trace.Wrap(err), sendRotateRequestTag{}) +} + +func (m *sendRotateRequestModel) init() tea.Cmd { + return tea.Batch(m.sendRotateRequest, m.spinner.Tick) +} + +func (m *sendRotateRequestModel) update(msg tea.Msg) tea.Cmd { + if m.success { + return nil + } + msg, ok := matchTaggedMsg(msg, sendRotateRequestTag{}) + if !ok { + s, cmd := m.spinner.Update(msg) + m.spinner = s + return cmd + } + switch msg := msg.(type) { + case error: + m.err = trace.Wrap(msg) + } + if m.err == nil { + m.success = true + } + return nil +} + +func (m *sendRotateRequestModel) view() string { + if m.err != nil { + return authRotateTheme.errorMessage.Render("Error sending rotate request:", m.err.Error()) + } + if !m.success { + var sb strings.Builder + sb.WriteString(authRotateTheme.highlight.Render(m.spinner.View())) + sb.WriteString(authRotateTheme.normal.Render("Sending CA rotation request")) + return sb.String() + } + var sb strings.Builder + sb.WriteString(authRotateTheme.highlight.Render("âś“ ")) + switch m.targetPhase { + case "init": + sb.WriteString(authRotateTheme.normal.Render("Initiated certificate authority rotation.")) + default: + sb.WriteString(authRotateTheme.normal.Render("Updated rotation phase to ")) + sb.WriteString(authRotateTheme.highlight.Render(m.targetPhase)) + sb.WriteString(authRotateTheme.normal.Render(".")) + } + return sb.String() +} + +type writerModel struct { + style lipgloss.Style + buf []byte + mu sync.Mutex +} + +func newWriterModel(style lipgloss.Style) *writerModel { + return &writerModel{style: style} +} + +func (m *writerModel) view() string { + m.mu.Lock() + defer m.mu.Unlock() + if len(m.buf) == 0 { + return "" + } + // This will always be printed by the caller with writeln, remove trailing + // newlines if present. + b := m.buf + if b[len(b)-1] == '\n' { + b = b[:len(b)-1] + } + return m.style.Render(string(b)) +} + +func (m *writerModel) Write(b []byte) (int, error) { + m.mu.Lock() + defer m.mu.Unlock() + m.buf = append(m.buf, b...) + return len(b), nil +} + +type waitForReadyModel struct { + client *authclient.Client + targetPhase string + kindReadyModels []*waitForKindReadyModel + manualSteps []string + acknowledged bool + skipped bool + acknowledgeBinding key.Binding + skipBinding key.Binding + quitBinding key.Binding + help help.Model +} + +func newWaitForReadyModel(client *authclient.Client, caID types.CertAuthID, targetPhase string) *waitForReadyModel { + m := &waitForReadyModel{ + client: client, + targetPhase: targetPhase, + manualSteps: manualSteps(caID.Type, targetPhase), + acknowledgeBinding: key.NewBinding(key.WithKeys("a"), key.WithHelp("a", "acknowledge manual steps completed")), + skipBinding: key.NewBinding(key.WithKeys("s"), key.WithHelp("s", "skip all checks (unsafe)")), + quitBinding: key.NewBinding(key.WithKeys("q"), key.WithHelp("q", "quit")), + help: help.New(), + } + if caID.Type != types.HostCA { + return m + } + m.kindReadyModels = []*waitForKindReadyModel{ + newWaitForKindReadyModel( + targetPhase, "auth_servers", adaptServerGetter(client.GetAuthServers)).withMinReady(1), + newWaitForKindReadyModel( + targetPhase, "proxies", adaptServerGetter(client.GetProxies)), + newWaitForKindReadyModel( + targetPhase, "nodes", adaptServerGetter(func() ([]types.Server, error) { + return apiclient.GetAllResources[types.Server](context.TODO(), client, &proto.ListResourcesRequest{ + ResourceType: types.KindNode, + Namespace: apidefaults.Namespace, + PredicateExpression: `resource.sub_kind == ""`, + }) + })), + newWaitForKindReadyModel( + targetPhase, "app_servers", adaptServerGetter(func() ([]types.AppServer, error) { + return client.GetApplicationServers(context.TODO(), apidefaults.Namespace) + })), + newWaitForKindReadyModel( + targetPhase, "db_servers", adaptServerGetter(func() ([]types.DatabaseServer, error) { + return client.GetDatabaseServers(context.TODO(), apidefaults.Namespace) + })), + newWaitForKindReadyModel( + targetPhase, "kube_servers", adaptServerGetter(func() ([]types.KubeServer, error) { + return client.GetKubernetesServers(context.TODO()) + })), + } + return m +} + +func adaptServerGetter[T rotatable](f func() ([]T, error)) func() ([]rotatable, error) { + return func() ([]rotatable, error) { + servers, err := f() + if err != nil { + return nil, trace.Wrap(err) + } + out := make([]rotatable, len(servers)) + for i, server := range servers { + out[i] = server + } + return out, nil + } +} + +func (m *waitForReadyModel) ready() bool { + if m.skipped { + return true + } + if len(m.manualSteps) > 0 && !m.acknowledged { + return false + } + for _, kindReadyModel := range m.kindReadyModels { + if !kindReadyModel.ready() { + return false + } + } + return true +} + +func (m *waitForReadyModel) init() tea.Cmd { + var cmds []tea.Cmd + for _, kindReadyModel := range m.kindReadyModels { + cmds = append(cmds, kindReadyModel.init()) + } + return tea.Batch(cmds...) +} + +func (m *waitForReadyModel) update(msg tea.Msg) tea.Cmd { + if m.ready() { + return nil + } + switch msg := msg.(type) { + case tea.KeyMsg: + switch { + case key.Matches(msg, m.acknowledgeBinding): + m.acknowledged = true + case key.Matches(msg, m.skipBinding): + m.skipped = true + for _, kindReadyModel := range m.kindReadyModels { + kindReadyModel.skipped = true + } + } + } + var cmds []tea.Cmd + for i := range m.kindReadyModels { + if m.kindReadyModels[i].ready() { + continue + } + cmds = append(cmds, m.kindReadyModels[i].update(msg)) + } + return tea.Batch(cmds...) +} + +func (m *waitForReadyModel) view() string { + var sb strings.Builder + for _, kindReadyModel := range m.kindReadyModels { + writeln(&sb, kindReadyModel.view()) + } + manualStepPrefix := authRotateTheme.errorMessage.Render("! ") + if m.acknowledged { + manualStepPrefix = authRotateTheme.highlight.Render("âś“ ") + } + for _, manualStep := range m.manualSteps { + writeln(&sb, lipgloss.JoinHorizontal(0, + manualStepPrefix, + authRotateTheme.normal.Width(maxWidth-2).Render(manualStep), + )) + } + if !m.ready() { + helpKeys := []key.Binding{m.acknowledgeBinding, m.skipBinding, m.quitBinding} + if m.acknowledged { + helpKeys = helpKeys[1:] + } + writeln(&sb, authRotateTheme.normal.PaddingTop(1).Render( + m.help.ShortHelpView(helpKeys), + )) + } + return sb.String() +} + +type readyStatus struct { + totalCount, readyCount int +} + +type waitForKindReadyModel struct { + targetPhase string + desc string + getter func() ([]rotatable, error) + minReady int + spinner spinner.Model + readyStatus readyStatus + err error + gotFirstResponse bool + skipped bool +} + +type rotatable interface { + GetRotation() types.Rotation +} + +func newWaitForKindReadyModel(targetPhase string, desc string, getter func() ([]rotatable, error)) *waitForKindReadyModel { + return &waitForKindReadyModel{ + targetPhase: targetPhase, + desc: desc, + getter: getter, + spinner: spinner.New(spinner.WithSpinner(spinner.Dot)), + } +} + +func (m *waitForKindReadyModel) withMinReady(n int) *waitForKindReadyModel { + m.minReady = n + return m +} + +func (m *waitForKindReadyModel) getKindServersStatus() tea.Msg { + servers, err := m.getter() + if err != nil { + return newTaggedMsg(trace.Wrap(err), m.desc) + } + ready := 0 + for _, server := range servers { + phase := server.GetRotation().Phase + if phase == m.targetPhase || m.targetPhase == "standby" && phase == "" { + ready++ + } + } + return newTaggedMsg(readyStatus{totalCount: len(servers), readyCount: ready}, m.desc) +} + +func (m *waitForKindReadyModel) ready() bool { + return m.gotFirstResponse && + m.readyStatus.readyCount >= m.minReady && + m.readyStatus.readyCount == m.readyStatus.totalCount +} + +func (m *waitForKindReadyModel) init() tea.Cmd { + return tea.Batch(m.getKindServersStatus, m.spinner.Tick) +} + +func (m *waitForKindReadyModel) update(msg tea.Msg) tea.Cmd { + msg, ok := matchTaggedMsg(msg, m.desc) + if !ok { + s, cmd := m.spinner.Update(msg) + m.spinner = s + return cmd + } + switch msg := msg.(type) { + case error: + m.err = trace.Wrap(msg) + return tea.Tick(updateInterval, func(time.Time) tea.Msg { return m.getKindServersStatus() }) + case readyStatus: + m.gotFirstResponse = true + m.err = nil + m.readyStatus = msg + if m.ready() { + return nil + } + return tea.Tick(updateInterval, func(time.Time) tea.Msg { return m.getKindServersStatus() }) + } + return nil +} + +func (m *waitForKindReadyModel) view() string { + if m.err != nil { + var sb strings.Builder + sb.WriteString(authRotateTheme.errorMessage.Render("x ")) + sb.WriteString(authRotateTheme.normal.Render("Error fetching ")) + sb.WriteString(authRotateTheme.highlight.Render(m.desc)) + sb.WriteString(authRotateTheme.normal.Render(" status: ")) + sb.WriteString(authRotateTheme.errorMessage.Render(m.err.Error())) + return sb.String() + } + if m.ready() { + var sb strings.Builder + sb.WriteString(authRotateTheme.highlight.Render("âś“ ")) + if m.readyStatus.totalCount == 0 { + sb.WriteString(authRotateTheme.normal.Render("No ")) + sb.WriteString(authRotateTheme.highlight.Render(m.desc)) + sb.WriteString(authRotateTheme.normal.Render(" found.")) + return sb.String() + } + sb.WriteString(authRotateTheme.normal.Render("All ")) + sb.WriteString(authRotateTheme.highlight.Render(m.desc)) + sb.WriteString(authRotateTheme.normal.Render(" are in the ")) + sb.WriteString(authRotateTheme.highlight.Render(m.targetPhase)) + sb.WriteString(authRotateTheme.normal.Render( + fmt.Sprintf(" phase (%d/%d).", m.readyStatus.readyCount, m.readyStatus.totalCount))) + return sb.String() + } + var sb strings.Builder + if m.skipped { + sb.WriteString(authRotateTheme.errorMessage.Render("! ")) + } else { + sb.WriteString(authRotateTheme.highlight.Render(m.spinner.View())) + } + if m.gotFirstResponse { + if m.skipped { + sb.WriteString(authRotateTheme.normal.Render("Skipped waiting for ")) + } else { + sb.WriteString(authRotateTheme.normal.Render("Waiting for ")) + } + sb.WriteString(authRotateTheme.highlight.Render(m.desc)) + sb.WriteString(authRotateTheme.normal.Render(" to enter ")) + sb.WriteString(authRotateTheme.highlight.Render(m.targetPhase)) + sb.WriteString(authRotateTheme.normal.Render(fmt.Sprintf(" phase (%d/%d). ", + m.readyStatus.readyCount, m.readyStatus.totalCount))) + } else { + if m.skipped { + sb.WriteString(authRotateTheme.normal.Render("Skipped checking current rotation phase of ")) + } else { + sb.WriteString(authRotateTheme.normal.Render("Checking current rotation phase of ")) + } + sb.WriteString(authRotateTheme.highlight.Render(m.desc)) + sb.WriteString(authRotateTheme.normal.Render(". ")) + } + sb.WriteString(authRotateTheme.normal.Render(fmt.Sprintf("Run 'tctl get %s' to check status.", m.desc))) + return sb.String() + +} + +type taggedMsg[T comparable] struct { + msg tea.Msg + tag T +} + +func newTaggedMsg[T comparable](msg tea.Msg, tag T) taggedMsg[T] { + return taggedMsg[T]{ + msg: msg, + tag: tag, + } +} + +func matchTaggedMsg[T comparable](msg tea.Msg, tag T) (tea.Msg, bool) { + if msg, ok := msg.(taggedMsg[T]); ok && msg.tag == tag { + return msg.msg, true + } + return msg, false +} + +func phaseHelpText(caType types.CertAuthType, currentPhase, targetPhase string) string { + var sb strings.Builder + switch targetPhase { + case "init": + initPhaseHelpText(&sb, caType) + case "update_clients": + updateClientsPhaseHelpText(&sb, caType) + case "update_servers": + updateServersPhaseHelpText(&sb, caType) + case "rollback": + rollbackPhaseHelpText(&sb) + case "standby": + standbyPhaseHelpText(&sb, caType, currentPhase) + } + return sb.String() +} + +func initPhaseHelpText(sb *strings.Builder, caType types.CertAuthType) { + sb.WriteString("The init phase initiates a new Certificate Authority (CA) rotation. ") + sb.WriteString("New CA key pairs and certificates will be generated and must be trusted but will not yet be used.") + switch caType { + case types.HostCA: + sb.WriteString("\nDuring this phase all Teleport services will automatically begin to trust the new SSH host key and X509 CA certificate.") + } +} + +func updateClientsPhaseHelpText(sb *strings.Builder, caType types.CertAuthType) { + sb.WriteString("In the update_clients phase the new CA keys become the active signing keys for all new certificates issued by the CA. ") + sb.WriteString("Clients will immediately begin to use their new certificates, but servers will continue to use their original certificates.") + switch caType { + case types.HostCA: + sb.WriteString("\nDuring this phase, all Teleport services will automatically retrieve new certificates issued by the new CA.") + case types.OpenSSHCA: + sb.WriteString("\nAll new connections to OpenSSH hosts will begin to use certificates issued by the new CA keys.") + case types.UserCA: + sb.WriteString("\nAll new connections to Windows desktops will begin to use certificates issued by the new CA certificate. ") + case types.DatabaseClientCA: + sb.WriteString("\nAll new database connections will begin to use certificates issued by the new CA certificate.") + default: + sb.WriteString("\nAll client certificates issued by this CA must be re-issued before proceeding to the update_servers phase.") + } +} + +func updateServersPhaseHelpText(sb *strings.Builder, caType types.CertAuthType) { + sb.WriteString("In the update_servers phase servers will begin to use certificates issued by the new CA.") +} + +func rollbackPhaseHelpText(sb *strings.Builder) { + sb.WriteString("In the rollback phase the original CA keys become the active signing keys for all new certificates issued by the CA. ") + sb.WriteString("The new CA certificates/keys remain trusted until proceeding to the standby phase.") +} + +func standbyPhaseHelpText(sb *strings.Builder, caType types.CertAuthType, previousPhase string) { + sb.WriteString("The standby phase completes the ") + switch previousPhase { + case "rollback": + sb.WriteString("rollback") + default: + sb.WriteString("rotation") + } + sb.WriteByte('.') + + switch caType { + case types.HostCA: + sb.WriteString("\nAfter entering the standby phase all Teleport Services will stop trusting the ") + switch previousPhase { + case "rollback": + sb.WriteString("new CA and exclusively trust the original CA") + default: + sb.WriteString("old CA") + } + sb.WriteString(" X509 certificate and SSH key.") + } +} + +func manualSteps(caType types.CertAuthType, phase string) []string { + const trustedClusterStep = "Wait up to 30 minutes for any root or leaf clusters to follow the rotation." + const remoteReloginStep = "If you are currently using tctl remotely and logged in with tsh, you must log out and log back in." + const offlineNodesStep = "If any Teleport services may currently be offline, wait for them to come online and follow the rotation." + switch caType { + case types.HostCA: + switch phase { + case "init": + return []string{offlineNodesStep, trustedClusterStep} + case "update_clients": + return []string{offlineNodesStep, trustedClusterStep, remoteReloginStep} + case "update_servers": + return []string{ + "Any OpenSSH hosts must be issued new host certificates signed by the new CA.", + offlineNodesStep, + trustedClusterStep, + } + case "rollback": + return []string{ + "Any OpenSSH host certificates reissued during the rotation must be reissued again to revert to the original issuing CA.", + offlineNodesStep, + trustedClusterStep, + } + case "standby": + return []string{offlineNodesStep, trustedClusterStep} + } + case types.OpenSSHCA: + switch phase { + case "init": + return []string{ + "Any OpenSSH hosts must be updated to trust both the new and old CA keys.", + trustedClusterStep, + } + case "update_clients": + return []string{trustedClusterStep} + case "update_servers": + return []string{trustedClusterStep} + case "rollback": + return []string{ + "Any OpenSSH hosts updated to trust the new CA keys during the update_servers phase should be reverted to only trust the original CA keys.", + trustedClusterStep, + } + case "standby": + return []string{ + "Any OpenSSH hosts should be updated to stop trusting the CA keys that have now been rotated out.", + trustedClusterStep, + } + } + case types.UserCA: + switch phase { + case "init": + return []string{ + "All Windows desktops must be updated to trust both the new and old CA certificates.", + trustedClusterStep, + } + case "update_clients": + return []string{trustedClusterStep} + case "update_servers": + return []string{ + "Wait up to 30 hours for all user sessions to expire, or else users may have to log out and log back in.", + trustedClusterStep, + remoteReloginStep, + } + case "rollback": + return []string{ + "Any Windows desktops updated to trust the new CA certificate during the update_servers phase should be reverted to only trust the original CA certificate.", + trustedClusterStep, + } + case "standby": + return []string{ + "All Windows desktops should be updated to stop trusting the CA certificates that have now been rotated out.", + trustedClusterStep, + } + } + case types.DatabaseCA: + switch phase { + case "init": + return []string{ + "If you also need to rotate the db_client CA, rotate it to the init phase now to reconfigure self-hosted databases with new server certificates and trusted client CAs simultaneously.", + "All self-hosted databases must be issued new certificates signed by the new CA.", + } + case "rollback": + return []string{"Any self-hosted database certificates reissued during the rotation must be reissued again to revert to the original issuing CA."} + } + case types.DatabaseClientCA: + switch phase { + case "init": + return []string{ + "If you also need to rotate the db_client CA, rotate it to the init phase now to reconfigure self-hosted databases with new server certificates and trusted client CAs simultaneously.", + "All self-hosted databases must be updated to trust both the new and old CA certificates.", + } + case "standby": + return []string{"All self-hosted databases should be updated to stop trusting the CA certificates that have now been rotated out."} + } + case types.SAMLIDPCA: + switch phase { + case "update_clients": + return []string{"Any service providers that rely on the SAML IdP must by updated to trust the new CA, follow the SAML IdP guide: https://goteleport.com/docs/admin-guides/access-controls/idps/saml-guide/"} + case "rollback": + return []string{"Any service provider configuration changes made during the rotation must be reverted."} + } + case types.OIDCIdPCA: + // No manual steps required. + return nil + case types.SPIFFECA: + // TODO(strideynet): populate any known manual steps during SPIFFE CA rotation. + fallthrough + case types.OktaCA: + // TODO(smallinsky): populate any known manual steps during Okta CA rotation. + fallthrough + default: + return []string{"Consult the CA rotation docs for any manual steps that may be required: https://goteleport.com/docs/admin-guides/management/operations/ca-rotation/"} + } + return nil +} + +func nextPhases(currentPhase string) []string { + switch currentPhase { + case "standby": + return []string{"init"} + case "init": + return []string{"update_clients", "rollback"} + case "update_clients": + return []string{"update_servers", "rollback"} + case "update_servers": + return []string{"standby", "rollback"} + case "rollback": + return []string{"standby"} + } + return nil +} + +var ( + optimisticPhases = [...]string{"init", "update_clients", "update_servers", "standby"} +) + +func remainingPhases(afterPhase string) []string { + switch afterPhase { + case "standby": + return optimisticPhases[:] + case "init": + return optimisticPhases[1:] + case "update_clients": + return optimisticPhases[2:] + case "update_servers": + return optimisticPhases[3:] + case "rollback": + return []string{"standby"} + } + return nil +} + +func writeln(sb *strings.Builder, s string) { + sb.WriteString(s) + sb.WriteByte('\n') +} + +func setupLoggers(logWriter io.Writer) { + slog.SetDefault(slog.New(logutils.NewSlogTextHandler( + logWriter, + logutils.SlogTextHandlerConfig{EnableColors: true}, + ))) + logrus.StandardLogger().SetOutput(logWriter) +} + +func setupMFAPrompt(client *authclient.Client, pingResp proto.PingResponse, promptWriter io.Writer) { + client.SetMFAPromptConstructor(func(opts ...mfa.PromptOpt) mfa.Prompt { + promptCfg := libmfa.NewPromptConfig(pingResp.ProxyPublicAddr, opts...) + return libmfa.NewCLIPrompt(&libmfa.CLIPromptConfig{ + PromptConfig: *promptCfg, + Writer: promptWriter, + StdinFunc: func() prompt.StdinReader { + return brokenStdinReader{} + }, + }) + }) +} + +var errNoStdin = fmt.Errorf("interactive CA rotation does not support reading passwords from stdin") + +// brokenStdinReader implements [prompt.StdinReader] and returns errNoStdin for +// all methods. Currently this should be unnecessary because MFA for admin +// actions only applies when the only MFA method is webauthn, which should never +// prompt for a password. If we ever enable MFA for admin actions with OTP, +// we'll hit this error instead of bubbletea competing for stdin with the +// password prompt. +type brokenStdinReader struct{} + +func (brokenStdinReader) IsTerminal() bool { return true } +func (brokenStdinReader) ReadContext(_ context.Context) ([]byte, error) { return nil, errNoStdin } +func (brokenStdinReader) ReadPassword(_ context.Context) ([]byte, error) { return nil, errNoStdin } + +func newSelectForm[T comparable](title string, options ...T) *huh.Form { + keyMap := huh.NewDefaultKeyMap() + keyMap.Quit = key.NewBinding(key.WithKeys("q"), key.WithHelp("q", "quit")) + selectField := &fieldWithKeyBinds{ + Field: huh.NewSelect[T](). + Key("selected"). + Options(huh.NewOptions(options...)...). + Title(title), + keyBinds: []key.Binding{ + keyMap.Select.Up, + keyMap.Select.Down, + keyMap.Select.Submit, + keyMap.Quit, + }, + } + return huh.NewForm( + huh.NewGroup(selectField).WithKeyMap(keyMap), + ).WithTheme(authRotateTheme.formTheme) +} + +type fieldWithKeyBinds struct { + huh.Field + keyBinds []key.Binding +} + +func (f *fieldWithKeyBinds) Update(msg tea.Msg) (tea.Model, tea.Cmd) { + field, cmd := f.Field.Update(msg) + f.Field = field.(huh.Field) + return f, cmd +} + +func (f *fieldWithKeyBinds) KeyBinds() []key.Binding { + return f.keyBinds +} diff --git a/tool/tctl/common/resource_command.go b/tool/tctl/common/resource_command.go index 66a916c6711b1..e8d798d8c7896 100644 --- a/tool/tctl/common/resource_command.go +++ b/tool/tctl/common/resource_command.go @@ -49,7 +49,6 @@ import ( dbobjectv1 "github.com/gravitational/teleport/api/gen/proto/go/teleport/dbobject/v1" dbobjectimportrulev1 "github.com/gravitational/teleport/api/gen/proto/go/teleport/dbobjectimportrule/v1" devicepb "github.com/gravitational/teleport/api/gen/proto/go/teleport/devicetrust/v1" - gitserverv1 "github.com/gravitational/teleport/api/gen/proto/go/teleport/gitserver/v1" loginrulepb "github.com/gravitational/teleport/api/gen/proto/go/teleport/loginrule/v1" machineidv1pb "github.com/gravitational/teleport/api/gen/proto/go/teleport/machineid/v1" pluginsv1 "github.com/gravitational/teleport/api/gen/proto/go/teleport/plugins/v1" @@ -1980,7 +1979,7 @@ func (rc *ResourceCommand) Delete(ctx context.Context, client *authclient.Client } fmt.Printf("static host user %q has been deleted\n", rc.ref.Name) case types.KindGitServer: - if _, err := client.GitServerClient().DeleteGitServer(ctx, &gitserverv1.DeleteGitServerRequest{Name: rc.ref.Name}); err != nil { + if err := client.GitServerClient().DeleteGitServer(ctx, rc.ref.Name); err != nil { return trace.Wrap(err) } fmt.Printf("git_server %q has been deleted\n", rc.ref.Name) @@ -3232,29 +3231,27 @@ func (rc *ResourceCommand) getCollection(ctx context.Context, client *authclient } return &accessMonitoringRuleCollection{items: rules}, nil case types.KindGitServer: - var servers []types.Server + var page, servers []types.Server // TODO(greedy52) use unified resource request once available. if rc.ref.Name != "" { - server, err := client.GitServerClient().GetGitServer(ctx, &gitserverv1.GetGitServerRequest{Name: rc.ref.Name}) + server, err := client.GitServerClient().GetGitServer(ctx, rc.ref.Name) if err != nil { return nil, trace.Wrap(err) } return &serverCollection{servers: append(servers, server)}, nil } - req := &gitserverv1.ListGitServersRequest{} + var err error + var token string for { - resp, err := client.GitServerClient().ListGitServers(ctx, req) + page, token, err = client.GitServerClient().ListGitServers(ctx, 0, token) if err != nil { return nil, trace.Wrap(err) } - for _, server := range resp.Servers { - servers = append(servers, server) - } - if resp.NextPageToken == "" { + servers = append(servers, page...) + if token == "" { break } - req.PageToken = resp.NextPageToken } // TODO(greedy52) consider making dedicated git server collection. return &serverCollection{servers: servers}, nil @@ -3676,14 +3673,10 @@ func (rc *ResourceCommand) createGitServer(ctx context.Context, client *authclie if err != nil { return trace.Wrap(err) } - serverV2, ok := server.(*types.ServerV2) - if !ok { - return trace.CompareFailed("expecting types.ServerV2 but got %T", server) - } if rc.IsForced() { - _, err = client.GitServerClient().UpsertGitServer(ctx, &gitserverv1.UpsertGitServerRequest{Server: serverV2}) + _, err = client.GitServerClient().UpsertGitServer(ctx, server) } else { - _, err = client.GitServerClient().CreateGitServer(ctx, &gitserverv1.CreateGitServerRequest{Server: serverV2}) + _, err = client.GitServerClient().CreateGitServer(ctx, server) } if err != nil { return trace.Wrap(err) @@ -3696,11 +3689,7 @@ func (rc *ResourceCommand) updateGitServer(ctx context.Context, client *authclie if err != nil { return trace.Wrap(err) } - serverV2, ok := server.(*types.ServerV2) - if !ok { - return trace.CompareFailed("expecting types.ServerV2 but got %T", server) - } - _, err = client.GitServerClient().UpdateGitServer(ctx, &gitserverv1.UpdateGitServerRequest{Server: serverV2}) + _, err = client.GitServerClient().UpdateGitServer(ctx, server) if err != nil { return trace.Wrap(err) } diff --git a/tool/tctl/common/resource_command_test.go b/tool/tctl/common/resource_command_test.go index a3dd729d72477..b3e13e9bffb6d 100644 --- a/tool/tctl/common/resource_command_test.go +++ b/tool/tctl/common/resource_command_test.go @@ -1939,11 +1939,15 @@ func testCreateAppServer(t *testing.T, clt *authclient.Client) { kind: app_server metadata: name: my-integration + labels: + account_id: "123456789012" spec: app: kind: app metadata: name: my-integration + labels: + account_id: "123456789012" spec: uri: https://console.aws.amazon.com integration: my-integration @@ -1987,7 +1991,7 @@ version: v3 appServers := mustDecodeJSON[[]*types.AppServerV3](t, buf) require.Len(t, appServers, 1) - expectedAppServer, err := types.NewAppServerForAWSOIDCIntegration("my-integration", "c6cfe5c2-653f-4e5d-a914-bfac5a7baf38", "integration.example.com") + expectedAppServer, err := types.NewAppServerForAWSOIDCIntegration("my-integration", "c6cfe5c2-653f-4e5d-a914-bfac5a7baf38", "integration.example.com", map[string]string{"account_id": "123456789012"}) require.NoError(t, err) require.Empty(t, cmp.Diff( expectedAppServer, diff --git a/tool/tctl/common/status_command.go b/tool/tctl/common/status_command.go index 40f6e90f2f63f..38f19c79ca71e 100644 --- a/tool/tctl/common/status_command.go +++ b/tool/tctl/common/status_command.go @@ -72,22 +72,12 @@ func (c *StatusCommand) TryRun(ctx context.Context, cmd string, client *authclie // Status is called to execute "status" CLI command. func (c *StatusCommand) Status(ctx context.Context, client *authclient.Client) error { - pingRsp, err := client.Ping(ctx) + pingResp, err := client.Ping(ctx) if err != nil { return trace.Wrap(err) } - var authorities []types.CertAuthority - for _, caType := range types.CertAuthTypes { - cas, err := client.GetCertAuthorities(ctx, caType, false) - if err != nil { - slog.WarnContext(ctx, "Failed to fetch CA.", "type", caType, "error", err) - continue - } - authorities = append(authorities, cas...) - } - - status, err := newStatusModel(pingRsp, authorities) + status, err := newStatusModel(ctx, client, pingResp) if err != nil { return trace.Wrap(err) } @@ -102,18 +92,23 @@ type statusModel struct { authorities []*authorityStatusModel } -func newStatusModel(pingResp proto.PingResponse, authorities []types.CertAuthority) (*statusModel, error) { +func newStatusModel(ctx context.Context, client *authclient.Client, pingResp proto.PingResponse) (*statusModel, error) { + var authorities []types.CertAuthority + for _, caType := range types.CertAuthTypes { + cas, err := client.GetCertAuthorities(ctx, caType, false) + if err != nil { + slog.WarnContext(ctx, "Failed to fetch CA", "type", caType, "error", err) + continue + } + authorities = append(authorities, cas...) + } cluster, err := newClusterStatusModel(pingResp, authorities) if err != nil { return nil, trace.Wrap(err) } authorityModels := make([]*authorityStatusModel, 0, len(authorities)) for _, authority := range authorities { - authorityStatus, err := newAuthorityStatusModel(authority) - if err != nil { - return nil, trace.Wrap(err) - } - authorityModels = append(authorityModels, authorityStatus) + authorityModels = append(authorityModels, newAuthorityStatusModel(authority)) } return &statusModel{ cluster: cluster, @@ -132,7 +127,7 @@ func (m *statusModel) renderText(w io.Writer, debug bool) error { summaryTable.AddRow([]string{"", caPin}) } } - if _, err := io.Copy(w, summaryTable.AsBuffer()); err != nil { + if err := summaryTable.WriteTo(w); err != nil { return trace.Wrap(err) } fmt.Fprintln(w, "") @@ -163,8 +158,7 @@ func (m *statusModel) renderText(w io.Writer, debug bool) error { keysTable.AddRow(row) } } - _, err := io.Copy(w, keysTable.AsBuffer()) - return trace.Wrap(err) + return trace.Wrap(keysTable.WriteTo(w)) } // sortRows sorts the rows by each column left to right. @@ -215,14 +209,14 @@ type authorityStatusModel struct { additionalTrustedKeys []*authorityKeyModel } -func newAuthorityStatusModel(authority types.CertAuthority) (*authorityStatusModel, error) { +func newAuthorityStatusModel(authority types.CertAuthority) *authorityStatusModel { return &authorityStatusModel{ clusterName: authority.GetClusterName(), authorityType: authority.GetType(), rotationStatus: authority.GetRotation(), activeKeys: newAuthorityKeyModels(authority.GetActiveKeys()), additionalTrustedKeys: newAuthorityKeyModels(authority.GetAdditionalTrustedKeys()), - }, nil + } } type authorityKeyModel struct { diff --git a/tool/teleport-update/main.go b/tool/teleport-update/main.go index ecd4dc7268267..aa01952a1dbec 100644 --- a/tool/teleport-update/main.go +++ b/tool/teleport-update/main.go @@ -80,6 +80,8 @@ type cliConfig struct { InstallSuffix string // SelfSetup mode for using the current version of the teleport-update to setup the update service. SelfSetup bool + // UpdateNow forces an immediate update. + UpdateNow bool } func Run(args []string) int { @@ -136,6 +138,8 @@ func Run(args []string) int { unpinCmd := app.Command("unpin", "Unpin the current version, allowing it to be updated.") updateCmd := app.Command("update", "Update the agent to the latest version, if a new version is available.") + updateCmd.Flag("now", "Force immediate update even if update window is not active."). + Short('n').BoolVar(&ccfg.UpdateNow) updateCmd.Flag("self-setup", "Use the current teleport-update binary to create systemd service config for auto-updates."). Short('s').Hidden().BoolVar(&ccfg.SelfSetup) @@ -345,7 +349,7 @@ func cmdUpdate(ctx context.Context, ccfg *cliConfig) error { } }() - if err := updater.Update(ctx); err != nil { + if err := updater.Update(ctx, ccfg.UpdateNow); err != nil { return trace.Wrap(err) } return nil diff --git a/tool/tsh/common/app_aws.go b/tool/tsh/common/app_aws.go index 0869d5c09cc01..7c11458b2f300 100644 --- a/tool/tsh/common/app_aws.go +++ b/tool/tsh/common/app_aws.go @@ -27,8 +27,9 @@ import ( "strings" "sync" - awsarn "github.com/aws/aws-sdk-go/aws/arn" - "github.com/aws/aws-sdk-go/aws/credentials" + "github.com/aws/aws-sdk-go-v2/aws" + "github.com/aws/aws-sdk-go-v2/aws/arn" + "github.com/aws/aws-sdk-go-v2/credentials" "github.com/google/uuid" "github.com/gravitational/trace" @@ -136,7 +137,7 @@ type awsApp struct { cf *CLIConf - credentials *credentials.Credentials + credentials aws.CredentialsProvider credentialsOnce sync.Once } @@ -168,13 +169,8 @@ func (a *awsApp) GetAppName() string { // The first method is always preferred as the original hostname is preserved // through forward proxy. func (a *awsApp) StartLocalProxies(ctx context.Context, opts ...alpnproxy.LocalProxyConfigOpt) error { - cred, err := a.GetAWSCredentials() - if err != nil { - return trace.Wrap(err) - } - awsMiddleware := &alpnproxy.AWSAccessMiddleware{ - AWSCredentials: cred, + AWSCredentialsV2Provider: a.GetAWSCredentialsProvider(), } // AWS endpoint URL mode @@ -184,14 +180,14 @@ func (a *awsApp) StartLocalProxies(ctx context.Context, opts ...alpnproxy.LocalP } // HTTPS proxy mode - err = a.StartLocalProxyWithForwarder(ctx, alpnproxy.MatchAWSRequests, alpnproxy.WithHTTPMiddleware(awsMiddleware)) + err := a.StartLocalProxyWithForwarder(ctx, alpnproxy.MatchAWSRequests, alpnproxy.WithHTTPMiddleware(awsMiddleware)) return trace.Wrap(err) } -// GetAWSCredentials generates fake AWS credentials that are used for -// signing an AWS request during AWS API calls and verified on local AWS proxy -// side. -func (a *awsApp) GetAWSCredentials() (*credentials.Credentials, error) { +// GetAWSCredentialsProvider returns an [aws.CredentialsProvider] that generates +// fake AWS credentials that are used for signing an AWS request during AWS API +// calls and verified on local AWS proxy side. +func (a *awsApp) GetAWSCredentialsProvider() aws.CredentialsProvider { // There is no specific format or value required for access key and secret, // as long as the AWS clients and the local proxy are using the same // credentials. The only constraint is the access key must have a length @@ -200,17 +196,13 @@ func (a *awsApp) GetAWSCredentials() (*credentials.Credentials, error) { // // https://docs.aws.amazon.com/STS/latest/APIReference/API_Credentials.html a.credentialsOnce.Do(func() { - a.credentials = credentials.NewStaticCredentials( + a.credentials = credentials.NewStaticCredentialsProvider( getEnvOrDefault(awsAccessKeyIDEnvVar, uuid.NewString()), getEnvOrDefault(awsSecretAccessKeyEnvVar, uuid.NewString()), "", ) }) - - if a.credentials == nil { - return nil, trace.BadParameter("missing credentials") - } - return a.credentials, nil + return a.credentials } // GetEnvVars returns required environment variables to configure the @@ -220,12 +212,7 @@ func (a *awsApp) GetEnvVars() (map[string]string, error) { return nil, trace.NotFound("ALPN proxy is not running") } - cred, err := a.GetAWSCredentials() - if err != nil { - return nil, trace.Wrap(err) - } - - credValues, err := cred.Get() + cred, err := a.GetAWSCredentialsProvider().Retrieve(context.Background()) if err != nil { return nil, trace.Wrap(err) } @@ -234,8 +221,8 @@ func (a *awsApp) GetEnvVars() (map[string]string, error) { // AWS CLI and SDKs can load credentials through environment variables. // // https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-envvars.html - "AWS_ACCESS_KEY_ID": credValues.AccessKeyID, - "AWS_SECRET_ACCESS_KEY": credValues.SecretAccessKey, + "AWS_ACCESS_KEY_ID": cred.AccessKeyID, + "AWS_SECRET_ACCESS_KEY": cred.SecretAccessKey, "AWS_CA_BUNDLE": a.appInfo.appLocalCAPath(a.cf.SiteName), } @@ -318,7 +305,7 @@ func getARNFromFlags(cf *CLIConf, app types.Application, logins []string) (strin } // Match by role ARN. - if awsarn.IsARN(cf.AWSRole) { + if arn.IsARN(cf.AWSRole) { if role, found := roles.FindRoleByARN(cf.AWSRole); found { return role.ARN, nil } diff --git a/tool/tsh/common/app_test.go b/tool/tsh/common/app_test.go index 87b9dcb24239b..20873f4d072fb 100644 --- a/tool/tsh/common/app_test.go +++ b/tool/tsh/common/app_test.go @@ -24,9 +24,11 @@ import ( "crypto/tls" "encoding/json" "fmt" + "io" "net/http" "net/http/httptest" "os/user" + "strings" "testing" "time" @@ -44,6 +46,7 @@ import ( "github.com/gravitational/teleport/lib/client" "github.com/gravitational/teleport/lib/events" "github.com/gravitational/teleport/lib/service/servicecfg" + "github.com/gravitational/teleport/lib/tlsca" testserver "github.com/gravitational/teleport/tool/teleport/testenv" ) @@ -597,3 +600,216 @@ uri: https://test-app.example.com:8443 }) } } + +func TestWriteAppTable(t *testing.T) { + defaultAppListings := []appListing{ + appListing{ + Proxy: "example.com", + Cluster: "foo-cluster", + App: mustMakeNewAppV3(t, types.Metadata{Name: "root-app"}, types.AppSpecV3{ + // Short URLs, because in tests the width of the term is just 80 characters and the public + // address column gets truncated very early. + PublicAddr: "https://root-app.example.com", + URI: "http://localhost:8080", + }), + }, + appListing{ + Proxy: "example.com", + Cluster: "bar-cluster", + App: mustMakeNewAppV3(t, types.Metadata{Name: "leaf-app"}, types.AppSpecV3{ + PublicAddr: "https://leaf-app.example.com", + URI: "http://localhost:4242", + }), + }, + } + appListingsWithMultiPort := append(defaultAppListings, + appListing{ + Proxy: "example.com", + Cluster: "foo-cluster", + App: mustMakeNewAppV3(t, types.Metadata{Name: "mp-root"}, types.AppSpecV3{ + PublicAddr: "https://mp-root.example.com", + URI: "tcp://localhost", + TCPPorts: []*types.PortRange{ + &types.PortRange{Port: 1337}, + &types.PortRange{Port: 4200, EndPort: 4242}, + }, + }), + }, + ) + + tests := []struct { + name string + config appTableConfig + appListings []appListing + wantHeaders []string + wantNoHeaders []string + wantValues []string + wantNoValues []string + }{ + { + name: "regular list", + config: appTableConfig{ + active: []tlsca.RouteToApp{}, + verbose: false, + listAll: false, + }, + appListings: defaultAppListings, + wantHeaders: []string{"Application", "Public Address"}, + // Public addresses are expected to be truncated when verbose mode is off. + wantValues: []string{"https://root-app...", "https://leaf-app...", "root-app", "leaf-app"}, + wantNoHeaders: []string{"URI", "Proxy", "Cluster", "Target Ports"}, + wantNoValues: []string{"http://localhost:8080", "foo-cluster", "bar-cluster", "1337"}, + }, + { + name: "regular list with active app", + config: appTableConfig{ + active: []tlsca.RouteToApp{ + tlsca.RouteToApp{Name: "root-app"}, + }, + verbose: false, + listAll: false, + }, + appListings: defaultAppListings, + wantHeaders: []string{"Application"}, + wantValues: []string{"> root-app", "leaf-app"}, + }, + { + name: "regular list with no apps", + config: appTableConfig{ + active: []tlsca.RouteToApp{}, + verbose: false, + listAll: false, + }, + appListings: []appListing{}, + wantHeaders: []string{"Application", "Public Address"}, + }, + { + name: "regular list with multi-port", + config: appTableConfig{ + active: []tlsca.RouteToApp{}, + verbose: false, + listAll: false, + }, + appListings: appListingsWithMultiPort, + wantHeaders: []string{"Target Ports", "Application", "Public Address"}, + // Public addresses are expected to be truncated when verbose mode is off. + wantValues: []string{"1337, 4200-4...", "https://mp-r...", "https://root...", "mp-root", "root-app"}, + wantNoHeaders: []string{"URI", "Proxy", "Cluster"}, + wantNoValues: []string{"http://localhost:8080", "foo-cluster", "bar-cluster"}, + }, + { + name: "verbose", + config: appTableConfig{ + active: []tlsca.RouteToApp{}, + verbose: true, + listAll: false, + }, + appListings: defaultAppListings, + wantHeaders: []string{"URI", "Application", "Public Address"}, + wantValues: []string{"http://localhost:8080", "http://localhost:4242", + "https://root-app.example.com", "https://leaf-app.example.com", "root-app", "leaf-app"}, + wantNoHeaders: []string{"Proxy", "Cluster", "Target Ports"}, + wantNoValues: []string{"foo-cluster", "bar-cluster", "1337"}, + }, + { + name: "verbose with multi-port", + config: appTableConfig{ + active: []tlsca.RouteToApp{}, + verbose: true, + listAll: false, + }, + appListings: appListingsWithMultiPort, + wantHeaders: []string{"Target Ports", "URI"}, + wantValues: []string{"1337, 4200-4242", "tcp://localhost", "https://mp-root.example.com", "mp-root"}, + wantNoHeaders: []string{"Proxy", "Cluster"}, + wantNoValues: []string{"foo-cluster", "bar-cluster"}, + }, + { + name: "list all", + config: appTableConfig{ + active: []tlsca.RouteToApp{}, + verbose: false, + listAll: true, + }, + appListings: defaultAppListings, + wantHeaders: []string{"Proxy", "Cluster", "Application", "Public Address"}, + // Public addresses are expected to be truncated when verbose mode is off. + wantValues: []string{"foo-cluste...", "bar-cluste...", "example.co...", "https://ro...", "https://le...", "root-app", "leaf-app"}, + wantNoHeaders: []string{"URI", "Target Ports"}, + wantNoValues: []string{"http://localhost:8080", "1337"}, + }, + { + name: "list all with multi-port", + config: appTableConfig{ + active: []tlsca.RouteToApp{}, + verbose: false, + listAll: true, + }, + appListings: appListingsWithMultiPort, + wantHeaders: []string{"Target Ports", "Proxy", "Cluster"}, + wantValues: []string{"1337, 420...", "foo-clust...", "example.c...", "https://m...", "mp-root"}, + wantNoHeaders: []string{"URI"}, + wantNoValues: []string{"http://localhost:8080"}, + }, + { + name: "verbose and list all", + config: appTableConfig{ + active: []tlsca.RouteToApp{}, + verbose: true, + listAll: true, + }, + appListings: defaultAppListings, + wantHeaders: []string{"Proxy", "Cluster", "URI", "Application", "Public Address"}, + wantValues: []string{"foo-cluster", "bar-cluster", "http://localhost:8080", "http://localhost:4242", + "https://root-app.example.com", "https://leaf-app.example.com", "root-app", "leaf-app"}, + }, + { + name: "verbose, list all, and multi-port", + config: appTableConfig{ + active: []tlsca.RouteToApp{}, + verbose: true, + listAll: true, + }, + appListings: appListingsWithMultiPort, + wantHeaders: []string{"Proxy", "Cluster", "URI", "Application", "Public Address"}, + wantValues: []string{"1337, 4200-4242", "foo-cluster", "tcp://localhost", + "https://mp-root.example.com", "mp-root"}, + }, + } + + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + var b bytes.Buffer + w := io.Writer(&b) + + err := writeAppTable(w, test.appListings, test.config) + require.NoError(t, err) + + lines := strings.SplitN(b.String(), "\n", 3) + headers := lines[0] + // The second line contains header separators ("------"), that's why it's skipped here. + values := lines[2] + + for _, wantHeader := range test.wantHeaders { + assert.Contains(t, headers, wantHeader) + } + for _, wantNoHeader := range test.wantNoHeaders { + assert.NotContains(t, headers, wantNoHeader) + } + + for _, wantValue := range test.wantValues { + assert.Contains(t, values, wantValue) + } + for _, wantNoValue := range test.wantNoValues { + assert.NotContains(t, values, wantNoValue) + } + }) + } +} + +func mustMakeNewAppV3(t *testing.T, meta types.Metadata, spec types.AppSpecV3) *types.AppV3 { + t.Helper() + app, err := types.NewAppV3(meta, spec) + require.NoError(t, err) + return app +} diff --git a/tool/tsh/common/git.go b/tool/tsh/common/git.go new file mode 100644 index 0000000000000..1e941c863fa0d --- /dev/null +++ b/tool/tsh/common/git.go @@ -0,0 +1,39 @@ +/* + * Teleport + * Copyright (C) 2024 Gravitational, Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package common + +import ( + "github.com/alecthomas/kingpin/v2" +) + +type gitCommands struct { + list *gitListCommand +} + +func newGitCommands(app *kingpin.Application) gitCommands { + git := app.Command("git", "Git server commands.") + cmds := gitCommands{ + newGitListCommand(git), + } + + // TODO(greedy52) hide the commands until all basic features are implemented. + git.Hidden() + cmds.list.Hidden() + return cmds +} diff --git a/tool/tsh/common/git_list.go b/tool/tsh/common/git_list.go new file mode 100644 index 0000000000000..2e70b534565bc --- /dev/null +++ b/tool/tsh/common/git_list.go @@ -0,0 +1,174 @@ +/* + * Teleport + * Copyright (C) 2024 Gravitational, Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package common + +import ( + "fmt" + "strings" + + "github.com/alecthomas/kingpin/v2" + "github.com/gravitational/trace" + + "github.com/gravitational/teleport" + apiclient "github.com/gravitational/teleport/api/client" + "github.com/gravitational/teleport/api/client/proto" + "github.com/gravitational/teleport/api/types" + "github.com/gravitational/teleport/lib/asciitable" + "github.com/gravitational/teleport/lib/client" + "github.com/gravitational/teleport/lib/defaults" +) + +// gitListCommand implements `tsh git ls`. +type gitListCommand struct { + *kingpin.CmdClause + + format string + labels string + predicateExpression string + searchKeywords string + + // fetchFn is the function to fetch git servers. Defaults to c.doFetch. + // Can be set for testing. + fetchFn func(*CLIConf, *client.TeleportClient) ([]types.Server, error) +} + +func newGitListCommand(parent *kingpin.CmdClause) *gitListCommand { + cmd := &gitListCommand{ + CmdClause: parent.Command("ls", "List Git servers."), + } + cmd.Flag("format", defaults.FormatFlagDescription(defaults.DefaultFormats...)). + Short('f'). + Default(teleport.Text). + EnumVar(&cmd.format, defaults.DefaultFormats...) + + cmd.Flag("search", searchHelp).StringVar(&cmd.searchKeywords) + cmd.Flag("query", queryHelp).StringVar(&cmd.predicateExpression) + cmd.Arg("labels", labelHelp).StringVar(&cmd.labels) + return cmd +} + +func (c *gitListCommand) run(cf *CLIConf) error { + c.init(cf) + + tc, err := makeClient(cf) + if err != nil { + return trace.Wrap(err) + } + + servers, err := c.fetchFn(cf, tc) + if err != nil { + return trace.Wrap(err) + } + return printGitServers(cf, servers) +} + +func (c *gitListCommand) init(cf *CLIConf) { + cf.Format = c.format + cf.Labels = c.labels + cf.PredicateExpression = c.predicateExpression + cf.SearchKeywords = c.searchKeywords + + if c.fetchFn == nil { + c.fetchFn = c.doFetch + } +} + +func (c *gitListCommand) doFetch(cf *CLIConf, tc *client.TeleportClient) ([]types.Server, error) { + var resources types.EnrichedResources + err := client.RetryWithRelogin(cf.Context, tc, func() error { + client, err := tc.ConnectToCluster(cf.Context) + if err != nil { + return trace.Wrap(err) + } + defer client.Close() + + resources, err = apiclient.GetAllUnifiedResources(cf.Context, client.AuthClient, &proto.ListUnifiedResourcesRequest{ + Kinds: []string{types.KindGitServer}, + SortBy: types.SortBy{Field: types.ResourceMetadataName}, + SearchKeywords: tc.SearchKeywords, + PredicateExpression: tc.PredicateExpression, + }) + return trace.Wrap(err) + }) + if err != nil { + return nil, trace.Wrap(err) + } + return resources.ToResourcesWithLabels().AsServers() +} + +func printGitServers(cf *CLIConf, servers []types.Server) error { + format := strings.ToLower(cf.Format) + switch format { + case teleport.Text, "": + return printGitServersAsText(cf, servers) + case teleport.JSON, teleport.YAML: + out, err := serializeNodes(servers, format) + if err != nil { + return trace.Wrap(err) + } + if _, err := fmt.Fprintln(cf.Stdout(), out); err != nil { + return trace.Wrap(err) + } + return nil + default: + return trace.BadParameter("unsupported format %q", format) + } +} + +func printGitServersAsText(cf *CLIConf, servers []types.Server) error { + var rows [][]string + var showLoginNote bool + for _, server := range servers { + // TODO(greedy52) fill in GitHub login when available from Profile. + login := "(n/a)*" + showLoginNote = true + + if github := server.GetGitHub(); github != nil { + rows = append(rows, []string{ + "GitHub", + github.Organization, + login, + github.GetOrganizationURL(), + }) + } else { + return trace.BadParameter("expecting Git server but got %v", server.GetKind()) + } + } + + t := asciitable.MakeTable([]string{"Type", "Organization", "Username", "URL"}, rows...) + if _, err := fmt.Fprintln(cf.Stdout(), t.AsBuffer().String()); err != nil { + return trace.Wrap(err) + } + + if showLoginNote { + fmt.Fprint(cf.Stdout(), gitLoginNote) + } + + fmt.Fprint(cf.Stdout(), gitCommandsGeneralHint) + return nil +} + +const gitLoginNote = "" + + "(n/a)*: Username will be retrieved automatically upon running git commands.\n" + + " Alternatively, run `tsh git login --github-org `.\n\n" + +const gitCommandsGeneralHint = "" + + "hint: use 'tsh git clone ' to clone a new repository\n" + + " use 'tsh git config update' to configure an existing repository to use Teleport\n" + + " once the repository is cloned or configured, use 'git' as normal\n\n" diff --git a/tool/tsh/common/git_list_test.go b/tool/tsh/common/git_list_test.go new file mode 100644 index 0000000000000..071bf0765e61e --- /dev/null +++ b/tool/tsh/common/git_list_test.go @@ -0,0 +1,136 @@ +/* + * Teleport + * Copyright (C) 2024 Gravitational, Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package common + +import ( + "bytes" + "fmt" + "testing" + + "github.com/gravitational/trace" + "github.com/stretchr/testify/require" + + "github.com/gravitational/teleport/api/profile" + "github.com/gravitational/teleport/api/types" + "github.com/gravitational/teleport/lib/client" +) + +func makeGitServer(t *testing.T, gitHubOrg string) types.Server { + t.Helper() + server, err := types.NewGitHubServer( + types.GitHubServerMetadata{ + Integration: gitHubOrg, + Organization: gitHubOrg, + }) + require.NoError(t, err) + return server +} + +func TestGitListCommand(t *testing.T) { + server1 := makeGitServer(t, "org1") + server2 := makeGitServer(t, "org2") + + tests := []struct { + name string + format string + fetchFn func(*CLIConf, *client.TeleportClient) ([]types.Server, error) + wantError bool + containsOutput []string + }{ + { + name: "fetch error", + fetchFn: func(c *CLIConf, client *client.TeleportClient) ([]types.Server, error) { + return nil, trace.ConnectionProblem(fmt.Errorf("bad connection"), "bad connection") + }, + wantError: true, + }, + { + name: "text format", + fetchFn: func(c *CLIConf, client *client.TeleportClient) ([]types.Server, error) { + return []types.Server{server1, server2}, nil + }, + containsOutput: []string{ + "Type Organization Username URL", + "GitHub org1 (n/a)* https://github.com/org1", + "GitHub org2 (n/a)* https://github.com/org2", + }, + }, + { + name: "json format", + format: "json", + fetchFn: func(c *CLIConf, client *client.TeleportClient) ([]types.Server, error) { + return []types.Server{server1, server2}, nil + }, + containsOutput: []string{ + `"kind": "git_server"`, + `"hostname": "org1.github-org"`, + `"hostname": "org2.github-org"`, + }, + }, + { + name: "yaml format", + format: "yaml", + fetchFn: func(c *CLIConf, client *client.TeleportClient) ([]types.Server, error) { + return []types.Server{server1, server2}, nil + }, + containsOutput: []string{ + "- kind: git_server", + "hostname: org1.github-org", + "hostname: org2.github-org", + }, + }, + } + + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + var capture bytes.Buffer + cf := &CLIConf{ + Proxy: "proxy", + Username: "alice", + OverrideStdout: &capture, + HomePath: t.TempDir(), + } + + // Create a empty profile so we don't ping proxy. + clientStore, err := initClientStore(cf, cf.Proxy) + require.NoError(t, err) + profile := &profile.Profile{ + SSHProxyAddr: "proxy:3023", + WebProxyAddr: "proxy:3080", + } + err = clientStore.SaveProfile(profile, true) + require.NoError(t, err) + + cmd := gitListCommand{ + format: test.format, + fetchFn: test.fetchFn, + } + + err = cmd.run(cf) + if test.wantError { + require.Error(t, err) + } else { + require.NoError(t, err) + for _, output := range test.containsOutput { + require.Contains(t, capture.String(), output) + } + } + }) + } +} diff --git a/tool/tsh/common/mfa.go b/tool/tsh/common/mfa.go index c540cce3b1228..404be014e1c0f 100644 --- a/tool/tsh/common/mfa.go +++ b/tool/tsh/common/mfa.go @@ -197,12 +197,14 @@ type mfaAddCommand struct { devName string devType string - // allowPasswordless is initially true if --allow-passwordless is set, false - // if not explicitly requested. - // It can only be set by users if wancli.IsFIDO2Available() is true. + // allowPasswordless and allowPasswordlessSet hold the state of the + // --(no-)allow-passwordless flag. + // + // allowPasswordless can only be set by users if wancli.IsFIDO2Available() is + // true. // Note that Touch ID registrations are always passwordless-capable, // regardless of other settings. - allowPasswordless bool + allowPasswordless, allowPasswordlessSet bool } func newMFAAddCommand(parent *kingpin.CmdClause) *mfaAddCommand { @@ -213,7 +215,9 @@ func newMFAAddCommand(parent *kingpin.CmdClause) *mfaAddCommand { c.Flag("type", fmt.Sprintf("Type of the new MFA device (%s)", strings.Join(defaultDeviceTypes, ", "))). EnumVar(&c.devType, defaultDeviceTypes...) if wancli.IsFIDO2Available() { - c.Flag("allow-passwordless", "Allow passwordless logins").BoolVar(&c.allowPasswordless) + c.Flag("allow-passwordless", "Allow passwordless logins"). + IsSetByUser(&c.allowPasswordlessSet). + BoolVar(&c.allowPasswordless) } return c } @@ -265,9 +269,7 @@ func (c *mfaAddCommand) run(cf *CLIConf) error { switch c.devType { case webauthnDeviceType: // Ask the user? - // c.allowPasswordless=false at this point only means that the flag wasn't - // explicitly set. - if !c.allowPasswordless && wancli.IsFIDO2Available() { + if !c.allowPasswordlessSet && wancli.IsFIDO2Available() { answer, err := prompt.PickOne(ctx, os.Stdout, prompt.Stdin(), "Allow passwordless logins", []string{"YES", "NO"}) if err != nil { return trace.Wrap(err) diff --git a/tool/tsh/common/tsh.go b/tool/tsh/common/tsh.go index 8c51c89641eda..38aed27a0f9da 100644 --- a/tool/tsh/common/tsh.go +++ b/tool/tsh/common/tsh.go @@ -1242,6 +1242,8 @@ func Run(ctx context.Context, args []string, opts ...CliOption) error { vnetAdminSetupCmd := newVnetAdminSetupCommand(app) vnetDaemonCmd := newVnetDaemonCommand(app) + gitCmd := newGitCommands(app) + if runtime.GOOS == constants.WindowsOS { bench.Hidden() } @@ -1619,6 +1621,8 @@ func Run(ctx context.Context, args []string, opts ...CliOption) error { err = vnetAdminSetupCmd.run(&cf) case vnetDaemonCmd.FullCommand(): err = vnetDaemonCmd.run(&cf) + case gitCmd.list.FullCommand(): + err = gitCmd.list.run(&cf) default: // Handle commands that might not be available. switch { @@ -2823,13 +2827,26 @@ func showApps(apps []types.Application, active []tlsca.RouteToApp, w io.Writer, format = strings.ToLower(format) switch format { case teleport.Text, "": - showAppsAsText(apps, active, verbose, w) + appListings := make([]appListing, 0, len(apps)) + for _, app := range apps { + appListings = append(appListings, appListing{App: app}) + } + + if err := writeAppTable(w, appListings, appTableConfig{ + listAll: false, // showApps lists apps from a single cluster. + active: active, + verbose: verbose, + }); err != nil { + return trace.Wrap(err) + } case teleport.JSON, teleport.YAML: out, err := serializeApps(apps, format) if err != nil { return trace.Wrap(err) } - fmt.Fprintln(w, out) + if _, err := fmt.Fprintln(w, out); err != nil { + return trace.Wrap(err) + } default: return trace.BadParameter("unsupported format %q", format) } @@ -2850,46 +2867,140 @@ func serializeApps(apps []types.Application, format string) (string, error) { return string(out), trace.Wrap(err) } -func getAppRow(proxy, cluster string, app types.Application, active []tlsca.RouteToApp, verbose bool) []string { - var row []string - if proxy != "" && cluster != "" { - row = append(row, proxy, cluster) - } +type appTableConfig struct { + // active is a list of apps for which the user retrieved a short-lived cert with tsh app login. + active []tlsca.RouteToApp + // verbose makes the table show extra columns. + verbose bool + // listAll makes the table render two extra columns: Proxy and Cluster. + listAll bool +} - name := app.GetName() - for _, a := range active { - if name == a.Name { - name = fmt.Sprintf("> %v", name) - break +func writeAppTable(w io.Writer, appListings []appListing, config appTableConfig) error { + includesMultiPortApp := slices.ContainsFunc(appListings, func(al appListing) bool { + return len(al.App.GetTCPPorts()) > 0 + }) + + getName := func(app types.Application) string { + isActive := slices.ContainsFunc(config.active, func(route tlsca.RouteToApp) bool { + // TODO(ravicious): This should be based on name _and_ route.ClusterName, so that we don't + // incorrectly show multiple apps with the same name but from different clusters as active. + // However, to do this we'd need to double check if route.ClusterName always matches + // appListing.Cluster (and also fill out that field in showApps). + return route.Name == app.GetName() + }) + + if isActive { + return fmt.Sprintf("> %s", app.GetName()) } - } - labels := common.FormatLabels(app.GetAllLabels(), verbose) - if verbose { - row = append(row, name, app.GetDescription(), app.GetProtocol(), app.GetPublicAddr(), app.GetURI(), labels) - } else { - row = append(row, name, app.GetDescription(), app.GetProtocol(), app.GetPublicAddr(), labels) + return app.GetName() + } + getLabels := func(app types.Application) string { + return common.FormatLabels(app.GetAllLabels(), config.verbose) } + getTargetPorts := func(app types.Application) string { + ports := make([]string, 0, len(app.GetTCPPorts())) + for _, portRange := range app.GetTCPPorts() { + var port string + if portRange.EndPort == 0 { + port = strconv.Itoa(int(portRange.Port)) + } else { + port = fmt.Sprintf("%d-%d", portRange.Port, portRange.EndPort) + } + ports = append(ports, port) + } + return strings.Join(ports, ", ") + } + + const labelsColumn = "Labels" + allColumns := []appTableColumn{ + appTableColumn{ + name: "Proxy", + getFromListing: appListing.GetProxy, + hide: !config.listAll, + }, + appTableColumn{ + name: "Cluster", + getFromListing: appListing.GetCluster, + hide: !config.listAll, + }, + appTableColumn{ + name: "Application", + get: getName, + }, + appTableColumn{ + name: "Description", + get: types.Application.GetDescription, + }, + appTableColumn{ + name: "Type", + get: types.Application.GetProtocol, + }, + appTableColumn{ + name: "Public Address", + get: types.Application.GetPublicAddr, + }, + appTableColumn{ + name: "Target Ports", + get: getTargetPorts, + hide: !includesMultiPortApp, + }, + appTableColumn{ + name: "URI", + get: types.Application.GetURI, + hide: !config.verbose, + }, + appTableColumn{ + name: labelsColumn, + get: getLabels, + }, + } + columns := slices.DeleteFunc(allColumns, func(column appTableColumn) bool { return column.hide }) + + headers := make([]string, 0, len(columns)) + for _, column := range columns { + headers = append(headers, column.name) + } + + rows := make([][]string, 0, len(appListings)) + for _, appListing := range appListings { + appRow := make([]string, 0, len(columns)) + + for _, column := range columns { + var content string + switch { + case column.get != nil: + content = column.get(appListing.App) + case column.getFromListing != nil: + content = column.getFromListing(appListing) + } - return row -} + appRow = append(appRow, content) + } -func showAppsAsText(apps []types.Application, active []tlsca.RouteToApp, verbose bool, w io.Writer) { - var rows [][]string - for _, app := range apps { - rows = append(rows, getAppRow("", "", app, active, verbose)) + rows = append(rows, appRow) } - // In verbose mode, print everything on a single line and include host UUID. + + // In verbose mode, print everything on a single line. // In normal mode, chunk the labels, print two per line and allow multiple - // lines per node. + // lines per app. var t asciitable.Table - if verbose { - t = asciitable.MakeTable([]string{"Application", "Description", "Type", "Public Address", "URI", "Labels"}, rows...) + if config.verbose { + t = asciitable.MakeTable(headers, rows...) } else { - t = asciitable.MakeTableWithTruncatedColumn( - []string{"Application", "Description", "Type", "Public Address", "Labels"}, rows, "Labels") + t = asciitable.MakeTableWithTruncatedColumn(headers, rows, labelsColumn) } - fmt.Fprintln(w, t.AsBuffer().String()) + + _, err := fmt.Fprintln(w, t.AsBuffer().String()) + return trace.Wrap(err) +} + +type appTableColumn struct { + name string + get func(app types.Application) string + getFromListing func(listing appListing) string + hide bool } func showDatabases(cf *CLIConf, databases []types.Database, active []tlsca.RouteToDatabase, accessChecker services.AccessChecker) error { @@ -5218,6 +5329,14 @@ type appListing struct { App types.Application `json:"app"` } +func (al appListing) GetProxy() string { + return al.Proxy +} + +func (al appListing) GetCluster() string { + return al.Cluster +} + type appListings []appListing func (l appListings) Len() int { @@ -5327,37 +5446,28 @@ func listAppsAllClusters(cf *CLIConf) error { format := strings.ToLower(cf.Format) switch format { case teleport.Text, "": - printAppsWithClusters(listings, active, cf.Verbose) + if err := writeAppTable(cf.Stdout(), listings, appTableConfig{ + listAll: true, + active: active, + verbose: cf.Verbose, + }); err != nil { + return trace.Wrap(err) + } + case teleport.JSON, teleport.YAML: out, err := serializeAppsWithClusters(listings, format) if err != nil { return trace.Wrap(err) } - fmt.Fprintln(cf.Stdout(), out) + if _, err := fmt.Fprintln(cf.Stdout(), out); err != nil { + return trace.Wrap(err) + } default: return trace.BadParameter("unsupported format %q", format) } return nil } -func printAppsWithClusters(apps []appListing, active []tlsca.RouteToApp, verbose bool) { - var rows [][]string - for _, app := range apps { - rows = append(rows, getAppRow(app.Proxy, app.Cluster, app.App, active, verbose)) - } - // In verbose mode, print everything on a single line and include host UUID. - // In normal mode, chunk the labels, print two per line and allow multiple - // lines per node. - var t asciitable.Table - if verbose { - t = asciitable.MakeTable([]string{"Proxy", "Cluster", "Application", "Description", "Type", "Public Address", "URI", "Labels"}, rows...) - } else { - t = asciitable.MakeTableWithTruncatedColumn( - []string{"Proxy", "Cluster", "Application", "Description", "Type", "Public Address", "Labels"}, rows, "Labels") - } - fmt.Println(t.AsBuffer().String()) -} - func serializeAppsWithClusters(apps []appListing, format string) (string, error) { var out []byte var err error diff --git a/web/packages/design/src/Alert/Alert.tsx b/web/packages/design/src/Alert/Alert.tsx index 68c5487b7788e..f8ce4b7269310 100644 --- a/web/packages/design/src/Alert/Alert.tsx +++ b/web/packages/design/src/Alert/Alert.tsx @@ -22,6 +22,8 @@ import { style, color, ColorProps } from 'styled-system'; import { IconProps } from 'design/Icon/Icon'; +import { StatusIcon, StatusKind } from 'design/StatusIcon'; + import { space, SpaceProps, width, WidthProps } from '../system'; import { Theme } from '../theme'; import * as Icon from '../Icon'; @@ -193,7 +195,12 @@ export const Alert = ({ - + ` ${backgroundColor} `; -const AlertIcon = ({ - kind, - customIcon: CustomIcon, - ...otherProps -}: { - kind: AlertKind | BannerKind; - customIcon?: React.ComponentType; -} & IconProps) => { - const commonProps = { role: 'graphics-symbol', ...otherProps }; - if (CustomIcon) { - return ; - } - switch (kind) { - case 'success': - return ; - case 'danger': - case 'outline-danger': - return ; - case 'info': - case 'outline-info': - return ; - case 'warning': - case 'outline-warn': - return ; - case 'neutral': - case 'primary': - return ; - } -}; - const iconContainerStyles = ({ kind, theme, @@ -468,7 +445,12 @@ export const Banner = ({ gap={3} alignItems="center" > - + {children} {details} @@ -525,3 +507,18 @@ const bannerColors = (theme: Theme, kind: BannerKind) => { }; } }; + +const iconKind = (kind: AlertKind | BannerKind): StatusKind => { + switch (kind) { + case 'outline-danger': + return 'danger'; + case 'outline-warn': + return 'warning'; + case 'outline-info': + return 'info'; + case 'primary': + return 'neutral'; + default: + return kind; + } +}; diff --git a/web/packages/design/src/Flex/Flex.story.jsx b/web/packages/design/src/Flex/Flex.story.jsx index b707f5770733d..dd64b1c07f0d9 100644 --- a/web/packages/design/src/Flex/Flex.story.jsx +++ b/web/packages/design/src/Flex/Flex.story.jsx @@ -67,3 +67,14 @@ export const Justified = () => ( ); + +export const Inline = () => ( + + + Box one + + + Box two + + +); diff --git a/web/packages/design/src/Flex/Flex.tsx b/web/packages/design/src/Flex/Flex.tsx index b0144a085cf42..df67f985c5e9e 100644 --- a/web/packages/design/src/Flex/Flex.tsx +++ b/web/packages/design/src/Flex/Flex.tsx @@ -42,10 +42,15 @@ export interface FlexProps FlexWrapProps, FlexDirectionProps, FlexBasisProps, - GapProps {} + GapProps { + /** + * Uses inline-flex instead of just flex as the display property. + */ + inline?: boolean; +} const Flex = styled(Box)` - display: flex; + display: ${props => (props.inline ? 'inline-flex' : 'flex')}; ${alignItems} ${justifyContent} ${flexWrap} diff --git a/web/packages/design/src/Menu/Menu.story.jsx b/web/packages/design/src/Menu/Menu.story.jsx deleted file mode 100644 index e7163eae7f11e..0000000000000 --- a/web/packages/design/src/Menu/Menu.story.jsx +++ /dev/null @@ -1,140 +0,0 @@ -/* - * Teleport - * Copyright (C) 2023 Gravitational, Inc. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -import React from 'react'; - -import { ButtonPrimary } from '../Button'; -import Box from '../Box'; -import Flex from '../Flex'; -import * as Icons from '../Icon'; - -import MenuItemIcon from './MenuItemIcon'; -import MenuItem from './MenuItem'; -import Menu from './Menu'; - -export default { - title: 'Design/Menu', -}; - -export const PlacementExample = () => ( - - - Test - Test2 - - - Test - Test2 - - - Logout - - - - - Test - Test2 - - -); - -export const IconExample = () => ( - - - - Test - - - - Test - - - - Test - - -); - -class SimpleMenu extends React.Component { - state = { - anchorEl: null, - }; - - handleClickListItem = event => { - this.setState({ anchorEl: event.currentTarget }); - }; - - handleMenuItemClick = () => { - this.setState({ anchorEl: null }); - }; - - handleClose = () => { - this.setState({ anchorEl: null }); - }; - - render() { - const { text, anchorOrigin, transformOrigin, children } = this.props; - const { anchorEl } = this.state; - return ( - - - {text} - - - {children} - - - ); - } -} diff --git a/web/packages/design/src/Menu/Menu.story.tsx b/web/packages/design/src/Menu/Menu.story.tsx new file mode 100644 index 0000000000000..1615f7774aab4 --- /dev/null +++ b/web/packages/design/src/Menu/Menu.story.tsx @@ -0,0 +1,188 @@ +/* + * Teleport + * Copyright (C) 2023 Gravitational, Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +import { PropsWithChildren, useRef, useState } from 'react'; + +import { ButtonPrimary } from '../Button'; +import Box from '../Box'; +import Flex from '../Flex'; +import * as Icons from '../Icon'; +import { H3 } from '../Text'; +import { Origin } from '../Popover'; + +import MenuItemIcon from './MenuItemIcon'; +import MenuItem, { + MenuItemSectionLabel, + MenuItemSectionSeparator, +} from './MenuItem'; +import Menu from './Menu'; +import MenuList from './MenuList'; + +export default { + title: 'Design/Menu', +}; + +export const PlacementExample = () => ( + + + Lorem + Ipsum + Dolor + Sit + Amet + + + Test + Test2 + + + Logout + + + + + Test + Test2 + + +); + +export const MenuItems = () => ( + + +

Label after separator

+ + Lorem ipsum + Dolor sit amet + + Leo vitae arcu + Donec volutpat + Mauris sit + Amet nisi tempor + +
+ +

Menu item after separator

+ + Lorem ipsum + Dolor sit amet + + Leo vitae arcu + Donec volutpat + Mauris sit + Amet nisi tempor + +
+
+); + +export const IconExample = () => ( + + + + Test + + + + Test + + + + Test + + +); + +const SimpleMenu = ( + props: PropsWithChildren<{ + text: string; + anchorOrigin?: Origin; + transformOrigin?: Origin; + }> +) => { + const anchorElRef = useRef(null); + const [isOpen, setIsOpen] = useState(false); + + const open = () => { + setIsOpen(true); + }; + const close = () => { + setIsOpen(false); + }; + + const { text, anchorOrigin, transformOrigin, children } = props; + + return ( + + + {text} + + + {children} + + + ); +}; + +const OpenMenu = (props: PropsWithChildren) => { + // MenuList uses a percent value in max-height combined with overflow: hidden, so we have + // to wrap it twice here to avoid issues with the menu being cut off. + return ( + + + {props.children} + + + ); +}; diff --git a/web/packages/design/src/Menu/MenuItem.tsx b/web/packages/design/src/Menu/MenuItem.tsx index a13f852f5b934..2346184b1cbd1 100644 --- a/web/packages/design/src/Menu/MenuItem.tsx +++ b/web/packages/design/src/Menu/MenuItem.tsx @@ -27,6 +27,7 @@ import { } from 'styled-system'; import { Theme } from 'design/theme/themes/types'; +import Flex from 'design/Flex'; const defaultValues = { fontSize: 1, @@ -41,6 +42,70 @@ interface ThemedMenuItemProps extends MenuItemProps { theme: Theme; } +// TODO(ravicious): This probably can be simplified when the time comes to do a redesign of Menu. +// For now it's based on the existing code from fromTheme so that we don't break anything. +const fromThemeBase = (props: { theme: Theme }) => { + const values = { + ...defaultValues, + ...props, + }; + return { + ...fontSize(values), + ...space(values), + ...color(values), + fontWeight: values.theme.regular, + }; +}; + +const MenuItemBase = styled(Flex)` + min-height: 40px; + box-sizing: border-box; + justify-content: flex-start; + align-items: center; + min-width: 140px; + overflow: hidden; + text-decoration: none; + white-space: nowrap; + color: ${props => props.theme.colors.text.main}; + + ${fromThemeBase} +`; + +export const MenuItemSectionLabel = styled(MenuItemBase).attrs({ + px: 2, + onClick: event => { + // Make sure that clicks on this element don't trigger onClick set on MenuList. + event.stopPropagation(); + }, +})` + font-weight: bold; + min-height: 16px; +`; + +export const MenuItemSectionSeparator = styled.hr.attrs({ + onClick: event => { + // Make sure that clicks on this element don't trigger onClick set on MenuList. + event.stopPropagation(); + }, +})` + background: ${props => props.theme.colors.interactive.tonal.neutral[1]}; + height: 1px; + border: 0; + font-size: 0; + + // Add padding to the label for extra visual space, but only when it follows a separator. + // If a separator follows a MenuItem, there's already enough visual space, so no extra space is + // needed. The hover state of MenuItem highlights everything right from the separator start to the + // end of MenuItem. + // + // Padding is used instead of margin here on purpose, so that there's no empty transparent space + // between Separator and Label – otherwise clicking on that space would count as a click on + // MenuList and not trigger onClick set on Separator or Label. + & + ${MenuItemSectionLabel} { + padding-top: ${props => props.theme.space[1]}px; + } +`; + const fromTheme = (props: ThemedMenuItemProps) => { const values = { ...defaultValues, @@ -64,17 +129,10 @@ const fromTheme = (props: ThemedMenuItemProps) => { }; }; -const MenuItem = styled.div.attrs({ role: 'menuitem' })` - min-height: 40px; - box-sizing: border-box; +const MenuItem = styled(MenuItemBase).attrs({ + role: 'menuitem', +})` cursor: ${props => (props.disabled ? 'not-allowed' : 'pointer')}; - display: flex; - justify-content: flex-start; - align-items: center; - min-width: 140px; - overflow: hidden; - text-decoration: none; - white-space: nowrap; color: ${props => props.disabled ? props.theme.colors.text.disabled diff --git a/web/packages/design/src/Menu/MenuList.jsx b/web/packages/design/src/Menu/MenuList.tsx similarity index 62% rename from web/packages/design/src/Menu/MenuList.jsx rename to web/packages/design/src/Menu/MenuList.tsx index 9b0cb68237eb3..7be01e726b360 100644 --- a/web/packages/design/src/Menu/MenuList.jsx +++ b/web/packages/design/src/Menu/MenuList.tsx @@ -16,45 +16,24 @@ * along with this program. If not, see . */ -import React from 'react'; -import PropTypes from 'prop-types'; -import styled from 'styled-components'; +import { ComponentProps } from 'react'; +import styled, { StyleFunction } from 'styled-components'; -class MenuList extends React.Component { - render() { - const { children, innerRef, ...other } = this.props; - return ( - - {children} - - ); - } -} - -const StyledMenuList = styled.div` +// TODO(ravicious): Put MenuList definition next to Menu once Menu is rewritten in TypeScript. +const MenuList = styled.div.attrs({ role: 'menu' })<{ + menuListCss?: StyleFunction>; +}>` background-color: ${props => props.theme.colors.levels.elevated}; border-radius: 4px; box-shadow: ${props => props.theme.boxShadow[0]}; box-sizing: border-box; max-height: calc(100% - 96px); overflow: hidden; + overflow-y: auto; position: relative; padding: 0; ${props => props.menuListCss && props.menuListCss(props)} `; -MenuList.propTypes = { - /** - * MenuList contents, normally `MenuItem`s. - */ - children: PropTypes.node, - /** - * @ignore - */ - menuListCss: PropTypes.func, -}; - -export default React.forwardRef((props, ref) => ( - -)); +export default MenuList; diff --git a/web/packages/design/src/Popover/Popover.tsx b/web/packages/design/src/Popover/Popover.tsx index abcd655818a4d..0de317099e523 100644 --- a/web/packages/design/src/Popover/Popover.tsx +++ b/web/packages/design/src/Popover/Popover.tsx @@ -738,7 +738,12 @@ export class Popover extends Component { BackdropProps={{ invisible: true, ...this.props.backdropProps }} {...other} > - + { * arrow tips. */ arrowMargin?: number; + + /** + * If false (default), positioning styles are updated only on the initial render of the children. + * + * If true, updates positioning styles of the popover whenever the children are resized. + * This is useful in situations where the children are updated asynchronously, e.g., after + * receiving a response over network. + */ + updatePositionOnChildResize?: boolean; } export const StyledPopover = styled(Flex)<{ diff --git a/web/packages/design/src/Popover/Transition.tsx b/web/packages/design/src/Popover/Transition.tsx index 4d4c65dc2f7fa..9f47bed69806b 100644 --- a/web/packages/design/src/Popover/Transition.tsx +++ b/web/packages/design/src/Popover/Transition.tsx @@ -16,18 +16,33 @@ * along with this program. If not, see . */ -import React, { useLayoutEffect } from 'react'; +import React, { RefObject, useLayoutEffect } from 'react'; +import { useResizeObserver } from 'design/utils/useResizeObserver'; + +/** + * Transition is a helper for firing certain effects from Popover, as it's way easier to use them + * this way than integrating with the component lifecycle. + */ export function Transition({ onEntering, + enablePaperResizeObserver, + paperRef, + onPaperResize, children, }: React.PropsWithChildren<{ onEntering: () => void; + enablePaperResizeObserver: boolean | undefined; + paperRef: RefObject; + onPaperResize: () => void; }>) { // Note: useLayoutEffect to prevent flickering improperly positioned popovers. // It's especially noticeable on Safari. - useLayoutEffect(() => { - onEntering(); - }, []); + useLayoutEffect(onEntering, []); + + useResizeObserver(paperRef, onPaperResize, { + enabled: enablePaperResizeObserver, + }); + return children; } diff --git a/web/packages/design/src/SlideTabs/SlideTabs.story.tsx b/web/packages/design/src/SlideTabs/SlideTabs.story.tsx index fa2ce7dbafa2b..bb3eb8c49818a 100644 --- a/web/packages/design/src/SlideTabs/SlideTabs.story.tsx +++ b/web/packages/design/src/SlideTabs/SlideTabs.story.tsx @@ -21,7 +21,7 @@ import React, { useState } from 'react'; import * as Icon from 'design/Icon'; import Flex from 'design/Flex'; -import { SlideTabs } from './SlideTabs'; +import { SlideTabs, TabSpec } from './SlideTabs'; export default { title: 'Design/SlideTabs', @@ -120,9 +120,33 @@ export const Small = () => { { ); }; -export const LoadingTab = () => { +export const StatusIcons = () => { + const [activeIndex, setActiveIndex] = useState(0); + const tabs: TabSpec[] = [ + { key: 'warning', title: 'warning', status: { kind: 'warning' } }, + { key: 'danger', title: 'danger', status: { kind: 'danger' } }, + { key: 'neutral', title: 'neutral', status: { kind: 'neutral' } }, + ]; return ( - null} - activeIndex={1} - isProcessing={true} - /> + + + + + ); }; diff --git a/web/packages/design/src/SlideTabs/SlideTabs.test.tsx b/web/packages/design/src/SlideTabs/SlideTabs.test.tsx index 4636655d25700..fe4137f34b28b 100644 --- a/web/packages/design/src/SlideTabs/SlideTabs.test.tsx +++ b/web/packages/design/src/SlideTabs/SlideTabs.test.tsx @@ -21,6 +21,8 @@ import { screen } from '@testing-library/react'; import { render, userEvent } from 'design/utils/testing'; +import * as Icon from 'design/Icon'; + import { SlideTabs, SlideTabsProps } from './SlideTabs'; describe('design/SlideTabs', () => { @@ -87,7 +89,12 @@ describe('design/SlideTabs', () => { ); diff --git a/web/packages/design/src/SlideTabs/SlideTabs.tsx b/web/packages/design/src/SlideTabs/SlideTabs.tsx index 6b92c5803fdf0..9a81f79fd99ac 100644 --- a/web/packages/design/src/SlideTabs/SlideTabs.tsx +++ b/web/packages/design/src/SlideTabs/SlideTabs.tsx @@ -17,10 +17,13 @@ */ import React, { useEffect, useRef } from 'react'; -import styled from 'styled-components'; +import styled, { useTheme } from 'styled-components'; import { Flex, Indicator } from 'design'; import { IconProps } from 'design/Icon/Icon'; +import { HoverTooltip } from 'design/Tooltip'; +import { Position } from 'design/Popover/Popover'; +import { StatusIcon, StatusKind } from 'design/StatusIcon'; export function SlideTabs({ appearance = 'square', @@ -31,7 +34,9 @@ export function SlideTabs({ isProcessing = false, disabled = false, fitContent = false, + hideStatusIconOnActiveTab, }: SlideTabsProps) { + const theme = useTheme(); const activeTab = useRef(null); const tabContainer = useRef(null); @@ -75,7 +80,15 @@ export function SlideTabs({ icon: Icon, ariaLabel, controls, + tooltip: { + content: tooltipContent, + position: tooltipPosition, + } = {}, + status: { kind: statusKind, ariaLabel: statusAriaLabel } = {}, } = toFullTabSpec(tabSpec, tabIndex); + const statusIconColorActive = hideStatusIconOnActiveTab + ? 'transparent' + : theme.colors.text.primaryInverse; let onClick = undefined; if (!disabled && !isProcessing) { @@ -86,32 +99,45 @@ export function SlideTabs({ } return ( - - {/* We need a separate tab content component, since the spinner, - when displayed, shouldn't take up space to prevent layout - jumping. TabContent serves as a positioning anchor whose left - edge is the left edge of the content (not the tab button, - which can be much wider). */} - - {selected && isProcessing && } - {Icon && } - {title} - - + + {/* We need a separate tab content component, since the status + icon, when displayed, shouldn't take up space to prevent + layout jumping. TabContent serves as a positioning anchor + whose left edge is the left edge of the content (not the tab + button, which can be much wider). */} + + + + + {Icon && } + {title} + + + ); })} {/* The tab slider is positioned absolutely and appears below the @@ -169,6 +195,13 @@ export type SlideTabsProps = { * but instead wraps its contents. */ fitContent?: boolean; + /** + * Hides the status icon on active tab. Note that this is not the same as + * simply making some tab's `tabSpec.status` field set conditionally on + * whether that tab is active or not. Using this field provides a smooth + * animation for transitions between active and inactive state. + */ + hideStatusIconOnActiveTab?: boolean; }; /** @@ -179,7 +212,7 @@ export type SlideTabsProps = { * TODO(bl-nero): remove the string option once Enterprise is migrated to * simplify it a bit. */ -type TabSpec = string | FullTabSpec; +export type TabSpec = string | FullTabSpec; type FullTabSpec = TabContentSpec & { /** Iteration key for the tab. */ @@ -190,6 +223,19 @@ type FullTabSpec = TabContentSpec & { * attribute set to "tabpanel". */ controls?: string; + tooltip?: { + content: React.ReactNode; + position?: Position; + }; + /** + * An icon that will be displayed on the side. The layout will stay the same + * whether the icon is there or not. If `isProcessing` prop is set to `true`, + * the icon for an active tab is replaced by a spinner. + */ + status?: { + kind: StatusKind; + ariaLabel?: string; + }; }; /** @@ -220,6 +266,48 @@ function toFullTabSpec(spec: TabSpec, index: number): FullTabSpec { }; } +function StatusIconOrSpinner({ + showSpinner, + statusKind, + size, + color, + ariaLabel, +}: { + showSpinner: boolean; + statusKind: StatusKind | undefined; + size: Size; + color: string | undefined; + ariaLabel: string | undefined; +}) { + if (showSpinner) { + return ; + } + + // This is one of these rare cases when there is a difference between + // property being undefined and not present at all: undefined props would + // override the default ones, but we want it them to interfere at all. + const optionalProps: { color?: string; 'aria-label'?: string } = {}; + if (color !== undefined) { + optionalProps.color = color; + } + if (ariaLabel !== undefined) { + optionalProps['aria-label'] = ariaLabel; + } + + if (!statusKind) { + return null; + } + + return ( + + ); +} + const TabSliderInner = styled.div<{ appearance: Appearance }>` height: 100%; background-color: ${({ theme }) => theme.colors.brand}; @@ -343,6 +431,9 @@ const TabList = styled.div<{ itemCount: number }>` const Spinner = styled(Indicator)` color: ${p => p.theme.colors.levels.deep}; +`; + +const StatusIconContainer = styled.div` position: absolute; left: -${p => p.theme.space[5]}px; `; diff --git a/web/packages/design/src/StatusIcon/StatusIcon.story.tsx b/web/packages/design/src/StatusIcon/StatusIcon.story.tsx new file mode 100644 index 0000000000000..5c9897c6d3896 --- /dev/null +++ b/web/packages/design/src/StatusIcon/StatusIcon.story.tsx @@ -0,0 +1,44 @@ +/** + * Teleport + * Copyright (C) 2024 Gravitational, Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +import { StoryObj } from '@storybook/react'; + +import Flex from 'design/Flex'; + +import { StatusIcon } from '.'; + +export default { + title: 'Design', +}; + +export const Story: StoryObj = { + name: 'StatusIcon', + render() { + return ( + + {(['neutral', 'danger', 'info', 'warning', 'success'] as const).map( + status => ( + + {status} + + ) + )} + + ); + }, +}; diff --git a/web/packages/design/src/StatusIcon/StatusIcon.tsx b/web/packages/design/src/StatusIcon/StatusIcon.tsx new file mode 100644 index 0000000000000..08fe46a020b22 --- /dev/null +++ b/web/packages/design/src/StatusIcon/StatusIcon.tsx @@ -0,0 +1,78 @@ +/** + * Teleport + * Copyright (C) 2024 Gravitational, Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +import React from 'react'; + +import { useTheme } from 'styled-components'; + +import * as Icon from 'design/Icon'; +import { IconProps } from 'design/Icon/Icon'; + +export type StatusKind = 'neutral' | 'danger' | 'info' | 'warning' | 'success'; + +export const StatusIcon = ({ + kind, + customIcon: CustomIcon, + ...otherProps +}: { + kind: StatusKind; + customIcon?: React.ComponentType; +} & IconProps) => { + const commonProps = { role: 'graphics-symbol', ...otherProps }; + const theme = useTheme(); + + if (CustomIcon) { + return ; + } + switch (kind) { + case 'success': + return ( + + ); + case 'danger': + return ( + + ); + case 'info': + return ( + + ); + case 'warning': + return ( + + ); + case 'neutral': + return ; + } +}; diff --git a/web/packages/design/src/StatusIcon/index.ts b/web/packages/design/src/StatusIcon/index.ts new file mode 100644 index 0000000000000..7c674b723d6af --- /dev/null +++ b/web/packages/design/src/StatusIcon/index.ts @@ -0,0 +1,19 @@ +/** + * Teleport + * Copyright (C) 2024 Gravitational, Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +export { StatusIcon, type StatusKind } from './StatusIcon'; diff --git a/web/packages/shared/components/ToolTip/HoverTooltip.tsx b/web/packages/design/src/Tooltip/HoverTooltip.tsx similarity index 98% rename from web/packages/shared/components/ToolTip/HoverTooltip.tsx rename to web/packages/design/src/Tooltip/HoverTooltip.tsx index e9e16bba58359..6dbaab58bdf0a 100644 --- a/web/packages/shared/components/ToolTip/HoverTooltip.tsx +++ b/web/packages/design/src/Tooltip/HoverTooltip.tsx @@ -18,6 +18,7 @@ import React, { PropsWithChildren, useState } from 'react'; import styled, { useTheme } from 'styled-components'; + import { Popover, Flex, Text } from 'design'; import { JustifyContentProps, FlexBasisProps } from 'design/system'; @@ -64,6 +65,7 @@ export const HoverTooltip: React.FC< // whether we want to show the tooltip. if ( target instanceof Element && + target.parentElement && target.scrollWidth > target.parentElement.offsetWidth ) { setAnchorEl(event.currentTarget); @@ -75,7 +77,7 @@ export const HoverTooltip: React.FC< } function handlePopoverClose() { - setAnchorEl(null); + setAnchorEl(undefined); } // Don't render the tooltip if the content is undefined. diff --git a/web/packages/shared/components/ToolTip/ToolTip.story.tsx b/web/packages/design/src/Tooltip/IconTooltip.story.tsx similarity index 82% rename from web/packages/shared/components/ToolTip/ToolTip.story.tsx rename to web/packages/design/src/Tooltip/IconTooltip.story.tsx index 1830fc4902e12..8062ae357752a 100644 --- a/web/packages/shared/components/ToolTip/ToolTip.story.tsx +++ b/web/packages/design/src/Tooltip/IconTooltip.story.tsx @@ -17,17 +17,19 @@ */ import React from 'react'; -import { Text, Flex, ButtonPrimary } from 'design'; import styled, { useTheme } from 'styled-components'; + +import { Text, Flex, ButtonPrimary } from 'design'; import { P } from 'design/Text/Text'; -import { logos } from 'teleport/components/LogoHero/LogoHero'; +import AGPLLogoLight from 'design/assets/images/agpl-light.svg'; +import AGPLLogoDark from 'design/assets/images/agpl-dark.svg'; -import { ToolTipInfo } from './ToolTip'; +import { IconTooltip } from './IconTooltip'; import { HoverTooltip } from './HoverTooltip'; export default { - title: 'Shared/ToolTip', + title: 'Design/Tooltip', }; export const ShortContent = () => ( @@ -36,25 +38,25 @@ export const ShortContent = () => ( Hover the icon - "some popover content" + "some popover content"
Hover the icon - "some popover content" + "some popover content"
Hover the icon - "some popover content" + "some popover content"
Hover the icon - "some popover content" + "some popover content"
); @@ -65,13 +67,18 @@ const Grid = styled.div` grid-template-rows: repeat(3, 100px); `; +const logos = { + light: AGPLLogoLight, + dark: AGPLLogoDark, +}; + export const LongContent = () => { const theme = useTheme(); return ( <> Hover the icon - +

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim @@ -84,7 +91,7 @@ export const LongContent = () => { cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

-
+

Here's some content that shouldn't interfere with the semi-transparent @@ -92,7 +99,7 @@ export const LongContent = () => {

- +
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim @@ -113,7 +120,7 @@ export const WithMutedIconColor = () => ( Hover the icon - "some popover content" + "some popover content" ); @@ -122,7 +129,7 @@ export const WithKindWarning = () => ( Hover the icon - "some popover content" + "some popover content" ); @@ -131,7 +138,7 @@ export const WithKindError = () => ( Hover the icon - "some popover content" + "some popover content" ); diff --git a/web/packages/shared/components/ToolTip/ToolTip.tsx b/web/packages/design/src/Tooltip/IconTooltip.tsx similarity index 95% rename from web/packages/shared/components/ToolTip/ToolTip.tsx rename to web/packages/design/src/Tooltip/IconTooltip.tsx index f80a3a6342b91..e7434272fe6f3 100644 --- a/web/packages/shared/components/ToolTip/ToolTip.tsx +++ b/web/packages/design/src/Tooltip/IconTooltip.tsx @@ -27,7 +27,7 @@ import { anchorOriginForPosition, transformOriginForPosition } from './shared'; type ToolTipKind = 'info' | 'warning' | 'error'; -export const ToolTipInfo: React.FC< +export const IconTooltip: React.FC< PropsWithChildren<{ trigger?: 'click' | 'hover'; position?: Position; @@ -46,15 +46,15 @@ export const ToolTipInfo: React.FC< kind = 'info', }) => { const theme = useTheme(); - const [anchorEl, setAnchorEl] = useState(); + const [anchorEl, setAnchorEl] = useState(); const open = Boolean(anchorEl); - function handlePopoverOpen(event) { + function handlePopoverOpen(event: React.MouseEvent) { setAnchorEl(event.currentTarget); } function handlePopoverClose() { - setAnchorEl(null); + setAnchorEl(undefined); } const triggerOnHoverProps = { @@ -121,8 +121,6 @@ const ToolTipIcon = ({ return ; case 'error': return ; - default: - kind satisfies never; } }; diff --git a/web/packages/teleterm/src/ui/ModalsHost/modals/AuthenticateWebDevice/AuthenticateWebDevice.story.tsx b/web/packages/design/src/Tooltip/index.ts similarity index 55% rename from web/packages/teleterm/src/ui/ModalsHost/modals/AuthenticateWebDevice/AuthenticateWebDevice.story.tsx rename to web/packages/design/src/Tooltip/index.ts index b6f35a6e673f2..1be43077b8952 100644 --- a/web/packages/teleterm/src/ui/ModalsHost/modals/AuthenticateWebDevice/AuthenticateWebDevice.story.tsx +++ b/web/packages/design/src/Tooltip/index.ts @@ -16,24 +16,5 @@ * along with this program. If not, see . */ -import React from 'react'; - -import { makeRootCluster } from 'teleterm/services/tshd/testHelpers'; -import { MockAppContextProvider } from 'teleterm/ui/fixtures/MockAppContextProvider'; - -import { AuthenticateWebDevice } from './AuthenticateWebDevice'; - -export default { - title: 'Teleterm/ModalsHost/AuthenticateWebDevice', -}; - -export const Dialog = () => ( - - {}} - onCancel={() => {}} - onAuthorize={async () => {}} - /> - -); +export { IconTooltip } from './IconTooltip'; +export { HoverTooltip } from './HoverTooltip'; diff --git a/web/packages/shared/components/ToolTip/shared.tsx b/web/packages/design/src/Tooltip/shared.tsx similarity index 100% rename from web/packages/shared/components/ToolTip/shared.tsx rename to web/packages/design/src/Tooltip/shared.tsx diff --git a/web/packages/design/src/utils/useResizeObserver.ts b/web/packages/design/src/utils/useResizeObserver.ts new file mode 100644 index 0000000000000..cd0218315f3cb --- /dev/null +++ b/web/packages/design/src/utils/useResizeObserver.ts @@ -0,0 +1,61 @@ +/** + * Teleport + * Copyright (C) 2024 Gravitational, Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +import { RefObject, useCallback, useLayoutEffect } from 'react'; + +/** + * useResizeObserver sets up a ResizeObserver for ref and calls callback on each resize. + * + * It does not fire if ref.current.contentRect.height is zero, to account for a special case in + * Connect where tabs are hidden using `display: none;`. + * + * Uses a layout effect underneath. If ref is conditionally rendered, set enabled to false when ref + * is null. + */ +export function useResizeObserver( + ref: RefObject, + callback: (entry: ResizeObserverEntry) => void, + { enabled = true } +): void { + const effect = useCallback(() => { + if (!ref.current || !enabled) { + return; + } + + const observer = new ResizeObserver(entries => { + const entry = entries[0]; + + // In Connect, when a tab becomes active, its outermost DOM element switches from `display: + // none` to `display: flex`. This callback is then fired with the height reported as zero. + // To avoid unnecessary calls to callback, return early here. + if (entry.contentRect.height === 0) { + return; + } + + callback(entry); + }); + + observer.observe(ref.current); + + return () => { + observer.disconnect(); + }; + }, [callback, ref, enabled]); + + useLayoutEffect(effect, [effect]); +} diff --git a/web/packages/shared/components/AccessRequests/AccessDuration/AccessDurationRequest.tsx b/web/packages/shared/components/AccessRequests/AccessDuration/AccessDurationRequest.tsx index 998245bbc58da..35cfac569c462 100644 --- a/web/packages/shared/components/AccessRequests/AccessDuration/AccessDurationRequest.tsx +++ b/web/packages/shared/components/AccessRequests/AccessDuration/AccessDurationRequest.tsx @@ -19,8 +19,9 @@ import React from 'react'; import { Flex, LabelInput, Text } from 'design'; +import { IconTooltip } from 'design/Tooltip'; + import Select, { Option } from 'shared/components/Select'; -import { ToolTipInfo } from 'shared/components/ToolTip'; export function AccessDurationRequest({ maxDuration, @@ -35,11 +36,11 @@ export function AccessDurationRequest({ Access Duration - + How long you would be given elevated privileges. Note that the time it takes to approve this request will be subtracted from the duration you requested. - + Access Request Lifetime - + The max duration of an access request, starting from its creation, until it expires. - + {getFormattedDurationTxt({ diff --git a/web/packages/shared/components/AccessRequests/NewRequest/RequestCheckout/RequestCheckout.tsx b/web/packages/shared/components/AccessRequests/NewRequest/RequestCheckout/RequestCheckout.tsx index 775c10f356267..fd4bc1578869d 100644 --- a/web/packages/shared/components/AccessRequests/NewRequest/RequestCheckout/RequestCheckout.tsx +++ b/web/packages/shared/components/AccessRequests/NewRequest/RequestCheckout/RequestCheckout.tsx @@ -39,6 +39,8 @@ import { ArrowBack, ChevronDown, ChevronRight, Warning } from 'design/Icon'; import Table, { Cell } from 'design/DataTable'; import { Danger } from 'design/Alert'; +import { HoverTooltip } from 'design/Tooltip'; + import Validation, { useRule, Validator } from 'shared/components/Validation'; import { Attempt } from 'shared/hooks/useAttemptNext'; import { pluralize } from 'shared/utils/text'; @@ -47,7 +49,6 @@ import { FieldCheckbox } from 'shared/components/FieldCheckbox'; import { mergeRefs } from 'shared/libs/mergeRefs'; import { TextSelectCopyMulti } from 'shared/components/TextSelectCopy'; import { RequestableResourceKind } from 'shared/components/AccessRequests/NewRequest/resource'; -import { HoverTooltip } from 'shared/components/ToolTip'; import { CreateRequest } from '../../Shared/types'; import { AssumeStartTime } from '../../AssumeStartTime/AssumeStartTime'; diff --git a/web/packages/shared/components/AccessRequests/ReviewRequests/RequestView/RequestReview/RequestReview.tsx b/web/packages/shared/components/AccessRequests/ReviewRequests/RequestView/RequestReview/RequestReview.tsx index 6a93e92656ac0..c21e4295c3afc 100644 --- a/web/packages/shared/components/AccessRequests/ReviewRequests/RequestView/RequestReview/RequestReview.tsx +++ b/web/packages/shared/components/AccessRequests/ReviewRequests/RequestView/RequestReview/RequestReview.tsx @@ -22,12 +22,13 @@ import { ButtonPrimary, Text, Box, Alert, Flex, Label, H3 } from 'design'; import { Warning } from 'design/Icon'; import { Radio } from 'design/RadioGroup'; +import { HoverTooltip } from 'design/Tooltip'; + import Validation, { Validator } from 'shared/components/Validation'; import { FieldSelect } from 'shared/components/FieldSelect'; import { Option } from 'shared/components/Select'; import { Attempt } from 'shared/hooks/useAsync'; import { requiredField } from 'shared/components/Validation/rules'; -import { HoverTooltip } from 'shared/components/ToolTip'; import { FieldTextArea } from 'shared/components/FieldTextArea'; import { AccessRequest, RequestState } from 'shared/services/accessRequests'; diff --git a/web/packages/shared/components/AccessRequests/ReviewRequests/RequestView/RequestView.test.tsx b/web/packages/shared/components/AccessRequests/ReviewRequests/RequestView/RequestView.test.tsx new file mode 100644 index 0000000000000..1ee774c4d75ae --- /dev/null +++ b/web/packages/shared/components/AccessRequests/ReviewRequests/RequestView/RequestView.test.tsx @@ -0,0 +1,71 @@ +/** + * Teleport + * Copyright (C) 2024 Gravitational, Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +import { render, screen } from 'design/utils/testing'; + +import { makeEmptyAttempt, makeSuccessAttempt } from 'shared/hooks/useAsync'; + +import { requestRolePending } from '../../fixtures'; + +import { RequestView, RequestViewProps } from './RequestView'; +import { RequestFlags } from './types'; + +const sampleFlags: RequestFlags = { + canAssume: false, + isAssumed: false, + canDelete: false, + canReview: true, + ownRequest: false, + isPromoted: false, +}; + +const props: RequestViewProps = { + user: 'loggedInUsername', + fetchRequestAttempt: makeSuccessAttempt(requestRolePending), + submitReviewAttempt: makeEmptyAttempt(), + getFlags: () => sampleFlags, + confirmDelete: false, + toggleConfirmDelete: () => null, + submitReview: () => null, + assumeRole: () => null, + fetchSuggestedAccessListsAttempt: makeSuccessAttempt([]), + assumeRoleAttempt: makeEmptyAttempt(), + assumeAccessList: () => null, + deleteRequestAttempt: makeEmptyAttempt(), + deleteRequest: () => null, +}; + +const reviewBoxText = `${props.user} - add a review`; + +test('renders review box if user can review', async () => { + render(); + expect(screen.getByText(reviewBoxText)).toBeInTheDocument(); +}); + +test('does not render review box if user cannot review', async () => { + render( + ({ + ...sampleFlags, + canReview: false, + })} + /> + ); + expect(screen.queryByText(reviewBoxText)).not.toBeInTheDocument(); +}); diff --git a/web/packages/shared/components/AccessRequests/ReviewRequests/RequestView/RequestView.tsx b/web/packages/shared/components/AccessRequests/ReviewRequests/RequestView/RequestView.tsx index 3bebbf52fc0b4..9a3e424787378 100644 --- a/web/packages/shared/components/AccessRequests/ReviewRequests/RequestView/RequestView.tsx +++ b/web/packages/shared/components/AccessRequests/ReviewRequests/RequestView/RequestView.tsx @@ -42,7 +42,8 @@ import { displayDateWithPrefixedTime } from 'design/datetime'; import { LabelKind } from 'design/LabelState/LabelState'; -import { HoverTooltip } from 'shared/components/ToolTip'; +import { HoverTooltip } from 'design/Tooltip'; + import { hasFinished, Attempt } from 'shared/hooks/useAsync'; import { diff --git a/web/packages/shared/components/AccessRequests/Shared/Shared.tsx b/web/packages/shared/components/AccessRequests/Shared/Shared.tsx index 97bf6987b2d6e..2159f6309c95e 100644 --- a/web/packages/shared/components/AccessRequests/Shared/Shared.tsx +++ b/web/packages/shared/components/AccessRequests/Shared/Shared.tsx @@ -21,7 +21,8 @@ import { ButtonPrimary, Text, Box, ButtonIcon, Menu } from 'design'; import { Info } from 'design/Icon'; import { displayDateWithPrefixedTime } from 'design/datetime'; -import { HoverTooltip } from 'shared/components/ToolTip'; +import { HoverTooltip } from 'design/Tooltip'; + import { AccessRequest } from 'shared/services/accessRequests'; export function PromotedMessage({ diff --git a/web/packages/shared/components/AdvancedSearchToggle/AdvancedSearchToggle.tsx b/web/packages/shared/components/AdvancedSearchToggle/AdvancedSearchToggle.tsx index 6800783daba6a..ea37fe2de003d 100644 --- a/web/packages/shared/components/AdvancedSearchToggle/AdvancedSearchToggle.tsx +++ b/web/packages/shared/components/AdvancedSearchToggle/AdvancedSearchToggle.tsx @@ -22,7 +22,7 @@ import { Text, Toggle, Link, Flex, H2 } from 'design'; import { P } from 'design/Text/Text'; -import { ToolTipInfo } from 'shared/components/ToolTip'; +import { IconTooltip } from 'design/Tooltip'; const GUIDE_URL = 'https://goteleport.com/docs/reference/predicate-language/#resource-filtering'; @@ -44,9 +44,9 @@ export function AdvancedSearchToggle(props: { > Advanced - + - +
); } diff --git a/web/packages/shared/components/ClusterDropdown/ClusterDropdown.tsx b/web/packages/shared/components/ClusterDropdown/ClusterDropdown.tsx index eb9babb16f43c..60846510fe90d 100644 --- a/web/packages/shared/components/ClusterDropdown/ClusterDropdown.tsx +++ b/web/packages/shared/components/ClusterDropdown/ClusterDropdown.tsx @@ -24,7 +24,7 @@ import { ChevronDown } from 'design/Icon'; import cfg from 'teleport/config'; import { Cluster } from 'teleport/services/clusters'; -import { HoverTooltip } from 'shared/components/ToolTip'; +import { HoverTooltip } from 'design/Tooltip'; export interface ClusterDropdownProps { clusterLoader: ClusterLoader; diff --git a/web/packages/shared/components/Controls/MultiselectMenu.tsx b/web/packages/shared/components/Controls/MultiselectMenu.tsx index f252cf7aa21be..98acea2a75d28 100644 --- a/web/packages/shared/components/Controls/MultiselectMenu.tsx +++ b/web/packages/shared/components/Controls/MultiselectMenu.tsx @@ -29,7 +29,7 @@ import { import { ChevronDown } from 'design/Icon'; import { CheckboxInput } from 'design/Checkbox'; -import { HoverTooltip } from 'shared/components/ToolTip'; +import { HoverTooltip } from 'design/Tooltip'; type MultiselectMenuProps = { options: { diff --git a/web/packages/shared/components/Controls/SortMenu.tsx b/web/packages/shared/components/Controls/SortMenu.tsx index d6bbc5cdf0d2d..a55dabad7929c 100644 --- a/web/packages/shared/components/Controls/SortMenu.tsx +++ b/web/packages/shared/components/Controls/SortMenu.tsx @@ -20,7 +20,7 @@ import React, { useState } from 'react'; import { ButtonBorder, Flex, Menu, MenuItem } from 'design'; import { ArrowDown, ArrowUp } from 'design/Icon'; -import { HoverTooltip } from 'shared/components/ToolTip'; +import { HoverTooltip } from 'design/Tooltip'; type SortMenuSort = { fieldName: Exclude; diff --git a/web/packages/shared/components/Controls/ViewModeSwitch.tsx b/web/packages/shared/components/Controls/ViewModeSwitch.tsx index 7997f2de29f66..62e5f94b36a3a 100644 --- a/web/packages/shared/components/Controls/ViewModeSwitch.tsx +++ b/web/packages/shared/components/Controls/ViewModeSwitch.tsx @@ -22,7 +22,7 @@ import { Rows, SquaresFour } from 'design/Icon'; import { ViewMode } from 'gen-proto-ts/teleport/userpreferences/v1/unified_resource_preferences_pb'; -import { HoverTooltip } from 'shared/components/ToolTip'; +import { HoverTooltip } from 'design/Tooltip'; export const ViewModeSwitch = ({ currentViewMode, diff --git a/web/packages/shared/components/FieldInput/FieldInput.tsx b/web/packages/shared/components/FieldInput/FieldInput.tsx index e8fceadf12214..1ea08bf39ed8f 100644 --- a/web/packages/shared/components/FieldInput/FieldInput.tsx +++ b/web/packages/shared/components/FieldInput/FieldInput.tsx @@ -28,8 +28,9 @@ import styled, { useTheme } from 'styled-components'; import { IconProps } from 'design/Icon/Icon'; import { InputMode, InputSize, InputType } from 'design/Input'; +import { IconTooltip } from 'design/Tooltip'; + import { useRule } from 'shared/components/Validation'; -import { ToolTipInfo } from 'shared/components/ToolTip'; const FieldInput = forwardRef( ( @@ -113,7 +114,7 @@ const FieldInput = forwardRef( > {label} - + ) : ( <>{label} diff --git a/web/packages/shared/components/FieldMultiInput/FieldMultiInput.story.tsx b/web/packages/shared/components/FieldMultiInput/FieldMultiInput.story.tsx index 5362236a8b24d..2f798d4d923d1 100644 --- a/web/packages/shared/components/FieldMultiInput/FieldMultiInput.story.tsx +++ b/web/packages/shared/components/FieldMultiInput/FieldMultiInput.story.tsx @@ -20,6 +20,12 @@ import React, { useState } from 'react'; import Box from 'design/Box'; +import { Button } from 'design/Button'; + +import Validation from 'shared/components/Validation'; + +import { arrayOf, requiredField } from '../Validation/rules'; + import { FieldMultiInput } from './FieldMultiInput'; export default { @@ -30,7 +36,21 @@ export function Story() { const [items, setItems] = useState([]); return ( - + + {({ validator }) => ( + <> + + + + )} + ); } diff --git a/web/packages/shared/components/FieldMultiInput/FieldMultiInput.test.tsx b/web/packages/shared/components/FieldMultiInput/FieldMultiInput.test.tsx index ce023a071053a..89b191e1e5b2d 100644 --- a/web/packages/shared/components/FieldMultiInput/FieldMultiInput.test.tsx +++ b/web/packages/shared/components/FieldMultiInput/FieldMultiInput.test.tsx @@ -19,20 +19,36 @@ import userEvent from '@testing-library/user-event'; import React, { useState } from 'react'; -import { render, screen } from 'design/utils/testing'; +import { act, render, screen } from 'design/utils/testing'; + +import Validation, { Validator } from 'shared/components/Validation'; + +import { arrayOf, requiredField } from '../Validation/rules'; import { FieldMultiInput, FieldMultiInputProps } from './FieldMultiInput'; const TestFieldMultiInput = ({ onChange, + refValidator, ...rest -}: Partial) => { +}: Partial & { + refValidator?: (v: Validator) => void; +}) => { const [items, setItems] = useState([]); const handleChange = (it: string[]) => { setItems(it); onChange?.(it); }; - return ; + return ( + + {({ validator }) => { + refValidator?.(validator); + return ( + + ); + }} + + ); }; test('adding, editing, and removing items', async () => { @@ -69,3 +85,35 @@ test('keyboard handling', async () => { await user.keyboard('{Enter}bananas'); expect(onChange).toHaveBeenLastCalledWith(['apples', 'bananas', 'oranges']); }); + +test('validation', async () => { + const user = userEvent.setup(); + let validator: Validator; + render( + { + validator = v; + }} + rule={arrayOf(requiredField('required'))} + /> + ); + + act(() => validator.validate()); + expect(validator.state.valid).toBe(true); + expect(screen.getByRole('textbox')).toHaveAccessibleDescription(''); + + await user.click(screen.getByRole('button', { name: 'Add More' })); + await user.type(screen.getAllByRole('textbox')[1], 'foo'); + act(() => validator.validate()); + expect(validator.state.valid).toBe(false); + expect(screen.getAllByRole('textbox')[0]).toHaveAccessibleDescription( + 'required' + ); + expect(screen.getAllByRole('textbox')[1]).toHaveAccessibleDescription(''); + + await user.type(screen.getAllByRole('textbox')[0], 'foo'); + act(() => validator.validate()); + expect(validator.state.valid).toBe(true); + expect(screen.getAllByRole('textbox')[0]).toHaveAccessibleDescription(''); + expect(screen.getAllByRole('textbox')[1]).toHaveAccessibleDescription(''); +}); diff --git a/web/packages/shared/components/FieldMultiInput/FieldMultiInput.tsx b/web/packages/shared/components/FieldMultiInput/FieldMultiInput.tsx index e1dbace8c97d5..48a12d403f313 100644 --- a/web/packages/shared/components/FieldMultiInput/FieldMultiInput.tsx +++ b/web/packages/shared/components/FieldMultiInput/FieldMultiInput.tsx @@ -21,15 +21,35 @@ import { ButtonSecondary } from 'design/Button'; import ButtonIcon from 'design/ButtonIcon'; import Flex from 'design/Flex'; import * as Icon from 'design/Icon'; -import Input from 'design/Input'; import { useRef } from 'react'; import styled, { useTheme } from 'styled-components'; +import { + precomputed, + Rule, + ValidationResult, +} from 'shared/components/Validation/rules'; +import { useRule } from 'shared/components/Validation'; + +import FieldInput from '../FieldInput'; + +type StringListValidationResult = ValidationResult & { + /** + * A list of validation results, one per list item. Note: results are + * optional just because `useRule` by default returns only + * `ValidationResult`. For the actual validation, it's not optional; if it's + * undefined, or there are fewer results in this list than the list items, + * the corresponding items will be treated as valid. + */ + results?: ValidationResult[]; +}; + export type FieldMultiInputProps = { label?: string; value: string[]; disabled?: boolean; onChange?(val: string[]): void; + rule?: Rule; }; /** @@ -45,7 +65,13 @@ export function FieldMultiInput({ value, disabled, onChange, + rule = defaultRule, }: FieldMultiInputProps) { + // It's important to first validate, and then treat an empty array as a + // single-item list with an empty string, since this "synthetic" empty + // string is technically not a part of the model and should not be + // validated. + const validationResult: StringListValidationResult = useRule(rule(value)); if (value.length === 0) { value = ['']; } @@ -90,8 +116,11 @@ export function FieldMultiInput({ // procedure whose complexity would probably outweigh the benefits). - onChange?.( @@ -99,6 +128,7 @@ export function FieldMultiInput({ ) } onKeyDown={e => handleKeyDown(i, e)} + mb={0} /> () => ({ valid: true }); + const Fieldset = styled.fieldset` border: none; margin: 0; diff --git a/web/packages/shared/components/FieldSelect/FieldSelect.story.tsx b/web/packages/shared/components/FieldSelect/FieldSelect.story.tsx index cecfa4e84dac0..dde0dc2b97dce 100644 --- a/web/packages/shared/components/FieldSelect/FieldSelect.story.tsx +++ b/web/packages/shared/components/FieldSelect/FieldSelect.story.tsx @@ -53,7 +53,10 @@ export function Default() { return ( {({ validator }) => { - validator.validate(); + // Prevent rendering loop. + if (!validator.state.validating) { + validator.validate(); + } return ( () => ({ valid: true }); @@ -95,7 +96,7 @@ export const FieldSelectWrapper = ({ {toolTipContent ? ( {label} - + ) : ( label diff --git a/web/packages/shared/components/FieldTextArea/FieldTextArea.tsx b/web/packages/shared/components/FieldTextArea/FieldTextArea.tsx index 545ef4d56ce17..c8bd7a1e0439d 100644 --- a/web/packages/shared/components/FieldTextArea/FieldTextArea.tsx +++ b/web/packages/shared/components/FieldTextArea/FieldTextArea.tsx @@ -27,9 +27,10 @@ import { TextAreaSize } from 'design/TextArea'; import { BoxProps } from 'design/Box'; +import { IconTooltip } from 'design/Tooltip'; + import { useRule } from 'shared/components/Validation'; -import { ToolTipInfo } from '../ToolTip'; import { HelperTextLine } from '../FieldInput/FieldInput'; export type FieldTextAreaProps = BoxProps & { @@ -140,7 +141,7 @@ export const FieldTextArea = forwardRef< > {label} - + ) : ( <>{label} diff --git a/web/packages/shared/components/FileTransfer/FileTransferActionBar.test.tsx b/web/packages/shared/components/FileTransfer/FileTransferActionBar.test.tsx new file mode 100644 index 0000000000000..9f948abeda683 --- /dev/null +++ b/web/packages/shared/components/FileTransfer/FileTransferActionBar.test.tsx @@ -0,0 +1,44 @@ +/** + * Teleport + * Copyright (C) 2024 Gravitational, Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +import { render, screen } from 'design/utils/testing'; + +import { FileTransferActionBar } from './FileTransferActionBar'; +import { FileTransferContextProvider } from './FileTransferContextProvider'; + +test('file transfer bar is enabled by default', async () => { + render( + + + + ); + + expect(screen.getByTitle('Download files')).toBeEnabled(); + expect(screen.getByTitle('Upload files')).toBeEnabled(); +}); + +test('file transfer is disable if no access', async () => { + render( + + + + ); + + expect(screen.getByTitle('Download files')).toBeDisabled(); + expect(screen.getByTitle('Upload files')).toBeDisabled(); +}); diff --git a/web/packages/shared/components/FileTransfer/FileTransferActionBar.tsx b/web/packages/shared/components/FileTransfer/FileTransferActionBar.tsx index de894ca2e0d89..74c0616f8add0 100644 --- a/web/packages/shared/components/FileTransfer/FileTransferActionBar.tsx +++ b/web/packages/shared/components/FileTransfer/FileTransferActionBar.tsx @@ -17,40 +17,59 @@ */ import React from 'react'; -import { Flex, ButtonIcon } from 'design'; +import { Flex, ButtonIcon, Text } from 'design'; import * as Icons from 'design/Icon'; +import { HoverTooltip } from 'design/Tooltip'; import { useFileTransferContext } from './FileTransferContextProvider'; type FileTransferActionBarProps = { isConnected: boolean; + // if any role has `options.ssh_file_copy: true` without any other role having `false` (false overrides). + hasAccess: boolean; }; export function FileTransferActionBar({ isConnected, + hasAccess, }: FileTransferActionBarProps) { const fileTransferContext = useFileTransferContext(); const areFileTransferButtonsDisabled = - fileTransferContext.openedDialog || !isConnected; + fileTransferContext.openedDialog || !isConnected || !hasAccess; return ( - + You are missing the{' '} + + ssh_file_copy + {' '} + role option. + + ) : null + } > - - - - - + + + + + + + ); } diff --git a/web/packages/shared/components/MenuLogin/MenuLogin.story.tsx b/web/packages/shared/components/MenuLogin/MenuLogin.story.tsx index a1bfb4270cdf9..224fa80ae365f 100644 --- a/web/packages/shared/components/MenuLogin/MenuLogin.story.tsx +++ b/web/packages/shared/components/MenuLogin/MenuLogin.story.tsx @@ -16,11 +16,12 @@ * along with this program. If not, see . */ -import React from 'react'; -import { Flex } from 'design'; +import { useEffect, useRef } from 'react'; +import { Flex, H3 } from 'design'; +import styled from 'styled-components'; import { MenuLogin } from './MenuLogin'; -import { MenuLoginHandle } from './types'; +import { LoginItem, MenuLoginHandle } from './types'; export default { title: 'Shared/MenuLogin', @@ -31,46 +32,125 @@ export const MenuLoginStory = () => ; function MenuLoginExamples() { return ( - []} - onSelect={() => null} - placeholder="Please provide user name…" - /> - new Promise(() => {})} - placeholder="MenuLogin in processing state" - onSelect={() => null} - /> - + +

No logins

+ []} + onSelect={() => null} + placeholder="Please provide user name…" + /> +
+ +

Processing state

+ new Promise(() => {})} + placeholder="MenuLogin in processing state" + onSelect={() => null} + /> +
+ +

With logins

+ +
+ +

With a lot of logins

+ +
); } -class SampleMenu extends React.Component { - menuRef = React.createRef(); +const Example = styled(Flex).attrs({ + gap: 2, + flexDirection: 'column', + alignItems: 'flex-start', +})``; - componentDidMount() { - this.menuRef.current.open(); - } +const SampleMenu = ({ + loginItems, + open = false, +}: { + loginItems: LoginItem[]; + open?: boolean; +}) => { + const menuRef = useRef(); - render() { - return ( - loginItems} - onSelect={() => null} - /> - ); - } -} + useEffect(() => { + if (open) { + menuRef.current.open(); + } + }, [open]); + + return ( + loginItems} + onSelect={() => null} + /> + ); +}; + +const makeLoginItem = (login: string) => ({ url: '', login }); -const loginItems = ['root', 'jazrafiba', 'evubale', 'ipizodu'].map(login => ({ - url: '', - login, -})); +const loginItems = ['root', 'jazrafiba', 'evubale', 'ipizodu'].map( + makeLoginItem +); +const aLotOfLoginItems = [ + 'root', + 'nyvpr@freire42.arg', + 'obo@qngnubfg.pb', + 'puneyvr@zlqbznva.bet', + 'qnir@erzbgrobk.pbz', + 'rir@flfgrzyvax.qri', + 'senax@pybhqlfcnpr.vb', + 'tenpr@grpuuho.hf', + 'unax@frpherybtva.ovm', + 'vil@argpbaarpg.gi', + 'wvyy@fnsrnpprff.ceb', + 'xra@erzbgryno.pb', + 'yran@qribcf.pybhq', + 'zvxr@ulcreabqr.bet', + 'avan@ybtzrva.klm', + 'bfpne@frpherubfg.arg', + 'cnhy@dhvpxpbaarpg.pb', + 'dhvaa@yvaxzr.ceb', + 'ehgu@snfgqngn.vb', + 'fgrir@npprffcbvag.qri', + 'gvan@pbzchgryvax.hf', + 'htb@frphercbeg.ovm', + 'iren@freirenpprff.gi', + 'jnyg@ybtvafgngvba.pbz', + 'kran@fnsrubfg.arg', + 'lhev@erzbgrfreire.pb', + 'mnen@pbaarpgyvax.vb', + 'nqnz@ploreabqr.pybhq', + 'orgu@flfgrztngr.bet', + 'pney@snfgybtva.ceb', + 'qvan@qngnjbeyq.ovm', + 'rq@ybtoevqtr.gi', + 'snl@frpherjnl.qri', + 'tvy@grpunpprff.hf', + 'uny@erzbgryvax.arg', + 'vqn@freirecbvag.pbz', + 'wnxr@pbaarpgceb.vb', + 'xnen@ybtfgngvba.bet', + 'yrb@npprffarg.pb', + 'znln@ploreyvax.gi', + 'abnu@erzbgrfcnpr.ovm', + 'bytn@frpherqngn.ceb', + 'crgr@dhvpxabqr.qri', + 'dhvaa@flfgrznpprff.hf', + 'eurn@ybtabqr.pbz', + 'fnen@erzbgrnpprff.arg', + 'gbz@pybhqfgngvba.pb', + 'hefhyn@ulcreyvax.vb', + 'ivp@frpheryvax.gi', + 'jvyy@freiretngr.ceb', + 'last@item.com', +].map(makeLoginItem); diff --git a/web/packages/shared/components/MenuLogin/MenuLogin.tsx b/web/packages/shared/components/MenuLogin/MenuLogin.tsx index 53b6c9d1fdd46..d45aa593ea36e 100644 --- a/web/packages/shared/components/MenuLogin/MenuLogin.tsx +++ b/web/packages/shared/components/MenuLogin/MenuLogin.tsx @@ -141,6 +141,9 @@ export const MenuLogin = React.forwardRef( open={isOpen} onClose={onClose} getContentAnchorEl={null} + // The list of logins is updated asynchronously, so Popover inside Menu needs to account + // for LoginItemList changing in size. + updatePositionOnChildResize > would cause a scroll bar to pop up and hide repeatedly. + m={1} css={` align-self: center; `} diff --git a/web/packages/shared/components/ToolTip/index.ts b/web/packages/shared/components/ToolTip/index.ts index c6518cad9b297..f1be185cb4ae6 100644 --- a/web/packages/shared/components/ToolTip/index.ts +++ b/web/packages/shared/components/ToolTip/index.ts @@ -16,5 +16,10 @@ * along with this program. If not, see . */ -export { ToolTipInfo } from './ToolTip'; -export { HoverTooltip } from './HoverTooltip'; +export { + /** @deprecated Use `TooltipInfo` from `design/Tooltip` */ + IconTooltip as ToolTipInfo, + + /** @deprecated Use `HoverTooltip` from `design/Tooltip` */ + HoverTooltip, +} from 'design/Tooltip'; diff --git a/web/packages/shared/components/UnifiedResources/CardsView/ResourceCard.tsx b/web/packages/shared/components/UnifiedResources/CardsView/ResourceCard.tsx index 8268c8b71d599..9d3f9ed608da1 100644 --- a/web/packages/shared/components/UnifiedResources/CardsView/ResourceCard.tsx +++ b/web/packages/shared/components/UnifiedResources/CardsView/ResourceCard.tsx @@ -26,7 +26,7 @@ import { ResourceIcon } from 'design/ResourceIcon'; import { makeLabelTag } from 'teleport/components/formatters'; -import { HoverTooltip } from 'shared/components/ToolTip'; +import { HoverTooltip } from 'design/Tooltip'; import { ResourceItemProps } from '../types'; import { PinButton } from '../shared/PinButton'; @@ -85,6 +85,8 @@ export function ResourceCard({ useLayoutEffect(() => { if (!labelsInnerContainer.current) return; + // TODO(ravicious): Use useResizeObserver instead. Ensure that the callback passed to + // useResizeObserver has a stable identity. const observer = new ResizeObserver(entries => { const container = entries[0]; diff --git a/web/packages/shared/components/UnifiedResources/FilterPanel.tsx b/web/packages/shared/components/UnifiedResources/FilterPanel.tsx index 6e62a50a3d4c9..d470abe9a9e9e 100644 --- a/web/packages/shared/components/UnifiedResources/FilterPanel.tsx +++ b/web/packages/shared/components/UnifiedResources/FilterPanel.tsx @@ -26,7 +26,8 @@ import { ChevronDown, ArrowsIn, ArrowsOut, Refresh } from 'design/Icon'; import { ViewMode } from 'gen-proto-ts/teleport/userpreferences/v1/unified_resource_preferences_pb'; -import { HoverTooltip } from 'shared/components/ToolTip'; +import { HoverTooltip } from 'design/Tooltip'; + import { SortMenu } from 'shared/components/Controls/SortMenu'; import { ViewModeSwitch } from 'shared/components/Controls/ViewModeSwitch'; diff --git a/web/packages/shared/components/UnifiedResources/ListView/ResourceListItem.tsx b/web/packages/shared/components/UnifiedResources/ListView/ResourceListItem.tsx index 0f2a34024536a..582a7c5ece831 100644 --- a/web/packages/shared/components/UnifiedResources/ListView/ResourceListItem.tsx +++ b/web/packages/shared/components/UnifiedResources/ListView/ResourceListItem.tsx @@ -26,7 +26,7 @@ import { ResourceIcon } from 'design/ResourceIcon'; import { makeLabelTag } from 'teleport/components/formatters'; -import { HoverTooltip } from 'shared/components/ToolTip'; +import { HoverTooltip } from 'design/Tooltip'; import { ResourceItemProps } from '../types'; import { PinButton } from '../shared/PinButton'; diff --git a/web/packages/shared/components/UnifiedResources/ResourceTab.tsx b/web/packages/shared/components/UnifiedResources/ResourceTab.tsx index 2533e2a203165..2deb131ffcde9 100644 --- a/web/packages/shared/components/UnifiedResources/ResourceTab.tsx +++ b/web/packages/shared/components/UnifiedResources/ResourceTab.tsx @@ -20,7 +20,7 @@ import React from 'react'; import styled from 'styled-components'; import { Box, Text } from 'design'; -import { HoverTooltip } from 'shared/components/ToolTip'; +import { HoverTooltip } from 'design/Tooltip'; import { PINNING_NOT_SUPPORTED_MESSAGE } from './UnifiedResources'; diff --git a/web/packages/shared/components/UnifiedResources/UnifiedResources.tsx b/web/packages/shared/components/UnifiedResources/UnifiedResources.tsx index 5426b0d908a74..d7608ee6c4cf2 100644 --- a/web/packages/shared/components/UnifiedResources/UnifiedResources.tsx +++ b/web/packages/shared/components/UnifiedResources/UnifiedResources.tsx @@ -43,7 +43,8 @@ import { AvailableResourceMode, } from 'gen-proto-ts/teleport/userpreferences/v1/unified_resource_preferences_pb'; -import { HoverTooltip } from 'shared/components/ToolTip'; +import { HoverTooltip } from 'design/Tooltip'; + import { makeEmptyAttempt, makeSuccessAttempt, @@ -399,6 +400,8 @@ export function UnifiedResources(props: UnifiedResourcesProps) { unifiedResourcePreferences.labelsViewMode === LabelsViewMode.EXPANDED; useLayoutEffect(() => { + // TODO(ravicious): Use useResizeObserver instead. Ensure that the callback passed to + // useResizeObserver has a stable identity. const resizeObserver = new ResizeObserver(entries => { const container = entries[0]; diff --git a/web/packages/shared/components/UnifiedResources/shared/CopyButton.tsx b/web/packages/shared/components/UnifiedResources/shared/CopyButton.tsx index a3a1a4ad12be6..43b9cb2217165 100644 --- a/web/packages/shared/components/UnifiedResources/shared/CopyButton.tsx +++ b/web/packages/shared/components/UnifiedResources/shared/CopyButton.tsx @@ -22,7 +22,7 @@ import ButtonIcon from 'design/ButtonIcon'; import { Check, Copy } from 'design/Icon'; import { copyToClipboard } from 'design/utils/copyToClipboard'; -import { HoverTooltip } from 'shared/components/ToolTip'; +import { HoverTooltip } from 'design/Tooltip'; export function CopyButton({ name, diff --git a/web/packages/shared/components/UnifiedResources/shared/PinButton.tsx b/web/packages/shared/components/UnifiedResources/shared/PinButton.tsx index 1eedee2db68a2..cde3b87142c04 100644 --- a/web/packages/shared/components/UnifiedResources/shared/PinButton.tsx +++ b/web/packages/shared/components/UnifiedResources/shared/PinButton.tsx @@ -21,7 +21,7 @@ import React, { useRef } from 'react'; import { PushPinFilled, PushPin } from 'design/Icon'; import ButtonIcon from 'design/ButtonIcon'; -import { HoverTooltip } from 'shared/components/ToolTip'; +import { HoverTooltip } from 'design/Tooltip'; import { PinningSupport } from '../types'; diff --git a/web/packages/shared/components/Validation/Validation.jsx b/web/packages/shared/components/Validation/Validation.jsx deleted file mode 100644 index 352a386bc35fd..0000000000000 --- a/web/packages/shared/components/Validation/Validation.jsx +++ /dev/null @@ -1,105 +0,0 @@ -/* - * Teleport - * Copyright (C) 2023 Gravitational, Inc. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -import React from 'react'; - -import { isObject } from 'shared/utils/highbar'; - -import Logger from '../../libs/logger'; - -const logger = Logger.create('validation'); - -// Validator handles input validation -export default class Validator { - valid = true; - - constructor() { - // store subscribers - this._subs = []; - } - - // adds a callback to the list of subscribers - subscribe(cb) { - this._subs.push(cb); - } - - // removes a callback from the list of subscribers - unsubscribe(cb) { - const index = this._subs.indexOf(cb); - if (index > -1) { - this._subs.splice(index, 1); - } - } - - addResult(result) { - // result can be a boolean value or an object - let isValid = false; - if (isObject(result)) { - isValid = result.valid; - } else { - logger.error(`rule should return a valid object`); - } - - this.valid = this.valid && Boolean(isValid); - } - - reset() { - this.valid = true; - this.validating = false; - } - - validate() { - this.reset(); - this.validating = true; - this._subs.forEach(cb => { - try { - cb(); - } catch (err) { - logger.error(err); - } - }); - - return this.valid; - } -} - -const ValidationContext = React.createContext({}); - -export function Validation(props) { - const [validator] = React.useState(() => new Validator()); - // handle render functions - const children = - typeof props.children === 'function' - ? props.children({ validator }) - : props.children; - - return ( - - {children} - - ); -} - -export function useValidation() { - const value = React.useContext(ValidationContext); - if (!(value instanceof Validator)) { - logger.warn('Missing Validation Context declaration'); - } - - return value; -} diff --git a/web/packages/shared/components/Validation/Validation.test.tsx b/web/packages/shared/components/Validation/Validation.test.tsx index 19f40a8d44986..a933e9d916af9 100644 --- a/web/packages/shared/components/Validation/Validation.test.tsx +++ b/web/packages/shared/components/Validation/Validation.test.tsx @@ -17,32 +17,22 @@ */ import React from 'react'; +import { render, fireEvent, screen, act } from 'design/utils/testing'; -import { render, fireEvent, screen } from 'design/utils/testing'; +import Validator, { Result, Validation, useValidation } from './Validation'; -import Logger from '../../libs/logger'; - -import Validator, { Validation, useValidation } from './Validation'; - -jest.mock('../../libs/logger', () => { - const mockLogger = { - error: jest.fn(), - warn: jest.fn(), - }; - - return { - create: () => mockLogger, - }; +afterEach(() => { + jest.restoreAllMocks(); }); -test('methods of Validator: sub, unsub, validate', () => { +test('methods of Validator: addRuleCallback, removeRuleCallback, validate', () => { const mockCb1 = jest.fn(); const mockCb2 = jest.fn(); const validator = new Validator(); // test suscribe - validator.subscribe(mockCb1); - validator.subscribe(mockCb2); + validator.addRuleCallback(mockCb1); + validator.addRuleCallback(mockCb2); // test validate runs all subscribed cb's expect(validator.validate()).toBe(true); @@ -51,42 +41,42 @@ test('methods of Validator: sub, unsub, validate', () => { jest.clearAllMocks(); // test unsubscribe method removes correct cb - validator.unsubscribe(mockCb2); + validator.removeRuleCallback(mockCb2); expect(validator.validate()).toBe(true); expect(mockCb1).toHaveBeenCalledTimes(1); expect(mockCb2).toHaveBeenCalledTimes(0); }); test('methods of Validator: addResult, reset', () => { + const consoleError = jest.spyOn(console, 'error').mockImplementation(); const validator = new Validator(); // test addResult for nil object const result = null; validator.addResult(result); - expect(Logger.create().error).toHaveBeenCalledTimes(1); + expect(consoleError).toHaveBeenCalledTimes(1); // test addResult for boolean validator.addResult(true); - expect(validator.valid).toBe(false); + expect(validator.state.valid).toBe(false); // test addResult with incorrect object - let resultObj = {}; - validator.addResult(resultObj); - expect(validator.valid).toBe(false); + validator.addResult({} as Result); + expect(validator.state.valid).toBe(false); // test addResult with correct object with "valid" prop from prior test set to false - resultObj = { valid: true }; + let resultObj = { valid: true }; validator.addResult(resultObj); - expect(validator.valid).toBe(false); + expect(validator.state.valid).toBe(false); // test reset validator.reset(); - expect(validator.valid).toBe(true); - expect(validator.validating).toBe(false); + expect(validator.state.valid).toBe(true); + expect(validator.state.validating).toBe(false); // test addResult with correct object with "valid" prop reset to true validator.addResult(resultObj); - expect(validator.valid).toBe(true); + expect(validator.state.valid).toBe(true); }); test('trigger validation via useValidation hook', () => { @@ -102,7 +92,7 @@ test('trigger validation via useValidation hook', () => {
); fireEvent.click(screen.getByRole('button')); - expect(validator.validating).toBe(true); + expect(validator.state.validating).toBe(true); }); test('trigger validation via render function', () => { @@ -122,5 +112,56 @@ test('trigger validation via render function', () => { ); fireEvent.click(screen.getByRole('button')); - expect(validator.validating).toBe(true); + expect(validator.state.validating).toBe(true); +}); + +test('rendering validation result via useValidation hook', () => { + let validator: Validator; + const TestComponent = () => { + validator = useValidation(); + return ( + <> +
Validating: {String(validator.state.validating)}
+
Valid: {String(validator.state.valid)}
+ + ); + }; + render( + + + + ); + validator.addRuleCallback(() => validator.addResult({ valid: false })); + + expect(screen.getByText('Validating: false')).toBeInTheDocument(); + expect(screen.getByText('Valid: true')).toBeInTheDocument(); + + act(() => validator.validate()); + expect(screen.getByText('Validating: true')).toBeInTheDocument(); + expect(screen.getByText('Valid: false')).toBeInTheDocument(); +}); + +test('rendering validation result via render function', () => { + let validator: Validator; + render( + + {props => { + validator = props.validator; + return ( + <> +
Validating: {String(validator.state.validating)}
+
Valid: {String(validator.state.valid)}
+ + ); + }} +
+ ); + validator.addRuleCallback(() => validator.addResult({ valid: false })); + + expect(screen.getByText('Validating: false')).toBeInTheDocument(); + expect(screen.getByText('Valid: true')).toBeInTheDocument(); + + act(() => validator.validate()); + expect(screen.getByText('Validating: true')).toBeInTheDocument(); + expect(screen.getByText('Valid: false')).toBeInTheDocument(); }); diff --git a/web/packages/shared/components/Validation/Validation.tsx b/web/packages/shared/components/Validation/Validation.tsx new file mode 100644 index 0000000000000..6450c2915a61d --- /dev/null +++ b/web/packages/shared/components/Validation/Validation.tsx @@ -0,0 +1,192 @@ +/* + * Teleport + * Copyright (C) 2023 Gravitational, Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +import React from 'react'; + +import { Logger } from 'design/logger'; + +import { isObject } from 'shared/utils/highbar'; +import { Store, useStore } from 'shared/libs/stores'; + +import { ValidationResult } from './rules'; + +const logger = new Logger('validation'); + +/** A per-rule callback that will be executed during validation. */ +type RuleCallback = () => void; + +export type Result = ValidationResult | boolean; + +type ValidatorState = { + /** Indicates whether the last validation was successful. */ + valid: boolean; + /** + * Indicates whether the validator has been activated by a call to + * `validate`. + */ + validating: boolean; +}; + +/** A store that handles input validation and makes its results accessible. */ +export default class Validator extends Store { + state = { + valid: true, + validating: false, + }; + + /** + * @deprecated For temporary Enterprise compatibility only. Use {@link state} + * instead. + */ + valid = true; + + /** Callbacks that will be executed upon validation. */ + private ruleCallbacks: RuleCallback[] = []; + + /** Adds a rule callback that will be executed upon validation. */ + addRuleCallback(cb: RuleCallback) { + this.ruleCallbacks.push(cb); + } + + /** Removes a rule callback. */ + removeRuleCallback(cb: RuleCallback) { + const index = this.ruleCallbacks.indexOf(cb); + if (index > -1) { + this.ruleCallbacks.splice(index, 1); + } + } + + addResult(result: Result) { + // result can be a boolean value or an object + let isValid = false; + if (isObject(result)) { + isValid = result.valid; + } else { + logger.error(`rule should return a valid object`); + } + + const valid = this.state.valid && Boolean(isValid); + this.setState({ valid }); + this.valid = valid; + } + + reset() { + this.setState({ + valid: true, + validating: false, + }); + this.valid = true; + } + + validate() { + this.reset(); + this.setState({ validating: true }); + for (const cb of this.ruleCallbacks) { + try { + cb(); + } catch (err) { + logger.error(err); + } + } + + return this.state.valid; + } +} + +const ValidationContext = React.createContext(undefined); + +type ValidationRenderFunction = (arg: { + validator: Validator; +}) => React.ReactNode; + +/** + * Installs a validation context that provides a {@link Validator} store. The + * store can be retrieved either through {@link useValidation} hook or by a + * render callback, e.g.: + * + * ``` + * function Component() { + * return ( + * + * {({validator}) => ( + * <> + * (...) + * + * + * )} + * + * ); + * } + * ``` + * + * The simplest way to use validation is validating on the view layer: just use + * a `rule` prop with `FieldInput` or a similar component and pass a rule like + * `requiredField`. + * + * Unfortunately, due to architectural limitations, this will not work well in + * scenarios where information about validity about given field or group of + * fields is required outside that field. In cases like this, the best option + * is to validate the model during render time on the top level (for example, + * execute an entire set of rules on a model using `runRules`). The result of + * model validation will then contain information about the validity of each + * field. It can then be used wherever it's needed, and also attached to + * appropriate inputs with a `precomputed` validation rule. Example: + * + * ``` + * function Component(model: Model) { + * const rules = { + * name: requiredField('required'), + * email: requiredEmailLike, + * } + * const validationResult = runRules(model, rules); + * } + * ``` + * + * Note that, as this example shows clearly, the validator itself, despite its + * name, doesn't really validate anything -- it merely aggregates validation + * results. Also it's worth mentioning that the validator will not do it + * without our help -- each validated field needs to be actually attached to a + * field, even if using a `precomputed` rule, for this to work. The validation + * callbacks registered by validation rules on the particular fields are the + * actual points where the errors are consumed by the validator. + */ +export function Validation(props: { + children?: React.ReactNode | ValidationRenderFunction; +}) { + const [validator] = React.useState(() => new Validator()); + useStore(validator); + // handle render functions + const children = + typeof props.children === 'function' + ? props.children({ validator }) + : props.children; + + return ( + + {children} + + ); +} + +export function useValidation(): Validator { + const validator = React.useContext(ValidationContext); + if (!validator) { + throw new Error('useValidation() called without a validation context'); + } + return useStore(validator); +} diff --git a/web/packages/shared/components/Validation/rules.test.ts b/web/packages/shared/components/Validation/rules.test.ts index a07b16fb7aaa7..07ee1bf434d01 100644 --- a/web/packages/shared/components/Validation/rules.test.ts +++ b/web/packages/shared/components/Validation/rules.test.ts @@ -25,6 +25,8 @@ import { requiredEmailLike, requiredIamRoleName, requiredPort, + runRules, + arrayOf, } from './rules'; describe('requiredField', () => { @@ -153,3 +155,60 @@ describe('requiredPort', () => { expect(requiredPort(port)()).toEqual(expected); }); }); + +test('runRules', () => { + expect( + runRules( + { foo: 'val1', bar: 'val2', irrelevant: undefined }, + { foo: requiredField('no foo'), bar: requiredField('no bar') } + ) + ).toEqual({ + valid: true, + fields: { + foo: { valid: true, message: '' }, + bar: { valid: true, message: '' }, + }, + }); + + expect( + runRules( + { foo: '', bar: 'val2', irrelevant: undefined }, + { foo: requiredField('no foo'), bar: requiredField('no bar') } + ) + ).toEqual({ + valid: false, + fields: { + foo: { valid: false, message: 'no foo' }, + bar: { valid: true, message: '' }, + }, + }); +}); + +test.each([ + { + name: 'invalid', + items: ['a', '', 'c'], + expected: { + valid: false, + results: [ + { valid: true, message: '' }, + { valid: false, message: 'required' }, + { valid: true, message: '' }, + ], + }, + }, + { + name: 'valid', + items: ['a', 'b', 'c'], + expected: { + valid: true, + results: [ + { valid: true, message: '' }, + { valid: true, message: '' }, + { valid: true, message: '' }, + ], + }, + }, +])('arrayOf: $name', ({ items, expected }) => { + expect(arrayOf(requiredField('required'))(items)()).toEqual(expected); +}); diff --git a/web/packages/shared/components/Validation/rules.ts b/web/packages/shared/components/Validation/rules.ts index 52063d67fce99..545f28a348fce 100644 --- a/web/packages/shared/components/Validation/rules.ts +++ b/web/packages/shared/components/Validation/rules.ts @@ -31,6 +31,8 @@ export interface ValidationResult { */ export type Rule = (value: T) => () => R; +type RuleResult = ReturnType>; + /** * requiredField checks for empty strings and arrays. * @@ -280,6 +282,83 @@ const requiredAll = return { valid: true }; }; +/** A result of the {@link arrayOf} validation rule. */ +export type ArrayValidationResult = ValidationResult & { + /** Results of validating each separate item. */ + results: R[]; +}; + +/** Validates an array by executing given rule on each of its elements. */ +const arrayOf = + ( + elementRule: Rule + ): Rule> => + (values: T[]) => + () => { + const results = values.map(v => elementRule(v)()); + return { results: results, valid: results.every(r => r.valid) }; + }; + +/** + * Passes a precomputed validation result instead of computing it inside the + * rule. + * + * This rule is a hacky way to allow the validation engine to operate with + * validation results computed outside of the validator's validation cycle. See + * the `Validation` component's documentation for more information about where + * this is useful and a detailed usage example. + */ +const precomputed = + (res: ValidationResult): Rule => + () => + () => + res; + +/** + * A set of rules to be executed using `runRules` on a model object. The rule + * set contains a subset of keys of the object. + */ +export type RuleSet = Record< + K, + Rule +>; + +/** A result of executing a set of rules on a model object. */ +export type RuleSetValidationResult> = { + valid: boolean; + /** + * Each member of the `fields` object corresponds to a rule from within the + * rule set and contains the result of validating a model field of the same + * name. + */ + fields: { [k in keyof R]: RuleResult }; // Record; +}; + +/** + * Executes a set of rules on a model object, producing a precomputed + * validation result that can be used with `precomputed` rule to inject to + * field components, but also allows for consuming the validation data outside + * these fields. + * + * `K` is the subset of model field names. + * `M` is the validated model. + */ +export const runRules = >( + model: M, + rules: RuleSet +): RuleSetValidationResult> => { + const fields = {} as { + [k in keyof RuleSet]: RuleResult[k]>; + }; + let valid = true; + for (const key in rules) { + const modelValue = model[key]; + fields[key] = rules[key](modelValue)(); + valid &&= fields[key].valid; + } + return { fields, valid }; +}; + export { requiredToken, requiredPassword, @@ -292,4 +371,6 @@ export { requiredMatchingRoleNameAndRoleArn, validAwsIAMRoleName, requiredPort, + arrayOf, + precomputed, }; diff --git a/web/packages/shared/components/Validation/useRule.js b/web/packages/shared/components/Validation/useRule.js index ad0ca82157cbf..e8d2a77e391ae 100644 --- a/web/packages/shared/components/Validation/useRule.js +++ b/web/packages/shared/components/Validation/useRule.js @@ -39,7 +39,7 @@ export default function useRule(cb) { // register to validation context to be called on cb() React.useEffect(() => { function onValidate() { - if (validator.validating) { + if (validator.state.validating) { const result = cb(); validator.addResult(result); rerender({}); @@ -47,18 +47,18 @@ export default function useRule(cb) { } // subscribe to store changes - validator.subscribe(onValidate); + validator.addRuleCallback(onValidate); // unsubscribe on unmount function cleanup() { - validator.unsubscribe(onValidate); + validator.removeRuleCallback(onValidate); } return cleanup; }, [cb]); // if validation has been requested, cb right away. - if (validator.validating) { + if (validator.state.validating) { return cb(); } diff --git a/web/packages/teleport/src/Audit/EventList/EventTypeCell.tsx b/web/packages/teleport/src/Audit/EventList/EventTypeCell.tsx index d403cb036f23d..b97b062a244d3 100644 --- a/web/packages/teleport/src/Audit/EventList/EventTypeCell.tsx +++ b/web/packages/teleport/src/Audit/EventList/EventTypeCell.tsx @@ -195,6 +195,7 @@ const EventIconMap: Record = { [eventCodes.CLIENT_DISCONNECT]: Icons.Info, [eventCodes.PORTFORWARD]: Icons.Info, [eventCodes.PORTFORWARD_FAILURE]: Icons.Info, + [eventCodes.PORTFORWARD_STOP]: Icons.Info, [eventCodes.SUBSYSTEM]: Icons.Info, [eventCodes.SUBSYSTEM_FAILURE]: Icons.Info, [eventCodes.LOCK_CREATED]: Icons.Lock, @@ -283,6 +284,8 @@ const EventIconMap: Record = { [eventCodes.PLUGIN_CREATE]: Icons.Info, [eventCodes.PLUGIN_UPDATE]: Icons.Info, [eventCodes.PLUGIN_DELETE]: Icons.Info, + [eventCodes.CONTACT_CREATE]: Icons.Info, + [eventCodes.CONTACT_DELETE]: Icons.Info, [eventCodes.UNKNOWN]: Icons.Question, }; diff --git a/web/packages/teleport/src/Bots/List/Bots.tsx b/web/packages/teleport/src/Bots/List/Bots.tsx index be383fbd32997..594a1840d7c52 100644 --- a/web/packages/teleport/src/Bots/List/Bots.tsx +++ b/web/packages/teleport/src/Bots/List/Bots.tsx @@ -19,7 +19,7 @@ import React, { useEffect, useState } from 'react'; import { useAttemptNext } from 'shared/hooks'; import { Link } from 'react-router-dom'; -import { HoverTooltip } from 'shared/components/ToolTip'; +import { HoverTooltip } from 'design/Tooltip'; import { Alert, Box, Button, Indicator } from 'design'; import { diff --git a/web/packages/teleport/src/Console/DocumentKubeExec/KubeExecDataDialog.tsx b/web/packages/teleport/src/Console/DocumentKubeExec/KubeExecDataDialog.tsx index 36b8b7a505820..e8261cdf026c3 100644 --- a/web/packages/teleport/src/Console/DocumentKubeExec/KubeExecDataDialog.tsx +++ b/web/packages/teleport/src/Console/DocumentKubeExec/KubeExecDataDialog.tsx @@ -35,7 +35,7 @@ import { import Validation from 'shared/components/Validation'; import FieldInput from 'shared/components/FieldInput'; import { requiredField } from 'shared/components/Validation/rules'; -import { ToolTipInfo } from 'shared/components/ToolTip'; +import { IconTooltip } from 'design/Tooltip'; type Props = { onClose(): void; @@ -123,11 +123,11 @@ function KubeExecDataDialog({ onClose, onExec }: Props) { Interactive shell - + You can start an interactive shell and have a bidirectional communication with the target pod, or you can run one-off command and see its output. - +
diff --git a/web/packages/teleport/src/Console/DocumentSsh/DocumentSsh.test.tsx b/web/packages/teleport/src/Console/DocumentSsh/DocumentSsh.test.tsx new file mode 100644 index 0000000000000..0003326ef754f --- /dev/null +++ b/web/packages/teleport/src/Console/DocumentSsh/DocumentSsh.test.tsx @@ -0,0 +1,68 @@ +/** + * Teleport + * Copyright (C) 2024 Gravitational, Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +import { render, screen } from 'design/utils/testing'; +import { MemoryRouter } from 'react-router'; +import 'jest-canvas-mock'; + +import { allAccessAcl } from 'teleport/mocks/contexts'; + +import ConsoleContext from '../consoleContext'; +import ConsoleContextProvider from '../consoleContextProvider'; + +import DocumentSsh from '.'; + +test('file transfer buttons are disabled if user does not have access', async () => { + const ctx = new ConsoleContext(); + ctx.storeUser.setState({ + acl: { ...allAccessAcl, fileTransferAccess: false }, + }); + render(); + expect(screen.getByTitle('Download files')).toBeDisabled(); +}); + +test('file transfer buttons are enabled if user has access', async () => { + const ctx = new ConsoleContext(); + ctx.storeUser.setState({ + acl: allAccessAcl, + }); + render(); + expect(screen.getByTitle('Download files')).toBeEnabled(); +}); + +function Component({ ctx }: { ctx: ConsoleContext }) { + return ( + + + + + + ); +} diff --git a/web/packages/teleport/src/Console/DocumentSsh/DocumentSsh.tsx b/web/packages/teleport/src/Console/DocumentSsh/DocumentSsh.tsx index 8a81c4ec6031b..01138ab3c70bf 100644 --- a/web/packages/teleport/src/Console/DocumentSsh/DocumentSsh.tsx +++ b/web/packages/teleport/src/Console/DocumentSsh/DocumentSsh.tsx @@ -36,6 +36,8 @@ import { useMfa } from 'teleport/lib/useMfa'; import Document from '../Document'; +import { useConsoleContext } from '../consoleContextProvider'; + import { Terminal, TerminalRef } from './Terminal'; import useSshSession from './useSshSession'; import { useFileTransfer } from './useFileTransfer'; @@ -49,6 +51,8 @@ export default function DocumentSshWrapper(props: PropTypes) { } function DocumentSsh({ doc, visible }: PropTypes) { + const ctx = useConsoleContext(); + const hasFileTransferAccess = ctx.storeUser.hasFileTransferAccess(); const terminalRef = useRef(); const { tty, status, closeDocument, session } = useSshSession(doc); const [showSearch, setShowSearch] = useState(false); @@ -130,7 +134,10 @@ function DocumentSsh({ doc, visible }: PropTypes) { return ( - + {status === 'loading' && ( diff --git a/web/packages/teleport/src/DesktopSession/TopBar.tsx b/web/packages/teleport/src/DesktopSession/TopBar.tsx index 9ab12b523067d..dcd5beaec4881 100644 --- a/web/packages/teleport/src/DesktopSession/TopBar.tsx +++ b/web/packages/teleport/src/DesktopSession/TopBar.tsx @@ -21,7 +21,7 @@ import { useTheme } from 'styled-components'; import { Text, TopNav, Flex } from 'design'; import { Clipboard, FolderShared } from 'design/Icon'; -import { HoverTooltip } from 'shared/components/ToolTip'; +import { HoverTooltip } from 'design/Tooltip'; import ActionMenu from './ActionMenu'; import { AlertDropdown } from './AlertDropdown'; diff --git a/web/packages/teleport/src/Discover/AwsMangementConsole/CreateAppAccess/CreateAppAccess.tsx b/web/packages/teleport/src/Discover/AwsMangementConsole/CreateAppAccess/CreateAppAccess.tsx index 4f0b1ea32146c..2c357df859a58 100644 --- a/web/packages/teleport/src/Discover/AwsMangementConsole/CreateAppAccess/CreateAppAccess.tsx +++ b/web/packages/teleport/src/Discover/AwsMangementConsole/CreateAppAccess/CreateAppAccess.tsx @@ -21,7 +21,7 @@ import styled from 'styled-components'; import { Box, Flex, Link, Mark, H3 } from 'design'; import TextEditor from 'shared/components/TextEditor'; import { Danger } from 'design/Alert'; -import { ToolTipInfo } from 'shared/components/ToolTip'; +import { IconTooltip } from 'design/Tooltip'; import { useAsync } from 'shared/hooks/useAsync'; import { P } from 'design/Text/Text'; @@ -81,7 +81,7 @@ export function CreateAppAccess() {

First configure your AWS IAM permissions

- + The following IAM permissions will be added as an inline policy named {IAM_POLICY_NAME} to IAM role{' '} {iamRoleName} @@ -94,7 +94,7 @@ export function CreateAppAccess() { />
- +

Run the command below on your{' '} diff --git a/web/packages/teleport/src/Discover/Database/DeployService/AutoDeploy/SelectSecurityGroups.tsx b/web/packages/teleport/src/Discover/Database/DeployService/AutoDeploy/SelectSecurityGroups.tsx index cc5ed4bb590b4..1717a082208ba 100644 --- a/web/packages/teleport/src/Discover/Database/DeployService/AutoDeploy/SelectSecurityGroups.tsx +++ b/web/packages/teleport/src/Discover/Database/DeployService/AutoDeploy/SelectSecurityGroups.tsx @@ -21,7 +21,7 @@ import React, { useState, useEffect } from 'react'; import { Text, Flex, Box, Indicator, ButtonSecondary, Subtitle3 } from 'design'; import * as Icons from 'design/Icon'; import { FetchStatus } from 'design/DataTable/types'; -import { HoverTooltip, ToolTipInfo } from 'shared/components/ToolTip'; +import { HoverTooltip, IconTooltip } from 'design/Tooltip'; import useAttempt from 'shared/hooks/useAttemptNext'; import { getErrMessage } from 'shared/utils/errorType'; import { pluralize } from 'shared/utils/text'; @@ -126,7 +126,7 @@ export const SelectSecurityGroups = ({ <> Select ECS Security Groups - + Select ECS security group(s) based on the following requirements:

    @@ -141,7 +141,7 @@ export const SelectSecurityGroups = ({
- +

diff --git a/web/packages/teleport/src/Discover/Database/DeployService/AutoDeploy/SelectSubnetIds.tsx b/web/packages/teleport/src/Discover/Database/DeployService/AutoDeploy/SelectSubnetIds.tsx index 785ec15fbda9e..8a6e93a0491b1 100644 --- a/web/packages/teleport/src/Discover/Database/DeployService/AutoDeploy/SelectSubnetIds.tsx +++ b/web/packages/teleport/src/Discover/Database/DeployService/AutoDeploy/SelectSubnetIds.tsx @@ -29,7 +29,7 @@ import { } from 'design'; import * as Icons from 'design/Icon'; import { FetchStatus } from 'design/DataTable/types'; -import { HoverTooltip, ToolTipInfo } from 'shared/components/ToolTip'; +import { HoverTooltip, IconTooltip } from 'design/Tooltip'; import { pluralize } from 'shared/utils/text'; import useAttempt from 'shared/hooks/useAttemptNext'; import { getErrMessage } from 'shared/utils/errorType'; @@ -121,12 +121,12 @@ export function SelectSubnetIds({ <> Select ECS Subnets - + A subnet has an outbound internet route if it has a route to an internet gateway or a NAT gateway in a public subnet. - + diff --git a/web/packages/teleport/src/Discover/Database/EnrollRdsDatabase/AutoDiscoverToggle.tsx b/web/packages/teleport/src/Discover/Database/EnrollRdsDatabase/AutoDiscoverToggle.tsx index 204e30b3e79d1..617d10ba79790 100644 --- a/web/packages/teleport/src/Discover/Database/EnrollRdsDatabase/AutoDiscoverToggle.tsx +++ b/web/packages/teleport/src/Discover/Database/EnrollRdsDatabase/AutoDiscoverToggle.tsx @@ -19,7 +19,7 @@ import React from 'react'; import { Box, Toggle } from 'design'; -import { ToolTipInfo } from 'shared/components/ToolTip'; +import { IconTooltip } from 'design/Tooltip'; export function AutoDiscoverToggle({ wantAutoDiscover, @@ -40,11 +40,11 @@ export function AutoDiscoverToggle({ Auto-enroll all databases for the selected VPC - + Auto-enroll will automatically identify all RDS databases (e.g. PostgreSQL, MySQL, Aurora) from the selected VPC and register them as database resources in your infrastructure. - + ); diff --git a/web/packages/teleport/src/Discover/Kubernetes/EnrollEKSCluster/EnrollEksCluster.tsx b/web/packages/teleport/src/Discover/Kubernetes/EnrollEKSCluster/EnrollEksCluster.tsx index e73fc6dfc3e15..2505da7275658 100644 --- a/web/packages/teleport/src/Discover/Kubernetes/EnrollEKSCluster/EnrollEksCluster.tsx +++ b/web/packages/teleport/src/Discover/Kubernetes/EnrollEKSCluster/EnrollEksCluster.tsx @@ -31,7 +31,7 @@ import { FetchStatus } from 'design/DataTable/types'; import { Danger } from 'design/Alert'; import useAttempt from 'shared/hooks/useAttemptNext'; -import { ToolTipInfo } from 'shared/components/ToolTip'; +import { IconTooltip } from 'design/Tooltip'; import { getErrMessage } from 'shared/utils/errorType'; import { EksMeta, useDiscover } from 'teleport/Discover/useDiscover'; @@ -435,11 +435,11 @@ export function EnrollEksCluster(props: AgentStepProps) { Enable Kubernetes App Discovery - + Teleport's Kubernetes App Discovery will automatically identify and enroll to Teleport HTTP applications running inside a Kubernetes cluster. - + Auto-enroll all EKS clusters for selected region - + Auto-enroll will automatically identify all EKS clusters from the selected region and register them as Kubernetes resources in your infrastructure. - + {showTable && ( diff --git a/web/packages/teleport/src/Discover/Server/DiscoveryConfigSsm/DiscoveryConfigSsm.tsx b/web/packages/teleport/src/Discover/Server/DiscoveryConfigSsm/DiscoveryConfigSsm.tsx index 6a7245bacf798..6846a09779e53 100644 --- a/web/packages/teleport/src/Discover/Server/DiscoveryConfigSsm/DiscoveryConfigSsm.tsx +++ b/web/packages/teleport/src/Discover/Server/DiscoveryConfigSsm/DiscoveryConfigSsm.tsx @@ -30,7 +30,7 @@ import { import styled from 'styled-components'; import { Danger, Info } from 'design/Alert'; import TextEditor from 'shared/components/TextEditor'; -import { ToolTipInfo } from 'shared/components/ToolTip'; +import { IconTooltip } from 'design/Tooltip'; import FieldInput from 'shared/components/FieldInput'; import { Rule } from 'shared/components/Validation/rules'; import Validation, { Validator } from 'shared/components/Validation'; @@ -317,7 +317,7 @@ export function DiscoveryConfigSsm() { {' '} to configure your IAM permissions.

- + The following IAM permissions will be added as an inline policy named {IAM_POLICY_NAME} to IAM role{' '} {arnResourceName} @@ -330,7 +330,7 @@ export function DiscoveryConfigSsm() { /> - + Auto-enroll all EC2 instances for selected region - + Auto-enroll will automatically identify all EC2 instances from the selected region and register them as node resources in your infrastructure. - + {wantAutoDiscover && ( diff --git a/web/packages/teleport/src/Discover/Shared/Aws/ConfigureIamPerms.tsx b/web/packages/teleport/src/Discover/Shared/Aws/ConfigureIamPerms.tsx index 4c491191152b8..0c244462b7507 100644 --- a/web/packages/teleport/src/Discover/Shared/Aws/ConfigureIamPerms.tsx +++ b/web/packages/teleport/src/Discover/Shared/Aws/ConfigureIamPerms.tsx @@ -21,7 +21,7 @@ import styled from 'styled-components'; import { Flex, Link, Box, H3 } from 'design'; import { assertUnreachable } from 'shared/utils/assertUnreachable'; import TextEditor from 'shared/components/TextEditor'; -import { ToolTipInfo } from 'shared/components/ToolTip'; +import { IconTooltip } from 'design/Tooltip'; import { P } from 'design/Text/Text'; @@ -179,11 +179,11 @@ export function ConfigureIamPerms({ <>

Configure your AWS IAM permissions

- + The following IAM permissions will be added as an inline policy named {iamPolicyName} to IAM role {iamRoleName} {editor} - +

{msg} Run the command below on your{' '} diff --git a/web/packages/teleport/src/Discover/Shared/ConfigureDiscoveryService/ConfigureDiscoveryServiceDirections.tsx b/web/packages/teleport/src/Discover/Shared/ConfigureDiscoveryService/ConfigureDiscoveryServiceDirections.tsx index 9017c990205f4..1b56b2d69e270 100644 --- a/web/packages/teleport/src/Discover/Shared/ConfigureDiscoveryService/ConfigureDiscoveryServiceDirections.tsx +++ b/web/packages/teleport/src/Discover/Shared/ConfigureDiscoveryService/ConfigureDiscoveryServiceDirections.tsx @@ -18,7 +18,7 @@ import { Box, Flex, Input, Text, Mark, H3, Subtitle3 } from 'design'; import styled from 'styled-components'; -import { ToolTipInfo } from 'shared/components/ToolTip'; +import { IconTooltip } from 'design/Tooltip'; import React from 'react'; @@ -71,7 +71,7 @@ discovery_service: Auto-enrolling requires you to configure a{' '} Discovery Service - +
@@ -100,7 +100,7 @@ discovery_service:

Step 2

Define a Discovery Group name{' '} - + diff --git a/web/packages/teleport/src/Discover/Shared/SecurityGroupPicker/SecurityGroupPicker.tsx b/web/packages/teleport/src/Discover/Shared/SecurityGroupPicker/SecurityGroupPicker.tsx index 7b66604e54a51..890eeee6cc60a 100644 --- a/web/packages/teleport/src/Discover/Shared/SecurityGroupPicker/SecurityGroupPicker.tsx +++ b/web/packages/teleport/src/Discover/Shared/SecurityGroupPicker/SecurityGroupPicker.tsx @@ -23,7 +23,7 @@ import Table, { Cell } from 'design/DataTable'; import { Danger } from 'design/Alert'; import { CheckboxInput } from 'design/Checkbox'; import { FetchStatus } from 'design/DataTable/types'; -import { ToolTipInfo } from 'shared/components/ToolTip'; +import { IconTooltip } from 'design/Tooltip'; import { Attempt } from 'shared/hooks/useAttemptNext'; @@ -163,13 +163,13 @@ export const SecurityGroupPicker = ({ if (sg.recommended && sg.tips?.length) { return ( - +
    {sg.tips.map((tip, index) => (
  • {tip}
  • ))}
-
+
); } diff --git a/web/packages/teleport/src/Integrations/Enroll/AwsOidc/ConfigureAwsOidcSummary.tsx b/web/packages/teleport/src/Integrations/Enroll/AwsOidc/ConfigureAwsOidcSummary.tsx index aecd67c00d114..b99521e8719ae 100644 --- a/web/packages/teleport/src/Integrations/Enroll/AwsOidc/ConfigureAwsOidcSummary.tsx +++ b/web/packages/teleport/src/Integrations/Enroll/AwsOidc/ConfigureAwsOidcSummary.tsx @@ -20,7 +20,7 @@ import React from 'react'; import styled from 'styled-components'; import { Flex, Box, H3, Text } from 'design'; import TextEditor from 'shared/components/TextEditor'; -import { ToolTipInfo } from 'shared/components/ToolTip'; +import { IconTooltip } from 'design/Tooltip'; import useStickyClusterId from 'teleport/useStickyClusterId'; @@ -61,7 +61,7 @@ export function ConfigureAwsOidcSummary({ }`; return ( - +

Running the command in AWS CloudShell does the following:

1. Configures an AWS IAM OIDC Identity Provider (IdP) @@ -76,7 +76,7 @@ export function ConfigureAwsOidcSummary({ /> -
+ ); } diff --git a/web/packages/teleport/src/Integrations/Enroll/AwsOidc/S3BucketConfiguration.tsx b/web/packages/teleport/src/Integrations/Enroll/AwsOidc/S3BucketConfiguration.tsx index a225196d65dfc..47452f3aa720e 100644 --- a/web/packages/teleport/src/Integrations/Enroll/AwsOidc/S3BucketConfiguration.tsx +++ b/web/packages/teleport/src/Integrations/Enroll/AwsOidc/S3BucketConfiguration.tsx @@ -19,7 +19,7 @@ import React from 'react'; import { Text, Flex } from 'design'; import FieldInput from 'shared/components/FieldInput'; -import { ToolTipInfo } from 'shared/components/ToolTip'; +import { IconTooltip } from 'design/Tooltip'; export function S3BucketConfiguration({ s3Bucket, @@ -32,11 +32,11 @@ export function S3BucketConfiguration({ <> Amazon S3 Location - + Deprecated. Amazon is now validating the IdP certificate against a list of root CAs. Storing the OpenID Configuration in S3 is no longer required, and should be removed to improve security. - + { {getStatusCodeTitle(item.statusCode)} {statusDescription && ( - {statusDescription} + {statusDescription} )} diff --git a/web/packages/teleport/src/Integrations/status/AwsOidc/AwsOidcHeader.tsx b/web/packages/teleport/src/Integrations/status/AwsOidc/AwsOidcHeader.tsx index 8d95d16a691c4..773efe7beb610 100644 --- a/web/packages/teleport/src/Integrations/status/AwsOidc/AwsOidcHeader.tsx +++ b/web/packages/teleport/src/Integrations/status/AwsOidc/AwsOidcHeader.tsx @@ -21,7 +21,7 @@ import { Link as InternalLink } from 'react-router-dom'; import { ButtonIcon, Flex, Label, Text } from 'design'; import { ArrowLeft } from 'design/Icon'; -import { HoverTooltip } from 'shared/components/ToolTip'; +import { HoverTooltip } from 'design/Tooltip'; import cfg from 'teleport/config'; import { getStatusAndLabel } from 'teleport/Integrations/helpers'; diff --git a/web/packages/teleport/src/JoinTokens/JoinTokens.tsx b/web/packages/teleport/src/JoinTokens/JoinTokens.tsx index 46e9100feab8b..862085cfd0157 100644 --- a/web/packages/teleport/src/JoinTokens/JoinTokens.tsx +++ b/web/packages/teleport/src/JoinTokens/JoinTokens.tsx @@ -42,7 +42,7 @@ import Dialog, { } from 'design/Dialog'; import { MenuButton } from 'shared/components/MenuAction'; import { Attempt, useAsync } from 'shared/hooks/useAsync'; -import { HoverTooltip } from 'shared/components/ToolTip'; +import { HoverTooltip } from 'design/Tooltip'; import { CopyButton } from 'shared/components/UnifiedResources/shared/CopyButton'; import { useTeleport } from 'teleport'; diff --git a/web/packages/teleport/src/JoinTokens/UpsertJoinTokenDialog.tsx b/web/packages/teleport/src/JoinTokens/UpsertJoinTokenDialog.tsx index 6daef672649c6..357c6a3d59471 100644 --- a/web/packages/teleport/src/JoinTokens/UpsertJoinTokenDialog.tsx +++ b/web/packages/teleport/src/JoinTokens/UpsertJoinTokenDialog.tsx @@ -29,7 +29,7 @@ import { Alert, } from 'design'; import styled from 'styled-components'; -import { HoverTooltip } from 'shared/components/ToolTip'; +import { HoverTooltip } from 'design/Tooltip'; import { Cross } from 'design/Icon'; import Validation from 'shared/components/Validation'; import FieldInput from 'shared/components/FieldInput'; diff --git a/web/packages/teleport/src/Main/LayoutContext.tsx b/web/packages/teleport/src/Main/LayoutContext.tsx index df15cc7548ff2..1228d3b8481be 100644 --- a/web/packages/teleport/src/Main/LayoutContext.tsx +++ b/web/packages/teleport/src/Main/LayoutContext.tsx @@ -39,6 +39,8 @@ export function LayoutContextProvider(props: PropsWithChildren) { const containerRef = useRef(); useEffect(() => { + // TODO(ravicious): Use useResizeObserver instead. Ensure that the callback passed to + // useResizeObserver has a stable identity. const resizeObserver = new ResizeObserver(entries => { const container = entries[0]; setCurrentWidth(container?.contentRect.width || 0); diff --git a/web/packages/teleport/src/Navigation/Navigation.tsx b/web/packages/teleport/src/Navigation/Navigation.tsx index 6450c575114bf..e50295ea5a1f9 100644 --- a/web/packages/teleport/src/Navigation/Navigation.tsx +++ b/web/packages/teleport/src/Navigation/Navigation.tsx @@ -21,7 +21,7 @@ import styled, { useTheme } from 'styled-components'; import { matchPath, useLocation, useHistory } from 'react-router'; import { Box, Text, Flex } from 'design'; -import { ToolTipInfo } from 'shared/components/ToolTip'; +import { IconTooltip } from 'design/Tooltip'; import cfg from 'teleport/config'; import { @@ -195,9 +195,9 @@ function LicenseFooter({ {title} - + {infoContent} - + {subText} diff --git a/web/packages/teleport/src/Navigation/SideNavigation/Section.tsx b/web/packages/teleport/src/Navigation/SideNavigation/Section.tsx index 8217106d5fd20..eb9d10c111b82 100644 --- a/web/packages/teleport/src/Navigation/SideNavigation/Section.tsx +++ b/web/packages/teleport/src/Navigation/SideNavigation/Section.tsx @@ -23,7 +23,7 @@ import styled, { css, useTheme } from 'styled-components'; import { Box, ButtonIcon, Flex, P2, Text } from 'design'; import { Theme } from 'design/theme'; import { ArrowLineLeft } from 'design/Icon'; -import { HoverTooltip, ToolTipInfo } from 'shared/components/ToolTip'; +import { HoverTooltip, IconTooltip } from 'design/Tooltip'; import cfg from 'teleport/config'; @@ -470,9 +470,9 @@ function LicenseFooter({ {title} - + {infoContent} - + {subText} diff --git a/web/packages/teleport/src/Notifications/Notifications.tsx b/web/packages/teleport/src/Notifications/Notifications.tsx index ada3dd3761af1..b64d1460e8041 100644 --- a/web/packages/teleport/src/Notifications/Notifications.tsx +++ b/web/packages/teleport/src/Notifications/Notifications.tsx @@ -24,7 +24,7 @@ import { Alert, Box, Flex, Indicator, Text } from 'design'; import { Notification as NotificationIcon, BellRinging } from 'design/Icon'; import Logger from 'shared/libs/logger'; import { useRefClickOutside } from 'shared/hooks/useRefClickOutside'; -import { HoverTooltip } from 'shared/components/ToolTip'; +import { HoverTooltip } from 'design/Tooltip'; import { useInfiniteScroll, diff --git a/web/packages/teleport/src/Roles/RoleEditor/EditorHeader.tsx b/web/packages/teleport/src/Roles/RoleEditor/EditorHeader.tsx index 37059aee38594..2ee25880cedad 100644 --- a/web/packages/teleport/src/Roles/RoleEditor/EditorHeader.tsx +++ b/web/packages/teleport/src/Roles/RoleEditor/EditorHeader.tsx @@ -17,20 +17,32 @@ */ import React from 'react'; -import { Flex, ButtonText, H2 } from 'design'; -import { HoverTooltip } from 'shared/components/ToolTip'; +import { Flex, ButtonText, H2, Indicator, Box } from 'design'; +import { HoverTooltip } from 'design/Tooltip'; import { Trash } from 'design/Icon'; import useTeleport from 'teleport/useTeleport'; import { Role } from 'teleport/services/resources'; +import { EditorTab, EditorTabs } from './EditorTabs'; + /** Renders a header button with role name and delete button. */ export const EditorHeader = ({ role = null, onDelete, + selectedEditorTab, + onEditorTabChange, + isProcessing, + standardEditorId, + yamlEditorId, }: { - onDelete?(): void; role?: Role; + onDelete(): void; + selectedEditorTab: EditorTab; + onEditorTabChange(t: EditorTab): void; + isProcessing: boolean; + standardEditorId: string; + yamlEditorId: string; }) => { const ctx = useTeleport(); const isCreating = !role; @@ -38,8 +50,24 @@ export const EditorHeader = ({ const hasDeleteAccess = ctx.storeUser.getRoleAccess().remove; return ( - -

{isCreating ? 'Create a New Role' : role?.metadata.name}

+ + +

+ {isCreating + ? 'Create a New Role' + : `Edit Role ${role?.metadata.name}`} +

+
+ + {isProcessing && } + + {!isCreating && ( { + const standardLabel = 'Switch to standard editor'; + const yamlLabel = 'Switch to YAML editor'; return ( ); }; diff --git a/web/packages/teleport/src/Roles/RoleEditor/RoleEditor.story.tsx b/web/packages/teleport/src/Roles/RoleEditor/RoleEditor.story.tsx index bf8313ceb4122..abd6ed5393f69 100644 --- a/web/packages/teleport/src/Roles/RoleEditor/RoleEditor.story.tsx +++ b/web/packages/teleport/src/Roles/RoleEditor/RoleEditor.story.tsx @@ -42,7 +42,7 @@ export default { } return ( - + diff --git a/web/packages/teleport/src/Roles/RoleEditor/RoleEditor.test.tsx b/web/packages/teleport/src/Roles/RoleEditor/RoleEditor.test.tsx index 235a0d83782a6..1376c078e80ff 100644 --- a/web/packages/teleport/src/Roles/RoleEditor/RoleEditor.test.tsx +++ b/web/packages/teleport/src/Roles/RoleEditor/RoleEditor.test.tsx @@ -75,10 +75,7 @@ afterEach(() => { test('rendering and switching tabs for new role', async () => { render(); - expect(screen.getByRole('tab', { name: 'Standard' })).toHaveAttribute( - 'aria-selected', - 'true' - ); + expect(getStandardEditorTab()).toHaveAttribute('aria-selected', 'true'); expect( screen.queryByRole('button', { name: /Reset to Standard Settings/i }) ).not.toBeInTheDocument(); @@ -86,7 +83,7 @@ test('rendering and switching tabs for new role', async () => { expect(screen.getByLabelText('Description')).toHaveValue(''); expect(screen.getByRole('button', { name: 'Create Role' })).toBeEnabled(); - await user.click(screen.getByRole('tab', { name: 'YAML' })); + await user.click(getYamlEditorTab()); expect(fromFauxYaml(await getTextEditorContents())).toEqual( withDefaults({ kind: 'role', @@ -103,7 +100,7 @@ test('rendering and switching tabs for new role', async () => { ); expect(screen.getByRole('button', { name: 'Create Role' })).toBeEnabled(); - await user.click(screen.getByRole('tab', { name: 'Standard' })); + await user.click(getStandardEditorTab()); await screen.findByLabelText('Role Name'); expect( screen.queryByRole('button', { name: /Reset to Standard Settings/i }) @@ -127,14 +124,11 @@ test('rendering and switching tabs for a non-standard role', async () => { originalRole={{ object: originalRole, yaml: originalYaml }} /> ); - expect(screen.getByRole('tab', { name: 'YAML' })).toHaveAttribute( - 'aria-selected', - 'true' - ); + expect(getYamlEditorTab()).toHaveAttribute('aria-selected', 'true'); expect(fromFauxYaml(await getTextEditorContents())).toEqual(originalRole); expect(screen.getByRole('button', { name: 'Update Role' })).toBeDisabled(); - await user.click(screen.getByRole('tab', { name: 'Standard' })); + await user.click(getStandardEditorTab()); expect( screen.getByRole('button', { name: 'Reset to Standard Settings' }) ).toBeVisible(); @@ -142,12 +136,12 @@ test('rendering and switching tabs for a non-standard role', async () => { expect(screen.getByLabelText('Description')).toHaveValue(''); expect(screen.getByRole('button', { name: 'Update Role' })).toBeDisabled(); - await user.click(screen.getByRole('tab', { name: 'YAML' })); + await user.click(getYamlEditorTab()); expect(fromFauxYaml(await getTextEditorContents())).toEqual(originalRole); expect(screen.getByRole('button', { name: 'Update Role' })).toBeDisabled(); // Switch once again, reset to standard - await user.click(screen.getByRole('tab', { name: 'Standard' })); + await user.click(getStandardEditorTab()); expect(screen.getByRole('button', { name: 'Update Role' })).toBeDisabled(); await user.click( screen.getByRole('button', { name: 'Reset to Standard Settings' }) @@ -155,13 +149,35 @@ test('rendering and switching tabs for a non-standard role', async () => { expect(screen.getByRole('button', { name: 'Update Role' })).toBeEnabled(); await user.type(screen.getByLabelText('Description'), 'some description'); - await user.click(screen.getByRole('tab', { name: 'YAML' })); + await user.click(getYamlEditorTab()); const editorContents = fromFauxYaml(await getTextEditorContents()); expect(editorContents.metadata.description).toBe('some description'); expect(editorContents.spec.deny).toEqual({}); expect(screen.getByRole('button', { name: 'Update Role' })).toBeEnabled(); }); +test('no double conversions when clicking already active tabs', async () => { + render(); + await user.click(getYamlEditorTab()); + await user.click(getStandardEditorTab()); + await user.type(screen.getByLabelText('Role Name'), '_2'); + await user.click(getStandardEditorTab()); + expect(screen.getByLabelText('Role Name')).toHaveValue('new_role_name_2'); + + await user.click(getYamlEditorTab()); + await user.clear(await findTextEditor()); + await user.type( + await findTextEditor(), + // Note: this is actually correct JSON syntax; the testing library uses + // braces for special keys, so we need to use double opening braces. + '{{"kind":"role", metadata:{{"name":"new_role_name_3"}}' + ); + await user.click(getYamlEditorTab()); + expect(await getTextEditorContents()).toBe( + '{"kind":"role", metadata:{"name":"new_role_name_3"}}' + ); +}); + test('canceling standard editor', async () => { const onCancel = jest.fn(); render(); @@ -175,7 +191,7 @@ test('canceling standard editor', async () => { test('canceling yaml editor', async () => { const onCancel = jest.fn(); render(); - await user.click(screen.getByRole('tab', { name: 'YAML' })); + await user.click(getYamlEditorTab()); await user.click(screen.getByRole('button', { name: 'Cancel' })); expect(onCancel).toHaveBeenCalled(); expect(userEventService.captureUserEvent).toHaveBeenCalledWith({ @@ -222,7 +238,7 @@ test('saving a new role after editing as YAML', async () => { render(); expect(screen.getByRole('button', { name: 'Create Role' })).toBeEnabled(); - await user.click(screen.getByRole('tab', { name: 'YAML' })); + await user.click(getYamlEditorTab()); await user.clear(await findTextEditor()); await user.type(await findTextEditor(), '{{"foo":"bar"}'); await user.click(screen.getByRole('button', { name: 'Create Role' })); @@ -247,7 +263,7 @@ test('error while yamlifying', async () => { .spyOn(yamlService, 'stringify') .mockRejectedValue(new Error('me no speak yaml')); render(); - await user.click(screen.getByRole('tab', { name: 'YAML' })); + await user.click(getYamlEditorTab()); expect(screen.getByText('me no speak yaml')).toBeVisible(); }); @@ -256,8 +272,8 @@ test('error while parsing', async () => { .spyOn(yamlService, 'parse') .mockRejectedValue(new Error('me no speak yaml')); render(); - await user.click(screen.getByRole('tab', { name: 'YAML' })); - await user.click(screen.getByRole('tab', { name: 'Standard' })); + await user.click(getYamlEditorTab()); + await user.click(getStandardEditorTab()); expect(screen.getByText('me no speak yaml')).toBeVisible(); }); @@ -280,6 +296,12 @@ const TestRoleEditor = (props: RoleEditorProps) => { ); }; +const getStandardEditorTab = () => + screen.getByRole('tab', { name: 'Switch to standard editor' }); + +const getYamlEditorTab = () => + screen.getByRole('tab', { name: 'Switch to YAML editor' }); + const findTextEditor = async () => within(await screen.findByTestId('text-editor-container')).getByRole( 'textbox' diff --git a/web/packages/teleport/src/Roles/RoleEditor/RoleEditor.tsx b/web/packages/teleport/src/Roles/RoleEditor/RoleEditor.tsx index cadef43e0ce26..6b084a65682c4 100644 --- a/web/packages/teleport/src/Roles/RoleEditor/RoleEditor.tsx +++ b/web/packages/teleport/src/Roles/RoleEditor/RoleEditor.tsx @@ -16,10 +16,12 @@ * along with this program. If not, see . */ -import { Alert, Box, Flex } from 'design'; -import React, { useState } from 'react'; +import { Alert, Flex } from 'design'; +import React, { useId, useState } from 'react'; import { useAsync } from 'shared/hooks/useAsync'; +import Validation, { Validator } from 'shared/components/Validation'; + import { Role, RoleWithYaml } from 'teleport/services/resources'; import { yamlService } from 'teleport/services/yaml'; import { YamlSupportedResourceKind } from 'teleport/services/yaml/types'; @@ -32,7 +34,7 @@ import { roleToRoleEditorModel as roleToRoleEditorModel, } from './standardmodel'; import { YamlEditorModel } from './yamlmodel'; -import { EditorTab, EditorTabs } from './EditorTabs'; +import { EditorTab } from './EditorTabs'; import { EditorHeader } from './EditorHeader'; import { StandardEditor } from './StandardEditor'; import { YamlEditor } from './YamlEditor'; @@ -59,6 +61,12 @@ export const RoleEditor = ({ onSave, onDelete, }: RoleEditorProps) => { + const idPrefix = useId(); + // These IDs are needed to connect accessibility attributes between the + // standard/YAML tab switcher and the switched panels. + const standardEditorId = `${idPrefix}-standard`; + const yamlEditorId = `${idPrefix}-yaml`; + const [standardModel, setStandardModel] = useState( () => { const role = originalRole?.object ?? newRole(); @@ -113,7 +121,18 @@ export const RoleEditor = ({ yamlifyAttempt.status === 'processing' || saveAttempt.status === 'processing'; - async function onTabChange(activeIndex: EditorTab) { + async function onTabChange(activeIndex: EditorTab, validator: Validator) { + // The code below is not idempotent, so we need to protect ourselves from + // an accidental model replacement. + if (activeIndex === selectedEditorTab) return; + + // Validate the model on tab switch, because the server-side yamlification + // requires model to be valid. However, if it's OK, we reset the validator. + // We don't want it to be validating at this point, since the user didn't + // attempt to submit the form. + if (!validator.validate()) return; + validator.reset(); + switch (activeIndex) { case EditorTab.Standard: { if (!yamlModel.content) { @@ -159,50 +178,59 @@ export const RoleEditor = ({ } return ( - - - {saveAttempt.status === 'error' && ( - - {saveAttempt.statusText} - - )} - {parseAttempt.status === 'error' && ( - - {parseAttempt.statusText} - - )} - {yamlifyAttempt.status === 'error' && ( - - {yamlifyAttempt.statusText} - - )} - - - - {selectedEditorTab === EditorTab.Standard && ( - handleSave({ object })} - onCancel={handleCancel} - standardEditorModel={standardModel} - isProcessing={isProcessing} - onChange={setStandardModel} - /> - )} - {selectedEditorTab === EditorTab.Yaml && ( - void (await handleSave({ yaml }))} - isProcessing={isProcessing} - onCancel={handleCancel} - originalRole={originalRole} - /> + + {({ validator }) => ( + + onTabChange(index, validator)} + isProcessing={isProcessing} + standardEditorId={standardEditorId} + yamlEditorId={yamlEditorId} + /> + {saveAttempt.status === 'error' && ( + + {saveAttempt.statusText} + + )} + {parseAttempt.status === 'error' && ( + + {parseAttempt.statusText} + + )} + {yamlifyAttempt.status === 'error' && ( + + {yamlifyAttempt.statusText} + + )} + {selectedEditorTab === EditorTab.Standard && ( +
+ handleSave({ object })} + onCancel={handleCancel} + standardEditorModel={standardModel} + isProcessing={isProcessing} + onChange={setStandardModel} + /> +
+ )} + {selectedEditorTab === EditorTab.Yaml && ( + + void (await handleSave({ yaml }))} + isProcessing={isProcessing} + onCancel={handleCancel} + originalRole={originalRole} + /> + + )} +
)} -
+ ); }; diff --git a/web/packages/teleport/src/Roles/RoleEditor/Shared.tsx b/web/packages/teleport/src/Roles/RoleEditor/Shared.tsx index e6cece6752920..3652e87a537ca 100644 --- a/web/packages/teleport/src/Roles/RoleEditor/Shared.tsx +++ b/web/packages/teleport/src/Roles/RoleEditor/Shared.tsx @@ -17,7 +17,7 @@ */ import { Box, ButtonPrimary, ButtonSecondary, Flex } from 'design'; -import { HoverTooltip } from 'shared/components/ToolTip'; +import { HoverTooltip } from 'design/Tooltip'; import useTeleport from 'teleport/useTeleport'; diff --git a/web/packages/teleport/src/Roles/RoleEditor/StandardEditor.test.tsx b/web/packages/teleport/src/Roles/RoleEditor/StandardEditor.test.tsx index 4497cbea441d7..fc8a1574637f0 100644 --- a/web/packages/teleport/src/Roles/RoleEditor/StandardEditor.test.tsx +++ b/web/packages/teleport/src/Roles/RoleEditor/StandardEditor.test.tsx @@ -19,26 +19,29 @@ import { render, screen, userEvent } from 'design/utils/testing'; import React, { useState } from 'react'; -import { within } from '@testing-library/react'; -import Validation from 'shared/components/Validation'; +import { act, within } from '@testing-library/react'; +import Validation, { Validator } from 'shared/components/Validation'; import selectEvent from 'react-select-event'; import TeleportContextProvider from 'teleport/TeleportContextProvider'; import { createTeleportContext } from 'teleport/mocks/contexts'; +import { ResourceKind } from 'teleport/services/resources'; + import { - AccessSpec, AppAccessSpec, DatabaseAccessSpec, KubernetesAccessSpec, newAccessSpec, newRole, roleToRoleEditorModel, + RuleModel, ServerAccessSpec, StandardEditorModel, WindowsDesktopAccessSpec, } from './standardmodel'; import { + AccessRules, AppAccessSpecSection, DatabaseAccessSpecSection, KubernetesAccessSpecSection, @@ -48,6 +51,12 @@ import { StandardEditorProps, WindowsDesktopAccessSpecSection, } from './StandardEditor'; +import { + AccessSpecValidationResult, + AccessRuleValidationResult, + validateAccessSpec, + validateAccessRule, +} from './validation'; const TestStandardEditor = (props: Partial) => { const ctx = createTeleportContext(); @@ -57,13 +66,15 @@ const TestStandardEditor = (props: Partial) => { }); return ( - + + + ); }; @@ -72,6 +83,8 @@ test('adding and removing sections', async () => { const user = userEvent.setup(); render(); expect(getAllSectionNames()).toEqual(['Role Metadata']); + await user.click(screen.getByRole('tab', { name: 'Resources' })); + expect(getAllSectionNames()).toEqual([]); await user.click( screen.getByRole('button', { name: 'Add New Specifications' }) @@ -85,7 +98,7 @@ test('adding and removing sections', async () => { ]); await user.click(screen.getByRole('menuitem', { name: 'Servers' })); - expect(getAllSectionNames()).toEqual(['Role Metadata', 'Servers']); + expect(getAllSectionNames()).toEqual(['Servers']); await user.click( screen.getByRole('button', { name: 'Add New Specifications' }) @@ -98,25 +111,21 @@ test('adding and removing sections', async () => { ]); await user.click(screen.getByRole('menuitem', { name: 'Kubernetes' })); - expect(getAllSectionNames()).toEqual([ - 'Role Metadata', - 'Servers', - 'Kubernetes', - ]); + expect(getAllSectionNames()).toEqual(['Servers', 'Kubernetes']); await user.click( within(getSectionByName('Servers')).getByRole('button', { name: 'Remove section', }) ); - expect(getAllSectionNames()).toEqual(['Role Metadata', 'Kubernetes']); + expect(getAllSectionNames()).toEqual(['Kubernetes']); await user.click( within(getSectionByName('Kubernetes')).getByRole('button', { name: 'Remove section', }) ); - expect(getAllSectionNames()).toEqual(['Role Metadata']); + expect(getAllSectionNames()).toEqual([]); }); test('collapsed sections still apply validation', async () => { @@ -137,6 +146,24 @@ test('collapsed sections still apply validation', async () => { expect(onSave).toHaveBeenCalled(); }); +test('invisible tabs still apply validation', async () => { + const user = userEvent.setup(); + const onSave = jest.fn(); + render(); + // Intentionally cause a validation error. + await user.clear(screen.getByLabelText('Role Name')); + // Switch to a different tab. + await user.click(screen.getByRole('tab', { name: 'Resources' })); + await user.click(screen.getByRole('button', { name: 'Create Role' })); + expect(onSave).not.toHaveBeenCalled(); + + // Switch back, make it valid. + await user.click(screen.getByRole('tab', { name: 'Invalid data Overview' })); + await user.type(screen.getByLabelText('Role Name'), 'foo'); + await user.click(screen.getByRole('button', { name: 'Create Role' })); + expect(onSave).toHaveBeenCalled(); +}); + const getAllMenuItemNames = () => screen.queryAllByRole('menuitem').map(m => m.textContent); @@ -148,71 +175,113 @@ const getSectionByName = (name: string) => // eslint-disable-next-line testing-library/no-node-access screen.getByRole('heading', { level: 3, name }).closest('details'); -const StatefulSection = ({ +function StatefulSection({ defaultValue, component: Component, onChange, + validatorRef, + validate, }: { - defaultValue: S; - component: React.ComponentType>; - onChange(spec: S): void; -}) => { - const [model, setModel] = useState(defaultValue); + defaultValue: Spec; + component: React.ComponentType>; + onChange(spec: Spec): void; + validatorRef?(v: Validator): void; + validate(arg: Spec): ValidationResult; +}) { + const [model, setModel] = useState(defaultValue); + const validation = validate(model); return ( - { - setModel(spec); - onChange(spec); - }} - /> + {({ validator }) => { + validatorRef?.(validator); + return ( + { + setModel(spec); + onChange(spec); + }} + /> + ); + }} ); -}; +} -test('ServerAccessSpecSection', async () => { - const user = userEvent.setup(); - const onChange = jest.fn(); - render( - - component={ServerAccessSpecSection} - defaultValue={newAccessSpec('node')} - onChange={onChange} - /> - ); - await user.click(screen.getByRole('button', { name: 'Add a Label' })); - await user.type(screen.getByPlaceholderText('label key'), 'some-key'); - await user.type(screen.getByPlaceholderText('label value'), 'some-value'); - await selectEvent.create(screen.getByLabelText('Logins'), 'root', { - createOptionText: 'Login: root', - }); - await selectEvent.create(screen.getByLabelText('Logins'), 'some-user', { - createOptionText: 'Login: some-user', +describe('ServerAccessSpecSection', () => { + const setup = () => { + const onChange = jest.fn(); + let validator: Validator; + render( + + component={ServerAccessSpecSection} + defaultValue={newAccessSpec('node')} + onChange={onChange} + validatorRef={v => { + validator = v; + }} + validate={validateAccessSpec} + /> + ); + return { user: userEvent.setup(), onChange, validator }; + }; + + test('editing', async () => { + const { user, onChange } = setup(); + await user.click(screen.getByRole('button', { name: 'Add a Label' })); + await user.type(screen.getByPlaceholderText('label key'), 'some-key'); + await user.type(screen.getByPlaceholderText('label value'), 'some-value'); + await selectEvent.create(screen.getByLabelText('Logins'), 'root', { + createOptionText: 'Login: root', + }); + await selectEvent.create(screen.getByLabelText('Logins'), 'some-user', { + createOptionText: 'Login: some-user', + }); + + expect(onChange).toHaveBeenLastCalledWith({ + kind: 'node', + labels: [{ name: 'some-key', value: 'some-value' }], + logins: [ + expect.objectContaining({ label: 'root', value: 'root' }), + expect.objectContaining({ label: 'some-user', value: 'some-user' }), + ], + } as ServerAccessSpec); }); - expect(onChange).toHaveBeenLastCalledWith({ - kind: 'node', - labels: [{ name: 'some-key', value: 'some-value' }], - logins: [ - expect.objectContaining({ label: 'root', value: 'root' }), - expect.objectContaining({ label: 'some-user', value: 'some-user' }), - ], - } as ServerAccessSpec); + test('validation', async () => { + const { user, validator } = setup(); + await user.click(screen.getByRole('button', { name: 'Add a Label' })); + await selectEvent.create(screen.getByLabelText('Logins'), '*', { + createOptionText: 'Login: *', + }); + act(() => validator.validate()); + expect( + screen.getByPlaceholderText('label key') + ).toHaveAccessibleDescription('required'); + expect( + screen.getByText('Wildcard is not allowed in logins') + ).toBeInTheDocument(); + }); }); describe('KubernetesAccessSpecSection', () => { const setup = () => { const onChange = jest.fn(); + let validator: Validator; render( - + component={KubernetesAccessSpecSection} defaultValue={newAccessSpec('kube_cluster')} onChange={onChange} + validatorRef={v => { + validator = v; + }} + validate={validateAccessSpec} /> ); - return { user: userEvent.setup(), onChange }; + return { user: userEvent.setup(), onChange, validator }; }; test('editing the spec', async () => { @@ -319,105 +388,259 @@ describe('KubernetesAccessSpecSection', () => { expect.objectContaining({ resources: [] }) ); }); + + test('validation', async () => { + const { user, validator } = setup(); + await user.click(screen.getByRole('button', { name: 'Add a Label' })); + await user.click(screen.getByRole('button', { name: 'Add a Resource' })); + await user.clear(screen.getByLabelText('Name')); + await user.clear(screen.getByLabelText('Namespace')); + act(() => validator.validate()); + expect( + screen.getByPlaceholderText('label key') + ).toHaveAccessibleDescription('required'); + expect(screen.getByLabelText('Name')).toHaveAccessibleDescription( + 'Resource name is required, use "*" for any resource' + ); + expect(screen.getByLabelText('Namespace')).toHaveAccessibleDescription( + 'Namespace is required for resources of this kind' + ); + }); }); -test('AppAccessSpecSection', async () => { - const user = userEvent.setup(); - const onChange = jest.fn(); - render( - - component={AppAccessSpecSection} - defaultValue={newAccessSpec('app')} - onChange={onChange} - /> - ); +describe('AppAccessSpecSection', () => { + const setup = () => { + const onChange = jest.fn(); + let validator: Validator; + render( + + component={AppAccessSpecSection} + defaultValue={newAccessSpec('app')} + onChange={onChange} + validatorRef={v => { + validator = v; + }} + validate={validateAccessSpec} + /> + ); + return { user: userEvent.setup(), onChange, validator }; + }; - await user.click(screen.getByRole('button', { name: 'Add a Label' })); - await user.type(screen.getByPlaceholderText('label key'), 'env'); - await user.type(screen.getByPlaceholderText('label value'), 'prod'); - await user.type( + const awsRoleArn = () => within(screen.getByRole('group', { name: 'AWS Role ARNs' })).getByRole( 'textbox' - ), - 'arn:aws:iam::123456789012:role/admin' - ); - await user.type( + ); + const azureIdentity = () => within(screen.getByRole('group', { name: 'Azure Identities' })).getByRole( 'textbox' - ), - '/subscriptions/1020304050607-cafe-8090-a0b0c0d0e0f0/resourceGroups/example-resource-group/providers/Microsoft.ManagedIdentity/userAssignedIdentities/admin' - ); - await user.type( + ); + const gcpServiceAccount = () => within( screen.getByRole('group', { name: 'GCP Service Accounts' }) - ).getByRole('textbox'), - 'admin@some-project.iam.gserviceaccount.com' - ); - expect(onChange).toHaveBeenLastCalledWith({ - kind: 'app', - labels: [{ name: 'env', value: 'prod' }], - awsRoleARNs: ['arn:aws:iam::123456789012:role/admin'], - azureIdentities: [ - '/subscriptions/1020304050607-cafe-8090-a0b0c0d0e0f0/resourceGroups/example-resource-group/providers/Microsoft.ManagedIdentity/userAssignedIdentities/admin', - ], - gcpServiceAccounts: ['admin@some-project.iam.gserviceaccount.com'], - } as AppAccessSpec); + ).getByRole('textbox'); + + test('editing', async () => { + const { user, onChange } = setup(); + await user.click(screen.getByRole('button', { name: 'Add a Label' })); + await user.type(screen.getByPlaceholderText('label key'), 'env'); + await user.type(screen.getByPlaceholderText('label value'), 'prod'); + await user.type(awsRoleArn(), 'arn:aws:iam::123456789012:role/admin'); + await user.type( + azureIdentity(), + '/subscriptions/1020304050607-cafe-8090-a0b0c0d0e0f0/resourceGroups/example-resource-group/providers/Microsoft.ManagedIdentity/userAssignedIdentities/admin' + ); + await user.type( + gcpServiceAccount(), + 'admin@some-project.iam.gserviceaccount.com' + ); + expect(onChange).toHaveBeenLastCalledWith({ + kind: 'app', + labels: [{ name: 'env', value: 'prod' }], + awsRoleARNs: ['arn:aws:iam::123456789012:role/admin'], + azureIdentities: [ + '/subscriptions/1020304050607-cafe-8090-a0b0c0d0e0f0/resourceGroups/example-resource-group/providers/Microsoft.ManagedIdentity/userAssignedIdentities/admin', + ], + gcpServiceAccounts: ['admin@some-project.iam.gserviceaccount.com'], + } as AppAccessSpec); + }); + + test('validation', async () => { + const { user, validator } = setup(); + await user.click(screen.getByRole('button', { name: 'Add a Label' })); + await user.type(awsRoleArn(), '*'); + await user.type(azureIdentity(), '*'); + await user.type(gcpServiceAccount(), '*'); + act(() => validator.validate()); + expect( + screen.getByPlaceholderText('label key') + ).toHaveAccessibleDescription('required'); + expect(awsRoleArn()).toHaveAccessibleDescription( + 'Wildcard is not allowed in AWS role ARNs' + ); + expect(azureIdentity()).toHaveAccessibleDescription( + 'Wildcard is not allowed in Azure identities' + ); + expect(gcpServiceAccount()).toHaveAccessibleDescription( + 'Wildcard is not allowed in GCP service accounts' + ); + }); }); -test('DatabaseAccessSpecSection', async () => { - const user = userEvent.setup(); - const onChange = jest.fn(); - render( - - component={DatabaseAccessSpecSection} - defaultValue={newAccessSpec('db')} - onChange={onChange} - /> - ); +describe('DatabaseAccessSpecSection', () => { + const setup = () => { + const onChange = jest.fn(); + let validator: Validator; + render( + + component={DatabaseAccessSpecSection} + defaultValue={newAccessSpec('db')} + onChange={onChange} + validatorRef={v => { + validator = v; + }} + validate={validateAccessSpec} + /> + ); + return { user: userEvent.setup(), onChange, validator }; + }; - await user.click(screen.getByRole('button', { name: 'Add a Label' })); - await user.type(screen.getByPlaceholderText('label key'), 'env'); - await user.type(screen.getByPlaceholderText('label value'), 'prod'); - await selectEvent.create(screen.getByLabelText('Database Names'), 'stuff', { - createOptionText: 'Database Name: stuff', + test('editing', async () => { + const { user, onChange } = setup(); + await user.click(screen.getByRole('button', { name: 'Add a Label' })); + await user.type(screen.getByPlaceholderText('label key'), 'env'); + await user.type(screen.getByPlaceholderText('label value'), 'prod'); + await selectEvent.create(screen.getByLabelText('Database Names'), 'stuff', { + createOptionText: 'Database Name: stuff', + }); + await selectEvent.create(screen.getByLabelText('Database Users'), 'mary', { + createOptionText: 'Database User: mary', + }); + await selectEvent.create(screen.getByLabelText('Database Roles'), 'admin', { + createOptionText: 'Database Role: admin', + }); + expect(onChange).toHaveBeenLastCalledWith({ + kind: 'db', + labels: [{ name: 'env', value: 'prod' }], + names: [expect.objectContaining({ label: 'stuff', value: 'stuff' })], + roles: [expect.objectContaining({ label: 'admin', value: 'admin' })], + users: [expect.objectContaining({ label: 'mary', value: 'mary' })], + } as DatabaseAccessSpec); }); - await selectEvent.create(screen.getByLabelText('Database Users'), 'mary', { - createOptionText: 'Database User: mary', + + test('validation', async () => { + const { user, validator } = setup(); + await user.click(screen.getByRole('button', { name: 'Add a Label' })); + await selectEvent.create(screen.getByLabelText('Database Roles'), '*', { + createOptionText: 'Database Role: *', + }); + act(() => validator.validate()); + expect( + screen.getByPlaceholderText('label key') + ).toHaveAccessibleDescription('required'); + expect( + screen.getByText('Wildcard is not allowed in database roles') + ).toBeInTheDocument(); }); - await selectEvent.create(screen.getByLabelText('Database Roles'), 'admin', { - createOptionText: 'Database Role: admin', +}); + +describe('WindowsDesktopAccessSpecSection', () => { + const setup = () => { + const onChange = jest.fn(); + let validator: Validator; + render( + + component={WindowsDesktopAccessSpecSection} + defaultValue={newAccessSpec('windows_desktop')} + onChange={onChange} + validatorRef={v => { + validator = v; + }} + validate={validateAccessSpec} + /> + ); + return { user: userEvent.setup(), onChange, validator }; + }; + + test('editing', async () => { + const { user, onChange } = setup(); + await user.click(screen.getByRole('button', { name: 'Add a Label' })); + await user.type(screen.getByPlaceholderText('label key'), 'os'); + await user.type(screen.getByPlaceholderText('label value'), 'win-xp'); + await selectEvent.create(screen.getByLabelText('Logins'), 'julio', { + createOptionText: 'Login: julio', + }); + expect(onChange).toHaveBeenLastCalledWith({ + kind: 'windows_desktop', + labels: [{ name: 'os', value: 'win-xp' }], + logins: [expect.objectContaining({ label: 'julio', value: 'julio' })], + } as WindowsDesktopAccessSpec); + }); + + test('validation', async () => { + const { user, validator } = setup(); + await user.click(screen.getByRole('button', { name: 'Add a Label' })); + act(() => validator.validate()); + expect( + screen.getByPlaceholderText('label key') + ).toHaveAccessibleDescription('required'); }); - expect(onChange).toHaveBeenLastCalledWith({ - kind: 'db', - labels: [{ name: 'env', value: 'prod' }], - names: [expect.objectContaining({ label: 'stuff', value: 'stuff' })], - roles: [expect.objectContaining({ label: 'admin', value: 'admin' })], - users: [expect.objectContaining({ label: 'mary', value: 'mary' })], - } as DatabaseAccessSpec); }); -test('WindowsDesktopAccessSpecSection', async () => { - const user = userEvent.setup(); - const onChange = jest.fn(); - render( - - component={WindowsDesktopAccessSpecSection} - defaultValue={newAccessSpec('windows_desktop')} - onChange={onChange} - /> - ); +describe('AccessRules', () => { + const setup = () => { + const onChange = jest.fn(); + let validator: Validator; + render( + + component={AccessRules} + defaultValue={[]} + onChange={onChange} + validatorRef={v => { + validator = v; + }} + validate={rules => rules.map(validateAccessRule)} + /> + ); + return { user: userEvent.setup(), onChange, validator }; + }; + + test('editing', async () => { + const { user, onChange } = setup(); + await user.click(screen.getByRole('button', { name: 'Add New' })); + await selectEvent.select(screen.getByLabelText('Resources'), [ + 'db', + 'node', + ]); + await selectEvent.select(screen.getByLabelText('Permissions'), [ + 'list', + 'read', + ]); + expect(onChange).toHaveBeenLastCalledWith([ + { + id: expect.any(String), + resources: [ + { label: ResourceKind.Database, value: 'db' }, + { label: ResourceKind.Node, value: 'node' }, + ], + verbs: [ + { label: 'list', value: 'list' }, + { label: 'read', value: 'read' }, + ], + }, + ] as RuleModel[]); + }); - await user.click(screen.getByRole('button', { name: 'Add a Label' })); - await user.type(screen.getByPlaceholderText('label key'), 'os'); - await user.type(screen.getByPlaceholderText('label value'), 'win-xp'); - await selectEvent.create(screen.getByLabelText('Logins'), 'julio', { - createOptionText: 'Login: julio', + test('validation', async () => { + const { user, validator } = setup(); + await user.click(screen.getByRole('button', { name: 'Add New' })); + act(() => validator.validate()); + expect( + screen.getByText('At least one resource kind is required') + ).toBeInTheDocument(); + expect( + screen.getByText('At least one permission is required') + ).toBeInTheDocument(); }); - expect(onChange).toHaveBeenLastCalledWith({ - kind: 'windows_desktop', - labels: [{ name: 'os', value: 'win-xp' }], - logins: [expect.objectContaining({ label: 'julio', value: 'julio' })], - } as WindowsDesktopAccessSpec); }); const reactSelectValueContainer = (input: HTMLInputElement) => diff --git a/web/packages/teleport/src/Roles/RoleEditor/StandardEditor.tsx b/web/packages/teleport/src/Roles/RoleEditor/StandardEditor.tsx index 01789e1f2f837..f17dce9ff179f 100644 --- a/web/packages/teleport/src/Roles/RoleEditor/StandardEditor.tsx +++ b/web/packages/teleport/src/Roles/RoleEditor/StandardEditor.tsx @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -import React, { useState } from 'react'; +import React, { useId, useState } from 'react'; import { Box, ButtonIcon, @@ -28,21 +28,22 @@ import { Text, } from 'design'; import FieldInput from 'shared/components/FieldInput'; -import Validation, { Validator } from 'shared/components/Validation'; -import { requiredField } from 'shared/components/Validation/rules'; +import { useValidation } from 'shared/components/Validation'; +import { + precomputed, + ValidationResult, +} from 'shared/components/Validation/rules'; import * as Icon from 'design/Icon'; -import { HoverTooltip, ToolTipInfo } from 'shared/components/ToolTip'; +import { HoverTooltip, IconTooltip } from 'design/Tooltip'; import styled, { useTheme } from 'styled-components'; - import { MenuButton, MenuItem } from 'shared/components/MenuAction'; - import { FieldSelect, FieldSelectCreatable, } from 'shared/components/FieldSelect'; +import { SlideTabs } from 'design/SlideTabs'; import { Role, RoleWithYaml } from 'teleport/services/resources'; - import { LabelsInput } from 'teleport/components/LabelsInput'; import { FieldMultiInput } from '../../../../shared/components/FieldMultiInput/FieldMultiInput'; @@ -65,7 +66,23 @@ import { AppAccessSpec, DatabaseAccessSpec, WindowsDesktopAccessSpec, + RuleModel, + resourceKindOptions, + verbOptions, + newRuleModel, } from './standardmodel'; +import { + validateRoleEditorModel, + MetadataValidationResult, + AccessSpecValidationResult, + ServerSpecValidationResult, + KubernetesSpecValidationResult, + KubernetesResourceValidationResult, + AppSpecValidationResult, + DatabaseSpecValidationResult, + WindowsDesktopSpecValidationResult, + AccessRuleValidationResult, +} from './validation'; import { EditorSaveCancelButton } from './Shared'; import { RequiresResetToStandard } from './RequiresResetToStandard'; @@ -92,13 +109,30 @@ export const StandardEditor = ({ }: StandardEditorProps) => { const isEditing = !!originalRole; const { roleModel } = standardEditorModel; + const validation = validateRoleEditorModel(roleModel); /** All spec kinds except those that are already in the role. */ const allowedSpecKinds = allAccessSpecKinds.filter(k => roleModel.accessSpecs.every(as => as.kind !== k) ); - function handleSave(validator: Validator) { + enum StandardEditorTab { + Overview, + Resources, + AccessRules, + Options, + } + + const [currentTab, setCurrentTab] = useState(StandardEditorTab.Overview); + const idPrefix = useId(); + const overviewTabId = `${idPrefix}-overview`; + const resourcesTabId = `${idPrefix}-resources`; + const accessRulesTabId = `${idPrefix}-access-rules`; + const optionsTabId = `${idPrefix}-options`; + + const validator = useValidation(); + + function handleSave() { if (!validator.validate()) { return; } @@ -158,103 +192,190 @@ export const StandardEditor = ({ }); } + function setRules(rules: RuleModel[]) { + handleChange({ + ...standardEditorModel.roleModel, + rules, + }); + } + return ( - - {({ validator }) => ( - <> - {roleModel.requiresReset && ( - - )} - - - handleChange({ ...roleModel, metadata })} - /> - {roleModel.accessSpecs.map(spec => ( + <> + {roleModel.requiresReset && ( + + )} + + + !s.valid) + ? validationErrorTabStatus + : undefined, + }, + { + key: StandardEditorTab.AccessRules, + title: 'Access Rules', + controls: accessRulesTabId, + status: + validator.state.validating && + validation.rules.some(s => !s.valid) + ? validationErrorTabStatus + : undefined, + }, + { + key: StandardEditorTab.Options, + title: 'Options', + controls: optionsTabId, + }, + ]} + activeIndex={currentTab} + onChange={setCurrentTab} + /> + +
+ handleChange({ ...roleModel, metadata })} + /> +
+
+ + {roleModel.accessSpecs.map((spec, i) => { + const validationResult = validation.accessSpecs[i]; + return ( setAccessSpec(value)} onRemove={() => removeAccessSpec(spec.kind)} /> - ))} - - - - Add New Specifications - - } - buttonProps={{ - size: 'medium', - fill: 'filled', - disabled: isProcessing || allowedSpecKinds.length === 0, - }} - > - {allowedSpecKinds.map(kind => ( - addAccessSpec(kind)}> - {specSections[kind].title} - - ))} - - - - - handleSave(validator)} - onCancel={onCancel} - disabled={ - isProcessing || - standardEditorModel.roleModel.requiresReset || - !standardEditorModel.isDirty - } - isEditing={isEditing} + ); + })} + + + + Add New Specifications + + } + buttonProps={{ + size: 'medium', + fill: 'filled', + disabled: isProcessing || allowedSpecKinds.length === 0, + }} + > + {allowedSpecKinds.map(kind => ( + addAccessSpec(kind)}> + {specSections[kind].title} + + ))} + + + +
+
+ - - )} - +
+
+ handleSave()} + onCancel={onCancel} + disabled={ + isProcessing || + standardEditorModel.roleModel.requiresReset || + !standardEditorModel.isDirty + } + isEditing={isEditing} + /> + ); }; -export type SectionProps = { - value: T; +export type SectionProps = { + value: Model; isProcessing: boolean; - onChange?(value: T): void; + validation?: ValidationResult; + onChange?(value: Model): void; }; +const validationErrorTabStatus = { + kind: 'danger', + ariaLabel: 'Invalid data', +} as const; + const MetadataSection = ({ value, isProcessing, + validation, onChange, -}: SectionProps) => ( +}: SectionProps) => (
onChange({ ...value, name: e.target.value })} /> ) => { const theme = useTheme(); const [expanded, setExpanded] = useState(true); const ExpandIcon = expanded ? Icon.Minus : Icon.Plus; const expandTooltip = expanded ? 'Collapse' : 'Expand'; + const validator = useValidation(); const handleExpand = (e: React.MouseEvent) => { // Don't let handle the event, we'll do it ourselves to keep @@ -311,7 +435,11 @@ const Section = ({ as="details" open={expanded} border={1} - borderColor={theme.colors.interactive.tonal.neutral[0]} + borderColor={ + validator.state.validating && !validation.valid + ? theme.colors.interactive.solid.danger.default + : theme.colors.interactive.tonal.neutral[0] + } borderRadius={3} >

{title}

- {tooltip && {tooltip}} + {tooltip && {tooltip}}
{removable && ( >; + component: React.ComponentType>; } > = { kube_cluster: { @@ -409,12 +537,16 @@ const specSections: Record< * A generic access spec section. Details are rendered by components from the * `specSections` map. */ -const AccessSpecSection = ({ +const AccessSpecSection = < + T extends AccessSpec, + V extends AccessSpecValidationResult, +>({ value, isProcessing, + validation, onChange, onRemove, -}: SectionProps & { +}: SectionProps & { onRemove?(): void; }) => { const { component: Body, title, tooltip } = specSections[value.kind]; @@ -425,8 +557,14 @@ const AccessSpecSection = ({ onRemove={onRemove} tooltip={tooltip} isProcessing={isProcessing} + validation={validation} > - +
); }; @@ -434,8 +572,9 @@ const AccessSpecSection = ({ export function ServerAccessSpecSection({ value, isProcessing, + validation, onChange, -}: SectionProps) { +}: SectionProps) { return ( <> @@ -445,6 +584,7 @@ export function ServerAccessSpecSection({ disableBtns={isProcessing} labels={value.labels} setLabels={labels => onChange?.({ ...value, labels })} + rule={precomputed(validation.fields.labels)} /> onChange?.({ ...value, logins })} + rule={precomputed(validation.fields.logins)} mt={3} mb={0} /> @@ -467,8 +608,9 @@ export function ServerAccessSpecSection({ export function KubernetesAccessSpecSection({ value, isProcessing, + validation, onChange, -}: SectionProps) { +}: SectionProps) { return ( <> onChange?.({ ...value, labels })} /> @@ -498,6 +641,7 @@ export function KubernetesAccessSpecSection({ onChange?.({ @@ -540,11 +684,13 @@ export function KubernetesAccessSpecSection({ function KubernetesResourceView({ value, + validation, isProcessing, onChange, onRemove, }: { value: KubernetesResourceModel; + validation: KubernetesResourceValidationResult; isProcessing: boolean; onChange(m: KubernetesResourceModel): void; onRemove(): void; @@ -590,6 +736,7 @@ function KubernetesResourceView({ } disabled={isProcessing} value={name} + rule={precomputed(validation.name)} onChange={e => onChange?.({ ...value, name: e.target.value })} /> onChange?.({ ...value, namespace: e.target.value })} /> ) { +}: SectionProps) { return ( @@ -632,6 +781,7 @@ export function AppAccessSpecSection({ disableBtns={isProcessing} labels={value.labels} setLabels={labels => onChange?.({ ...value, labels })} + rule={precomputed(validation.fields.labels)} /> onChange?.({ ...value, awsRoleARNs: arns })} + rule={precomputed(validation.fields.awsRoleARNs)} /> onChange?.({ ...value, azureIdentities: ids })} + rule={precomputed(validation.fields.azureIdentities)} /> onChange?.({ ...value, gcpServiceAccounts: accts })} + rule={precomputed(validation.fields.gcpServiceAccounts)} /> ); @@ -659,8 +812,9 @@ export function AppAccessSpecSection({ export function DatabaseAccessSpecSection({ value, isProcessing, + validation, onChange, -}: SectionProps) { +}: SectionProps) { return ( <> @@ -671,6 +825,7 @@ export function DatabaseAccessSpecSection({ disableBtns={isProcessing} labels={value.labels} setLabels={labels => onChange?.({ ...value, labels })} + rule={precomputed(validation.fields.labels)} /> onChange?.({ ...value, roles })} + rule={precomputed(validation.fields.roles)} mb={0} /> @@ -730,8 +886,9 @@ export function DatabaseAccessSpecSection({ export function WindowsDesktopAccessSpecSection({ value, isProcessing, + validation, onChange, -}: SectionProps) { +}: SectionProps) { return ( <> @@ -742,6 +899,7 @@ export function WindowsDesktopAccessSpecSection({ disableBtns={isProcessing} labels={value.labels} setLabels={labels => onChange?.({ ...value, labels })} + rule={precomputed(validation.fields.labels)} /> ) { + function addRule() { + onChange?.([...value, newRuleModel()]); + } + function setRule(rule: RuleModel) { + onChange?.(value.map(r => (r.id === rule.id ? rule : r))); + } + function removeRule(id: string) { + onChange?.(value.filter(r => r.id !== id)); + } + return ( + + {value.map((rule, i) => ( + removeRule(rule.id)} + /> + ))} + + + Add New + + + ); +} + +function AccessRule({ + value, + isProcessing, + validation, + onChange, + onRemove, +}: SectionProps & { + onRemove?(): void; +}) { + const { resources, verbs } = value; + return ( +
+ onChange?.({ ...value, resources: r })} + rule={precomputed(validation.fields.resources)} + /> + onChange?.({ ...value, verbs: v })} + rule={precomputed(validation.fields.verbs)} + mb={0} + /> +
+ ); +} + export const EditorWrapper = styled(Box)<{ mute?: boolean }>` opacity: ${p => (p.mute ? 0.4 : 1)}; pointer-events: ${p => (p.mute ? 'none' : '')}; diff --git a/web/packages/teleport/src/Roles/RoleEditor/standardmodel.test.ts b/web/packages/teleport/src/Roles/RoleEditor/standardmodel.test.ts index 616e36673bbfe..157eee00c85e3 100644 --- a/web/packages/teleport/src/Roles/RoleEditor/standardmodel.test.ts +++ b/web/packages/teleport/src/Roles/RoleEditor/standardmodel.test.ts @@ -16,7 +16,12 @@ * along with this program. If not, see . */ -import { Role } from 'teleport/services/resources'; +import { + KubernetesResource, + ResourceKind, + Role, + Rule, +} from 'teleport/services/resources'; import { Label as UILabel } from 'teleport/components/LabelsInput/LabelsInput'; @@ -25,6 +30,7 @@ import { Labels } from 'teleport/services/resources'; import { labelsModelToLabels, labelsToModel, + newAccessSpec, RoleEditorModel, roleEditorModelToRole, roleToRoleEditorModel, @@ -37,6 +43,7 @@ const minimalRole = () => const minimalRoleModel = (): RoleEditorModel => ({ metadata: { name: 'foobar' }, accessSpecs: [], + rules: [], requiresReset: false, }); @@ -211,88 +218,217 @@ describe.each<{ name: string; role: Role; model: RoleEditorModel }>([ }); describe('roleToRoleEditorModel', () => { - it('detects unknown fields', () => { - const minRole = minimalRole(); - const roleModelWithReset: RoleEditorModel = { - ...minimalRoleModel(), - requiresReset: true, - }; - - expect(roleToRoleEditorModel(minRole).requiresReset).toEqual(false); - - expect( - roleToRoleEditorModel({ ...minRole, unknownField: 123 } as Role) - ).toEqual(roleModelWithReset); + const minRole = minimalRole(); + const roleModelWithReset: RoleEditorModel = { + ...minimalRoleModel(), + requiresReset: true, + }; + + test.each<{ name: string; role: Role; model?: RoleEditorModel }>([ + { + name: 'unknown fields in Role', + role: { ...minRole, unknownField: 123 } as Role, + }, - expect( - roleToRoleEditorModel({ + { + name: 'unknown fields in metadata', + role: { ...minRole, metadata: { name: 'foobar', unknownField: 123 }, - } as Role) - ).toEqual(roleModelWithReset); + } as Role, + }, - expect( - roleToRoleEditorModel({ + { + name: 'unknown fields in spec', + role: { ...minRole, spec: { ...minRole.spec, unknownField: 123 }, - } as Role) - ).toEqual(roleModelWithReset); + } as Role, + }, - expect( - roleToRoleEditorModel({ + { + name: 'unknown fields in spec.allow', + role: { ...minRole, spec: { ...minRole.spec, allow: { ...minRole.spec.allow, unknownField: 123 }, }, - } as Role) - ).toEqual(roleModelWithReset); + } as Role, + }, - expect( - roleToRoleEditorModel({ + { + name: 'unknown fields in KubernetesResource', + role: { ...minRole, spec: { ...minRole.spec, - deny: { ...minRole.spec.deny, unknownField: 123 }, + allow: { + ...minRole.spec.allow, + kubernetes_resources: [ + { kind: 'job', unknownField: 123 } as KubernetesResource, + ], + }, }, - } as Role) - ).toEqual(roleModelWithReset); + } as Role, + model: { + ...roleModelWithReset, + accessSpecs: [ + { + ...newAccessSpec('kube_cluster'), + resources: [expect.any(Object)], + }, + ], + }, + }, - expect( - roleToRoleEditorModel({ + { + name: 'unsupported resource kind in KubernetesResource', + role: { ...minRole, spec: { ...minRole.spec, - deny: { ...minRole.spec.deny, unknownField: 123 }, + allow: { + ...minRole.spec.allow, + kubernetes_resources: [ + { kind: 'illegal' } as unknown as KubernetesResource, + { kind: 'job' }, + ], + }, }, - } as Role) - ).toEqual(roleModelWithReset); + } as Role, + model: { + ...roleModelWithReset, + accessSpecs: [ + { + ...newAccessSpec('kube_cluster'), + resources: [ + expect.objectContaining({ kind: { value: 'job', label: 'Job' } }), + ], + }, + ], + }, + }, - expect( - roleToRoleEditorModel({ + { + name: 'unsupported verb in KubernetesResource', + role: { ...minRole, spec: { ...minRole.spec, - options: { ...minRole.spec.options, unknownField: 123 }, + allow: { + ...minRole.spec.allow, + kubernetes_resources: [ + { + kind: '*', + verbs: ['illegal', 'get'], + } as unknown as KubernetesResource, + ], + }, }, - } as Role) - ).toEqual(roleModelWithReset); + } as Role, + model: { + ...roleModelWithReset, + accessSpecs: [ + { + ...newAccessSpec('kube_cluster'), + resources: [ + expect.objectContaining({ + verbs: [{ value: 'get', label: 'get' }], + }), + ], + }, + ], + }, + }, - expect( - roleToRoleEditorModel({ + { + name: 'unknown fields in Rule', + role: { ...minRole, spec: { ...minRole.spec, - options: { - ...minRole.spec.options, - idp: { saml: { enabled: true }, unknownField: 123 }, + allow: { + ...minRole.spec.allow, + rules: [{ unknownField: 123 } as Rule], }, }, - } as Role) - ).toEqual(roleModelWithReset); + } as Role, + model: { + ...roleModelWithReset, + rules: [expect.any(Object)], + }, + }, - expect( - roleToRoleEditorModel({ + { + name: 'unsupported resource kind in Rule', + role: { + ...minRole, + spec: { + ...minRole.spec, + allow: { + ...minRole.spec.allow, + rules: [{ resources: ['illegal', 'node'] } as unknown as Rule], + }, + }, + } as Role, + model: { + ...roleModelWithReset, + rules: [ + expect.objectContaining({ + resources: [{ value: 'node', label: 'node' }], + }), + ], + }, + }, + + { + name: 'unsupported verb in Rule', + role: { + ...minRole, + spec: { + ...minRole.spec, + allow: { + ...minRole.spec.allow, + rules: [{ verbs: ['illegal', 'create'] } as unknown as Rule], + }, + }, + } as Role, + model: { + ...roleModelWithReset, + rules: [ + expect.objectContaining({ + verbs: [{ value: 'create', label: 'create' }], + }), + ], + }, + }, + + { + name: 'unknown fields in spec.deny', + role: { + ...minRole, + spec: { + ...minRole.spec, + deny: { ...minRole.spec.deny, unknownField: 123 }, + }, + } as Role, + }, + + { + name: 'unknown fields in spec.options', + role: { + ...minRole, + spec: { + ...minRole.spec, + options: { ...minRole.spec.options, unknownField: 123 }, + }, + } as Role, + }, + + { + name: 'unknown fields in spec.options.idp.saml', + role: { ...minRole, spec: { ...minRole.spec, @@ -301,11 +437,12 @@ describe('roleToRoleEditorModel', () => { idp: { saml: { enabled: true, unknownField: 123 } }, }, }, - } as Role) - ).toEqual(roleModelWithReset); + } as Role, + }, - expect( - roleToRoleEditorModel({ + { + name: 'unknown fields in spec.options.record_session', + role: { ...minRole, spec: { ...minRole.spec, @@ -317,9 +454,14 @@ describe('roleToRoleEditorModel', () => { }, }, }, - } as Role) - ).toEqual(roleModelWithReset); - }); + } as Role, + }, + ])( + 'requires reset because of $name', + ({ role, model = roleModelWithReset }) => { + expect(roleToRoleEditorModel(role)).toEqual(model); + } + ); test('version change requires reset', () => { expect(roleToRoleEditorModel({ ...minimalRole(), version: 'v1' })).toEqual({ @@ -471,6 +613,46 @@ describe('roleToRoleEditorModel', () => { }); }); +it('creates a rule model', () => { + expect( + roleToRoleEditorModel({ + ...minimalRole(), + spec: { + ...minimalRole().spec, + allow: { + rules: [ + { + resources: [ResourceKind.User, ResourceKind.DatabaseService], + verbs: ['read', 'list'], + }, + { resources: [ResourceKind.Lock], verbs: ['create'] }, + ], + }, + }, + }) + ).toEqual({ + ...minimalRoleModel(), + rules: [ + { + id: expect.any(String), + resources: [ + { label: 'user', value: 'user' }, + { label: 'db_service', value: 'db_service' }, + ], + verbs: [ + { label: 'read', value: 'read' }, + { label: 'list', value: 'list' }, + ], + }, + { + id: expect.any(String), + resources: [{ label: 'lock', value: 'lock' }], + verbs: [{ label: 'create', value: 'create' }], + }, + ], + } as RoleEditorModel); +}); + test('labelsToModel', () => { expect(labelsToModel({ foo: 'bar', doubleFoo: ['bar1', 'bar2'] })).toEqual([ { name: 'foo', value: 'bar' }, @@ -562,6 +744,43 @@ describe('roleEditorModelToRole', () => { }, } as Role); }); + + it('converts a rule model', () => { + expect( + roleEditorModelToRole({ + ...minimalRoleModel(), + rules: [ + { + id: 'dummy-id-1', + resources: [ + { label: 'user', value: ResourceKind.User }, + { label: 'db_service', value: ResourceKind.DatabaseService }, + ], + verbs: [ + { label: 'read', value: 'read' }, + { label: 'list', value: 'list' }, + ], + }, + { + id: 'dummy-id-2', + resources: [{ label: 'lock', value: ResourceKind.Lock }], + verbs: [{ label: 'create', value: 'create' }], + }, + ], + }) + ).toEqual({ + ...minimalRole(), + spec: { + ...minimalRole().spec, + allow: { + rules: [ + { resources: ['user', 'db_service'], verbs: ['read', 'list'] }, + { resources: ['lock'], verbs: ['create'] }, + ], + }, + }, + } as Role); + }); }); test('labelsModelToLabels', () => { diff --git a/web/packages/teleport/src/Roles/RoleEditor/standardmodel.ts b/web/packages/teleport/src/Roles/RoleEditor/standardmodel.ts index 8dbb945f55583..6826957c127c2 100644 --- a/web/packages/teleport/src/Roles/RoleEditor/standardmodel.ts +++ b/web/packages/teleport/src/Roles/RoleEditor/standardmodel.ts @@ -17,7 +17,6 @@ */ import { equalsDeep } from 'shared/utils/highbar'; - import { Option } from 'shared/components/Select'; import { @@ -26,8 +25,14 @@ import { Role, RoleConditions, } from 'teleport/services/resources'; - import { Label as UILabel } from 'teleport/components/LabelsInput/LabelsInput'; +import { + KubernetesResourceKind, + KubernetesVerb, + ResourceKind, + Rule, + Verb, +} from 'teleport/services/resources/types'; import { defaultOptions } from './withDefaults'; @@ -47,6 +52,7 @@ export type StandardEditorModel = { export type RoleEditorModel = { metadata: MetadataModel; accessSpecs: AccessSpec[]; + rules: RuleModel[]; /** * Indicates whether the current resource, as described by YAML, is * accurately represented by this editor model. If it's not, the user needs @@ -108,29 +114,6 @@ export type KubernetesResourceModel = { }; type KubernetesResourceKindOption = Option; -type KubernetesResourceKind = - | '*' - | 'pod' - | 'secret' - | 'configmap' - | 'namespace' - | 'service' - | 'serviceaccount' - | 'kube_node' - | 'persistentvolume' - | 'persistentvolumeclaim' - | 'deployment' - | 'replicaset' - | 'statefulset' - | 'daemonset' - | 'clusterrole' - | 'kube_role' - | 'clusterrolebinding' - | 'rolebinding' - | 'cronjob' - | 'job' - | 'certificatesigningrequest' - | 'ingress'; /** * All possible resource kind drop-down options. This array needs to be kept in @@ -171,20 +154,14 @@ export const kubernetesResourceKindOptions: KubernetesResourceKindOption[] = [ ).toSorted((a, b) => a.label.localeCompare(b.label)), ]; -type KubernetesVerbOption = Option; -type KubernetesVerb = - | '*' - | 'get' - | 'create' - | 'update' - | 'patch' - | 'delete' - | 'list' - | 'watch' - | 'deletecollection' - | 'exec' - | 'portforward'; +const optionsToMap = (opts: Option[]) => + new Map(opts.map(o => [o.value, o])); +const kubernetesResourceKindOptionsMap = optionsToMap( + kubernetesResourceKindOptions +); + +type KubernetesVerbOption = Option; /** * All possible Kubernetes verb drop-down options. This array needs to be kept * in sync with `KubernetesVerbs` in `api/types/constants.go. @@ -214,6 +191,33 @@ export const kubernetesVerbOptions: KubernetesVerbOption[] = [ .toSorted((a, b) => a.localeCompare(b)) .map(stringToOption), ]; +const kubernetesVerbOptionsMap = optionsToMap(kubernetesVerbOptions); + +type ResourceKindOption = Option; +export const resourceKindOptions: ResourceKindOption[] = Object.values( + ResourceKind +) + .toSorted() + .map(stringToOption); +const resourceKindOptionsMap = optionsToMap(resourceKindOptions); + +type VerbOption = Option; +export const verbOptions: VerbOption[] = ( + [ + '*', + 'create', + 'create_enroll_token', + 'delete', + 'enroll', + 'list', + 'read', + 'readnosecrets', + 'rotate', + 'update', + 'use', + ] as const +).map(stringToOption); +const verbOptionsMap = optionsToMap(verbOptions); /** Model for the server access specification section. */ export type ServerAccessSpec = AccessSpecBase<'node'> & { @@ -240,6 +244,13 @@ export type WindowsDesktopAccessSpec = AccessSpecBase<'windows_desktop'> & { logins: readonly Option[]; }; +export type RuleModel = { + /** Autogenerated ID to be used with the `key` property. */ + id: string; + resources: readonly ResourceKindOption[]; + verbs: readonly VerbOption[]; +}; + const roleVersion = 'v7'; /** @@ -301,6 +312,14 @@ export function newKubernetesResourceModel(): KubernetesResourceModel { }; } +export function newRuleModel(): RuleModel { + return { + id: crypto.randomUUID(), + resources: [], + verbs: [], + }; +} + /** * Converts a role to its in-editor UI model representation. The resulting * model may be marked as requiring reset if the role contains unsupported @@ -314,11 +333,14 @@ export function roleToRoleEditorModel( // has been left. Therefore, we don't want Lint to warn us that we didn't use // some of the fields. // eslint-disable-next-line @typescript-eslint/no-unused-vars - const { kind, metadata, spec, version, ...rest } = role; - const { name, description, revision, ...mRest } = metadata; - const { allow, deny, options, ...sRest } = spec; - const { accessSpecs, requiresReset: allowRequiresReset } = - roleConditionsToAccessSpecs(allow); + const { kind, metadata, spec, version, ...unsupported } = role; + const { name, description, revision, ...unsupportedMetadata } = metadata; + const { allow, deny, options, ...unsupportedSpecs } = spec; + const { + accessSpecs, + rules, + requiresReset: allowRequiresReset, + } = roleConditionsToModel(allow); return { metadata: { @@ -327,13 +349,14 @@ export function roleToRoleEditorModel( revision: originalRole?.metadata?.revision, }, accessSpecs, + rules, requiresReset: revision !== originalRole?.metadata?.revision || version !== roleVersion || !( - isEmpty(rest) && - isEmpty(mRest) && - isEmpty(sRest) && + isEmpty(unsupported) && + isEmpty(unsupportedMetadata) && + isEmpty(unsupportedSpecs) && isEmpty(deny) && equalsDeep(options, defaultOptions()) ) || @@ -345,10 +368,9 @@ export function roleToRoleEditorModel( * Converts a `RoleConditions` instance (an "allow" or "deny" section, to be * specific) to a list of access specification models. */ -function roleConditionsToAccessSpecs(conditions: RoleConditions): { - accessSpecs: AccessSpec[]; - requiresReset: boolean; -} { +function roleConditionsToModel( + conditions: RoleConditions +): Pick { const { node_labels, logins, @@ -369,7 +391,10 @@ function roleConditionsToAccessSpecs(conditions: RoleConditions): { windows_desktop_labels, windows_desktop_logins, - ...rest + + rules, + + ...unsupportedConditions } = conditions; const accessSpecs: AccessSpec[] = []; @@ -386,7 +411,10 @@ function roleConditionsToAccessSpecs(conditions: RoleConditions): { const kubeGroupsModel = stringsToOptions(kubernetes_groups ?? []); const kubeLabelsModel = labelsToModel(kubernetes_labels); - const kubeResourcesModel = kubernetesResourcesToModel(kubernetes_resources); + const { + model: kubeResourcesModel, + requiresReset: kubernetesResourcesRequireReset, + } = kubernetesResourcesToModel(kubernetes_resources); if (someNonEmpty(kubeGroupsModel, kubeLabelsModel, kubeResourcesModel)) { accessSpecs.push({ kind: 'kube_cluster', @@ -443,9 +471,16 @@ function roleConditionsToAccessSpecs(conditions: RoleConditions): { }); } + const { model: rulesModel, requiresReset: rulesRequireReset } = + rulesToModel(rules); + return { accessSpecs, - requiresReset: !isEmpty(rest), + rules: rulesModel, + requiresReset: + kubernetesResourcesRequireReset || + rulesRequireReset || + !isEmpty(unsupportedConditions), }; } @@ -481,18 +516,69 @@ function stringsToOptions(arr: T[]): Option[] { function kubernetesResourcesToModel( resources: KubernetesResource[] | undefined -): KubernetesResourceModel[] { - return (resources ?? []).map( - ({ kind, name, namespace = '', verbs = [] }) => ({ +): { model: KubernetesResourceModel[]; requiresReset: boolean } { + const result = (resources ?? []).map(kubernetesResourceToModel); + return { + model: result.map(r => r.model).filter(m => m !== undefined), + requiresReset: result.some(r => r.requiresReset), + }; +} + +function kubernetesResourceToModel(res: KubernetesResource): { + model?: KubernetesResourceModel; + requiresReset: boolean; +} { + const { kind, name, namespace = '', verbs = [], ...unsupported } = res; + const kindOption = kubernetesResourceKindOptionsMap.get(kind); + const verbOptions = verbs.map(verb => kubernetesVerbOptionsMap.get(verb)); + const knownVerbOptions = verbOptions.filter(v => v !== undefined); + return { + model: + kindOption !== undefined + ? { + id: crypto.randomUUID(), + kind: kindOption, + name, + namespace, + verbs: knownVerbOptions, + } + : undefined, + requiresReset: + kindOption === undefined || + verbOptions.length !== knownVerbOptions.length || + !isEmpty(unsupported), + }; +} + +function rulesToModel(rules: Rule[]): { + model: RuleModel[]; + requiresReset: boolean; +} { + const result = (rules ?? []).map(ruleToModel); + return { + model: result.map(r => r.model), + requiresReset: result.some(r => r.requiresReset), + }; +} + +function ruleToModel(rule: Rule): { model: RuleModel; requiresReset: boolean } { + const { resources = [], verbs = [], ...unsupported } = rule; + const resourcesModel = resources.map(k => resourceKindOptionsMap.get(k)); + const knownResourcesModel = resourcesModel.filter(m => m !== undefined); + const verbsModel = verbs.map(v => verbOptionsMap.get(v)); + const knownVerbsModel = verbsModel.filter(m => m !== undefined); + const requiresReset = + !isEmpty(unsupported) || + knownResourcesModel.length !== resourcesModel.length || + knownVerbsModel.length !== verbs.length; + return { + model: { id: crypto.randomUUID(), - kind: kubernetesResourceKindOptions.find(o => o.value === kind), - name, - namespace, - verbs: verbs.map(verb => - kubernetesVerbOptions.find(o => o.value === verb) - ), - }) - ); + resources: knownResourcesModel, + verbs: knownVerbsModel, + }, + requiresReset, + }; } function isEmpty(obj: object) { @@ -569,6 +655,13 @@ export function roleEditorModelToRole(roleModel: RoleEditorModel): Role { } } + if (roleModel.rules.length > 0) { + role.spec.allow.rules = roleModel.rules.map(role => ({ + resources: role.resources.map(r => r.value), + verbs: role.verbs.map(v => v.value), + })); + } + return role; } @@ -590,7 +683,7 @@ export function labelsModelToLabels(uiLabels: UILabel[]): Labels { return labels; } -function optionsToStrings(opts: readonly Option[]): string[] { +function optionsToStrings(opts: readonly Option[]): T[] { return opts.map(opt => opt.value); } diff --git a/web/packages/teleport/src/Roles/RoleEditor/validation.ts b/web/packages/teleport/src/Roles/RoleEditor/validation.ts new file mode 100644 index 0000000000000..d7ca5b05f7144 --- /dev/null +++ b/web/packages/teleport/src/Roles/RoleEditor/validation.ts @@ -0,0 +1,182 @@ +/** + * Teleport + * Copyright (C) 2024 Gravitational, Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +import { + arrayOf, + requiredField, + RuleSetValidationResult, + runRules, + ValidationResult, +} from 'shared/components/Validation/rules'; + +import { Option } from 'shared/components/Select'; + +import { KubernetesResourceKind } from 'teleport/services/resources'; + +import { nonEmptyLabels } from 'teleport/components/LabelsInput/LabelsInput'; + +import { + AccessSpec, + KubernetesResourceModel, + MetadataModel, + RoleEditorModel, + RuleModel, +} from './standardmodel'; + +const kubernetesClusterWideResourceKinds: KubernetesResourceKind[] = [ + 'namespace', + 'kube_node', + 'persistentvolume', + 'clusterrole', + 'clusterrolebinding', + 'certificatesigningrequest', +]; + +export function validateRoleEditorModel({ + metadata, + accessSpecs, + rules, +}: RoleEditorModel) { + return { + metadata: validateMetadata(metadata), + accessSpecs: accessSpecs.map(validateAccessSpec), + rules: rules.map(validateAccessRule), + }; +} + +function validateMetadata(model: MetadataModel): MetadataValidationResult { + return runRules(model, metadataRules); +} + +const metadataRules = { name: requiredField('Role name is required') }; +export type MetadataValidationResult = RuleSetValidationResult< + typeof metadataRules +>; + +export function validateAccessSpec( + spec: AccessSpec +): AccessSpecValidationResult { + const { kind } = spec; + switch (kind) { + case 'kube_cluster': + return runRules(spec, kubernetesValidationRules); + case 'node': + return runRules(spec, serverValidationRules); + case 'app': + return runRules(spec, appSpecValidationRules); + case 'db': + return runRules(spec, databaseSpecValidationRules); + case 'windows_desktop': + return runRules(spec, windowsDesktopSpecValidationRules); + default: + kind satisfies never; + } +} + +export type AccessSpecValidationResult = + | ServerSpecValidationResult + | KubernetesSpecValidationResult + | AppSpecValidationResult + | DatabaseSpecValidationResult + | WindowsDesktopSpecValidationResult; + +const validKubernetesResource = (res: KubernetesResourceModel) => () => { + const name = requiredField( + 'Resource name is required, use "*" for any resource' + )(res.name)(); + const namespace = kubernetesClusterWideResourceKinds.includes(res.kind.value) + ? { valid: true } + : requiredField('Namespace is required for resources of this kind')( + res.namespace + )(); + return { + valid: name.valid && namespace.valid, + name, + namespace, + }; +}; +export type KubernetesResourceValidationResult = { + name: ValidationResult; + namespace: ValidationResult; +}; + +const kubernetesValidationRules = { + labels: nonEmptyLabels, + resources: arrayOf(validKubernetesResource), +}; +export type KubernetesSpecValidationResult = RuleSetValidationResult< + typeof kubernetesValidationRules +>; + +const noWildcard = (message: string) => (value: string) => () => { + const valid = value !== '*'; + return { valid, message: valid ? '' : message }; +}; + +const noWildcardOptions = (message: string) => (options: Option[]) => () => { + const valid = options.every(o => o.value !== '*'); + return { valid, message: valid ? '' : message }; +}; + +const serverValidationRules = { + labels: nonEmptyLabels, + logins: noWildcardOptions('Wildcard is not allowed in logins'), +}; +export type ServerSpecValidationResult = RuleSetValidationResult< + typeof serverValidationRules +>; + +const appSpecValidationRules = { + labels: nonEmptyLabels, + awsRoleARNs: arrayOf(noWildcard('Wildcard is not allowed in AWS role ARNs')), + azureIdentities: arrayOf( + noWildcard('Wildcard is not allowed in Azure identities') + ), + gcpServiceAccounts: arrayOf( + noWildcard('Wildcard is not allowed in GCP service accounts') + ), +}; +export type AppSpecValidationResult = RuleSetValidationResult< + typeof appSpecValidationRules +>; + +const databaseSpecValidationRules = { + labels: nonEmptyLabels, + roles: noWildcardOptions('Wildcard is not allowed in database roles'), +}; +export type DatabaseSpecValidationResult = RuleSetValidationResult< + typeof databaseSpecValidationRules +>; + +const windowsDesktopSpecValidationRules = { + labels: nonEmptyLabels, +}; +export type WindowsDesktopSpecValidationResult = RuleSetValidationResult< + typeof windowsDesktopSpecValidationRules +>; + +export const validateAccessRule = (accessRule: RuleModel) => + runRules(accessRule, accessRuleValidationRules); + +const accessRuleValidationRules = { + resources: requiredField('At least one resource kind is required'), + verbs: requiredField('At least one permission is required'), +}; +export type AccessRuleValidationResult = RuleSetValidationResult< + typeof accessRuleValidationRules +>; diff --git a/web/packages/teleport/src/Roles/Roles.tsx b/web/packages/teleport/src/Roles/Roles.tsx index 3bf968247b6ba..2419052bf8db1 100644 --- a/web/packages/teleport/src/Roles/Roles.tsx +++ b/web/packages/teleport/src/Roles/Roles.tsx @@ -184,7 +184,7 @@ export function Roles(props: State) { )} - + {convertAttempt.status === 'processing' && ( . */ -import React from 'react'; import { MemoryRouter, Route, Router } from 'react-router'; import { createMemoryHistory } from 'history'; import { fireEvent, render, screen, waitFor } from 'design/utils/testing'; @@ -89,7 +88,7 @@ describe('teleport/components/Welcome', () => { expect(auth.fetchPasswordToken).toHaveBeenCalled(); }); - expect(screen.getByText(/confirm password/i)).toBeInTheDocument(); + expect(await screen.findByText(/confirm password/i)).toBeInTheDocument(); }); it('should have correct welcome prompt flow for reset', async () => { @@ -123,7 +122,7 @@ describe('teleport/components/Welcome', () => { }); expect(auth.fetchPasswordToken).toHaveBeenCalled(); - expect(screen.getByText(/submit/i)).toBeInTheDocument(); + expect(await screen.findByText(/submit/i)).toBeInTheDocument(); }); it('reset password', async () => { @@ -217,7 +216,7 @@ describe('teleport/components/Welcome', () => { }); // Trigger submit. - await user.click(screen.getByText(/submit/i)); + await user.click(await screen.findByText(/submit/i)); expect(auth.resetPasswordWithWebauthn).toHaveBeenCalledWith( expect.objectContaining({ diff --git a/web/packages/teleport/src/components/ExternalAuditStorageCta/ExternalAuditStorageCta.tsx b/web/packages/teleport/src/components/ExternalAuditStorageCta/ExternalAuditStorageCta.tsx index c8bd62b70cb80..6db1714a2fe41 100644 --- a/web/packages/teleport/src/components/ExternalAuditStorageCta/ExternalAuditStorageCta.tsx +++ b/web/packages/teleport/src/components/ExternalAuditStorageCta/ExternalAuditStorageCta.tsx @@ -25,7 +25,7 @@ import { ButtonPrimary, ButtonSecondary } from 'design/Button'; import Flex from 'design/Flex'; import Text from 'design/Text'; -import { HoverTooltip } from 'shared/components/ToolTip'; +import { HoverTooltip } from 'design/Tooltip'; import cfg from 'teleport/config'; import { IntegrationKind } from 'teleport/services/integrations'; diff --git a/web/packages/teleport/src/components/LabelsInput/LabelsInput.test.tsx b/web/packages/teleport/src/components/LabelsInput/LabelsInput.test.tsx index eaee3b29c7ea6..8f8c07ea95d0c 100644 --- a/web/packages/teleport/src/components/LabelsInput/LabelsInput.test.tsx +++ b/web/packages/teleport/src/components/LabelsInput/LabelsInput.test.tsx @@ -17,7 +17,10 @@ */ import { render, fireEvent, screen } from 'design/utils/testing'; +import Validation, { Validator } from 'shared/components/Validation'; +import { act } from '@testing-library/react'; +import { Label, LabelsInput, LabelsRule, nonEmptyLabels } from './LabelsInput'; import { Default, Custom, @@ -102,3 +105,119 @@ test('removing last label is not possible due to requiring labels', async () => expect(screen.getByPlaceholderText('label key')).toBeInTheDocument(); expect(screen.getByPlaceholderText('label value')).toBeInTheDocument(); }); + +describe('validation rules', () => { + function setup(labels: Label[], rule: LabelsRule) { + let validator: Validator; + render( + + {({ validator: v }) => { + validator = v; + return ( + {}} rule={rule} /> + ); + }} + + ); + return { validator }; + } + + describe.each([ + { name: 'explicitly enforced standard rule', rule: nonEmptyLabels }, + { name: 'implicit standard rule', rule: undefined }, + ])('$name', ({ rule }) => { + test('invalid', () => { + const { validator } = setup( + [ + { name: '', value: 'foo' }, + { name: 'bar', value: '' }, + { name: 'asdf', value: 'qwer' }, + ], + rule + ); + act(() => validator.validate()); + expect(validator.state.valid).toBe(false); + expect(screen.getAllByRole('textbox')[0]).toHaveAccessibleDescription( + 'required' + ); // '' + expect(screen.getAllByRole('textbox')[1]).toHaveAccessibleDescription(''); // 'foo' + expect(screen.getAllByRole('textbox')[2]).toHaveAccessibleDescription(''); // 'bar' + expect(screen.getAllByRole('textbox')[3]).toHaveAccessibleDescription( + 'required' + ); // '' + expect(screen.getAllByRole('textbox')[4]).toHaveAccessibleDescription(''); // 'asdf' + expect(screen.getAllByRole('textbox')[5]).toHaveAccessibleDescription(''); // 'qwer' + }); + + test('valid', () => { + const { validator } = setup( + [ + { name: '', value: 'foo' }, + { name: 'bar', value: '' }, + { name: 'asdf', value: 'qwer' }, + ], + rule + ); + act(() => validator.validate()); + expect(validator.state.valid).toBe(false); + expect(screen.getAllByRole('textbox')[0]).toHaveAccessibleDescription( + 'required' + ); // '' + expect(screen.getAllByRole('textbox')[1]).toHaveAccessibleDescription(''); // 'foo' + expect(screen.getAllByRole('textbox')[2]).toHaveAccessibleDescription(''); // 'bar' + expect(screen.getAllByRole('textbox')[3]).toHaveAccessibleDescription( + 'required' + ); // '' + expect(screen.getAllByRole('textbox')[4]).toHaveAccessibleDescription(''); // 'asdf' + expect(screen.getAllByRole('textbox')[5]).toHaveAccessibleDescription(''); // 'qwer' + }); + }); + + const nameNotFoo: LabelsRule = (labels: Label[]) => () => { + const results = labels.map(label => ({ + name: + label.name === 'foo' + ? { valid: false, message: 'no foo please' } + : { valid: true }, + value: { valid: true }, + })); + return { + valid: results.every(r => r.name.valid && r.value.valid), + results: results, + }; + }; + + test('custom rule, invalid', async () => { + const { validator } = setup( + [ + { name: 'foo', value: 'bar' }, + { name: 'bar', value: 'foo' }, + ], + nameNotFoo + ); + act(() => validator.validate()); + expect(validator.state.valid).toBe(false); + expect(screen.getAllByRole('textbox')[0]).toHaveAccessibleDescription( + 'no foo please' + ); // 'foo' key + expect(screen.getAllByRole('textbox')[1]).toHaveAccessibleDescription(''); + expect(screen.getAllByRole('textbox')[2]).toHaveAccessibleDescription(''); + expect(screen.getAllByRole('textbox')[3]).toHaveAccessibleDescription(''); + }); + + test('custom rule, valid', async () => { + const { validator } = setup( + [ + { name: 'xyz', value: 'bar' }, + { name: 'bar', value: 'foo' }, + ], + nameNotFoo + ); + act(() => validator.validate()); + expect(validator.state.valid).toBe(true); + expect(screen.getAllByRole('textbox')[0]).toHaveAccessibleDescription(''); + expect(screen.getAllByRole('textbox')[1]).toHaveAccessibleDescription(''); + expect(screen.getAllByRole('textbox')[2]).toHaveAccessibleDescription(''); + expect(screen.getAllByRole('textbox')[3]).toHaveAccessibleDescription(''); + }); +}); diff --git a/web/packages/teleport/src/components/LabelsInput/LabelsInput.tsx b/web/packages/teleport/src/components/LabelsInput/LabelsInput.tsx index f163d7df0e0de..eee6025249817 100644 --- a/web/packages/teleport/src/components/LabelsInput/LabelsInput.tsx +++ b/web/packages/teleport/src/components/LabelsInput/LabelsInput.tsx @@ -19,8 +19,17 @@ import styled from 'styled-components'; import { Flex, Box, ButtonSecondary, ButtonIcon } from 'design'; import FieldInput from 'shared/components/FieldInput'; -import { Validator, useValidation } from 'shared/components/Validation'; -import { requiredField } from 'shared/components/Validation/rules'; +import { + Validator, + useRule, + useValidation, +} from 'shared/components/Validation'; +import { + precomputed, + requiredField, + Rule, + ValidationResult, +} from 'shared/components/Validation/rules'; import * as Icons from 'design/Icon'; import { inputGeometry } from 'design/Input/Input'; @@ -34,6 +43,24 @@ export type LabelInputTexts = { placeholder: string; }; +type LabelListValidationResult = ValidationResult & { + /** + * A list of validation results, one per label. Note: items are optional just + * because `useRule` by default returns only `ValidationResult`. For the + * actual validation, it's not optional; if it's undefined, or there are + * fewer items in this list than the labels, a default validation rule will + * be used instead. + */ + results?: LabelValidationResult[]; +}; + +type LabelValidationResult = { + name: ValidationResult; + value: ValidationResult; +}; + +export type LabelsRule = Rule; + export function LabelsInput({ labels = [], setLabels, @@ -44,6 +71,7 @@ export function LabelsInput({ labelKey = { fieldName: 'Key', placeholder: 'label key' }, labelVal = { fieldName: 'Value', placeholder: 'label value' }, inputWidth = 200, + rule = defaultRule, }: { labels: Label[]; setLabels(l: Label[]): void; @@ -57,8 +85,15 @@ export function LabelsInput({ * Makes it so at least one label is required */ areLabelsRequired?: boolean; + /** + * A rule for validating the list of labels as a whole. Note that contrary to + * other input fields, the labels input will default to validating every + * input as required if this property is undefined. + */ + rule?: LabelsRule; }) { const validator = useValidation() as Validator; + const validationResult: LabelListValidationResult = useRule(rule(labels)); function addLabel() { setLabels([...labels, { name: '', value: '' }]); @@ -92,11 +127,8 @@ export function LabelsInput({ setLabels(newList); }; - const requiredUniqueKey = value => () => { + const requiredKey = value => () => { // Check for empty length and duplicate key. - // TODO(bl-nero): This function doesn't really check for uniqueness; it - // needs to be fixed. This control should probably be merged with - // `LabelsCreater`, which has this feature working correctly. let notValid = !value || value.length === 0; return { @@ -121,12 +153,18 @@ export function LabelsInput({ )} {labels.map((label, index) => { + const validationItem: LabelValidationResult | undefined = + validationResult.results?.[index]; return ( () => ({ valid: true }); + const SmallText = styled.span` font-size: ${p => p.theme.fontSizes[1]}px; font-weight: lighter; `; + +export const nonEmptyLabels: LabelsRule = labels => () => { + const results = labels.map(label => ({ + name: requiredField('required')(label.name)(), + value: requiredField('required')(label.value)(), + })); + return { + valid: results.every(r => r.name.valid && r.value.valid), + results: results, + }; +}; diff --git a/web/packages/teleport/src/mocks/contexts.ts b/web/packages/teleport/src/mocks/contexts.ts index d44f57b5da2f1..2d1378f964fd3 100644 --- a/web/packages/teleport/src/mocks/contexts.ts +++ b/web/packages/teleport/src/mocks/contexts.ts @@ -60,6 +60,7 @@ export const allAccessAcl: Acl = { desktopSessionRecordingEnabled: true, directorySharingEnabled: true, reviewRequests: true, + fileTransferAccess: true, license: fullAccess, download: fullAccess, plugins: fullAccess, diff --git a/web/packages/teleport/src/services/audit/makeEvent.ts b/web/packages/teleport/src/services/audit/makeEvent.ts index d1ef126aba40e..1c174e69d9412 100644 --- a/web/packages/teleport/src/services/audit/makeEvent.ts +++ b/web/packages/teleport/src/services/audit/makeEvent.ts @@ -231,6 +231,11 @@ export const formatters: Formatters = { format: ({ user, error }) => `User [${user}] port forwarding request failed: ${error}`, }, + [eventCodes.PORTFORWARD_STOP]: { + type: 'port', + desc: 'Port Forwarding Stopped', + format: ({ user }) => `User [${user}] stopped port forwarding`, + }, [eventCodes.SAML_CONNECTOR_CREATED]: { type: 'saml.created', desc: 'SAML Connector Created', @@ -505,7 +510,20 @@ export const formatters: Formatters = { [eventCodes.SESSION_START]: { type: 'session.start', desc: 'Session Started', - format: ({ user, sid }) => `User [${user}] has started a session [${sid}]`, + format: event => { + const user = event.user || ''; + + if (event.proto === 'kube') { + if (!event.kubernetes_cluster) { + return `User [${user}] has started a Kubernetes session [${event.sid}]`; + } + return `User [${user}] has started a session [${event.sid}] on Kubernetes cluster [${event.kubernetes_cluster}]`; + } + + const node = + event.server_hostname || event.server_addr || event.server_id; + return `User [${user}] has started a session [${event.sid}] on node [${node}] `; + }, }, [eventCodes.SESSION_UPLOAD]: { type: 'session.upload', @@ -1855,6 +1873,20 @@ export const formatters: Formatters = { return `User [${user}] deleted a plugin [${name}]`; }, }, + [eventCodes.CONTACT_CREATE]: { + type: 'contact.create', + desc: 'Contact Created', + format: ({ user, email, contact_type }) => { + return `User [${user}] created a [${contactTypeStr(contact_type)}] contact [${email}]`; + }, + }, + [eventCodes.CONTACT_DELETE]: { + type: 'contact.delete', + desc: 'Contact Deleted', + format: ({ user, email, contact_type }) => { + return `User [${user}] deleted a [${contactTypeStr(contact_type)}] contact [${email}]`; + }, + }, [eventCodes.UNKNOWN]: { type: 'unknown', desc: 'Unknown Event', @@ -1906,3 +1938,14 @@ function formatMembers(members: { member_name: string }[]) { return `${pluralize(memberNames.length, 'member')} [${memberNamesJoined}]`; } + +function contactTypeStr(type: number): string { + switch (type) { + case 1: + return 'Business'; + case 2: + return 'Security'; + default: + return `Unknown type: ${type}`; + } +} diff --git a/web/packages/teleport/src/services/audit/types.ts b/web/packages/teleport/src/services/audit/types.ts index fbcbf635b2bd9..6e232cf5d59d2 100644 --- a/web/packages/teleport/src/services/audit/types.ts +++ b/web/packages/teleport/src/services/audit/types.ts @@ -143,6 +143,7 @@ export const eventCodes = { OIDC_CONNECTOR_DELETED: 'T8101I', OIDC_CONNECTOR_UPDATED: 'T8102I', PORTFORWARD_FAILURE: 'T3003E', + PORTFORWARD_STOP: 'T3003S', PORTFORWARD: 'T3003I', RECOVERY_TOKEN_CREATED: 'T6001I', PRIVILEGE_TOKEN_CREATED: 'T6002I', @@ -303,6 +304,8 @@ export const eventCodes = { PLUGIN_CREATE: 'PG001I', PLUGIN_UPDATE: 'PG002I', PLUGIN_DELETE: 'PG003I', + CONTACT_CREATE: 'TCTC001I', + CONTACT_DELETE: 'TCTC002I', } as const; /** @@ -392,6 +395,7 @@ export type RawEvents = { typeof eventCodes.OIDC_CONNECTOR_UPDATED >; [eventCodes.PORTFORWARD]: RawEvent; + [eventCodes.PORTFORWARD_STOP]: RawEvent; [eventCodes.PORTFORWARD_FAILURE]: RawEvent< typeof eventCodes.PORTFORWARD_FAILURE, { @@ -530,6 +534,11 @@ export type RawEvents = { typeof eventCodes.SESSION_START, { sid: string; + kubernetes_cluster: string; + proto: string; + server_hostname: string; + server_addr: string; + server_id: string; } >; [eventCodes.SESSION_REJECT]: RawEvent< @@ -1715,6 +1724,20 @@ export type RawEvents = { server_hostname: string; } >; + [eventCodes.CONTACT_CREATE]: RawEvent< + typeof eventCodes.CONTACT_CREATE, + { + email: string; + contact_type: number; + } + >; + [eventCodes.CONTACT_DELETE]: RawEvent< + typeof eventCodes.CONTACT_DELETE, + { + email: string; + contact_type: number; + } + >; }; /** diff --git a/web/packages/teleport/src/services/resources/types.ts b/web/packages/teleport/src/services/resources/types.ts index 27047d1c9f0b5..c5a17f313e872 100644 --- a/web/packages/teleport/src/services/resources/types.ts +++ b/web/packages/teleport/src/services/resources/types.ts @@ -83,17 +83,250 @@ export type RoleConditions = { windows_desktop_labels?: Labels; windows_desktop_logins?: string[]; + + rules?: Rule[]; }; export type Labels = Record; export type KubernetesResource = { - kind?: string; + kind?: KubernetesResourceKind; name?: string; namespace?: string; - verbs?: string[]; + verbs?: KubernetesVerb[]; }; +/** + * Supported Kubernetes resource kinds. This type needs to be kept in sync with + * `KubernetesResourcesKinds` in `api/types/constants.go, as well as + * `kubernetesResourceKindOptions` in + * `web/packages/teleport/src/Roles/RoleEditor/standardmodel.ts`. + */ +export type KubernetesResourceKind = + | '*' + | 'pod' + | 'secret' + | 'configmap' + | 'namespace' + | 'service' + | 'serviceaccount' + | 'kube_node' + | 'persistentvolume' + | 'persistentvolumeclaim' + | 'deployment' + | 'replicaset' + | 'statefulset' + | 'daemonset' + | 'clusterrole' + | 'kube_role' + | 'clusterrolebinding' + | 'rolebinding' + | 'cronjob' + | 'job' + | 'certificatesigningrequest' + | 'ingress'; + +/** + * Supported Kubernetes resource verbs. This type needs to be kept in sync with + * `KubernetesVerbs` in `api/types/constants.go, as well as + * `kubernetesVerbOptions` in + * `web/packages/teleport/src/Roles/RoleEditor/standardmodel.ts`. + */ +export type KubernetesVerb = + | '*' + | 'get' + | 'create' + | 'update' + | 'patch' + | 'delete' + | 'list' + | 'watch' + | 'deletecollection' + | 'exec' + | 'portforward'; + +export type Rule = { + resources?: ResourceKind[]; + verbs?: Verb[]; +}; + +export enum ResourceKind { + Wildcard = '*', + + // This list was taken from all of the `Kind*` constants in + // `api/types/constants.go`. Please keep these in sync. + + // Resources backed by objects in the backend database. + AccessGraphSecretAuthorizedKey = 'access_graph_authorized_key', + AccessGraphSecretPrivateKey = 'access_graph_private_key', + AccessGraphSettings = 'access_graph_settings', + AccessList = 'access_list', + AccessListMember = 'access_list_member', + AccessListReview = 'access_list_review', + AccessMonitoringRule = 'access_monitoring_rule', + AccessRequest = 'access_request', + App = 'app', + AppOrSAMLIdPServiceProvider = 'app_server_or_saml_idp_sp', + AppServer = 'app_server', + AuditQuery = 'audit_query', + AuthServer = 'auth_server', + AutoUpdateAgentRollout = 'autoupdate_agent_rollout', + AutoUpdateConfig = 'autoupdate_config', + AutoUpdateVersion = 'autoupdate_version', + Bot = 'bot', + BotInstance = 'bot_instance', + CertAuthority = 'cert_authority', + ClusterAlert = 'cluster_alert', + ClusterAuditConfig = 'cluster_audit_config', + ClusterAuthPreference = 'cluster_auth_preference', + ClusterMaintenanceConfig = 'cluster_maintenance_config', + ClusterName = 'cluster_name', + ClusterNetworkingConfig = 'cluster_networking_config', + ConnectionDiagnostic = 'connection_diagnostic', + CrownJewel = 'crown_jewel', + Database = 'db', + DatabaseObject = 'db_object', + DatabaseObjectImportRule = 'db_object_import_rule', + DatabaseServer = 'db_server', + DatabaseService = 'db_service', + Device = 'device', + DiscoveryConfig = 'discovery_config', + DynamicWindowsDesktop = 'dynamic_windows_desktop', + ExternalAuditStorage = 'external_audit_storage', + GitServer = 'git_server', + // Ignoring duplicate: KindGithub = "github" + GithubConnector = 'github', + GlobalNotification = 'global_notification', + HeadlessAuthentication = 'headless_authentication', + Identity = 'identity', + IdentityCenterAccount = 'aws_ic_account', + IdentityCenterAccountAssignment = 'aws_ic_account_assignment', + IdentityCenterPermissionSet = 'aws_ic_permission_set', + IdentityCenterPrincipalAssignment = 'aws_ic_principal_assignment', + Installer = 'installer', + Instance = 'instance', + Integration = 'integration', + KubeCertificateSigningRequest = 'certificatesigningrequest', + KubeClusterRole = 'clusterrole', + KubeClusterRoleBinding = 'clusterrolebinding', + KubeConfigmap = 'configmap', + KubeCronjob = 'cronjob', + KubeDaemonSet = 'daemonset', + KubeDeployment = 'deployment', + KubeIngress = 'ingress', + KubeJob = 'job', + KubeNamespace = 'namespace', + KubeNode = 'kube_node', + KubePersistentVolume = 'persistentvolume', + KubePersistentVolumeClaim = 'persistentvolumeclaim', + KubePod = 'pod', + KubeReplicaSet = 'replicaset', + KubeRole = 'kube_role', + KubeRoleBinding = 'rolebinding', + KubeSecret = 'secret', + KubeServer = 'kube_server', + KubeService = 'service', + KubeServiceAccount = 'serviceaccount', + KubeStatefulset = 'statefulset', + KubeWaitingContainer = 'kube_ephemeral_container', + KubernetesCluster = 'kube_cluster', + License = 'license', + Lock = 'lock', + LoginRule = 'login_rule', + MFADevice = 'mfa_device', + // Ignoring duplicate: KindNamespace = "namespace" + NetworkRestrictions = 'network_restrictions', + Node = 'node', + Notification = 'notification', + // Ignoring duplicate: KindOIDC = "oidc" + OIDCConnector = 'oidc', + OktaAssignment = 'okta_assignment', + OktaImportRule = 'okta_import_rule', + Plugin = 'plugin', + PluginData = 'plugin_data', + PluginStaticCredentials = 'plugin_static_credentials', + ProvisioningPrincipalState = 'provisioning_principal_state', + Proxy = 'proxy', + RecoveryCodes = 'recovery_codes', + RemoteCluster = 'remote_cluster', + ReverseTunnel = 'tunnel', + Role = 'role', + // Ignoring duplicate: KindSAML = "saml" + SAMLConnector = 'saml', + SAMLIdPServiceProvider = 'saml_idp_service_provider', + SPIFFEFederation = 'spiffe_federation', + SecurityReport = 'security_report', + SecurityReportCostLimiter = 'security_report_cost_limiter', + SecurityReportState = 'security_report_state', + Semaphore = 'semaphore', + ServerInfo = 'server_info', + SessionRecordingConfig = 'session_recording_config', + SessionTracker = 'session_tracker', + State = 'state', + StaticHostUser = 'static_host_user', + StaticTokens = 'static_tokens', + Token = 'token', + TrustedCluster = 'trusted_cluster', + TunnelConnection = 'tunnel_connection', + UIConfig = 'ui_config', + User = 'user', + UserGroup = 'user_group', + UserLastSeenNotification = 'user_last_seen_notification', + UserLoginState = 'user_login_state', + UserNotificationState = 'user_notification_state', + UserTask = 'user_task', + UserToken = 'user_token', + UserTokenSecrets = 'user_token_secrets', + VnetConfig = 'vnet_config', + WatchStatus = 'watch_status', + WebSession = 'web_session', + WebToken = 'web_token', + WindowsDesktop = 'windows_desktop', + WindowsDesktopService = 'windows_desktop_service', + + // Resources that have no actual data representation, but serve for checking + // access to various features. + AccessGraph = 'access_graph', + AccessPluginData = 'access_plugin_data', + AuthConnector = 'auth_connector', + Billing = 'billing', + ClusterConfig = 'cluster_config', + Connectors = 'connectors', + DatabaseCertificate = 'database_certificate', + Download = 'download', + Event = 'event', + GithubRequest = 'github_request', + HostCert = 'host_cert', + IdentityCenter = 'aws_identity_center', + JWT = 'jwt', + OIDCRequest = 'oidc_request', + SAMLRequest = 'saml_request', + SSHSession = 'ssh_session', + Session = 'session', + UnifiedResource = 'unified_resource', + UsageEvent = 'usage_event', + + // For completeness: these kind constants were not included here, as they + // refer to resource subkind names that are not used for access control. + // + // KindAppSession = "app_session" + // KindSAMLIdPSession = "saml_idp_session" + // KindSnowflakeSession = "snowflake_session" +} + +export type Verb = + | '*' + | 'create' + | 'create_enroll_token' + | 'delete' + | 'enroll' + | 'list' + | 'read' + | 'readnosecrets' + | 'rotate' + | 'update' + | 'use'; + /** * Teleport role options in full format, as returned from Teleport API. Note * that its fields follow the snake case convention to match the wire format. diff --git a/web/packages/teleport/src/services/user/makeAcl.ts b/web/packages/teleport/src/services/user/makeAcl.ts index 5fe0a7768cfa5..560add4279e31 100644 --- a/web/packages/teleport/src/services/user/makeAcl.ts +++ b/web/packages/teleport/src/services/user/makeAcl.ts @@ -40,6 +40,11 @@ export function makeAcl(json): Acl { const db = json.db || defaultAccess; const desktops = json.desktops || defaultAccess; const reviewRequests = json.reviewRequests ?? false; + // TODO (avatus) change default to false in v19. We do not want someone + // who _can_ access file transfers to be denied access because an older cluster + // doesn't return the valid permission. If they don't have access, the action will + // still fail with an error, so this is merely a UX improvment. + const fileTransferAccess = json.fileTransferAccess ?? true; // use nullish coalescing to prevent default from overriding a strictly false value const connectionDiagnostic = json.connectionDiagnostic || defaultAccess; // Defaults to true, see RFD 0049 // https://github.com/gravitational/teleport/blob/master/rfd/0049-desktop-clipboard.md#security @@ -115,6 +120,7 @@ export function makeAcl(json): Acl { accessMonitoringRule, discoverConfigs, contacts, + fileTransferAccess, }; } diff --git a/web/packages/teleport/src/services/user/types.ts b/web/packages/teleport/src/services/user/types.ts index 76ea8202d8f35..37239dcd8d34d 100644 --- a/web/packages/teleport/src/services/user/types.ts +++ b/web/packages/teleport/src/services/user/types.ts @@ -108,6 +108,7 @@ export interface Acl { bots: Access; accessMonitoringRule: Access; contacts: Access; + fileTransferAccess: boolean; } // AllTraits represent all the traits defined for a user. diff --git a/web/packages/teleport/src/services/user/user.test.ts b/web/packages/teleport/src/services/user/user.test.ts index d75023f3f7dc4..f734942a9d4fa 100644 --- a/web/packages/teleport/src/services/user/user.test.ts +++ b/web/packages/teleport/src/services/user/user.test.ts @@ -288,6 +288,7 @@ test('undefined values in context response gives proper default values', async ( clipboardSharingEnabled: true, desktopSessionRecordingEnabled: true, directorySharingEnabled: true, + fileTransferAccess: true, }; expect(response).toEqual({ diff --git a/web/packages/teleport/src/services/websession/websession.ts b/web/packages/teleport/src/services/websession/websession.ts index 35f3763fdddfd..a9371db9e060d 100644 --- a/web/packages/teleport/src/services/websession/websession.ts +++ b/web/packages/teleport/src/services/websession/websession.ts @@ -26,9 +26,8 @@ import { KeysEnum, storageService } from 'teleport/services/storageService'; import makeBearerToken from './makeBearerToken'; import { RenewSessionRequest } from './types'; -// Time to determine when to renew session which is -// when expiry time of token is less than 3 minutes. -const RENEW_TOKEN_TIME = 180 * 1000; +const MAX_RENEW_TOKEN_TIME = 180000; // 3m +const MIN_RENEW_TOKEN_TIME = 30000; // 30s const TOKEN_CHECKER_INTERVAL = 15 * 1000; // every 15 sec const logger = Logger.create('services/session'); @@ -146,11 +145,14 @@ const session = { return false; } - // Renew session if token expiry time is less than 3 minutes. + // Renew session if token expiry time is less than renewTime (with MIN_ and + // MAX_RENEW_TOKEN_TIME as floor and ceiling, respectively). // Browsers have js timer throttling behavior in inactive tabs that can go // up to 100s between timer calls from testing. 3 minutes seems to be a safe number // with extra padding. - return this._timeLeft() < RENEW_TOKEN_TIME; + let renewTime = Math.min(this._ttl() / 10, MAX_RENEW_TOKEN_TIME); + renewTime = Math.max(renewTime, MIN_RENEW_TOKEN_TIME); + return this._timeLeft() < renewTime; }, _renewToken(req: RenewSessionRequest = {}, signal?: AbortSignal) { @@ -214,6 +216,21 @@ const session = { return delta; }, + _ttl() { + const token = this._getBearerToken(); + if (!token) { + return 0; + } + + let { expiresIn, created } = token; + if (!created || !expiresIn) { + return 0; + } + + expiresIn = expiresIn * 1000; + return expiresIn; + }, + _shouldCheckStatus() { if (this._getIsRenewing()) { return false; diff --git a/web/packages/teleport/src/stores/storeUserContext.ts b/web/packages/teleport/src/stores/storeUserContext.ts index 878bf68c95405..e50f9fb9d6e61 100644 --- a/web/packages/teleport/src/stores/storeUserContext.ts +++ b/web/packages/teleport/src/stores/storeUserContext.ts @@ -161,6 +161,10 @@ export default class StoreUserContext extends Store { return this.state.acl.samlIdpServiceProvider; } + hasFileTransferAccess() { + return this.state.acl.fileTransferAccess; + } + // hasPrereqAccessToAddAgents checks if user meets the prerequisite // access to add an agent: // - user should be able to create provisioning tokens diff --git a/web/packages/teleterm/src/services/tshd/app.ts b/web/packages/teleterm/src/services/tshd/app.ts index fa4440c54c1d8..1d7c4a5c90c7e 100644 --- a/web/packages/teleterm/src/services/tshd/app.ts +++ b/web/packages/teleterm/src/services/tshd/app.ts @@ -16,7 +16,12 @@ * along with this program. If not, see . */ -import { App, Cluster } from 'teleterm/services/tshd/types'; +import { + App, + PortRange, + RouteToApp, +} from 'gen-proto-ts/teleport/lib/teleterm/v1/app_pb'; +import { Cluster } from 'gen-proto-ts/teleport/lib/teleterm/v1/cluster_pb'; /** Returns a URL that opens the web app in the browser. */ export function getWebAppLaunchUrl({ @@ -108,3 +113,13 @@ export function getAppAddrWithProtocol(source: App): string { return addrWithProtocol; } + +export const formatPortRange = (portRange: PortRange): string => + portRange.endPort === 0 + ? portRange.port.toString() + : `${portRange.port}-${portRange.endPort}`; + +export const publicAddrWithTargetPort = (routeToApp: RouteToApp): string => + routeToApp.targetPort + ? `${routeToApp.publicAddr}:${routeToApp.targetPort}` + : routeToApp.publicAddr; diff --git a/web/packages/teleterm/src/services/tshd/fixtures/mocks.ts b/web/packages/teleterm/src/services/tshd/fixtures/mocks.ts index 8696b36ee532d..8d0fa6999711d 100644 --- a/web/packages/teleterm/src/services/tshd/fixtures/mocks.ts +++ b/web/packages/teleterm/src/services/tshd/fixtures/mocks.ts @@ -101,7 +101,13 @@ export class MockTshClient implements TshdClient { getSuggestedAccessLists = () => new MockedUnaryCall({ accessLists: [] }); promoteAccessRequest = () => new MockedUnaryCall({}); updateTshdEventsServerAddress = () => new MockedUnaryCall({}); - authenticateWebDevice = () => new MockedUnaryCall({}); + authenticateWebDevice = () => + new MockedUnaryCall({ + confirmationToken: { + id: '123456789', + token: '7c8e7438-abe1-4cbc-b3e6-bd233bba967c', + }, + }); startHeadlessWatcher = () => new MockedUnaryCall({}); } diff --git a/web/packages/teleterm/src/services/tshd/testHelpers.ts b/web/packages/teleterm/src/services/tshd/testHelpers.ts index f05ad0c234094..0ad30524df7ed 100644 --- a/web/packages/teleterm/src/services/tshd/testHelpers.ts +++ b/web/packages/teleterm/src/services/tshd/testHelpers.ts @@ -16,7 +16,10 @@ * along with this program. If not, see . */ -import { ShowResources } from 'gen-proto-ts/teleport/lib/teleterm/v1/cluster_pb'; +import { + ACL, + ShowResources, +} from 'gen-proto-ts/teleport/lib/teleterm/v1/cluster_pb'; import { TrustedDeviceRequirement } from 'gen-proto-ts/teleport/legacy/types/trusted_device_requirement_pb'; import * as tsh from './types'; @@ -73,6 +76,7 @@ export const makeApp = (props: Partial = {}): tsh.App => ({ samlApp: false, uri: appUri, awsRoles: [], + tcpPorts: [], ...props, }); @@ -113,6 +117,115 @@ export const makeLeafCluster = ( ...props, }); +export const makeAcl = (props: Partial = {}) => ({ + recordedSessions: { + list: true, + read: true, + edit: true, + create: true, + delete: true, + use: true, + }, + activeSessions: { + list: true, + read: true, + edit: true, + create: true, + delete: true, + use: true, + }, + authConnectors: { + list: true, + read: true, + edit: true, + create: true, + delete: true, + use: true, + }, + roles: { + list: true, + read: true, + edit: true, + create: true, + delete: true, + use: true, + }, + users: { + list: true, + read: true, + edit: true, + create: true, + delete: true, + use: true, + }, + trustedClusters: { + list: true, + read: true, + edit: true, + create: true, + delete: true, + use: true, + }, + events: { + list: true, + read: true, + edit: true, + create: true, + delete: true, + use: true, + }, + tokens: { + list: true, + read: true, + edit: true, + create: true, + delete: true, + use: true, + }, + servers: { + list: true, + read: true, + edit: true, + create: true, + delete: true, + use: true, + }, + apps: { + list: true, + read: true, + edit: true, + create: true, + delete: true, + use: true, + }, + dbs: { + list: true, + read: true, + edit: true, + create: true, + delete: true, + use: true, + }, + kubeservers: { + list: true, + read: true, + edit: true, + create: true, + delete: true, + use: true, + }, + accessRequests: { + list: true, + read: true, + edit: true, + create: true, + delete: true, + use: true, + }, + reviewRequests: true, + ...props, +}); + export const makeLoggedInUser = ( props: Partial = {} ): tsh.LoggedInUser => ({ @@ -120,112 +233,7 @@ export const makeLoggedInUser = ( name: 'alice', isDeviceTrusted: false, trustedDeviceRequirement: TrustedDeviceRequirement.NOT_REQUIRED, - acl: { - recordedSessions: { - list: true, - read: true, - edit: true, - create: true, - delete: true, - use: true, - }, - activeSessions: { - list: true, - read: true, - edit: true, - create: true, - delete: true, - use: true, - }, - authConnectors: { - list: true, - read: true, - edit: true, - create: true, - delete: true, - use: true, - }, - roles: { - list: true, - read: true, - edit: true, - create: true, - delete: true, - use: true, - }, - users: { - list: true, - read: true, - edit: true, - create: true, - delete: true, - use: true, - }, - trustedClusters: { - list: true, - read: true, - edit: true, - create: true, - delete: true, - use: true, - }, - events: { - list: true, - read: true, - edit: true, - create: true, - delete: true, - use: true, - }, - tokens: { - list: true, - read: true, - edit: true, - create: true, - delete: true, - use: true, - }, - servers: { - list: true, - read: true, - edit: true, - create: true, - delete: true, - use: true, - }, - apps: { - list: true, - read: true, - edit: true, - create: true, - delete: true, - use: true, - }, - dbs: { - list: true, - read: true, - edit: true, - create: true, - delete: true, - use: true, - }, - kubeservers: { - list: true, - read: true, - edit: true, - create: true, - delete: true, - use: true, - }, - accessRequests: { - list: true, - read: true, - edit: true, - create: true, - delete: true, - use: true, - }, - }, + acl: makeAcl(), sshLogins: [], roles: [], requestableRoles: [], diff --git a/web/packages/teleterm/src/ui/ClusterConnect/ClusterLogin/ClusterLogin.tsx b/web/packages/teleterm/src/ui/ClusterConnect/ClusterLogin/ClusterLogin.tsx index 72c173ccaf11c..5503a1e243036 100644 --- a/web/packages/teleterm/src/ui/ClusterConnect/ClusterLogin/ClusterLogin.tsx +++ b/web/packages/teleterm/src/ui/ClusterConnect/ClusterLogin/ClusterLogin.tsx @@ -34,6 +34,7 @@ import { PrimaryAuthType } from 'shared/services'; import { AuthSettings } from 'teleterm/ui/services/clusters/types'; import { ClusterConnectReason } from 'teleterm/ui/services/modals'; import { getTargetNameFromUri } from 'teleterm/services/tshd/gateway'; +import { publicAddrWithTargetPort } from 'teleterm/services/tshd/app'; import { outermostPadding } from '../spacing'; @@ -170,7 +171,7 @@ const getTargetDesc = (reason: ClusterConnectReason): React.ReactNode => { } } case 'reason.vnet-cert-expired': { - return {reason.publicAddr}; + return {publicAddrWithTargetPort(reason.routeToApp)}; } default: { reason satisfies never; diff --git a/web/packages/teleterm/src/ui/ClusterConnect/ClusterLogin/ClusterLoginReason.story.tsx b/web/packages/teleterm/src/ui/ClusterConnect/ClusterLogin/ClusterLoginReason.story.tsx index ab6517f4cce67..3c85c93504876 100644 --- a/web/packages/teleterm/src/ui/ClusterConnect/ClusterLogin/ClusterLoginReason.story.tsx +++ b/web/packages/teleterm/src/ui/ClusterConnect/ClusterLogin/ClusterLoginReason.story.tsx @@ -16,10 +16,11 @@ * along with this program. If not, see . */ import { - appUri, + makeApp, makeDatabaseGateway, makeKubeGateway, } from 'teleterm/services/tshd/testHelpers'; +import { routing } from 'teleterm/ui/uri'; import { TestContainer, makeProps } from './storyHelpers'; import { ClusterLoginPresentation } from './ClusterLogin'; @@ -77,12 +78,45 @@ export const GatewayCertExpiredWithoutGateway = () => { }; export const VnetCertExpired = () => { + const app = makeApp(); const props = makeProps(); props.initAttempt.data.allowPasswordless = false; props.reason = { kind: 'reason.vnet-cert-expired', - targetUri: appUri, - publicAddr: 'tcp-app.teleport.example.com', + targetUri: app.uri, + routeToApp: { + name: 'tcp-app', + publicAddr: 'tcp-app.teleport.example.com', + clusterName: routing.parseAppUri(app.uri).params.rootClusterId, + uri: app.endpointUri, + targetPort: 0, + }, + }; + + return ( + + + + ); +}; + +export const VnetCertExpiredMultiPort = () => { + const app = makeApp({ + endpointUri: 'tcp://localhost', + tcpPorts: [{ port: 1337, endPort: 0 }], + }); + const props = makeProps(); + props.initAttempt.data.allowPasswordless = false; + props.reason = { + kind: 'reason.vnet-cert-expired', + targetUri: app.uri, + routeToApp: { + name: 'tcp-app', + publicAddr: 'tcp-app.teleport.example.com', + clusterName: routing.parseAppUri(app.uri).params.rootClusterId, + uri: app.endpointUri, + targetPort: 1337, + }, }; return ( diff --git a/web/packages/teleterm/src/ui/ConnectMyComputer/DocumentConnectMyComputer/Setup.test.tsx b/web/packages/teleterm/src/ui/ConnectMyComputer/DocumentConnectMyComputer/Setup.test.tsx index 849499de392c2..f3c90df14a358 100644 --- a/web/packages/teleterm/src/ui/ConnectMyComputer/DocumentConnectMyComputer/Setup.test.tsx +++ b/web/packages/teleterm/src/ui/ConnectMyComputer/DocumentConnectMyComputer/Setup.test.tsx @@ -22,6 +22,7 @@ import { render, screen, waitFor } from 'design/utils/testing'; import { act } from '@testing-library/react'; import { + makeAcl, makeLoggedInUser, makeRootCluster, makeServer, @@ -116,7 +117,7 @@ function setupAppContext(): { } { const cluster = makeRootCluster({ loggedInUser: makeLoggedInUser({ - acl: { + acl: makeAcl({ tokens: { create: true, list: true, @@ -125,7 +126,7 @@ function setupAppContext(): { delete: true, use: true, }, - }, + }), }), }); const appContext = new MockAppContext({ diff --git a/web/packages/teleterm/src/ui/ConnectMyComputer/access.test.ts b/web/packages/teleterm/src/ui/ConnectMyComputer/access.test.ts index cbe29910e407d..c4a75a5c6c4ab 100644 --- a/web/packages/teleterm/src/ui/ConnectMyComputer/access.test.ts +++ b/web/packages/teleterm/src/ui/ConnectMyComputer/access.test.ts @@ -18,7 +18,7 @@ import { makeRuntimeSettings } from 'teleterm/mainProcess/fixtures/mocks'; import { Platform } from 'teleterm/mainProcess/types'; -import { makeLoggedInUser } from 'teleterm/services/tshd/testHelpers'; +import { makeAcl, makeLoggedInUser } from 'teleterm/services/tshd/testHelpers'; import { ConnectMyComputerAccess, @@ -63,7 +63,7 @@ const testCases: { test.each(testCases)('$name', testCase => { const loggedInUser = makeLoggedInUser({ - acl: { + acl: makeAcl({ tokens: { create: testCase.canCreateToken, edit: false, @@ -72,7 +72,7 @@ test.each(testCases)('$name', testCase => { read: false, delete: false, }, - }, + }), }); const runtimeSettings = makeRuntimeSettings({ platform: testCase.platform }); diff --git a/web/packages/teleterm/src/ui/ConnectMyComputer/connectMyComputerContext.test.tsx b/web/packages/teleterm/src/ui/ConnectMyComputer/connectMyComputerContext.test.tsx index 47f5e9efb4c69..55913e30c231a 100644 --- a/web/packages/teleterm/src/ui/ConnectMyComputer/connectMyComputerContext.test.tsx +++ b/web/packages/teleterm/src/ui/ConnectMyComputer/connectMyComputerContext.test.tsx @@ -26,6 +26,7 @@ import { MockAppContext } from 'teleterm/ui/fixtures/mocks'; import { AgentProcessState } from 'teleterm/mainProcess/types'; import * as resourcesContext from 'teleterm/ui/DocumentCluster/resourcesContext'; import { + makeAcl, makeLoggedInUser, makeRootCluster, makeServer, @@ -49,7 +50,7 @@ beforeAll(() => { function getMocks() { const rootCluster = makeRootCluster({ loggedInUser: makeLoggedInUser({ - acl: { + acl: makeAcl({ tokens: { create: true, edit: false, @@ -58,7 +59,7 @@ function getMocks() { read: false, delete: false, }, - }, + }), }), }); const appContext = new MockAppContext({ diff --git a/web/packages/teleterm/src/ui/DocumentAccessRequests/ReviewAccessRequest/useReviewAccessRequest.ts b/web/packages/teleterm/src/ui/DocumentAccessRequests/ReviewAccessRequest/useReviewAccessRequest.ts index e85b0b278789a..ed0f182ca9c33 100644 --- a/web/packages/teleterm/src/ui/DocumentAccessRequests/ReviewAccessRequest/useReviewAccessRequest.ts +++ b/web/packages/teleterm/src/ui/DocumentAccessRequests/ReviewAccessRequest/useReviewAccessRequest.ts @@ -181,11 +181,13 @@ function getRequestFlags( ? reviewed.state === 'PENDING' : request.state === 'PENDING'; + const canReview = !ownRequest && isPendingState && user.acl.reviewRequests; + return { canAssume, isAssumed, canDelete, - canReview: !ownRequest && isPendingState, + canReview, isPromoted, ownRequest, }; diff --git a/web/packages/teleterm/src/ui/DocumentAuthorizeWebSession/DocumentAuthorizeWebSession.story.tsx b/web/packages/teleterm/src/ui/DocumentAuthorizeWebSession/DocumentAuthorizeWebSession.story.tsx new file mode 100644 index 0000000000000..7b697092f7c62 --- /dev/null +++ b/web/packages/teleterm/src/ui/DocumentAuthorizeWebSession/DocumentAuthorizeWebSession.story.tsx @@ -0,0 +1,90 @@ +/** + * Teleport + * Copyright (C) 2024 Gravitational, Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +import { wait } from 'shared/utils/wait'; + +import { MockAppContextProvider } from 'teleterm/ui/fixtures/MockAppContextProvider'; +import { + makeRootCluster, + makeLoggedInUser, + rootClusterUri, +} from 'teleterm/services/tshd/testHelpers'; +import { MockAppContext } from 'teleterm/ui/fixtures/mocks'; +import { MockWorkspaceContextProvider } from 'teleterm/ui/fixtures/MockWorkspaceContextProvider'; +import * as types from 'teleterm/ui/services/workspacesService'; +import { MockedUnaryCall } from 'teleterm/services/tshd/cloneableClient'; + +import { DocumentAuthorizeWebSession } from './DocumentAuthorizeWebSession'; + +export default { + title: 'Teleterm/DocumentAuthorizeWebSession', +}; + +const doc: types.DocumentAuthorizeWebSession = { + uri: '/docs/e2hyt5', + rootClusterUri: rootClusterUri, + kind: 'doc.authorize_web_session', + title: 'Authorize Web Session', + webSessionRequest: { + redirectUri: '', + token: '', + id: '', + }, +}; + +export function DeviceNotTrusted() { + const rootCluster = makeRootCluster(); + const appContext = new MockAppContext(); + appContext.clustersService.setState(draftState => { + draftState.clusters.set(rootCluster.uri, rootCluster); + }); + return ( + + + + + + ); +} + +export function DeviceTrusted() { + const rootCluster = makeRootCluster({ + loggedInUser: makeLoggedInUser({ isDeviceTrusted: true }), + }); + const appContext = new MockAppContext(); + appContext.clustersService.setState(draftState => { + draftState.clusters.set(rootCluster.uri, rootCluster); + }); + appContext.clustersService.authenticateWebDevice = async () => { + await wait(2_000); + return new MockedUnaryCall({ + confirmationToken: { + id: '123456789', + token: '7c8e7438-abe1-4cbc-b3e6-bd233bba967c', + }, + }); + }; + + return ( + + + + + + ); +} diff --git a/web/packages/teleterm/src/ui/DocumentAuthorizeWebSession/DocumentAuthorizeWebSession.test.tsx b/web/packages/teleterm/src/ui/DocumentAuthorizeWebSession/DocumentAuthorizeWebSession.test.tsx new file mode 100644 index 0000000000000..c06ff109ff93c --- /dev/null +++ b/web/packages/teleterm/src/ui/DocumentAuthorizeWebSession/DocumentAuthorizeWebSession.test.tsx @@ -0,0 +1,105 @@ +/** + * Teleport + * Copyright (C) 2024 Gravitational, Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +import { render, screen } from 'design/utils/testing'; +import userEvent from '@testing-library/user-event'; + +import { MockAppContextProvider } from 'teleterm/ui/fixtures/MockAppContextProvider'; +import { MockWorkspaceContextProvider } from 'teleterm/ui/fixtures/MockWorkspaceContextProvider'; +import { + makeRootCluster, + makeLoggedInUser, + rootClusterUri, +} from 'teleterm/services/tshd/testHelpers'; +import * as types from 'teleterm/ui/services/workspacesService'; +import { MockAppContext } from 'teleterm/ui/fixtures/mocks'; + +import { DocumentAuthorizeWebSession } from './DocumentAuthorizeWebSession'; + +const doc: types.DocumentAuthorizeWebSession = { + uri: '/docs/e2hyt5', + rootClusterUri: rootClusterUri, + kind: 'doc.authorize_web_session', + title: 'Authorize Web Session', + webSessionRequest: { + redirectUri: '', + token: '', + id: '', + }, +}; + +test('authorize button is disabled when device is not trusted', async () => { + const rootCluster = makeRootCluster({ + loggedInUser: makeLoggedInUser({ isDeviceTrusted: false }), + }); + const appContext = new MockAppContext(); + appContext.clustersService.setState(draftState => { + draftState.clusters.set(rootCluster.uri, rootCluster); + }); + + render( + + + + + + ); + + expect(await screen.findByText(/This device is not trusted/)).toBeVisible(); + expect(await screen.findByText(/Authorize Session/)).toBeDisabled(); +}); + +test('authorizing a session opens its URL and closes document', async () => { + jest.spyOn(window, 'open').mockImplementation(); + const rootCluster = makeRootCluster({ + loggedInUser: makeLoggedInUser({ isDeviceTrusted: true }), + }); + const appContext = new MockAppContext(); + appContext.clustersService.setState(draftState => { + draftState.clusters.set(rootCluster.uri, rootCluster); + }); + appContext.workspacesService.setState(draftState => { + draftState.workspaces[rootCluster.uri] = { + localClusterUri: rootCluster.uri, + documents: [doc], + location: undefined, + accessRequests: undefined, + }; + }); + + render( + + + + + + ); + + const button = await screen.findByText(/Authorize Session/); + await userEvent.click(button); + + expect(await screen.findByText(/Session Authorized/)).toBeVisible(); + expect(window.open).toHaveBeenCalledWith( + 'https://teleport-local:3080/webapi/devices/webconfirm?id=123456789&token=7c8e7438-abe1-4cbc-b3e6-bd233bba967c' + ); + expect( + appContext.workspacesService + .getWorkspaceDocumentService(rootCluster.uri) + .getDocuments() + ).toHaveLength(0); +}); diff --git a/web/packages/teleterm/src/ui/DocumentAuthorizeWebSession/DocumentAuthorizeWebSession.tsx b/web/packages/teleterm/src/ui/DocumentAuthorizeWebSession/DocumentAuthorizeWebSession.tsx new file mode 100644 index 0000000000000..461a8de679ae4 --- /dev/null +++ b/web/packages/teleterm/src/ui/DocumentAuthorizeWebSession/DocumentAuthorizeWebSession.tsx @@ -0,0 +1,196 @@ +/** + * Teleport + * Copyright (C) 2024 Gravitational, Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +import { Text, Alert, ButtonPrimary, H1, ButtonText } from 'design'; +import Flex from 'design/Flex'; +import { useAsync, Attempt } from 'shared/hooks/useAsync'; +import { processRedirectUri } from 'shared/redirects'; +import { Cluster } from 'gen-proto-ts/teleport/lib/teleterm/v1/cluster_pb'; +import { DeviceConfirmationToken } from 'gen-proto-ts/teleport/devicetrust/v1/device_confirmation_token_pb'; + +import Document from 'teleterm/ui/Document'; +import { routing } from 'teleterm/ui/uri'; +import { retryWithRelogin } from 'teleterm/ui/utils'; +import { useAppContext } from 'teleterm/ui/appContextProvider'; +import * as types from 'teleterm/ui/services/workspacesService'; +import { WebSessionRequest } from 'teleterm/ui/services/workspacesService'; +import { useWorkspaceContext } from 'teleterm/ui/Documents'; + +export function DocumentAuthorizeWebSession(props: { + doc: types.DocumentAuthorizeWebSession; + visible: boolean; +}) { + const ctx = useAppContext(); + const { documentsService } = useWorkspaceContext(); + const rootCluster = ctx.clustersService.findCluster(props.doc.rootClusterUri); + const [authorizeAttempt, authorize] = useAsync(async () => { + const { + response: { confirmationToken }, + } = await retryWithRelogin(ctx, props.doc.rootClusterUri, () => + ctx.clustersService.authenticateWebDevice( + props.doc.rootClusterUri, + props.doc.webSessionRequest + ) + ); + return confirmationToken; + }); + const clusterName = routing.parseClusterName(props.doc.rootClusterUri); + const canAuthorize = rootCluster.loggedInUser?.isDeviceTrusted; + + async function authorizeAndCloseDocument() { + const [confirmationToken, error] = await authorize(); + if (!error) { + const url = buildAuthorizedSessionUrl( + rootCluster, + props.doc.webSessionRequest, + confirmationToken + ); + // This endpoint verifies the token and "upgrades" the web session and redirects to "/web". + window.open(url); + closeAndNotify(); + } + } + + function openUnauthorizedAndCloseDocument() { + const url = buildUnauthorizedSessionUrl( + rootCluster, + props.doc.webSessionRequest + ); + window.open(url); + closeAndNotify(); + } + + function closeAndNotify() { + documentsService.close(props.doc.uri); + ctx.notificationsService.notifyInfo( + 'Web session has been opened in the browser' + ); + } + + return ( + + +

Authorize Web Session

+ + {/*It's technically possible to open a deep link to authorize a session on a device that is not enrolled.*/} + {!canAuthorize && ( + + To authorize a web session, you must first{' '} + + enroll your device + + . Then log out of Teleport Connect, log back in, and try + again. + + } + > + This device is not trusted + + )} + {authorizeAttempt.status === 'error' && ( + + Could not authorize the session + + )} + + Would you like to authorize a device trust web session for{' '} + {clusterName}? +
+ The session will automatically open in a new browser tab. +
+ + + {getButtonText(authorizeAttempt)} + + + Open Session Without Device Trust + + +
+
+
+ ); +} + +const confirmPath = 'webapi/devices/webconfirm'; + +function buildAuthorizedSessionUrl( + rootCluster: Cluster, + webSessionRequest: WebSessionRequest, + confirmationToken: DeviceConfirmationToken +): string { + const { redirectUri } = webSessionRequest; + + let url = `https://${rootCluster.proxyHost}/${confirmPath}?id=${confirmationToken.id}&token=${confirmationToken.token}`; + if (redirectUri) { + url = `${url}&redirect_uri=${redirectUri}`; + } + return url; +} + +function buildUnauthorizedSessionUrl( + rootCluster: Cluster, + webSessionRequest: WebSessionRequest +): string { + // processedRedirectUri is the path part of the redirectUri. + // Unlike in buildAuthorizedSessionUrl, here we return a full path to open + // instead of including redirection as the `redirect_uri` query parameter. + const processedRedirectUri = processRedirectUri( + webSessionRequest.redirectUri + ); + return `https://${rootCluster.proxyHost}${processedRedirectUri}`; +} + +function getButtonText(attempt: Attempt): string { + switch (attempt.status) { + case '': + case 'error': + return 'Authorize Session'; + case 'processing': + return 'Authorizing Session…'; + case 'success': + return 'Session Authorized'; + } +} diff --git a/web/packages/teleterm/src/ui/DocumentAuthorizeWebSession/index.ts b/web/packages/teleterm/src/ui/DocumentAuthorizeWebSession/index.ts new file mode 100644 index 0000000000000..ffd92d5d17b86 --- /dev/null +++ b/web/packages/teleterm/src/ui/DocumentAuthorizeWebSession/index.ts @@ -0,0 +1,19 @@ +/** + * Teleport + * Copyright (C) 2024 Gravitational, Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +export * from './DocumentAuthorizeWebSession'; diff --git a/web/packages/teleterm/src/ui/DocumentCluster/ActionButtons.story.tsx b/web/packages/teleterm/src/ui/DocumentCluster/ActionButtons.story.tsx index 3b397d9b6093f..30d09f3abc99a 100644 --- a/web/packages/teleterm/src/ui/DocumentCluster/ActionButtons.story.tsx +++ b/web/packages/teleterm/src/ui/DocumentCluster/ActionButtons.story.tsx @@ -18,6 +18,8 @@ import { Flex, Text, Box } from 'design'; +import { Meta } from '@storybook/react'; + import { makeApp, makeRootCluster, @@ -38,41 +40,48 @@ import { AccessRequestButton, } from './ActionButtons'; -export default { - title: 'Teleterm/DocumentCluster/ActionButtons', +type StoryProps = { + vnet: boolean; + lotsOfMenuItems: boolean; }; -export function ActionButtons() { - const appContext = new MockAppContext(); - prepareAppContext(appContext); +const meta: Meta = { + title: 'Teleterm/DocumentCluster/ActionButtons', + component: Buttons, + argTypes: { + vnet: { control: { type: 'boolean' } }, + lotsOfMenuItems: { + control: { type: 'boolean' }, + description: + // TODO(ravicious): Support this prop in more places than just TCP ports. + 'Renders long lists of options in menus. Currently works only with ports for multi-port TCP apps.', + }, + }, + args: { + vnet: true, + lotsOfMenuItems: false, + }, +}; - return ( - - - - - - - - ); -} +export default meta; -export function WithoutVnet() { - const appContext = new MockAppContext({ platform: 'win32' }); +export function Story(props: StoryProps) { + const platform = props.vnet ? 'darwin' : 'win32'; + const appContext = new MockAppContext({ platform }); prepareAppContext(appContext); return ( - + ); } -function Buttons() { +function Buttons(props: StoryProps) { return ( @@ -80,6 +89,10 @@ function Buttons() { TCP app
+ + multi-port TCP app + + Web app @@ -146,6 +159,28 @@ function TcpApp() { ); } +function TcpMultiPortApp(props: { lotsOfMenuItems: boolean }) { + let tcpPorts = [ + { port: 1337, endPort: 0 }, + { port: 4242, endPort: 0 }, + { port: 54221, endPort: 61879 }, + ]; + + if (props.lotsOfMenuItems) { + tcpPorts = new Array(50).fill(tcpPorts).flat(); + } + + return ( + + ); +} + function HttpApp() { return ( + + Available target ports + {props.app.tcpPorts.map((portRange, index) => ( + props.connectWithVnet(portRange.port)} + > + {formatPortRange(portRange)} + + ))} + + ); + } + return ( props.connectWithVnet()} > - Connect to local port + Connect without VNet + {$targetPorts} ); } diff --git a/web/packages/teleterm/src/ui/DocumentCluster/DocumentCluster.story.tsx b/web/packages/teleterm/src/ui/DocumentCluster/DocumentCluster.story.tsx index bfdab4a8309eb..f2472378077d8 100644 --- a/web/packages/teleterm/src/ui/DocumentCluster/DocumentCluster.story.tsx +++ b/web/packages/teleterm/src/ui/DocumentCluster/DocumentCluster.story.tsx @@ -35,6 +35,7 @@ import { makeApp, rootClusterUri, leafClusterUri, + makeAcl, } from 'teleterm/services/tshd/testHelpers'; import { ResourcesService } from 'teleterm/ui/services/resources'; @@ -168,7 +169,7 @@ export const OnlineEmptyResourcesAndCanAddResourcesAndConnectComputer = () => { uri: rootClusterDoc.clusterUri, loggedInUser: makeLoggedInUser({ userType: tsh.LoggedInUser_UserType.LOCAL, - acl: { + acl: makeAcl({ tokens: { create: true, list: true, @@ -177,7 +178,7 @@ export const OnlineEmptyResourcesAndCanAddResourcesAndConnectComputer = () => { read: true, use: true, }, - }, + }), }), }) ); @@ -204,7 +205,7 @@ export const OnlineEmptyResourcesAndCanAddResourcesButCannotConnectComputer = uri: rootClusterDoc.clusterUri, loggedInUser: makeLoggedInUser({ userType: tsh.LoggedInUser_UserType.SSO, - acl: { + acl: makeAcl({ tokens: { create: true, list: true, @@ -213,7 +214,7 @@ export const OnlineEmptyResourcesAndCanAddResourcesButCannotConnectComputer = read: true, use: true, }, - }, + }), }), }) ); @@ -238,7 +239,7 @@ export const OnlineEmptyResourcesAndCannotAddResources = () => { makeRootCluster({ uri: rootClusterDoc.clusterUri, loggedInUser: makeLoggedInUser({ - acl: { + acl: makeAcl({ tokens: { create: false, list: true, @@ -247,7 +248,7 @@ export const OnlineEmptyResourcesAndCannotAddResources = () => { read: true, use: true, }, - }, + }), }), }) ); diff --git a/web/packages/teleterm/src/ui/DocumentCluster/DocumentCluster.test.tsx b/web/packages/teleterm/src/ui/DocumentCluster/DocumentCluster.test.tsx index 095730980aa9a..1c4903d5b59c8 100644 --- a/web/packages/teleterm/src/ui/DocumentCluster/DocumentCluster.test.tsx +++ b/web/packages/teleterm/src/ui/DocumentCluster/DocumentCluster.test.tsx @@ -27,6 +27,7 @@ import { MockWorkspaceContextProvider } from 'teleterm/ui/fixtures/MockWorkspace import { makeRootCluster, makeLoggedInUser, + makeAcl, } from 'teleterm/services/tshd/testHelpers'; import * as tsh from 'teleterm/services/tshd/types'; import { ConnectMyComputerContextProvider } from 'teleterm/ui/ConnectMyComputer'; @@ -50,7 +51,7 @@ it('displays a button for Connect My Computer in the empty state if the user can uri: doc.clusterUri, loggedInUser: makeLoggedInUser({ userType: tsh.LoggedInUser_UserType.LOCAL, - acl: { + acl: makeAcl({ tokens: { create: true, list: true, @@ -59,7 +60,7 @@ it('displays a button for Connect My Computer in the empty state if the user can read: true, use: true, }, - }, + }), }), }) ); @@ -123,7 +124,7 @@ it('does not display a button for Connect My Computer in the empty state if the uri: doc.clusterUri, loggedInUser: makeLoggedInUser({ userType: tsh.LoggedInUser_UserType.LOCAL, - acl: { + acl: makeAcl({ tokens: { create: false, list: true, @@ -132,7 +133,7 @@ it('does not display a button for Connect My Computer in the empty state if the read: true, use: true, }, - }, + }), }), }) ); diff --git a/web/packages/teleterm/src/ui/DocumentTerminal/DocumentTerminal.tsx b/web/packages/teleterm/src/ui/DocumentTerminal/DocumentTerminal.tsx index 503383cbdb651..def77da4ec252 100644 --- a/web/packages/teleterm/src/ui/DocumentTerminal/DocumentTerminal.tsx +++ b/web/packages/teleterm/src/ui/DocumentTerminal/DocumentTerminal.tsx @@ -133,7 +133,12 @@ export function DocumentTerminal(props: { autoFocusDisabled={true} > - + {attempt.status === 'success' && ( ; case 'doc.connect_my_computer': return ; + case 'doc.authorize_web_session': + return ; default: return ( diff --git a/web/packages/teleterm/src/ui/ModalsHost/ModalsHost.tsx b/web/packages/teleterm/src/ui/ModalsHost/ModalsHost.tsx index 3ccb6f6c164ad..ba276907d9037 100644 --- a/web/packages/teleterm/src/ui/ModalsHost/ModalsHost.tsx +++ b/web/packages/teleterm/src/ui/ModalsHost/ModalsHost.tsx @@ -32,7 +32,6 @@ import { assertUnreachable } from '../utils'; import { UsageData } from './modals/UsageData'; import { UserJobRole } from './modals/UserJobRole'; import { ReAuthenticate } from './modals/ReAuthenticate'; -import { AuthenticateWebDevice } from './modals/AuthenticateWebDevice/AuthenticateWebDevice'; import { ChangeAccessRequestKind } from './modals/ChangeAccessRequestKind'; import { AskPin, ChangePin, OverwriteSlot, Touch } from './modals/HardwareKeys'; @@ -87,20 +86,6 @@ function renderDialog({ } switch (dialog.kind) { - case 'device-trust-authorize': { - return ( -